BIO & select problem

classic Classic list List threaded Threaded
18 messages Options
Reply | Threaded
Open this post in threaded view
|

BIO & select problem

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

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: BIO & select problem

Dr. Stephen Henson
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                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: BIO & select problem

jim marshall
Dr. Stephen Henson wrote:

> 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                    [hidden email]
> Automated List Manager                           [hidden email]
>
Hi Steve,
  Thanks again for your help. What you suggested is very similar to what
I was doing orginally (although I was using errno and not
BIO_should_retry). When the code is setup as you describe (see code
below) what happens is that the first couple of times the 'select' call
is made it returns with a -1 with errno set to EINTR. If I let it
continue it does this like 4 times and then select 'seems' to start
working, in that it will actually timeout (wait 2 seconds before
returning). However client connections are never detected. For example
if I connect with the openssl command line tool, the tool says

"CONNECTED(00000003)"

But select just continues to return 0 (and the app pauses for 2 seconds
at a time).

void startListening(BIO* sock)
{
     int acceptRet = -1;
     acceptRet = BIO_do_accept(sock);
     if (acceptRet > 0)
     {
         BIO* client = NULL;
         SSL* ssl = NULL;
         client = BIO_pop(sock);
         BIO_set_nbio_accept(client, 1);
         ssl = SSL_new(gCtx);
         if (ssl != NULL)
         {
             SSL_set_bio(ssl, client, client);
             SSL_set_accept_state(ssl);
             starthandler(ssl))
         } else {
             handleSSLError("SSL_startListening");
         }
     } else {
         if (BIO_should_retry(sock) == 0)
         {
             int reason = 0;
             (void) BIO_get_retry_BIO(sock, &reason);
             printf("SSL_startListening: BIO_do_accept returned %d,
error: %s",
            reason, strerror(reason));
         } else {
             int waitVal = 0;
             acceptRet = BIO_get_fd(sock, NULL);
             do {
                 fd_set fds;
                 struct timeval tv;
                 /* Wait up to two seconds. */
                 tv.tv_sec = 2;
                 tv.tv_usec = 0;
                 /* Watch the socket to see when it has input. */
                 FD_ZERO(&fds);
                 FD_SET(acceptRet, &fds);
                 /* see if we have any activity on the socket */
                 waitVal = select(acceptRet, &fds, NULL, NULL, &tv);
                 if (waitVal < 0)
                 {
                     char* err = strerror(errno);
                     printf("select error: %s\n", err);
                     fflush(stdout);
                     if (errno != EINTR) return;
                 }
             } while (waitVal == 0);
         }
     }
}

Note if I change the final else clause to just do a "Sleep(1)" I can
accept connections no problem.

I appreciate any feedback. I'm sure I'm doing something wrong...

Thanks
Jim

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

RE: BIO & select problem

JoelKatz
In reply to this post by jim marshall

> /* 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);

What happens when you pass 'select' fd sets that make sense and set the
first parameter appropriately?

DS


______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: BIO & select problem

Dr. Stephen Henson
In reply to this post by jim marshall
On Wed, Sep 12, 2007, Jim Marshall wrote:

> Hi Steve,
>  Thanks again for your help. What you suggested is very similar to what
> I was doing orginally (although I was using errno and not
> BIO_should_retry). When the code is setup as you describe (see code
> below) what happens is that the first couple of times the 'select' call
> is made it returns with a -1 with errno set to EINTR. If I let it
> continue it does this like 4 times and then select 'seems' to start
> working, in that it will actually timeout (wait 2 seconds before
> returning). However client connections are never detected. For example
> if I connect with the openssl command line tool, the tool says
>
> "CONNECTED(00000003)"
>
> But select just continues to return 0 (and the app pauses for 2 seconds
> at a time).
>

Ah sorry been a while since I've done this kind of stuff. Try making an
initial call to BIO_do_accept() outside the main loop. The first call should
set up the accept BIO and the second one check for an incoming connection.

If that doesn't work I'll check some code I have which does use accept BIOs
and non-blocking I/O in a server application.

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                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: BIO & select problem

Victor Duchovni
In reply to this post by JoelKatz
On Wed, Sep 12, 2007 at 11:48:42PM -0700, David Schwartz wrote:

>
> > /* 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);
>
> What happens when you pass 'select' fd sets that make sense and set the
> first parameter appropriately?

i.e. (acceptSock + 1) not (acceptSock).

--
        Viktor.
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: BIO & select problem

Steve Thompson
On Thu, 13 Sep 2007, Victor Duchovni wrote:

> On Wed, Sep 12, 2007 at 11:48:42PM -0700, David Schwartz wrote:
>
>>
>>> /* 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);
>>
>> What happens when you pass 'select' fd sets that make sense and set the
>> first parameter appropriately?
>
> i.e. (acceptSock + 1) not (acceptSock).

And the FD_xxx inside the select loop?

-steve
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: BIO & select problem

jim marshall
In reply to this post by Dr. Stephen Henson
Dr. Stephen Henson wrote:
>
> Ah sorry been a while since I've done this kind of stuff. Try making an
> initial call to BIO_do_accept() outside the main loop. The first call should
> set up the accept BIO and the second one check for an incoming connection.
No worries!  I appreciate any help. I've been banging my head against
the wall for 5 days now and haven't made any progress, so I don't mind
trying different things.

>
> If that doesn't work I'll check some code I have which does use accept BIOs
> and non-blocking I/O in a server application.
Note sure I follow what you mean here.  I have two functions,
openSSLSocket which sets up the socket, which basically does 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 */
             if (BIO_do_accept(ret) < 0)
... set error and return ret else just return ret ...

Then I have the startListening function which I outlined in my previous
message. So I have a startup type function which does something like
this (not the real code here):
     BIO* theBio = openSSLSocket(hostString);
     ... if no error ...
     startListening(theBio);

Is that not correct?

Thanks again
-Jim

>
> 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                    [hidden email]
> Automated List Manager                           [hidden email]
>

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: BIO & select problem

jim marshall
In reply to this post by JoelKatz


David Schwartz wrote:

>> /* 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);
>
> What happens when you pass 'select' fd sets that make sense and set the
> first parameter appropriately?

Dave,
  I appreciate you taking the time to respond, but I do not follow what
your saying. If I thought what I was doing wasn't sane I wouldn't do it.
  So I'm not sure how to make the code 'sane'?
My original code was just one fd_set for the read case and I passed NULL
for the write and except parameters, but I had the same problem so I
added the write and except cases as a test. Since this is an accept call
that I am trying to make I would expect that all I need is the read
option but since it didn't work I tried something else.
>
> DS
>
>
> ______________________________________________________________________
> OpenSSL Project                                 http://www.openssl.org
> User Support Mailing List                    [hidden email]
> Automated List Manager                           [hidden email]
>

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: BIO & select problem

jim marshall
In reply to this post by Victor Duchovni
Victor Duchovni wrote:

> On Wed, Sep 12, 2007 at 11:48:42PM -0700, David Schwartz wrote:
>
>>> /* 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);
>> What happens when you pass 'select' fd sets that make sense and set the
>> first parameter appropriately?
>
> i.e. (acceptSock + 1) not (acceptSock).
>
Pardon my ignorance, but why do you need to specify acceptSock+1?  I
tried this and it fixed the problem, but I don't understand why.

Thank!

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: BIO & select problem

jim marshall
In reply to this post by Steve Thompson
Steve Thompson wrote:

> On Thu, 13 Sep 2007, Victor Duchovni wrote:
>
>> On Wed, Sep 12, 2007 at 11:48:42PM -0700, David Schwartz wrote:
>>
>>>
>>>>     /* 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);
>>>
>>> What happens when you pass 'select' fd sets that make sense and set the
>>> first parameter appropriately?
>>
>> i.e.    (acceptSock + 1) not (acceptSock).
>
> And the FD_xxx inside the select loop?
DOH!  Good point!!
>
> -steve
> ______________________________________________________________________
> OpenSSL Project                                 http://www.openssl.org
> User Support Mailing List                    
> [hidden email]
> Automated List Manager                          
> [hidden email]
>

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: BIO & select problem

Victor Duchovni
In reply to this post by jim marshall
On Thu, Sep 13, 2007 at 01:08:06PM -0400, Jim Marshall wrote:

> Victor Duchovni wrote:
> >On Wed, Sep 12, 2007 at 11:48:42PM -0700, David Schwartz wrote:
> >
> >>> /* 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);
> >>What happens when you pass 'select' fd sets that make sense and set the
> >>first parameter appropriately?
> >
> >i.e. (acceptSock + 1) not (acceptSock).
> >
> Pardon my ignorance, but why do you need to specify acceptSock+1?  I
> tried this and it fixed the problem, but I don't understand why.

This is described in the select() manpage.

--
        Viktor.
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: BIO & select problem

jim marshall
Victor Duchovni wrote:

> On Thu, Sep 13, 2007 at 01:08:06PM -0400, Jim Marshall wrote:
>
>> Victor Duchovni wrote:
>>> On Wed, Sep 12, 2007 at 11:48:42PM -0700, David Schwartz wrote:
>>>
>>>>> /* 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);
>>>> What happens when you pass 'select' fd sets that make sense and set the
>>>> first parameter appropriately?
>>> i.e. (acceptSock + 1) not (acceptSock).
>>>
>> Pardon my ignorance, but why do you need to specify acceptSock+1?  I
>> tried this and it fixed the problem, but I don't understand why.
>
> This is described in the select() manpage.
>
So it is:
"nfds  is the highest-numbered file descriptor in any of the three sets,
plus 1"

When I read this I didn't realize I had to add one to the socket, I
thought the select call would deal with that :O. Thanks for the insight,
I really appreciate your help!

-Jim

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: BIO & select problem

Victor Duchovni
On Thu, Sep 13, 2007 at 02:09:20PM -0400, Jim Marshall wrote:

> >>Pardon my ignorance, but why do you need to specify acceptSock+1?  I
> >>tried this and it fixed the problem, but I don't understand why.
> >
> >This is described in the select() manpage.
> >
> So it is:
> "nfds  is the highest-numbered file descriptor in any of the three sets,
> plus 1"
>
> When I read this I didn't realize I had to add one to the socket, I
> thought the select call would deal with that :O. Thanks for the insight,
> I really appreciate your help!

You are telling select *how-many* bits of the bitmask to use, not the
highest numbered fd.

--
        Viktor.
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: BIO & select problem

jim marshall
Victor Duchovni wrote:

> On Thu, Sep 13, 2007 at 02:09:20PM -0400, Jim Marshall wrote:
>
>>>> Pardon my ignorance, but why do you need to specify acceptSock+1?  I
>>>> tried this and it fixed the problem, but I don't understand why.
>>> This is described in the select() manpage.
>>>
>> So it is:
>> "nfds  is the highest-numbered file descriptor in any of the three sets,
>> plus 1"
>>
>> When I read this I didn't realize I had to add one to the socket, I
>> thought the select call would deal with that :O. Thanks for the insight,
>> I really appreciate your help!
>
> You are telling select *how-many* bits of the bitmask to use, not the
> highest numbered fd.
>
*scratching head*
  ok, so this confuses me, obviously I'm easily confused :(  in your
previous response you indicated I should use "(acceptRet + 1)". Isn't
'acceptRet' the fd (acceptRet = BIO_get_fd(sock, NULL);)? So should I do
that or use '1' as the first parameter or (acceptRet + 1)?

Thanks, and sorry.
-Jim

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: BIO & select problem

Victor Duchovni
On Thu, Sep 13, 2007 at 02:45:38PM -0400, Jim Marshall wrote:

> >You are telling select *how-many* bits of the bitmask to use, not the
> >highest numbered fd.

I should have said, "one tells select()" not "you are telling select",
sorry. The n+1 usage is correct, because this is the number of bits,
including the bit for fd == 0.

--
        Viktor.
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

RE: BIO & select problem

JoelKatz
In reply to this post by jim marshall

> David Schwartz wrote:
> >> /* 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);
> >
> > What happens when you pass 'select' fd sets that make sense and set the
> > first parameter appropriately?

> Dave,
>   I appreciate you taking the time to respond, but I do not follow what
> your saying. If I thought what I was doing wasn't sane I wouldn't do it.
>   So I'm not sure how to make the code 'sane'?

Since you aren't waiting for any exceptional events, you shouldn't be
passing anything as an exception set. Since this is an accepting socket,
writability doesn't apply.

> My original code was just one fd_set for the read case and I passed NULL
> for the write and except parameters, but I had the same problem so I
> added the write and except cases as a test. Since this is an accept call
> that I am trying to make I would expect that all I need is the read
> option but since it didn't work I tried something else.

When you try something that's like a wild guess at what might possibly be
the issue, you need to *undo* it when it doesn't fix anything. Otherwise
you'll wind up with eight things broken rather than one. Most likely your
whole problem was passing the wrong first number to 'select'.

The first number is the size of the fd sets. If you're interested in file
descriptor 9, you need an fd set of size 10 (slots for fds 0, 1, 2, 3, 4, 5,
6, 7, 8, and 9). So you need to add one to 'acceptSock'.

DS


______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: BIO & select problem

jim marshall
David Schwartz wrote:

>> David Schwartz wrote:
>>>> /* 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);
>>> What happens when you pass 'select' fd sets that make sense and set the
>>> first parameter appropriately?
>
>> Dave,
>>   I appreciate you taking the time to respond, but I do not follow what
>> your saying. If I thought what I was doing wasn't sane I wouldn't do it.
>>   So I'm not sure how to make the code 'sane'?
>
> Since you aren't waiting for any exceptional events, you shouldn't be
> passing anything as an exception set. Since this is an accepting socket,
> writability doesn't apply.
>
>> My original code was just one fd_set for the read case and I passed NULL
>> for the write and except parameters, but I had the same problem so I
>> added the write and except cases as a test. Since this is an accept call
>> that I am trying to make I would expect that all I need is the read
>> option but since it didn't work I tried something else.
>
> When you try something that's like a wild guess at what might possibly be
> the issue, you need to *undo* it when it doesn't fix anything. Otherwise
> you'll wind up with eight things broken rather than one. Most likely your
> whole problem was passing the wrong first number to 'select'.
Your point is well taken, I just cut & pasted the current code instead
of changing it back to the original. The problem was the first parameter
to select, I had mis-read the man page,

Thanks

>
> The first number is the size of the fd sets. If you're interested in file
> descriptor 9, you need an fd set of size 10 (slots for fds 0, 1, 2, 3, 4, 5,
> 6, 7, 8, and 9). So you need to add one to 'acceptSock'.
>
> DS
>
>
> ______________________________________________________________________
> OpenSSL Project                                 http://www.openssl.org
> User Support Mailing List                    [hidden email]
> Automated List Manager                           [hidden email]
>

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]