Re: API SSL_Connect fails and always returns SSL_ERROR_WANT_READ causes infinite loop in application

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

As per the suggestion from openssl documentation whenever the SSL API returns SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE, The calling process then must repeat the call after taking appropriate action to satisfy the needs of SSL_connect().

I am copying the code bits here, 

  do
  {
/* Clear openssl error queue */
ERR_clear_error();

/* Initiate SSL Handshake */
aRetValue = SSL_connect(ivSSL);

if (aRetValue <= 0)
{
  aTlsError = SSL_get_error(ivSSL, aRetValue);
  
  switch(aTlsError)
  {
case SSL_ERROR_WANT_READ:  
case SSL_ERROR_WANT_WRITE:
{
  /* Select on the socket for read/write events */
  retry = pollSocketForEvents(aTlsError);            --------------> Function is copied below

  /* Nothing to do, retry to connect again*/
  LOGG_DBUG(Logger::M3UA_LOG,"Link-%d SSL_connect() fails to connect "
  "need to retry, returned error code %d , retry ? %s", ivLink->getLinkId(), aTlsError, retry?"true":"false");
}
break;

case SSL_ERROR_SYSCALL:

if (EWOULDBLOCK == errno || EAGAIN == errno)
{
  /* Nothing to do, retry to connect again */
}
else
{
  int aRet = ERR_get_error_line(&aFile, &aLine);
  
  LOGG_DBUG(Logger::M3UA_LOG,"Link-%d SSL File : %s , Line number : %d , "
"Socket Id %d, Linux Error Code %d",ivLink->getLinkId(), aFile, aLine, getFd(), errno);
  
  LOGG_DBUG(Logger::M3UA_LOG,"Link-%d SSL_connect () :: Result Code : %d ",ivLink->getLinkId(), aTlsError);

  retry = false;
}

break;

default:
{
  int aRet = ERR_get_error_line(&aFile, &aLine);
  
  LOGG_DBUG(Logger::M3UA_LOG,"Link-%d (SSL_connect) Failed to connect to server, "
" Socket Id %d, Return Value %d ", ivLink->getLinkId(), getFd(), aTlsError);
  
  LOGG_DBUG(Logger::M3UA_LOG,"Link-%d SSL File : %s , Line number : %d , Linux Error Code %d",ivLink->getLinkId(), aFile, aLine, errno);

  retry = false;
}
break;
  }    
}
  }while (aRetValue != 1 && retry != false);


bool TlsAssociation::pollSocketForEvents(long aTlsError)
{
/* This function is to implement the SSL Socket call behaviour
  http://jmarshall.com/stuff/handling-nbio-errors-in-openssl.html */
  
fd_set readFds, writeFds;
struct timeval timeout;
int retValue;

int nfds = getFd();

FD_ZERO (&readFds);
FD_ZERO (&writeFds);
FD_SET(nfds, &readFds);
FD_SET(nfds, &writeFds);

/* Wait for 5 Seconds */
timeout.tv_usec = 0;
timeout.tv_sec = 5;

if (SSL_ERROR_WANT_READ == aTlsError)
{
retValue = select(nfds + 1, &readFds, NULL, NULL, &timeout);
if (retValue <= 0)
{
// Timeout or error just return failure
return false;
}
}

if (SSL_ERROR_WANT_WRITE == aTlsError)
{
retValue = select(nfds + 1, NULL, &writeFds, NULL, &timeout);
if (retValue <= 0)
// Timeout or error just return failure
return false;
}
}

return true;
}



Thanks,
Mahesh G S



On Tue, Nov 14, 2017 at 4:01 PM, Graham Leggett <minfrin@xxxxxxxx> wrote:
On 14 Nov 2017, at 12:00 PM, mahesh gs <mahesh116@xxxxxxxxx> wrote:

We have application that provide DTLS security for SCTP connections. During our testing we found that API "SSL_connect " fail and always returns SSL_ERROR_WANT_READ which causes infinite loop in the application.

Are you properly handling that SSL_ERROR_WANT_READ, or are you ignoring it?

The message isn’t an error (the symbol was misnamed), it just means openssl is asking you permission to read. If your code is saying "yes openssl you may read" when you actually aren’t ready you’ll end up in an infinite loop.

Regards,
Graham


--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users


-- 
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux