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

问题描述 投票:0回答:1

这是我的问题: 在调用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 打印出“error: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);
}

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

sockets networking openssl nonblocking
1个回答
2
投票

SSL_ERROR_WANT_READ 意味着我需要重试 SSL_accept 和 SSL_connect。

是的,但这不是故事的全部。 您应该仅在套接字可读后重试调用,例如您需要使用

select
poll
或类似的函数来等待,直到套接字变得可读。同样适用于 SSL_ERROR_WANT_WRITE,但这里你必须等待套接字变得可写。

如果你不等待就重试,它可能最终会成功,但前提是在有数百次失败的调用之后。虽然这样做

select
并不能保证它会在下一次调用时立即成功,但它只需要几次 SSL_connect/SSL_accept 调用就可以成功,并且同时不会忙于循环并占用 CPU。

© www.soinside.com 2019 - 2024. All rights reserved.