[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openssl-users
Subject:    RE: Q about the darkspell gadgets
From:       Michael Wojcik <Michael.Wojcik () merant ! com>
Date:       2000-04-28 22:37:27
[Download RAW message or body]

> -----Original Message-----
> From: Brian Snyder [mailto:BSnyder@reliacast.com]
> Sent: Friday, April 28, 2000 1:21 PM
> 
> This is a snippet of code from the darkspell gadgets.  

[A typical Stevens-style "readn" function.]

> (Replace read with SSL_read and you have a reader for an SSL enabled
> connection).
> 
> My question is why does this print out some code that is less then 4096
> bytes...ever? 
> It seems that this would not return and print the 'buf' until its read
> 'readSize' (4096) worth of characters.
> 
> However, short of user interaction to kill the server, how does this work,
> so that it will receive an arbitrary reply, without hanging forever until
> waiting on 4096 bytes?  IE:  Where is it reading the 'content-length'
field
> so it really knows how much data to get?

I haven't looked at the darkspell code, but I'll comment on the behavior of
the Unix read(2) system call with sockets, which is what we seem to have
here.  You may know all of this already, of course, but it may be helpful
for others.

When read is called for N bytes on a TCP socket:

- If there is any application data available for reading, read() copies that
data into the caller's buffer and sets the return value to the number of
bytes copied.

- If there is no application data available and a TCP FIN has been received
from the peer for this conversation, read() returns 0, its EOF indicator.  A
FIN (usually) means the remote application has closed the conversation
cleanly.

- If there is no data available and any of various error conditions occur,
read() returns -1 and sets errno appropriately.

- If there is neither application data nor a FIN nor an error, read() will
block until one of those things is received, or it's interrupted by a
signal.  (The latter behavior is somewhat system-dependent.)

The purpose of readn() is to loop calling read() until it reports EOF or an
error, or it receives a certain amount of data.  In effect, readn() is like
read() except for a more stringent condition for returning data.  So yes,
it'll block until it gets its 4096 bytes - *unless* it gets EOF or an error
from read().

Perhaps the gadget was written for HTTP/1.0, and so doesn't take into
account persistent connections?  If the connection isn't persistent, the
server will close it after it sends the response.  readn() will loop calling
read() until it's gotten all of the data; then it will get a 0 on the next
call to read() and return.

If the connection is persistent, and the server sends less than 4096 bytes
and doesn't close the connection, readn() will indeed block forever (unless
an error kicks it out).

readn() is meant to be used when the caller knows the peer is supposed to be
sending that much data.  Calling it with a fixed buffer size when you could
be receiving variable-length data is simply wrong.  If the caller wants to
receive data until the remote application closes its end, readn() will work,
but it hides what the caller really wants to do.  In any case, a more robust
application would probably employ some kind of timeout processing using
poll() or its equivalent (or multithreading, though that design has certain
drawbacks) to get out of the read() if data isn't received in a certain
timeframe - regardless of whether it knows how much data to receive.

And, of course, a good HTTP/1.1 application should be paying attention to
the Content-length header if present, or the Transfer Encoding, or
whatever's applicable to that particular flow.  (Content-length isn't
present if the "chunked" Transfer Encoding is being used.  See RFC 2616.)

Michael Wojcik             michael.wojcik@merant.com
MERANT
Department of English, Miami University
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majordomo@openssl.org

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic