I have a BIO object which is buffering a SSL connection. How do I poll the connection to see if i can call a read without blocking?
The OpenSSL website says:
One technique sometimes used with blocking sockets is to use a system call (such as select(), poll() or equivalent) to determine when data is available and then call read() to read the data. The equivalent with BIOs (that is call select() on the underlying I/O structure and then call BIO_read() to read the data) should not 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.
The problem here is that I cannot change the type of the connection as it is made elsewhere. Is there another way to accomplish my goal?
You can probably use
fcntl(2)‘sF_SETFLto set theO_NONBLOCKflag on the file descriptor. Since the socket is being used via OpenSSL’s BIO utilities by the time you want to set this flag, it should be fine — the rest of your application cannot make use of the data from the socket until it has passed through the BIO routines.Thus I believe that you can change the connection type.
I see in the
bio.hheader an API that looks made for your case:though there is the following caveat in the manual:
Perhaps the underlying BIO interface isn’t expecting to change once the connection is made; it would be worth trying this with the explicit
fcntl(2)call yourself — perhaps it’ll all Just Work.