Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

blocking BIO_read

245 views
Skip to first unread message

Laura Arhire

unread,
Aug 27, 2009, 8:25:54 AM8/27/09
to
Hey

I'm using the BIO abstraction for reading/writing to sockets - a small
part of the BIO_read method is unclear: For a blocking socket, will the
BIO_read call block until the length provided in the call is filled in
the buffer, or will it return as soon as it managed to read anything
from the socket?

I see that the underlying implementation uses recv() - recv blocks
until something is available: when something is available for reading,
read up to len bytes and copy it to the provided buffer, then return,
i.e. the length is used as a maximum value. From reading the openssl
code I think that BIO_read behaves in the same way as recv - which means
that if I want to read a specific number of bytes (no more, no less), I
need to loop until I get everything I need. Can anyone confirm this ?

Thank you,

--
Laura

______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openss...@openssl.org
Automated List Manager majo...@openssl.org

Ger Hobbelt

unread,
Aug 27, 2009, 4:43:39 PM8/27/09
to
On Thu, Aug 27, 2009 at 2:24 PM, Laura
Arhire<laura....@endion-software.com> wrote:
> Hey
>
> I'm using the BIO abstraction for reading/writing to sockets - a small part
> of the BIO_read method is unclear: For a blocking socket, will the BIO_read
> call block until the length provided in the call is filled in the buffer,
> or will it return as soon as it managed to read anything from the socket?
>
> I see that the underlying implementation uses recv() - recv blocks until
> something is available: when something is available for reading, read up to
> len bytes and copy it to the provided buffer, then return, i.e. the length
> is used as a maximum value. From reading the openssl code I think that
> BIO_read behaves in the same way as recv - which means that if I want to
> read a specific number of bytes (no more, no less), I need to loop until I
> get everything I need. Can anyone confirm this ?

Confirmed.
BIO_read won't wait/guarantee that the requested number of bytes are
delivered all, so you'll indeed need to loop to get them all (or an
error due to connection issues) if you want to receive a predetermined
number of bytes.


For completeness / additive: note that 'officially', you should check
the BIO_should_retry() call on error (negative error code return),
i.e.

---snip[stripped]---
...
i = BIO_read(bio,buf,bufsize);
if (i < 0)
{
// error condition - possibly
if (BIO_should_retry(bio))
{
if (BIO_should_read(bio))
...
if (BIO_should_write(bio))
...
}
else
{
// real error. process the error the way you want/need
ERR_print_errors(bio_err);
got fail_dramatically;
}
}
else if (i == 0)
{
// blocking --> conn termination
...
break;
}
else
{
// collect the returned bytes; shift buf, etc., then wait for the rest
...
}
---snip---

as this is what it should look like for any and all BIOs, i.e. when
your BIO-using code layer should not be specifically aware of the
chain/device peculiarities accessed through the BIO abstraction layer.

In the case of raw socket I/O, the 'should_retry' won't fire, at least
not with the current implementation on UNIX. Which might be a bother
regarding testability versus 'correct' use/implementation of the i/o
abstraction. Once you're stacking, say, and SSL BIO into this BIO
chain however, things will certainly look /very/ different and you'll
surely need that should_retry/etc. code in there.

Take care,

Ger

--
Met vriendelijke groeten / Best regards,

Ger Hobbelt

--------------------------------------------------
web: http://www.hobbelt.com/
http://www.hebbut.net/
mail: g...@hobbelt.com
mobile: +31-6-11 120 978
--------------------------------------------------

Laura Arhire

unread,
Aug 28, 2009, 3:00:55 AM8/28/09
to
This is a multi-part message in MIME format.
--------------070708070201060408040602
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Thank you very much!

--
Laura


--------------070708070201060408040602
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Thank you very much!<br>
<br>
Ger Hobbelt wrote:
<blockquote
cite="mid:561cc61d0908271343q7d6...@mail.gmail.com"
type="cite">
<pre wrap="">On Thu, Aug 27, 2009 at 2:24 PM, Laura
Arhire<a class="moz-txt-link-rfc2396E" href="mailto:laura....@endion-software.com">&lt;laura....@endion-software.com&gt;</a> wrote:
</pre>
<blockquote type="cite">
<pre wrap="">Hey

I'm using the BIO abstraction for reading/writing to sockets - a small part
of the BIO_read method is unclear: For a blocking socket, will the BIO_read
call block until the length provided in the call is filled in the buffer,
or will it return as soon as it managed to read anything from the socket?

I see that the underlying implementation uses recv() - recv blocks until
something is available: when something is available for reading, read up to
len bytes and copy it to the provided buffer, then return, i.e. the length
is used as a maximum value. From reading the openssl code I think that
BIO_read behaves in the same way as recv - which means that if I want to
read a specific number of bytes (no more, no less), I need to loop until I
get everything I need. Can anyone confirm this ?

</pre>
</blockquote>
<pre wrap=""><!---->


Confirmed.
BIO_read won't wait/guarantee that the requested number of bytes are
delivered all, so you'll indeed need to loop to get them all (or an
error due to connection issues) if you want to receive a predetermined
number of bytes.


For completeness / additive: note that 'officially', you should check
the BIO_should_retry() call on error (negative error code return),
i.e.

---snip[stripped]---
...
i = BIO_read(bio,buf,bufsize);

if (i &lt; 0)


{
// error condition - possibly
if (BIO_should_retry(bio))
{
if (BIO_should_read(bio))
...
if (BIO_should_write(bio))
...
}
else
{
// real error. process the error the way you want/need
ERR_print_errors(bio_err);
got fail_dramatically;
}
}
else if (i == 0)
{

// blocking --&gt; conn termination


...
break;
}
else
{
// collect the returned bytes; shift buf, etc., then wait for the rest
...
}
---snip---

as this is what it should look like for any and all BIOs, i.e. when
your BIO-using code layer should not be specifically aware of the
chain/device peculiarities accessed through the BIO abstraction layer.

In the case of raw socket I/O, the 'should_retry' won't fire, at least
not with the current implementation on UNIX. Which might be a bother
regarding testability versus 'correct' use/implementation of the i/o
abstraction. Once you're stacking, say, and SSL BIO into this BIO
chain however, things will certainly look /very/ different and you'll
surely need that should_retry/etc. code in there.

Take care,

Ger

</pre>
</blockquote>
<br>
<pre class="moz-signature" cols="72">--
Laura</pre>
</body>
</html>

--------------070708070201060408040602--

0 new messages