OpenSSL and Signals

Socket functions such as send and receive may be interrupted by signals. Because of this, some additional code is needed, for example. to check errno == EINTR . This is described on the corresponding manual pages.

I wonder how it works when using OpenSSL functions? SSL_write , SSL_read . The pages of their people do not say anything about signals. I also tried using Google for this, but with no luck. Do you know that OpenSSL processes signals internally, or is some additional code needed? If so, how can I check if a function call was interrupted by a signal?

Update:

OpenSSL doesn't seem to handle repetitions. It sets only the “should try again” flag on the BIO object. Therefore, I need to use something like this to determine if the call has been interrupted and a retry is required:

 int result = SSL_write(ssl, buff, length); if ((result < 0) && BIO_should_retry(SSL_get_wbio(ssl))) // need to retry int result = SSL_read(ssl, buff, length); if ((result < 0) && BIO_should_retry(SSL_get_rbio(ssl))) // need to retry 
+7
c ++ c linux signals openssl
source share
1 answer

How libray OpenSSL cannot make any assumptions about how signals are handled by a particular program using it. Thus, it must handle the case when a system call is interrupted when a signal is received.

Check if it makes sense to repeat the failed read() implemented inside OpenSSL.

Use BIO_should_retry() if the error is BIO_read() (or BIO_write() ).

For an example, read here: http://cvs.openssl.org/rlog?f=openssl/demos/bio/sconnect.c

The appropriate implementation code should be:

 static int sock_read(BIO *b, char *out, int outl) { int ret=0; if (out != NULL) { clear_socket_error(); ret=readsocket(b->num,out,outl); BIO_clear_retry_flags(b); if (ret <= 0) { if (BIO_sock_should_retry(ret)) BIO_set_retry_read(b); } } return(ret); } 

Relevant features here:

( get_last_socket_error() returns errno on most IXish platforms)

 int BIO_sock_should_retry(int i) { int err; if ((i == 0) || (i == -1)) { err=get_last_socket_error(); #if defined(OPENSSL_SYS_WINDOWS) && 0 /* more microsoft stupidity? perhaps not? Ben 4/1/99 */ if ((i == -1) && (err == 0)) return(1); #endif return(BIO_sock_non_fatal_error(err)); } return(0); } int BIO_sock_non_fatal_error(int err) { switch (err) { #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_NETWARE) # if defined(WSAEWOULDBLOCK) case WSAEWOULDBLOCK: # endif # if 0 /* This appears to always be an error */ # if defined(WSAENOTCONN) case WSAENOTCONN: # endif # endif #endif #ifdef EWOULDBLOCK # ifdef WSAEWOULDBLOCK # if WSAEWOULDBLOCK != EWOULDBLOCK case EWOULDBLOCK: # endif # else case EWOULDBLOCK: # endif #endif #if defined(ENOTCONN) case ENOTCONN: #endif #ifdef EINTR case EINTR: #endif #ifdef EAGAIN # if EWOULDBLOCK != EAGAIN case EAGAIN: # endif #endif #ifdef EPROTO case EPROTO: #endif #ifdef EINPROGRESS case EINPROGRESS: #endif #ifdef EALREADY case EALREADY: #endif return(1); /* break; */ default: break; } return(0); } 

See sock_read() more details here: http://cvs.openssl.org/rlog?f=openssl/crypto/bio/bss_sock.c

(Sources cited along with the derogation used are from version 1.0.1e.)

+3
source share

All Articles