OpenSSL非阻塞套接字接受并连接失败

时间:2014-06-19 16:57:20

标签: sockets networking openssl connect nonblocking

这是我的问题: 在调用accept或connect之前将套接字设置为非阻塞是不是很糟糕?或者它应该使用阻塞接受和连接,然后将套接字更改为非阻塞?

我是OpenSSL的新手,对网络编程不是很有经验。我的问题是我尝试使用OpenSSL与非阻塞套接字网络来增加安全性。当我在服务器端调用SSL_accept而在客户端调用SSL_connect时,使用

检查返回错误代码
SSL_get_error(m_ssl, n);
char error[65535];
ERR_error_string_n(ERR_get_error(), error, 65535);

SSL_get_error的返回码表示SSL_ERROR_WANT_READ,而ERR_error_string_n打印出"错误:00000000:lib(0):func(0):reason(0)",我认为这意味着没有错误。 SSL_ERROR_WANT_READ表示我需要重试SSL_accept和SSL_connect。

然后我使用循环来重试这些函数,但这只会导致无限循环:(

我相信我已正确初始化SSL,这是代码

//CRYPTO_malloc_init(); 
SSL_library_init();

const SSL_METHOD *method;

// load & register all cryptos, etc.
OpenSSL_add_all_algorithms();
// load all error messages
SSL_load_error_strings();

if (server) {
    // create new server-method instance
    method = SSLv23_server_method();
}
else {
    // create new client-method instance
    method = SSLv23_client_method();
}

// create new context from method
m_ctx = SSL_CTX_new(method);
if (m_ctx == NULL) {
    throwError(-1);
}

如果有任何部分我没有提及,但你认为这可能是问题,请告诉我。

1 个答案:

答案 0 :(得分:2)

  

SSL_ERROR_WANT_READ表示我需要重试SSL_accept和SSL_connect。

是的,但这不是完整的故事。 只有在套接字可读后才应重试调用,例如你需要使用selectpoll或类似的函数来等待,直到套接字可读。同样适用于SSL_ERROR_WANT_WRITE,但在这里你必须等待套接字可写。

如果你只是在没有等待的情况下重试,它可能最终会成功,但只有在完成100次失败的呼叫之后。虽然执行select并不能保证它会在下次调用时立即成功,但只需要几次SSL_connect / SSL_accept调用,直到它成功为止,并且它不会繁忙循环并同时吃掉CPU。