gpt4 book ai didi

c++ - OpenSSL 和信号

转载 作者:IT王子 更新时间:2023-10-29 00:22:06 26 4
gpt4 key购买 nike

sendreceive 等套接字函数可以被信号中断。因此,需要一些额外的代码,例如检查 errno == EINTR。这在相应的手册页中有描述。

我想知道在使用 OpenSSL 函数时这是如何工作的,例如SSL_write, SSL_read。他们的手册页没有说明任何关于信号的内容。我也试着用谷歌搜索这个,但没有运气。您知道 OpenSSL 是在内部处理信号,还是需要一些额外的代码?如果是,如何检查函数调用是否被信号中断?

更新:

看起来 OpenSSL 不处理重试。它只在 BIO 对象上设置“应该重试”标志。所以我需要使用类似这样的东西来检测调用是否被中断并需要重试:

int result = SSL_write(ssl, buff, length);
if ((result < 0) && BIO_should_retry(SSL_get_wbio(ssl)))
// need to retry

int result = SSL_read(ssl, buff, length);
if ((result < 0) && BIO_should_retry(SSL_get_rbio(ssl)))
// need to retry

最佳答案

作为一个库,OpenSSL 不能对使用它的特定程序如何处理信号做出任何假设。因此它需要处理系统调用在接收到信号时被中断的情况。

检查重试失败的 read() 是否有意义在 OpenSSL 中实现。

如果 BIO_read()(或 BIO_write())失败,请使用 BIO_should_retry()

阅读此处的示例:http://cvs.openssl.org/rlog?f=openssl/demos/bio/sconnect.c

实现的相关代码如下:

static int sock_read(BIO *b, char *out, int outl)
{
int ret=0;

if (out != NULL)
{
clear_socket_error();
ret=readsocket(b->num,out,outl);
BIO_clear_retry_flags(b);
if (ret <= 0)
{
if (BIO_sock_should_retry(ret))
BIO_set_retry_read(b);
}
}
return(ret);
}

相关的引用函数在这里:

(get_last_socket_error() 在大多数 IXish 平台上返回 errno)

int BIO_sock_should_retry(int i)
{
int err;

if ((i == 0) || (i == -1))
{
err=get_last_socket_error();

#if defined(OPENSSL_SYS_WINDOWS) && 0 /* more microsoft stupidity? perhaps not? Ben 4/1/99 */
if ((i == -1) && (err == 0))
return(1);
#endif

return(BIO_sock_non_fatal_error(err));
}
return(0);
}


int BIO_sock_non_fatal_error(int err)
{
switch (err)
{
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_NETWARE)
# if defined(WSAEWOULDBLOCK)
case WSAEWOULDBLOCK:
# endif

# if 0 /* This appears to always be an error */
# if defined(WSAENOTCONN)
case WSAENOTCONN:
# endif
# endif
#endif

#ifdef EWOULDBLOCK
# ifdef WSAEWOULDBLOCK
# if WSAEWOULDBLOCK != EWOULDBLOCK
case EWOULDBLOCK:
# endif
# else
case EWOULDBLOCK:
# endif
#endif

#if defined(ENOTCONN)
case ENOTCONN:
#endif

#ifdef EINTR
case EINTR:
#endif

#ifdef EAGAIN
# if EWOULDBLOCK != EAGAIN
case EAGAIN:
# endif
#endif

#ifdef EPROTO
case EPROTO:
#endif

#ifdef EINPROGRESS
case EINPROGRESS:
#endif

#ifdef EALREADY
case EALREADY:
#endif
return(1);
/* break; */
default:
break;
}
return(0);
}

详情请见sock_read() 此处检查:http://cvs.openssl.org/rlog?f=openssl/crypto/bio/bss_sock.c

(引用的来源以及使用的缩进来自版本 1.0.1e。)

关于c++ - OpenSSL 和信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24188013/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com