mirror of
https://github.com/sogou/workflow.git
synced 2026-10-26 01:30:47 +08:00
Support TLS SNI on server side.
This commit is contained in:
@@ -56,6 +56,8 @@ protected:
|
||||
this->ssl_connect_timeout = ssl_connect_timeout;
|
||||
}
|
||||
|
||||
SSL_CTX *get_ssl_ctx() const { return this->ssl_ctx; }
|
||||
|
||||
private:
|
||||
virtual int create_connect_fd()
|
||||
{
|
||||
@@ -181,6 +183,8 @@ protected:
|
||||
this->ssl_accept_timeout = ssl_accept_timeout;
|
||||
}
|
||||
|
||||
SSL_CTX *get_ssl_ctx() const { return this->ssl_ctx; }
|
||||
|
||||
private:
|
||||
virtual CommSession *new_session(long long seq, CommConnection *conn) = 0;
|
||||
virtual void handle_stop(int error) { }
|
||||
|
||||
@@ -173,7 +173,7 @@ public:
|
||||
}
|
||||
|
||||
SSL_CTX *get_ssl_client_ctx() { return ssl_client_ctx_; }
|
||||
SSL_CTX *get_ssl_server_ctx() { return ssl_server_ctx_; }
|
||||
SSL_CTX *new_ssl_server_ctx() { return SSL_CTX_new(SSLv23_server_method()); }
|
||||
|
||||
private:
|
||||
__SSLManager()
|
||||
@@ -189,14 +189,11 @@ private:
|
||||
|
||||
ssl_client_ctx_ = SSL_CTX_new(SSLv23_client_method());
|
||||
assert(ssl_client_ctx_ != NULL);
|
||||
ssl_server_ctx_ = SSL_CTX_new(SSLv23_server_method());
|
||||
assert(ssl_server_ctx_ != NULL);
|
||||
}
|
||||
|
||||
~__SSLManager()
|
||||
{
|
||||
SSL_CTX_free(ssl_client_ctx_);
|
||||
SSL_CTX_free(ssl_server_ctx_);
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
//free ssl to avoid memory leak
|
||||
@@ -224,7 +221,6 @@ private:
|
||||
|
||||
private:
|
||||
SSL_CTX *ssl_client_ctx_;
|
||||
SSL_CTX *ssl_server_ctx_;
|
||||
};
|
||||
|
||||
class IOServer : public IOService
|
||||
@@ -559,9 +555,9 @@ SSL_CTX *WFGlobal::get_ssl_client_ctx()
|
||||
return __SSLManager::get_instance()->get_ssl_client_ctx();
|
||||
}
|
||||
|
||||
SSL_CTX *WFGlobal::get_ssl_server_ctx()
|
||||
SSL_CTX *WFGlobal::new_ssl_server_ctx()
|
||||
{
|
||||
return __SSLManager::get_instance()->get_ssl_server_ctx();
|
||||
return __SSLManager::get_instance()->new_ssl_server_ctx();
|
||||
}
|
||||
|
||||
ExecQueue *WFGlobal::get_exec_queue(const std::string& queue_name)
|
||||
|
||||
@@ -111,7 +111,7 @@ public:
|
||||
static DNSCache *get_dns_cache();
|
||||
static RouteManager *get_route_manager();
|
||||
static SSL_CTX *get_ssl_client_ctx();
|
||||
static SSL_CTX *get_ssl_server_ctx();
|
||||
static SSL_CTX *new_ssl_server_ctx();
|
||||
static ExecQueue *get_exec_queue(const std::string& queue_name);
|
||||
static Executor *get_compute_executor();
|
||||
static IOService *get_io_service();
|
||||
|
||||
+45
-7
@@ -49,6 +49,42 @@ private:
|
||||
std::atomic<size_t> *conn_count;
|
||||
};
|
||||
|
||||
long WFServerBase::ssl_ctx_callback(SSL *ssl, int *al, void *arg)
|
||||
{
|
||||
WFServerBase *server = (WFServerBase *)arg;
|
||||
const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
|
||||
SSL_CTX *ssl_ctx = server->get_server_ssl_ctx(servername);
|
||||
|
||||
if (!ssl_ctx)
|
||||
return SSL_TLSEXT_ERR_NOACK;
|
||||
|
||||
if (ssl_ctx != server->get_ssl_ctx())
|
||||
SSL_set_SSL_CTX(ssl, ssl_ctx);
|
||||
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
}
|
||||
|
||||
int WFServerBase::init_ssl_ctx(const char *cert_file, const char *key_file)
|
||||
{
|
||||
SSL_CTX *ssl_ctx = WFGlobal::new_ssl_server_ctx();
|
||||
|
||||
if (!ssl_ctx)
|
||||
return -1;
|
||||
|
||||
SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_NONE, NULL);
|
||||
if (SSL_CTX_use_certificate_file(ssl_ctx, cert_file, SSL_FILETYPE_PEM) > 0 &&
|
||||
SSL_CTX_use_PrivateKey_file(ssl_ctx, key_file, SSL_FILETYPE_PEM) > 0 &&
|
||||
SSL_CTX_set_tlsext_servername_callback(ssl_ctx, ssl_ctx_callback) > 0 &&
|
||||
SSL_CTX_set_tlsext_servername_arg(ssl_ctx, this) > 0)
|
||||
{
|
||||
this->set_ssl(ssl_ctx, this->params.ssl_accept_timeout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SSL_CTX_free(ssl_ctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int WFServerBase::init(const struct sockaddr *bind_addr, socklen_t addrlen,
|
||||
const char *cert_file, const char *key_file)
|
||||
{
|
||||
@@ -65,17 +101,11 @@ int WFServerBase::init(const struct sockaddr *bind_addr, socklen_t addrlen,
|
||||
|
||||
if (key_file && cert_file)
|
||||
{
|
||||
SSL_CTX *ssl_ctx = WFGlobal::get_ssl_server_ctx();
|
||||
|
||||
SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_NONE, NULL);
|
||||
if (SSL_CTX_use_certificate_file(ssl_ctx, cert_file, SSL_FILETYPE_PEM) <= 0 ||
|
||||
SSL_CTX_use_PrivateKey_file(ssl_ctx, key_file, SSL_FILETYPE_PEM) <= 0)
|
||||
if (this->init_ssl_ctx(cert_file, key_file) < 0)
|
||||
{
|
||||
this->deinit();
|
||||
return -1;
|
||||
}
|
||||
|
||||
this->set_ssl(ssl_ctx, params.ssl_accept_timeout);
|
||||
}
|
||||
|
||||
this->scheduler = WFGlobal::get_scheduler();
|
||||
@@ -131,12 +161,17 @@ void WFServerBase::handle_unbound()
|
||||
int WFServerBase::start(const struct sockaddr *bind_addr, socklen_t addrlen,
|
||||
const char *cert_file, const char *key_file)
|
||||
{
|
||||
SSL_CTX *ssl_ctx;
|
||||
|
||||
if (this->init(bind_addr, addrlen, cert_file, key_file) >= 0)
|
||||
{
|
||||
if (this->scheduler->bind(this) >= 0)
|
||||
return 0;
|
||||
|
||||
ssl_ctx = this->get_ssl_ctx();
|
||||
this->deinit();
|
||||
if (ssl_ctx)
|
||||
SSL_CTX_free(ssl_ctx);
|
||||
}
|
||||
|
||||
return -1;
|
||||
@@ -225,6 +260,7 @@ void WFServerBase::shutdown()
|
||||
|
||||
void WFServerBase::wait_finish()
|
||||
{
|
||||
SSL_CTX *ssl_ctx = this->get_ssl_ctx();
|
||||
std::unique_lock<std::mutex> lock(this->mutex);
|
||||
|
||||
while (!this->unbind_finish)
|
||||
@@ -233,5 +269,7 @@ void WFServerBase::wait_finish()
|
||||
this->deinit();
|
||||
this->unbind_finish = false;
|
||||
lock.unlock();
|
||||
if (ssl_ctx)
|
||||
SSL_CTX_free(ssl_ctx);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <functional>
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
@@ -144,6 +145,15 @@ public:
|
||||
public:
|
||||
size_t get_conn_count() const { return this->conn_count; }
|
||||
|
||||
private:
|
||||
/* Override this function to implement server that supports TLS SNI.
|
||||
* "servername" will be NULL if client does not set a host name.
|
||||
* Returning NULL to indicate that servername is not supported. */
|
||||
virtual SSL_CTX *get_server_ssl_ctx(const char *servername)
|
||||
{
|
||||
return this->get_ssl_ctx();
|
||||
}
|
||||
|
||||
protected:
|
||||
WFServerParams params;
|
||||
|
||||
@@ -153,6 +163,8 @@ protected:
|
||||
private:
|
||||
int init(const struct sockaddr *bind_addr, socklen_t addrlen,
|
||||
const char *cert_file, const char *key_file);
|
||||
int init_ssl_ctx(const char *cert_file, const char *key_file);
|
||||
static long ssl_ctx_callback(SSL *ssl, int *al, void *arg);
|
||||
virtual int create_listen_fd();
|
||||
virtual void handle_unbound();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user