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

 
 

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

Submitted by:  Bjørn Christensen <cybear>
Submitted on:  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

Add a New Comment (Rich Markup)
   

You are not logged in

Please log in, so followups can be emailed to you.

 

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>
Project 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>
Project 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)
  •  

    Do you think this task is very important?
    If so, you can add your encouragement to it.
    This task has 0 encouragements so far.

    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.7