"Reddie, Steven" wrote:
> 
> [Firstly, I'm working with 0.9.5a, but the relevant 0.9.6 source seems to be
> unchanged.]
> 
> This may be a bigger problem than just my specific case, but here is what
> I've found:
> 
> We are using BIO_do_handshake() to accept socket connections, which results
> in a call to BIO_accept().  Calling BIO_accept() on a non-blocking socket
> with no connections pending results in a fatal error on Win32, but not on
> other platforms.  The reason for this difference seems to be in the
> processing of BIO_sock_should_retry().  This function contains:
> 
> #if defined(WINDOWS) && 0 /* more microsoft stupidity? perhaps not? Ben
> 4/1/99 */
>         if ((i == -1) && (err == 0))
>                 return(1);
> #endif
> 
> In the case that I'm witnessing, the above if-statement evaluates to true.
> So, if the "&& 0" in the #ifdef is removed, the Win32 behaviour is the same
> as on other platforms.  Should the "&& 0" be removed?
> 
> However, the correct solution may be more specific.  At the time that accept
> fails, WSAGetLastError() returns WSAEWOULDBLOCK.  By the time that
> BIO_sock_should_retry() is called, WSAGetLastError() returns 0, which I
> guess is why the above code was added in the first place.  Obviously some
> Win32 call, or socket call, between the accept, and the
> BIO_sock_should_retry() is resetting the error code.
> 
> Any suggestions for the correct way to rectify this situation?
> 

You shouldn't really call BIO_sock_should_retry() you should call
BIO_should_retry() and friends on the accept BIO however...

There definitely seems to be a bug here and not just Win32. I tried a
similar thing under Linux, you get the -1 return value with no pending
connection but none of the retry flags are set. Analysis of the BIO code
suggests it doesn't even implement non blocking semantics for the
underlying accept() call.

I suspect this will need another I/O special condition, like that for
connect. I'll look into it.

Now as to what you should do. You normally call BIO_do_accept() once to
setup the socket and the second call awaits an incoming connection. 

I suspect the only way to be sure of things, until the BIO code is
working properly, is to extract the underlying socket after the initial
BIO_do_accept() then manually process accept() (using select() or
equivalent) until a valid incoming connection is received then wrap the
returned connected socket in a socket BIO.

Steve.
-- 
Dr Stephen N. Henson.   http://www.drh-consultancy.demon.co.uk/
Personal Email: [EMAIL PROTECTED] 
Senior crypto engineer, Celo Communications: http://www.celocom.com/
Core developer of the   OpenSSL project: http://www.openssl.org/
Business Email: [EMAIL PROTECTED] PGP key: via homepage.

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

Reply via email to