I am using Openssl-0.9.8x as follows:
bio = BIO_new_ssl_connect(ctx);
BIO_get_ssl(bio, & ssl);
SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
BIO_set_nbio(bio, 1);
in_addr_t serverIP = inet_addr(HTTPS_SERVER_IP);
BIO_set_conn_ip(bio, &serverIP );
BIO_set_conn_port(bio, HTTPS_SERVER_PORT_STR);
while(1) {
printf("BIO_do_connect start>>>>\n");
if(BIO_do_connect(bio) <= 0 && BIO_should_retry(bio)) {
sleep(1);
printf("BIO_do_connect retry>>>>\n");
}
else {
printf("Connect success.\n");
}
}
It works fine when the internet connection is OK (i.e. it can connect to the server). But, when the internet connection is limited (i.e. it can't connect to the server), the BIO_do_connect()
is blocked after one or more times of retry.
The output as follows:
BIO_do_connect start>>>>
BIO_do_connect retry>>>>
BIO_do_connect start>>>>
BIO_do_connect retry>>>>
BIO_do_connect start>>>>
Finally, it is blocked in BIO_do_connect(...)
? why this happened?
It is probably your use of SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY)
.
From the 0.9.8 man page:
SSL_MODE_AUTO_RETRY
Never bother the application with retries if the transport is blocking.
If a renegotiation take place during normal operation, a
SSL_read() or SSL_write() would return
with -1 and indicate the need to retry with SSL_ERROR_WANT_READ.
In a non-blocking environment applications must be prepared to handle
incomplete read/write operations.
In a blocking environment, applications are not always prepared to
deal with read/write operations returning without success report. The
flag SSL_MODE_AUTO_RETRY will cause read/write operations to only
return after the handshake and successful completion.
The effect of SSL_MODE_AUTO_RETRY
is to automatically retry operations that would otherwise return back to application code (even when the using blocking connections). It doesn't make any sense to use it when you want non-blocking operation.
Try removing that line completely.
By the way 0.9.8 is out of support and is no longer receiving security updates. You really ought to upgrade to a more recent version.
Add the following:
in_addr_t serverIP = inet_addr(HTTPS_SERVER_IP);
BIO_set_conn_ip(bio, &serverIP );
BIO_set_conn_port(bio, HTTPS_SERVER_PORT_STR);