我正在编写一个服务(在C for CentOS中),它必须通过SSL与第三方REST API建立大量的出站SSL连接。
OpenSSL用于创建与远程服务器的安全连接的建立。在初始化ssl_connection之后,我使用epoll队列注册返回的文件描述符。
我可以连接并执行API事务。之后,远程服务器终止连接,我们在fd上获得EPOLLRDHUP,因此调用我们的清理例程。
signal(SIGPIPE,SIG_IGN);
if(PS(endpoint)->ssl != NULL)
{
if(SSL_shutdown(PS(endpoint)->ssl)==0)
{
SSL_shutdown(PS(endpoint)->ssl);
}
}
if(PS(endpoint)->web != NULL)
{
BIO_free(PS(endpoint)->web); // This can cause a SIGPIPE, especialy when debugging!
PS(endpoint)->web = NULL;
}
通过此关闭过程,一切似乎都没问题,不会抛出任何错误。
但是 - 每个后续连接都会占用下一个系统fd,并且所有文件描述符都会耗尽,达到操作系统软限制1028.
所以问题是fd没有被关闭并被释放回内核?
通过
确认ls /proc/$PID/fd/ | wc -l
任何人都可以帮助正确的OpenSSL会话关闭程序吗?
答案 0 :(得分:2)
SSL_shutdown
文档提到,它只是发送关闭通知,以便在两端正确关闭TLS连接
它实际上并没有关闭套接字,你的应用程序应该在fd上明确地调用close()
,以便正确关闭套接字。
由于您当前的套接字没有正确关闭,FD不会被重用,每个新套接字都会获得新的FD,最终会超出您提到的限制