mainGnuTLS - Support: sr #107464, Secure Connections on AIX using...

 
 

sr #107464: Secure Connections on AIX using non blocking socket

Submitter:  Bjørn Christensen <cybear>
Submitted:  Wed 25 Aug 2010 12:44:30 PM UTC
   
 
Category:  None Priority:  5 - Normal
Severity:  3 - Normal Status:  Wont Do
Privacy:  Public Assigned to:  None
Open/Closed:  Closed Operating System:  *BSD
* Mandatory Fields

Add a New Comment Rich Markup
   

Sat 02 Oct 2010 09:36:04 PM UTC, comment #2: 

I close this because it is an AIX related bug, that we cannot fix in a clean way.

Nikos Mavrogiannopoulos <nmav>
Group administrator
Wed 25 Aug 2010 02:14:44 PM UTC, comment #1: 

If you instead call gnutls_transport_set_lowat() with a value of zero, would it solve your problem? It might be that AIX does not support the MSG_PEEK value to recv().

Nikos Mavrogiannopoulos <nmav>
Group administrator
Wed 25 Aug 2010 12:44:30 PM UTC, original submission:  




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);
}


Bjørn Christensen <cybear>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by nmav (Posted a comment)
  • -email is unavailable- added by cybear (Submitted the item)
  • -email is unavailable- added by cybear (AIX Problem)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only logged-in users can vote.

     

    Follow 3 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2010-10-02 nmav StatusNone Wont Do
        Open/ClosedOpen Closed
    2010-08-25 cybear Carbon-Copy- Added cybear

    Back to the top

    Powered by Savane 3.13-3230.
    Corresponding source code