Hi All,
   I am facing a problem accepting SSL connections. I have a simple
multi-threaded SSL web server. For test purposes I have also written 
a simple SSL client. 
   When I open an instance of IE (5.0) or Navigator(4.7),the browser
opens multiple connections with my server (one for each URI) and the
SSL transaction completes successfully. I can also browse other links
over SSL. But when I close the browser and open another instance of
it, the server gets caught in an infinite loop. It keeps getting
SSL_WANT_READ and on reading keeps returning 0 bytes read. The SSL
state dump shows 'SSL_accept: SSLv3 error in read client hello B'. For
connections that get negotiated successfully I see SSL_accept: SSLv3
read client hello A' and other then other correct handshake messages
follow.
But for the problem I cited it keeps saying 'SSL_WANT_READ' and
'SSL_accept: SSLv3 error in read client hello B' continuously in an
infinite loop.
   My own test client is capable of spawning multiple threads,
each of which issues the same set of 'GET' requests and terminates the
connection. It seems to work fine. Only the browsers are giving me a
problem. And also my client works fine with sessionID caching ON or
OFF.

I am unable to understand the reason for this anomaly.
  
I am attaching some code below that does SSL_read. Kindly note that I
do an implicit SSL_accept. 
I call DoSSLRead in response to a read event on the client socket. The
function that calls DoSSLRead
reads n number of bytes from the client and writes them to the web
server module.

// This function is called only when there is data to be received on
the socket.
// DoSSLRead reads data upto a max size of iSize and then returns.
// Returns -1 if failure.
//iSize is the size of data buffer (2K)
int DoSSLRead(SSL *pSSL, char * pData, int iSize, BOOL & bMoreData)
{
    int nBytesRead = 0; //number of bytes read
    int iRet1, iRet2, iRet3;
    bMoreData = FALSE; //Is there more data to be read ??
    while (nBytesRead < iSize)
    {
        iRet1 = SSL_read(pSSL, (pData + nBytesRead), (iSize - nBytesRead)) ;
        if (iRet1 > 0)
        {
            nBytesRead += iRet1;
        }
        iRet2 = SSL_get_error(pSSL,iRet1);
        switch (iRet2) 
        {
            case SSL_ERROR_NONE:
                iRet3 = SSL_pending(pSSL);
                if (iRet3)
                {
                    if (nBytesRead == iSize)
                    {
                        // There is more data pending but
                        // we have filled up the buffer completely.
                        // Indicate to the caller that more
                        // data is available and return.
                        bMoreData = TRUE;
                        return nBytesRead;
                    }
                    else
                    {
                        // There is more data pending and
                        // we still have not filled the buffer
                        // completely so call SSL_read again.
                        continue;
                    }
                }
                else
                {
                    // There is no more data pending.
                    // Return the no. of bytes read.
                    return nBytesRead;
                }
                break;

            case SSL_ERROR_WANT_READ:
                // The data is available but SSL wants us to
                // call SSL_read again. We should call SSL_read
                // but only if we still haven't filled up
                // the buffer.
                if (SSL_in_init(pSSL))
                {
                    if (nBytesRead < iSize)
                    {
                        continue;
                    }
                    else
                    {
                        bMoreData = TRUE;
                        return nBytesRead;
                    }
                }
                else 
                {
                    return nBytesRead;
                }
                break;
            case SSL_ERROR_WANT_WRITE:
                break; 
            case SSL_ERROR_WANT_X509_LOOKUP:
                break;
            case SSL_ERROR_SYSCALL:
                return -1; //terminate the connection
            case SSL_ERROR_SSL:
                return -1; //terminate the connection
            case SSL_ERROR_ZERO_RETURN:
                return -1; //terminate the connection
            default:
                DEBUGMSG("(DoSSLRead): UnHandled iRet2 = %d!!!\n", iRet2);
                return -1; // for now terminate the connection
        }//end of switch
    }//end of while
    return nBytesRead;
} //end of DoSSLRead


I would appreciate very much any help I can get.

Thanks,
Amit.
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [EMAIL PROTECTED]
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to