SSL_close_all 函数的源码如下:
void
SSL_close_all
(
SSL
*
ssl
,
SSL_CTX
*
ctx
,
int
client_fd
)
{
s_log
(
eDEBUG1
,
"calling shutdown(%i, SHUT_RDWR)"
,
client_fd
);
if
(
shutdown
(
client_fd
,
SHUT_RDWR
)
<
0
)
{
s_log
(
eERROR
,
"shutdown(%i, SHUT_RDWR): %.100s (%i)"
,
client_fd
,
strerror
(
errno
),
errno
);
s_log
(
eDEBUG1
,
"calling exit(%i)"
,
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
s_log
(
eDEBUG1
,
"calling close(%i)"
,
client_fd
);
if
(
close
(
client_fd
)
<
0
)
{
s_log
(
eERROR
,
"close(%i): %.100s (%i)"
,
client_fd
,
strerror
(
errno
),
errno
);
s_log
(
eDEBUG1
,
"calling exit(%i)"
,
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
s_log
(
eDEBUG2
,
"calling SSL_shutdown(%x)"
,
ssl
);
if
(
SSL_shutdown
(
ssl
)
<
0
)
{
s_log
(
eERROR
,
"SSL_shutdown: %.100s (%i)"
,
strerror
(
errno
),
errno
);
s_log
(
eDEBUG1
,
"calling exit(%i)"
,
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
s_log
(
eDEBUG2
,
"calling SSL_free(%x)"
,
ssl
);
SSL_free
(
ssl
);
s_log
(
eDEBUG2
,
"calling SSL_CTX_free(%x)"
,
ctx
);
SSL_CTX_free
(
ctx
);
}
|
在出现问题的服务器上使用 "strace" 对 easd 进程的系统调用进行跟踪, 发现
shutdown(client_fd,
SHUT_RDWR) 使 socket 连接双方不能通过 client_fd 进行发送和接收;
close(client_fd) 关闭 socket 连接 client_fd
SSL_shutdown(ssl) 先往 client_fd 中写入数据, 再关闭 client_fd ( ssl 中应该含有 client_fd )
由上可知, 原有的代码会因为文件描述符引发 bug (关闭后还进行写入操作)
不知道原先很多系统中, 运行程序并没有报 bug, 猜测是因为不同的库对 SSL_shutdown() 的实现不同.
因此, 对于报 bug 的服务器 SSL_close_all
函数的代码应该改为:
voidSSL_close_all(SSL*ssl,SSL_CTX*ctx,intclient_fd)
{
s_log
(
eDEBUG2
,
"calling SSL_shutdown(%x)"
,
ssl
);
if
(
SSL_shutdown
(
ssl
)
<
0
)
{
s_log
(
eERROR
,
"SSL_shutdown: %.100s (%i)"
,
strerror
(
errno
),
errno
);
s_log
(
eDEBUG1
,
"calling exit(%i)"
,
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
s_log(eDEBUG1,"calling close(%i)",client_fd);
if
(
close
(
client_fd
)
<
0
)
{
s_log
(
eERROR
,
"close(%i): %.100s (%i)"
,
client_fd
,
strerror
(
errno
),
errno
);
s_log
(
eDEBUG1
,
"calling exit(%i)"
,
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
s_log
(
eDEBUG2
,
"calling SSL_free(%x)"
,
ssl
);
SSL_free
(
ssl
);
s_log
(
eDEBUG2
,
"calling SSL_CTX_free(%x)"
,
ctx
);
SSL_CTX_free
(
ctx
);
}
|