Discussion:
BIO_set_nbio_accept functionality
Jim Marshall
2007-08-30 20:26:28 UTC
Permalink
I'm looking at using non-blocking I/O in some places in my code, and I
have a question. The 'BIO_set_nbio_accept' says it will set the
underlying socket to blocking/non-blocking mode, but all the examples
and stuff I see say to use
'BIO_socket_ioctl(SSL_get_fd(ssl),FIONBIO,&sl)'. Can
'BIO_set_nbio_accept' be used to change the state of an SSL socket?

Thank you
Jim

______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users-MCmKBN63+***@public.gmane.org
Automated List Manager majordomo-MCmKBN63+***@public.gmane.org
Jim Marshall
2007-09-03 18:31:16 UTC
Permalink
Post by Jim Marshall
I'm looking at using non-blocking I/O in some places in my code, and I
have a question. The 'BIO_set_nbio_accept' says it will set the
underlying socket to blocking/non-blocking mode, but all the examples
and stuff I see say to use
'BIO_socket_ioctl(SSL_get_fd(ssl),FIONBIO,&sl)'. Can
'BIO_set_nbio_accept' be used to change the state of an SSL socket?
Thank you
Jim
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List
Automated List Manager
No one has a comment on this? Did I miss something in a FAQ or something?

______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users-MCmKBN63+***@public.gmane.org
Automated List Manager majordomo-MCmKBN63+***@public.gmane.org
Jim Fox
2007-09-03 21:18:08 UTC
Permalink
Doesn't need a faq. The man page says the purpose of the
BIO_set_nbio_accept macro is to set blocking or non-blocking mode.
Seems like that's what it will do.

Jim
Post by Jim Marshall
Post by Jim Marshall
I'm looking at using non-blocking I/O in some places in my code,
and I have a question. The 'BIO_set_nbio_accept' says it will set
the underlying socket to blocking/non-blocking mode, but all the
examples and stuff I see say to use 'BIO_socket_ioctl(SSL_get_fd
(ssl),FIONBIO,&sl)'. Can 'BIO_set_nbio_accept' be used to change
the state of an SSL socket?
Thank you
Jim
_____________________________________________________________________
_
OpenSSL Project http://
www.openssl.org
User Support Mailing List openssl-
Automated List Manager
No one has a comment on this? Did I miss something in a FAQ or something?
______________________________________________________________________
OpenSSL Project http://www.openssl.org
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users-MCmKBN63+***@public.gmane.org
Automated List Manager majordomo-MCmKBN63+***@public.gmane.org
Dr. Stephen Henson
2007-09-04 17:17:06 UTC
Permalink
Post by Jim Fox
Doesn't need a faq. The man page says the purpose of the
BIO_set_nbio_accept macro is to set blocking or non-blocking mode.
Seems like that's what it will do.
Jim
Post by Jim Marshall
I'm looking at using non-blocking I/O in some places in my code, and
I have a question. The 'BIO_set_nbio_accept' says it will set the
underlying socket to blocking/non-blocking mode, but all the examples
and stuff I see say to use
'BIO_socket_ioctl(SSL_get_fd(ssl),FIONBIO,&sl)'. Can
'BIO_set_nbio_accept' be used to change the state of an SSL socket?
Thank you
Jim
Yes I know that, but all the examples I have seen do not use this macro.
As an aside I tried using it this past weekend and it did not seem to
work, the socket was not set to non-blocking mode as I expected.
That works on an accept BIO and sets the accept socket to non-blocking mode.

The macro BIO_set_nbio() sets BIOs to non-blocking mode in general. However
note that this only takes place during initialization so if you make the call
after the BIO has been used (e.g. connected or I/O performed) it wont work.

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-MCmKBN63+***@public.gmane.org
Automated List Manager majordomo-MCmKBN63+***@public.gmane.org
Jim Marshall
2007-09-07 15:00:42 UTC
Permalink
Post by Dr. Stephen Henson
Post by Jim Fox
Doesn't need a faq. The man page says the purpose of the
BIO_set_nbio_accept macro is to set blocking or non-blocking mode.
Seems like that's what it will do.
Jim
Post by Jim Marshall
I'm looking at using non-blocking I/O in some places in my code, and
I have a question. The 'BIO_set_nbio_accept' says it will set the
underlying socket to blocking/non-blocking mode, but all the examples
and stuff I see say to use
'BIO_socket_ioctl(SSL_get_fd(ssl),FIONBIO,&sl)'. Can
'BIO_set_nbio_accept' be used to change the state of an SSL socket?
Thank you
Jim
Yes I know that, but all the examples I have seen do not use this macro.
As an aside I tried using it this past weekend and it did not seem to
work, the socket was not set to non-blocking mode as I expected.
That works on an accept BIO and sets the accept socket to non-blocking mode.
The macro BIO_set_nbio() sets BIOs to non-blocking mode in general. However
note that this only takes place during initialization so if you make the call
after the BIO has been used (e.g. connected or I/O performed) it wont work.
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
Thanks for the feedback, but the BIO_set_nbio still doesn't seem to
work. Here is what I am doing. I have a function which creates the
accept BIO and calls BIO_set_nbio as follows (this is obviously trimmed
down from my actual function):

BIO* ret = BIO_new_accept(hostString);
if (ret != NULL)
{
BIO_set_nbio(ret, 1); // This returns 1??
BIO_set_bind_mode(ret, BIO_BIND_REUSEADDR);
/* bind & listen */
if (BIO_do_accept(ret) > 0)
{
return ret;
}
...

now in my elsewhere in the program I have a 'startlistening' function
which does the following:

acceptRet = BIO_do_accept(sock);
if (acceptRet > 0)
{
BIO* client = NULL;
SSL* ssl = NULL;
client = BIO_pop(sock);
ssl = SSL_new(gCtx);
...

I would expect that the BIO_do_accept would return immediately if there
was no connections waiting. It does not.

Any thoughts on what I am doing wrong?

Thanks
Jim

______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users-MCmKBN63+***@public.gmane.org
Automated List Manager majordomo-MCmKBN63+***@public.gmane.org
Jim Fox
2007-09-07 15:20:47 UTC
Permalink
Use "BIO_set_nbio_accept" and this will work as you want it to.

Jim
Post by Jim Marshall
Thanks for the feedback, but the BIO_set_nbio still doesn't seem to
work. Here is what I am doing. I have a function which creates the
accept BIO and calls BIO_set_nbio as follows (this is obviously
BIO* ret = BIO_new_accept(hostString);
if (ret != NULL)
{
BIO_set_nbio(ret, 1); // This returns 1??
BIO_set_bind_mode(ret, BIO_BIND_REUSEADDR);
/* bind & listen */
if (BIO_do_accept(ret) > 0)
{
return ret;
}
...
now in my elsewhere in the program I have a 'startlistening'
acceptRet = BIO_do_accept(sock);
if (acceptRet > 0)
{
BIO* client = NULL;
SSL* ssl = NULL;
client = BIO_pop(sock);
ssl = SSL_new(gCtx);
...
I would expect that the BIO_do_accept would return immediately if
there was no connections waiting. It does not.
Any thoughts on what I am doing wrong?
Thanks
Jim
______________________________________________________________________
OpenSSL Project http://www.openssl.org
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users-MCmKBN63+***@public.gmane.org
Automated List Manager majordomo-MCmKBN63+***@public.gmane.org
Jim Marshall
2007-09-07 17:56:10 UTC
Permalink
Post by Jim Fox
Use "BIO_set_nbio_accept" and this will work as you want it to.
Jim
Arg, thanks Jim - somewhere along the line I mixed that up! Changing to
that causes the BIO_do_accept call to not block. Although BIO_do_accept
returns -1 and errno is set to EAGAIN, the SSL_get_error() function
returns SSL_ERROR_NONE. is that expected?

So beyond the BIO_do_accept, I used the openssl client program to
connect to my server. I was expecting the above to make all the sockets
non-blocking, but when I called SSL_read in my code it seems to block
for data. I tried using the BIO_set_nbio an BIO_set_nbio_accept calls
but no joy.

Basically i am trying to make all the socket calls non-blocking, what am
I missing?

Thanks again
-Jim

______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users-MCmKBN63+***@public.gmane.org
Automated List Manager majordomo-MCmKBN63+***@public.gmane.org
Dr. Stephen Henson
2007-09-07 18:33:26 UTC
Permalink
Post by Jim Marshall
Post by Jim Fox
Use "BIO_set_nbio_accept" and this will work as you want it to.
Jim
Arg, thanks Jim - somewhere along the line I mixed that up! Changing to
that causes the BIO_do_accept call to not block. Although BIO_do_accept
returns -1 and errno is set to EAGAIN, the SSL_get_error() function
returns SSL_ERROR_NONE. is that expected?
So beyond the BIO_do_accept, I used the openssl client program to
connect to my server. I was expecting the above to make all the sockets
non-blocking, but when I called SSL_read in my code it seems to block
for data. I tried using the BIO_set_nbio an BIO_set_nbio_accept calls
but no joy.
Basically i am trying to make all the socket calls non-blocking, what am
I missing?
Have you called BIO_set_nbio() on the accept BIO as well?

BIO_set_nbio_accept() makes the accept BIO non blocking so waiting for an
incoming connection does not block.

BIO_set_nbio() makes all subsequent connected BIOs non-blocking.

The SSL_get_error() calls return depends on where you called it. If the BIO
doesn't have an associated SSL structure then the BIO_should_retry() and calls
should be used instead.

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-MCmKBN63+***@public.gmane.org
Automated List Manager majordomo-MCmKBN63+***@public.gmane.org
Jim Marshall
2007-09-07 19:23:45 UTC
Permalink
Post by Dr. Stephen Henson
Post by Jim Marshall
Post by Jim Fox
Use "BIO_set_nbio_accept" and this will work as you want it to.
Jim
Arg, thanks Jim - somewhere along the line I mixed that up! Changing to
that causes the BIO_do_accept call to not block. Although BIO_do_accept
returns -1 and errno is set to EAGAIN, the SSL_get_error() function
returns SSL_ERROR_NONE. is that expected?
So beyond the BIO_do_accept, I used the openssl client program to
connect to my server. I was expecting the above to make all the sockets
non-blocking, but when I called SSL_read in my code it seems to block
for data. I tried using the BIO_set_nbio an BIO_set_nbio_accept calls
but no joy.
Basically i am trying to make all the socket calls non-blocking, what am
I missing?
Have you called BIO_set_nbio() on the accept BIO as well?
BIO_set_nbio_accept() makes the accept BIO non blocking so waiting for an
incoming connection does not block.
BIO_set_nbio() makes all subsequent connected BIOs non-blocking.
The SSL_get_error() calls return depends on where you called it. If the BIO
doesn't have an associated SSL structure then the BIO_should_retry() and calls
should be used instead.
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
Thanks for the feedback, unfortunately I don't fully follow you.

In my code I have a 'opensocket' function in which I do this:

ret = BIO_new_accept(hostString);
if (ret != NULL)
{
BIO_set_nbio_accept(ret, 1);
BIO_set_bind_mode(ret, BIO_BIND_REUSEADDR);
/* bind & listen */
if (BIO_do_accept(ret) < 0)
...

Then i have a function called 'startListening" which I do the following:

acceptRet = BIO_do_accept(sock);
if (acceptRet > 0)
{
BIO* client = NULL;
SSL* ssl = NULL;
client = BIO_pop(sock);
// also tried BIO_set_nbio_accept on the line below
BIO_set_nbio(client, 1);
BIO_set_nbio_accept(client, 1);
ssl = SSL_new(gCtx);
if (ssl != NULL)
{
SSL_set_bio(ssl, client, client);
SSL_set_accept_state(ssl);
...

Am I placing the call in the wrong place?

Thanks

______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users-MCmKBN63+***@public.gmane.org
Automated List Manager majordomo-MCmKBN63+***@public.gmane.org
Dr. Stephen Henson
2007-09-07 20:09:43 UTC
Permalink
Post by Jim Marshall
Thanks for the feedback, unfortunately I don't fully follow you.
ret = BIO_new_accept(hostString);
if (ret != NULL)
{
BIO_set_nbio_accept(ret, 1);
BIO_set_bind_mode(ret, BIO_BIND_REUSEADDR);
/* bind & listen */
if (BIO_do_accept(ret) < 0)
...
acceptRet = BIO_do_accept(sock);
if (acceptRet > 0)
{
BIO* client = NULL;
SSL* ssl = NULL;
client = BIO_pop(sock);
// also tried BIO_set_nbio_accept on the line below
BIO_set_nbio(client, 1);
BIO_set_nbio_accept(client, 1);
ssl = SSL_new(gCtx);
if (ssl != NULL)
{
SSL_set_bio(ssl, client, client);
SSL_set_accept_state(ssl);
...
Am I placing the call in the wrong place?
Add a call BIO_set_nbio(ret, 1) after the call to BIO_set_nbio_accept() in the
"opensocket" function.

You shouldn't need the other BIO_set_nbio() calls then.

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-MCmKBN63+***@public.gmane.org
Automated List Manager majordomo-MCmKBN63+***@public.gmane.org
Jim Marshall
2007-09-11 13:12:43 UTC
Permalink
Post by Dr. Stephen Henson
Post by Jim Marshall
Thanks for the feedback, unfortunately I don't fully follow you.
ret = BIO_new_accept(hostString);
if (ret != NULL)
{
BIO_set_nbio_accept(ret, 1);
BIO_set_bind_mode(ret, BIO_BIND_REUSEADDR);
/* bind & listen */
if (BIO_do_accept(ret) < 0)
...
acceptRet = BIO_do_accept(sock);
if (acceptRet > 0)
{
BIO* client = NULL;
SSL* ssl = NULL;
client = BIO_pop(sock);
// also tried BIO_set_nbio_accept on the line below
BIO_set_nbio(client, 1);
BIO_set_nbio_accept(client, 1);
ssl = SSL_new(gCtx);
if (ssl != NULL)
{
SSL_set_bio(ssl, client, client);
SSL_set_accept_state(ssl);
...
Am I placing the call in the wrong place?
Add a call BIO_set_nbio(ret, 1) after the call to BIO_set_nbio_accept() in the
"opensocket" function.
You shouldn't need the other BIO_set_nbio() calls then.
Thank you, this worked great!

I appreciate your help.
-Jim
Post by Dr. Stephen Henson
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
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users-MCmKBN63+***@public.gmane.org
Automated List Manager majordomo-MCmKBN63+***@public.gmane.org
Jim Fox
2007-09-07 18:31:27 UTC
Permalink
So beyond the BIO_do_accept, I used the openssl client program to connect to
my server. I was expecting the above to make all the sockets non-blocking,
but when I called SSL_read in my code it seems to block for data. I tried
using the BIO_set_nbio an BIO_set_nbio_accept calls but no joy.
Basically i am trying to make all the socket calls non-blocking, what am I
missing?
As far as I know you have to separately do the non-blocking setup
for both the listen socket and the accept socket.

What works for me is this: (continuing from your previous example)

.. previous listening code .. (with the BIO_set_nbio_accept)

acceptRet = BIO_do_accept(sock);
if (acceptRet > 0)
{
BIO* client = NULL;
SSL* ssl = NULL;
client = BIO_pop(sock);
ssl = SSL_new(gCtx);

then something like:

SSL_set_bio(ssl, client, client);
SSL_set_accept_state(ssl);
int sl = 1;
BIO_socket_ioctl(SSL_get_fd(ssl),FIONBIO,&sl);


I suppose it's a full circle return to the "everybody
uses BIO_socket_ioctl," but it does work.

Jim

______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users-MCmKBN63+***@public.gmane.org
Automated List Manager majordomo-MCmKBN63+***@public.gmane.org
Jim Marshall
2007-09-11 13:13:30 UTC
Permalink
Post by Jim Fox
Post by Jim Marshall
So beyond the BIO_do_accept, I used the openssl client program to
connect to my server. I was expecting the above to make all the
sockets non-blocking, but when I called SSL_read in my code it seems
to block for data. I tried using the BIO_set_nbio an
BIO_set_nbio_accept calls but no joy.
Basically i am trying to make all the socket calls non-blocking, what
am I missing?
As far as I know you have to separately do the non-blocking setup
for both the listen socket and the accept socket.
What works for me is this: (continuing from your previous example)
.. previous listening code .. (with the BIO_set_nbio_accept)
acceptRet = BIO_do_accept(sock);
if (acceptRet > 0)
{
BIO* client = NULL;
SSL* ssl = NULL;
client = BIO_pop(sock);
ssl = SSL_new(gCtx);
SSL_set_bio(ssl, client, client);
SSL_set_accept_state(ssl);
int sl = 1;
BIO_socket_ioctl(SSL_get_fd(ssl),FIONBIO,&sl);
I suppose it's a full circle return to the "everybody
uses BIO_socket_ioctl," but it does work.
Thanks for taking the time to answer my question Jim, I appreciate it!

-Jim
Post by Jim Fox
Jim
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List
Automated List Manager
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users-MCmKBN63+***@public.gmane.org
Automated List Manager majordomo-MCmKBN63+***@public.gmane.org
Loading...