On Wed, Sep 12, 2007, Jim Marshall wrote:

> I have setup my BIO to be non-blocking in my server. In my server I want 
> to use 'select' to detect when there is a connection available, but for 
> some reason it is not working. either select returns '-1' with errno set 
> to EINTR or select returns 0, but it has not waited for 2 seconds for a 
> connection. Maybe someone can give me an idea what I am doing wrong?
> 
> here is the code I am using:
> 
> void startListening(BIO* sock) {
>       int acceptSock = BIO_get_fd(sock, NULL);
>         int waitVal = 0;
>         fd_set rfds, wfds, efds;
>         struct timeval tv;
>         /* Wait up to two seconds. */
>         tv.tv_sec = 2;
>         tv.tv_usec = 0;
>       /* This is just one of the tests I have tried */
>         FD_ZERO(&rfds);
>         FD_SET(acceptSock, &rfds);
>         FD_ZERO(&wfds);
>         FD_SET(acceptSock, &wfds);
>         FD_ZERO(&rfds);
>         FD_SET(acceptSock, &efds);
>         do {
>               /* see if we have any activity on the socket */
>                 waitVal = select(acceptSock, &rfds, &wfds, &efds, &tv);
>                 if (waitVal < 0)
>                 {
>                     char* err = strerror(errno);
>                     printf("select error: %s\n", err);
>                     fflush(stdout);
>                   return;
>                 } if (waitVal > 0) {
>                       BIO_do_accept(sock)
>                       handleAccept(sock);
>               }
>             } while (waitVal == 0);
> ...
> }
> 
> If I change this code to do a 'BIO_do_accept' and the call 'sleep(1)' 
> when 'BIO_do_accept' returns -1 and errno is EAGAIN it seems to work 
> fine. But that means my server could be sleeping when a request come in.
> 
> Any thoughts?
> 
> Thanks
> Jim
> 
> p.s.
>  The BIO passed into the function above is created like this:
> 
>       ret = BIO_new_accept(hostString);
>         if (ret != NULL)
>         {
>             /* set the accept socket to non-blocking */
>             BIO_set_nbio_accept(ret, 1);
>             /* set sockets created from this accept socket to 
> non-blocking */
>             BIO_set_nbio(ret, 1);
>             BIO_set_bind_mode(ret, BIO_BIND_REUSEADDR);
>             /* bind & listen */
>             val = BIO_do_accept(ret)
> ...
> 
> it is returned to a calling function which in turn calls startListening.
> 

Well you should loop round calling BIO_do_accept() in the startListening()
function and not call it outside. Check the return value and if >0 a
connection has occurred and you can process it.

If <=0 check the status with BIO_should_retry() if that returns 0 some error
has occurred.

If BIO_should_retry() is true get the fd from the BIO and wait for a
connection condition: what you wait for depends on the OS but select (or
similar) for a read condition is typical.

Steve.
--
Dr Stephen N. Henson. Email, S/MIME and PGP keys: see homepage
OpenSSL project core developer and freelance consultant.
Funding needed! Details on homepage.
Homepage: http://www.drh-consultancy.demon.co.uk
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to