[sr #107464] Secure Connections on AIX using non blocking socket
Bjørn Christensen
INVALID.NOREPLY at gnu.org
Wed Aug 25 14:44:31 CEST 2010
URL:
<http://savannah.gnu.org/support/?107464>
Summary: Secure Connections on AIX using non blocking socket
Project: GnuTLS
Submitted by: cybear
Submitted on: Wed Aug 25 12:44:30 2010
Category: None
Priority: 5 - Normal
Severity: 3 - Normal
Status: None
Privacy: Public
Assigned to: None
Originator Email:
Open/Closed: Open
Discussion Lock: Any
Operating System: *BSD
_______________________________________________________
Details:
I have a tool that uses GNUTLS and are ported between different platforms
Windows, Linux and AIX. The tool are working on Windows and Linux but causing
problems on AIX.
The behaviour is failing handshake. And from the log file I can see:
READ: -1 returned from b, errno=0 gerrno=0
Comming from line 310 of gnutls_buffers.c and followed by an assertion in
line 329 of gnutls_buffers.c
>From inspecting the code it looks like recv is returning -1 but not setting
the errno. I am uncertain what could cause recv to return result like this. I
am using non-blocking sockets and recv are called with the MSG_PEEK option.
I have made the changes below to make the GNUTLS library complete the
Handshake.
I am changing the err from 0 to EAGAIN
err=err==0?EAGAIN:err; // HACK by BHC
All of the _gnutls_read function below from version (2.10.1)
/* This function is like read. But it does not return -1 on error.
* It does return gnutls_errno instead.
*
* Flags are only used if the default recv() function is being used.
*/
static ssize_t
_gnutls_read (gnutls_session_t session, void *iptr,
size_t sizeOfPtr, int flags)
{
size_t left;
ssize_t i = 0;
char *ptr = iptr;
unsigned j, x, sum = 0;
gnutls_transport_ptr_t fd = session->internals.transport_recv_ptr;
session->internals.direction = 0;
left = sizeOfPtr;
while (left > 0)
{
session->internals.errnum = 0;
if (session->internals._gnutls_pull_func == NULL)
{
i = recv (GNUTLS_POINTER_TO_INT (fd), &ptr[sizeOfPtr - left],
left, flags);
_gnutls_read_log ("BHC: %d returned from %p, errno=%d gerrno=%d\n",
(int) i, fd, errno, session->internals.errnum);
#if HAVE_WINSOCK2_H
if (i < 0)
{
int tmperr = WSAGetLastError ();
switch (tmperr)
{
case WSAEWOULDBLOCK:
session->internals.errnum = EAGAIN;
break;
case WSAEINTR:
session->internals.errnum = EINTR;
break;
default:
session->internals.errnum = EIO;
break;
}
WSASetLastError (tmperr);
}
#endif
}
else
i = session->internals._gnutls_pull_func (fd,
&ptr[sizeOfPtr -
left], left);
if (i < 0)
{
int err = session->internals.errnum ? session->internals.errnum
: errno;
_gnutls_read_log ("READ: %d returned from %p, errno=%d gerrno=%d\n",
(int) i, fd, errno, session->internals.errnum);
err=err==0?EAGAIN:err; // HACK by BHC
if (err == EAGAIN || err == EINTR)
{
if (sizeOfPtr - left > 0)
{
_gnutls_read_log ("READ: returning %d bytes from %p\n",
(int) (sizeOfPtr - left), fd);
goto finish;
}
if (err == EAGAIN)
return GNUTLS_E_AGAIN;
return GNUTLS_E_INTERRUPTED;
}
else
{
gnutls_assert ();
return GNUTLS_E_PULL_ERROR;
}
}
else
{
_gnutls_read_log ("READ: Got %d bytes from %p\n", (int) i, fd);
if (i == 0)
break; /* EOF */
}
left -= i;
}
finish:
if (_gnutls_log_level >= 7)
{
char line[128];
char tmp[16];
_gnutls_read_log ("READ: read %d bytes from %p\n",
(int) (sizeOfPtr - left), fd);
for (x = 0; x < ((sizeOfPtr - left) / 16) + 1; x++)
{
line[0] = 0;
sprintf (tmp, "%.4x - ", x);
_gnutls_str_cat (line, sizeof (line), tmp);
for (j = 0; j < 16; j++)
{
if (sum < (sizeOfPtr - left))
{
sprintf (tmp, "%.2x ", ((unsigned char *) ptr)[sum++]);
_gnutls_str_cat (line, sizeof (line), tmp);
}
}
_gnutls_read_log ("%s\n", line);
}
}
return (sizeOfPtr - left);
}
_______________________________________________________
Reply to this item at:
<http://savannah.gnu.org/support/?107464>
_______________________________________________
Message sent via/by Savannah
http://savannah.gnu.org/
More information about the Gnutls-devel
mailing list