Francois
Francois

Reputation: 51

Set connection timeout for SSL_read in OpenSSL in C++

I am developing a linux application which communicates with OpenSSL. I am currently running some robustness tests and one of the is giving me a hard time.

I plug out the Ethernet cable when my program is downloading a big file and I wish that it stops after 30seconds for example. But it never stop.

I use SSL_read and this is where it blocks :

count = SSL_read(ssl, buffer, BUFSIZE);

Is it possible to set a timeout to SSL_read ?

I have tried SSL_CTX_set_timeout() but it is not working. I have also seen that it was maybe possible to use select() but I don't understand how to use it with SSL_read()

Upvotes: 5

Views: 5393

Answers (1)

Drejc
Drejc

Reputation: 531

You can do that in the same way as you do it with "normal" sockets. Basically, you set the timeval on a socket passed to ssl and the SSL_read will return -1 when the time set in timeval passes if nothing is received. Example below (uninteresting parts are written in pseudo):

struct timeval tv;
char buffer[1024];

// socket, bind, listen, ... 

// accept 
int new_fd = accept(...)

tv.tv_sec = 5; // 5 seconds
tv.tv_usec = 0;
setsockopt(new_fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);

// assign fd to ssl ...

//  blocking method will return -1 if nothing is received after 5 seconds
int cnt = SSL_read(ssl, buffer, sizeof buffer);

if (cnt == -1) return; // connection error or timeout

EDIT

To check if it is timeout do it like so:

int ssl_error = SSL_get_error(ssl, cnt);
if (ssl_error == SSL_ERROR_SYSCALL) {
    printf("SSL_read failed with errno: %d", errno);
    if (errno == EAGAIN || errno == EWOULDBLOCK) {
        printf("Timeout");
    } else {
        // Other socket errors
    }
} else {
    // Other SSL errors
}

Upvotes: 2

Related Questions