C++ SSL\u CTX\u集合\u tlsext\u服务器名\u未调用回调函数

C++ SSL\u CTX\u集合\u tlsext\u服务器名\u未调用回调函数,c++,c,ssl,openssl,C++,C,Ssl,Openssl,我正在编写一个https服务器,我需要在使用SNI的ssl_accept()之前从客户端获取主机名。我使用SSL_CTX_set_tlsext_servername_callback()来接收主机名,但根本不会调用回调。这是我的部分代码 // Server Name Indication callback from OpenSSL static int serverNameCallback(SSL *ssl, int *ad, void *arg) { if (ssl == NULL)

我正在编写一个https服务器,我需要在使用SNI的ssl_accept()之前从客户端获取主机名。我使用SSL_CTX_set_tlsext_servername_callback()来接收主机名,但根本不会调用回调。这是我的部分代码

// Server Name Indication callback from OpenSSL
static int serverNameCallback(SSL *ssl, int *ad, void *arg) 
{
    if (ssl == NULL)
        return SSL_TLSEXT_ERR_NOACK;

    const char* servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
    printf("ServerName: %s\n", servername);
}

int main()
{
    //some code 
    const SSL_METHOD *method;
    SSL_CTX *ctx;

    method = SSLv3_server_method();  
    ctx = SSL_CTX_new(method);   
    if ( ctx == NULL )
    { 
        printf("SSL_ctx_new() error\n");
    }

    int ret = SSL_CTX_set_tlsext_servername_callback(ctx, serverNameCallback);
}

SSL握手在SSL_accept中完成。服务器名称在握手中传输。因此,只能从ssl_accept内部调用回调,而不能在之前调用

我正在编写一个https服务器,我需要在使用SNI的ssl_accept()之前从客户端获取主机名

您不需要调用
SSL\u CTX\u set\u tlsext\u servername\u callback
。OpenSSL库将在握手过程中为您调用它

SSLv2和SSLv3客户端不会调用SNI回调。这是因为SNI是TLS的扩展

如果客户端是Windows XP(或不使用TLS扩展的类似客户端),则将调用SNI回调,但
servername
将为
NULL
。在这种情况下,您应该使用默认的服务器上下文

如果客户机使用TLS并向s发送服务器名称,则将调用SNI回调。在回调中,您应该(1)确定默认证书和上下文是否正常。如果正常,则返回
SSL\u TLSEXT\u ERR\u OK
。(2) 如果可以提供更合适的证书,请使用
SSL\u set\u SSL\u CTX
在新上下文中交换,并返回
SSL\u TLSEXT\u ERR\u OK

如果遇到错误(如
NULL
servername
),则应返回
SSL\u TLSEXT\u ERR\u NOACK
。您还可以返回另外两个错误代码。这两个都对连接是致命的,IIRC


回调的实现细节见。

非常感谢:)@jww我已经设置了SSL\u CTX\u set\u tlsext\u servername\u回调(CTX,serverNameCallback);在init_openssl()之后;ctx=创建上下文();配置上下文(ctx);但从未调用回调函数。你能给我一些样品吗?