From 4041156461457749bf871e2a9f30b9fe6370c426 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Wed, 13 Sep 2000 00:20:24 +0000 Subject: [PATCH] Clarify some of the I/O issues. Add case of using select() and blocking I/O with BIOs and why you shouldn't (thanks Bodo!). --- doc/crypto/BIO_read.pod | 20 ++++++++++++--- doc/crypto/BIO_should_retry.pod | 43 +++++++++------------------------ 2 files changed, 28 insertions(+), 35 deletions(-) diff --git a/doc/crypto/BIO_read.pod b/doc/crypto/BIO_read.pod index 6c001a3092..e7eb5ea045 100644 --- a/doc/crypto/BIO_read.pod +++ b/doc/crypto/BIO_read.pod @@ -38,16 +38,28 @@ the operation is not implemented in the specific BIO type. =head1 NOTES A 0 or -1 return is not necessarily an indication of an error. In -particular when the source/sink is non-blocking or of a certain type (for -example an SSL BIO can retry even if the underlying connection is blocking) +particular when the source/sink is non-blocking or of a certain type it may merely be an indication that no data is currently available and that -the application should retry the operation later. L -can be called to determine the precise cause. +the application should retry the operation later. + +One technique sometimes used with blocking sockets is to use a system call +(such as select(), poll() or eqivalent) to determine when data is available +and then call read() to read the data. The eqivalent with BIOs (that is call +select() on the underlying I/O structure and then call BIO_read() to +read the data) should B be used because a single call to BIO_read() +can cause several reads (and writes in the case of SSL BIOs) on the underlying +I/O structure and may block as a result. Instead select() (or equivalent) +should be combined with non blocking I/O so successive reads will request +a retry instead of blocking. + +See the L for details of how to +determine the cause of a retry and other I/O issues. If the BIO_gets() function is not supported by a BIO then it possible to work around this by adding a buffering BIO L to the chain. =head1 SEE ALSO +L TBA diff --git a/doc/crypto/BIO_should_retry.pod b/doc/crypto/BIO_should_retry.pod index ab67a46114..6d291b1888 100644 --- a/doc/crypto/BIO_should_retry.pod +++ b/doc/crypto/BIO_should_retry.pod @@ -46,7 +46,7 @@ reason other than reading or writing is the cause of the condition. BIO_get_retry_reason() returns a mask of the cause of a retry condition consisting of the values B, B, B though current BIO types will only set one of -these (Q: is this correct?). +these. BIO_get_retry_BIO() determines the precise reason for the special condition, it returns the BIO that caused this condition and if @@ -55,7 +55,7 @@ the reason code and the action that should be taken depends on the type of BIO that resulted in this condition. BIO_get_retry_reason() returns the reason for a special condition if -pass the relevant BIO, for example as returned by BIO_get_retry_BIO(). +passed the relevant BIO, for example as returned by BIO_get_retry_BIO(). =head1 NOTES @@ -68,27 +68,17 @@ has reached EOF. Some BIO types may place additional information on the error queue. For more details see the individual BIO type manual pages. -If the underlying I/O structure is in a blocking mode then most BIO -types will not signal a retry condition, because the underlying I/O +If the underlying I/O structure is in a blocking mode almost all current +BIO types will not request a retry, because the underlying I/O calls will not. If the application knows that the BIO type will never signal a retry then it need not call BIO_should_retry() after a failed BIO I/O call. This is typically done with file BIOs. -The presence of an SSL BIO is an exception to this rule: it can -request a retry because the handshake process is underway (either -initially or due to a session renegotiation) even if the underlying -I/O structure (for example a socket) is in a blocking mode. - -The action an application should take after a BIO has signalled that a -retry is required depends on the BIO that caused the retry. - -If the underlying I/O structure is in a blocking mode then the BIO -call can be retried immediately. That is something like this can be -done: - - do { - len = BIO_read(bio, buf, len); - } while((len <= 0) && BIO_should_retry(bio)); +SSL BIOs are the only current exception to this rule: they can request a +retry even if the underlying I/O structure is blocking, if a handshake +occurs during a call to BIO_read(). An application can retry the failed +call immediately or avoid this situation by setting SSL_MODE_AUTO_RETRY +on the underlying SSL structure. While an application may retry a failed non blocking call immediately this is likely to be very inefficient because the call will fail @@ -100,18 +90,9 @@ For example if the cause is ultimately a socket and BIO_should_read() is true then a call to select() may be made to wait until data is available and then retry the BIO operation. By combining the retry conditions of several non blocking BIOs in a single select() call -it is possible to service several BIOs in a single thread. - -The cause of the retry condition may not be the same as the call that -made it: for example if BIO_write() fails BIO_should_read() can be -true. One possible reason for this is that an SSL handshake is taking -place. - -Even if data is read from the underlying I/O structure this does not -imply that the next BIO I/O call will succeed. For example if an -encryption BIO reads only a fraction of a block it will not be -able to pass any data to the application until a complete block has -been read. +it is possible to service several BIOs in a single thread, though +the performance may be poor if SSL BIOs are present because long delays +can occur during the initial handshake process. It is possible for a BIO to block indefinitely if the underlying I/O structure cannot process or return any data. This depends on the behaviour of -- GitLab