我希望与OpenSSL建立多个连接。
我应该为每个新连接创建新的SSL_CTX context
,还是接受一个context
的所有连接?
我应该对内存或具有启动/停止连接的内容执行其他操作,但
除外close(_socket); //socket which accept the connection
SSL_shutdown(_ssl); //_ssl — SSL connection
SSL_free (_ssl);
答案 0 :(得分:4)
我应该为每个新连接创建新的SSL_CTX上下文还是接受具有一个上下文的所有连接?
取决于服务器名称和不同证书的数量。
如果您有一个服务器名称和一个证书,则使用一个默认上下文。
如果您有多个服务器名称和一个证书,请使用一个默认上下文。
如果您有多个服务器名称和多个证书,请参阅下面的SNI或servername回调以及在上下文中进行交换。
如果您的服务器使用不同的证书来侦听foo.com
和bar.com
,那么您将需要三个上下文。一个默认上下文用于非SNI客户端,一个上下文用于foo.com
,一个上下文用于bar.com
。
实际上,两个网站之间唯一可能发生变化的是提供的证书。所以你听默认的上下文。 如果客户端通过SNI提供了服务器名称,那么您在servername回调和SSL_set_SSL_CTX
中交换其他两个上下文之一。以下是它的外观:
static int ServerNameCallback(SSL *ssl, int *ad, void *arg)
{
UNUSED(ad);
UNUSED(arg);
ASSERT(ssl);
if (ssl == NULL)
return SSL_TLSEXT_ERR_NOACK;
const char* servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
ASSERT(servername && servername[0]);
if (!servername || servername[0] == '\0')
return SSL_TLSEXT_ERR_NOACK;
/* Need a certificate and context for this domain */
SSL_CTX* ctx = GetServerContext(servername);
ASSERT(ctx != NULL);
if (ctx == NULL)
return SSL_TLSEXT_ERR_NOACK;
/* We should not be peeking into the object like this... */
ASSERT(ctx != ssl->ctx);
/* Useless return value */
SSL_CTX* v = SSL_set_SSL_CTX(ssl, ctx);
return SSL_TLSEXT_ERR_OK;
}
GetServerContext
只提供foo.com
或bar.com
的背景信息。它创建一次,然后重用相同的。
对于默认上下文,使用SSL_CTX_set_tlsext_servername_callback
设置servername回调。没有必要为非默认上下文设置它。
SSL_CTX_set_tlsext_servername_callback(ctx, ServerNameCallback);
引用了上下文,因此您可以重复使用它们。
我是否应该使用内存或其他内容执行其他操作 开始/停止连接,
除外close(_socket); //socket which accept the connection SSL_shutdown(_ssl); //_ssl — SSL connection SSL_free (_ssl);
在这里,您应该寻求对该主题的治疗。例如,您不应在close
之前致电SSL_shutdown
。第一次调用SSL_shutdown
可能会失败,因此您需要知道下一步该做什么。
有关受试者的治疗,请参阅Eric Rescorla的教程:An Introduction to OpenSSL Programming, Part I of II和An Introduction to OpenSSL Programming, Part II of II。或者获取这本书:Network Security with OpenSSL。