当没有连接互联网时,非阻塞BIO_do_connect被阻止

时间:2016-08-11 03:10:21

标签: c linux ssl openssl

我使用Openssl-0.9.8x如下:

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");
    }
}

当互联网连接正常(即它可以连接到服务器)时,它可以正常工作。但是,当互联网连接受限(即它无法连接到服务器)时,BIO_do_connect()在重试一次或多次后被阻止。 输出如下:

BIO_do_connect start>>>>
BIO_do_connect retry>>>>
BIO_do_connect start>>>>
BIO_do_connect retry>>>>
BIO_do_connect start>>>>

最后,它在BIO_do_connect(...)被屏蔽?为什么会这样?

2 个答案:

答案 0 :(得分:1)

可能是您使用SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY)

从0.9.8手册页:

  

SSL_MODE_AUTO_RETRY

     

如果传输阻塞,请不要在重试时打扰应用程序。       如果在正常操作期间进行重新协商,a       SSL_read()或SSL_write()将返回       使用-1并指示需要使用SSL_ERROR_WANT_READ重试。       在非阻塞环境中,应用程序必须准备好处理       不完整的读/写操作。       在阻塞环境中,应用程序并不总是准备好       处理返回没有成功报告的读/写操作。该       标志SSL_MODE_AUTO_RETRY将仅导致读/写操作       握手和成功完成后返回。

SSL_MODE_AUTO_RETRY的作用是自动重试否则将返回应用程序代码的操作(即使使用阻塞连接)。当你想要非阻塞操作时,使用它是没有任何意义的。

尝试完全删除该行。

顺便说一句,0.9.8不受支持,不再接收安全更新。你真的应该升级到更新的版本。

答案 1 :(得分:-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);