mirror of
https://github.com/nginx/nginx.git
synced 2025-01-18 17:23:30 +08:00
Stream: DTLS support.
The change adds support for DTLS encryption to udp connections. TLS and DTLS connections may coexist in one server. DTLS termination example: listen 9000 udp ssl; DTLS proxy example: listen 9000 udp; proxy_ssl on; proxy_pass 127.0.0.1:9000; Based on previous work by Vladimir Homutov.
This commit is contained in:
parent
37728de184
commit
fa3d4ad088
@ -11,10 +11,16 @@
|
||||
|
||||
|
||||
#define NGX_SSL_PASSWORD_BUFFER_SIZE 4096
|
||||
#define NGX_SSL_COOKIE_SECRET_LENGTH 32
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_uint_t engine; /* unsigned engine:1; */
|
||||
ngx_uint_t engine; /* unsigned engine:1; */
|
||||
|
||||
#if (NGX_SSL_DTLS)
|
||||
u_char cookie_secret[NGX_SSL_COOKIE_SECRET_LENGTH];
|
||||
BIO_METHOD *method;
|
||||
#endif
|
||||
} ngx_openssl_conf_t;
|
||||
|
||||
|
||||
@ -82,6 +88,17 @@ static time_t ngx_ssl_parse_time(
|
||||
#endif
|
||||
ASN1_TIME *asn1time, ngx_log_t *log);
|
||||
|
||||
#if (NGX_SSL_DTLS)
|
||||
static ngx_int_t ngx_ssl_try_listen(ngx_connection_t *c);
|
||||
static int ngx_ssl_shared_send(BIO *b, const char *in, int inl);
|
||||
static int ngx_ssl_shared_recv(BIO *b, char *out, int outl);
|
||||
static long ngx_ssl_shared_ctrl(BIO *b, int cmd, long num, void *ptr);
|
||||
static int ngx_ssl_generate_cookie(SSL *ssl, unsigned char *cookie,
|
||||
unsigned int *cookie_len);
|
||||
static int ngx_ssl_verify_cookie(SSL *ssl, const unsigned char *cookie,
|
||||
unsigned int cookie_len);
|
||||
#endif
|
||||
|
||||
static void *ngx_openssl_create_conf(ngx_cycle_t *cycle);
|
||||
static char *ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
||||
static void ngx_openssl_exit(ngx_cycle_t *cycle);
|
||||
@ -276,7 +293,18 @@ ngx_ssl_init(ngx_log_t *log)
|
||||
ngx_int_t
|
||||
ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
|
||||
{
|
||||
ssl->ctx = SSL_CTX_new(SSLv23_method());
|
||||
const SSL_METHOD *method;
|
||||
|
||||
#if (NGX_SSL_DTLS)
|
||||
if (ssl->udp) {
|
||||
method = DTLS_method();
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
method = SSLv23_method();
|
||||
}
|
||||
|
||||
ssl->ctx = SSL_CTX_new(method);
|
||||
|
||||
if (ssl->ctx == NULL) {
|
||||
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "SSL_CTX_new() failed");
|
||||
@ -410,6 +438,11 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
|
||||
|
||||
SSL_CTX_set_info_callback(ssl->ctx, ngx_ssl_info_callback);
|
||||
|
||||
#if (NGX_SSL_DTLS)
|
||||
SSL_CTX_set_cookie_generate_cb(ssl->ctx, ngx_ssl_generate_cookie);
|
||||
SSL_CTX_set_cookie_verify_cb(ssl->ctx, ngx_ssl_verify_cookie);
|
||||
#endif
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
@ -1615,6 +1648,28 @@ ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags)
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
#if (NGX_SSL_DTLS)
|
||||
if (c->shared) {
|
||||
BIO *bio;
|
||||
ngx_openssl_conf_t *oscf;
|
||||
|
||||
sc->try_listen = 1;
|
||||
|
||||
oscf = (ngx_openssl_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx,
|
||||
ngx_openssl_module);
|
||||
|
||||
bio = BIO_new(oscf->method);
|
||||
if (bio == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
BIO_set_app_data(bio, c);
|
||||
BIO_set_init(bio, 1);
|
||||
|
||||
SSL_set_bio(sc->connection, bio, bio);
|
||||
|
||||
} else
|
||||
#endif
|
||||
if (SSL_set_fd(sc->connection, c->fd) == 0) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_fd() failed");
|
||||
return NGX_ERROR;
|
||||
@ -1688,6 +1743,12 @@ ngx_ssl_handshake(ngx_connection_t *c)
|
||||
ngx_err_t err;
|
||||
ngx_int_t rc;
|
||||
|
||||
#if (NGX_SSL_DTLS)
|
||||
if (c->ssl->try_listen) {
|
||||
return ngx_ssl_try_listen(c);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_READ_EARLY_DATA_SUCCESS
|
||||
if (c->ssl->try_early_data) {
|
||||
return ngx_ssl_try_early_data(c);
|
||||
@ -5868,6 +5929,227 @@ ngx_ssl_parse_time(
|
||||
}
|
||||
|
||||
|
||||
#if (NGX_SSL_DTLS)
|
||||
|
||||
static ngx_int_t
|
||||
ngx_ssl_try_listen(ngx_connection_t *c)
|
||||
{
|
||||
int n, sslerr;
|
||||
BIO *rbio;
|
||||
ngx_err_t err;
|
||||
#ifdef LIBRESSL_VERSION_NUMBER
|
||||
static ngx_sockaddr_t speer;
|
||||
static struct sockaddr *peer;
|
||||
#else
|
||||
static BIO_ADDR *peer;
|
||||
#endif
|
||||
|
||||
if (peer == NULL) {
|
||||
#ifdef LIBRESSL_VERSION_NUMBER
|
||||
peer = &speer.sockaddr;
|
||||
#else
|
||||
peer = BIO_ADDR_new();
|
||||
|
||||
if (peer == NULL) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_ADDR_new() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
n = DTLSv1_listen(c->ssl->connection, peer);
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "DTLSv1_listen: %d", n);
|
||||
|
||||
if (n > 0) {
|
||||
c->ssl->try_listen = 0;
|
||||
return ngx_ssl_handshake(c);
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
/* n < 0 */
|
||||
|
||||
rbio = SSL_get_rbio(c->ssl->connection);
|
||||
if (rbio && BIO_should_retry(rbio)) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
sslerr = SSL_get_error(c->ssl->connection, n);
|
||||
|
||||
err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
|
||||
|
||||
c->read->error = 1;
|
||||
|
||||
ngx_ssl_connection_error(c, sslerr, err, "DTLSv1_listen() failed");
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ngx_ssl_shared_send(BIO *b, const char *in, int inl)
|
||||
{
|
||||
ssize_t n;
|
||||
ngx_connection_t *c;
|
||||
|
||||
c = BIO_get_app_data(b);
|
||||
|
||||
BIO_clear_retry_flags(b);
|
||||
|
||||
n = ngx_udp_send(c, (u_char *) in, inl);
|
||||
|
||||
if (n == NGX_ERROR) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"ssl shared send failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (n == NGX_AGAIN) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"ssl shared send not ready");
|
||||
BIO_set_retry_write(b);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "ssl shared send n:%z", n);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ngx_ssl_shared_recv(BIO *b, char *out, int outl)
|
||||
{
|
||||
ssize_t n;
|
||||
ngx_buf_t *bb;
|
||||
ngx_connection_t *c;
|
||||
|
||||
c = BIO_get_app_data(b);
|
||||
|
||||
n = 0;
|
||||
|
||||
if (out) {
|
||||
BIO_clear_retry_flags(b);
|
||||
|
||||
bb = c->buffer;
|
||||
|
||||
if (bb && bb->pos != bb->last) {
|
||||
/* TODO move to ngx_udp_shared_recv() */
|
||||
|
||||
n = ngx_min(outl, bb->last - bb->pos);
|
||||
ngx_memcpy(out, bb->pos, n);
|
||||
bb->pos = bb->last;
|
||||
|
||||
goto done;
|
||||
}
|
||||
|
||||
n = ngx_udp_shared_recv(c, (u_char *) out, outl);
|
||||
|
||||
if (n == NGX_ERROR) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"ssl shared recv failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (n == NGX_AGAIN) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"ssl shared recv not ready");
|
||||
BIO_set_retry_read(b);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "ssl shared recv n:%z", n);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
static long
|
||||
ngx_ssl_shared_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
{
|
||||
long ret;
|
||||
#if (NGX_DEBUG)
|
||||
ngx_connection_t *c;
|
||||
|
||||
c = BIO_get_app_data(b);
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"ssl shared ctrl c:%d n:%l", cmd, num);
|
||||
#endif
|
||||
|
||||
switch (cmd) {
|
||||
case BIO_CTRL_DGRAM_QUERY_MTU:
|
||||
case BIO_CTRL_DGRAM_GET_MTU:
|
||||
case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
|
||||
/* TODO MTU discovery */
|
||||
ret = 1200;
|
||||
break;
|
||||
case BIO_CTRL_FLUSH:
|
||||
ret = 1;
|
||||
break;
|
||||
default:
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ngx_ssl_generate_cookie(SSL *ssl, unsigned char *cookie,
|
||||
unsigned int *cookie_len)
|
||||
{
|
||||
ngx_connection_t *c;
|
||||
ngx_openssl_conf_t *oscf;
|
||||
|
||||
c = ngx_ssl_get_connection(ssl);
|
||||
|
||||
oscf = (ngx_openssl_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx,
|
||||
ngx_openssl_module);
|
||||
|
||||
/* SHA256_DIGEST_LENGTH <= DTLS1_COOKIE_LENGTH */
|
||||
|
||||
if (HMAC(EVP_sha256(), oscf->cookie_secret, NGX_SSL_COOKIE_SECRET_LENGTH,
|
||||
(u_char *) c->sockaddr, c->socklen, cookie, cookie_len)
|
||||
== NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ngx_ssl_verify_cookie(SSL *ssl, const unsigned char *cookie,
|
||||
unsigned int cookie_len)
|
||||
{
|
||||
unsigned int ocookie_len;
|
||||
u_char ocookie[DTLS1_COOKIE_LENGTH];
|
||||
|
||||
if (ngx_ssl_generate_cookie(ssl, ocookie, &ocookie_len) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cookie_len != ocookie_len
|
||||
|| ngx_memcmp(cookie, ocookie, cookie_len) != 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static void *
|
||||
ngx_openssl_create_conf(ngx_cycle_t *cycle)
|
||||
{
|
||||
@ -5884,6 +6166,23 @@ ngx_openssl_create_conf(ngx_cycle_t *cycle)
|
||||
* oscf->engine = 0;
|
||||
*/
|
||||
|
||||
#if (NGX_SSL_DTLS)
|
||||
|
||||
if (!RAND_bytes(oscf->cookie_secret, NGX_SSL_COOKIE_SECRET_LENGTH)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
oscf->method = BIO_meth_new(BIO_TYPE_DGRAM, "nginx dgram wrapper");
|
||||
if (oscf->method == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BIO_meth_set_write(oscf->method, ngx_ssl_shared_send);
|
||||
BIO_meth_set_read(oscf->method, ngx_ssl_shared_recv);
|
||||
BIO_meth_set_ctrl(oscf->method, ngx_ssl_shared_ctrl);
|
||||
|
||||
#endif
|
||||
|
||||
return oscf;
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,10 @@
|
||||
|
||||
#endif
|
||||
|
||||
#if (!defined OPENSSL_IS_BORINGSSL && !defined OPENSSL_NO_DTLS \
|
||||
&& !NGX_WIN32 && OPENSSL_VERSION_NUMBER >= 0x10100000L)
|
||||
#define NGX_SSL_DTLS 1
|
||||
#endif
|
||||
|
||||
#define ngx_ssl_session_t SSL_SESSION
|
||||
#define ngx_ssl_conn_t SSL
|
||||
@ -95,6 +99,10 @@ struct ngx_ssl_s {
|
||||
|
||||
ngx_rbtree_t staple_rbtree;
|
||||
ngx_rbtree_node_t staple_sentinel;
|
||||
|
||||
#if (NGX_SSL_DTLS)
|
||||
ngx_uint_t udp; /* unsigned udp:1; */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@ -128,6 +136,7 @@ struct ngx_ssl_connection_s {
|
||||
unsigned shutdown_without_free:1;
|
||||
unsigned handshake_buffer_set:1;
|
||||
unsigned session_timeout_set:1;
|
||||
unsigned try_listen:1;
|
||||
unsigned try_early_data:1;
|
||||
unsigned in_early:1;
|
||||
unsigned in_ocsp:1;
|
||||
|
@ -13,8 +13,6 @@
|
||||
#if !(NGX_WIN32)
|
||||
|
||||
static void ngx_close_accepted_udp_connection(ngx_connection_t *c);
|
||||
static ssize_t ngx_udp_shared_recv(ngx_connection_t *c, u_char *buf,
|
||||
size_t size);
|
||||
static ngx_int_t ngx_insert_udp_connection(ngx_connection_t *c);
|
||||
static ngx_connection_t *ngx_lookup_udp_connection(ngx_listening_t *ls,
|
||||
struct sockaddr *sockaddr, socklen_t socklen,
|
||||
@ -365,7 +363,7 @@ ngx_close_accepted_udp_connection(ngx_connection_t *c)
|
||||
}
|
||||
|
||||
|
||||
static ssize_t
|
||||
ssize_t
|
||||
ngx_udp_shared_recv(ngx_connection_t *c, u_char *buf, size_t size)
|
||||
{
|
||||
ssize_t n;
|
||||
|
@ -56,6 +56,7 @@ ngx_int_t ngx_get_srcaddr_cmsg(struct cmsghdr *cmsg,
|
||||
|
||||
void ngx_event_recvmsg(ngx_event_t *ev);
|
||||
ssize_t ngx_sendmsg(ngx_connection_t *c, struct msghdr *msg, int flags);
|
||||
ssize_t ngx_udp_shared_recv(ngx_connection_t *c, u_char *buf, size_t size);
|
||||
void ngx_udp_rbtree_insert_value(ngx_rbtree_node_t *temp,
|
||||
ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
|
||||
#endif
|
||||
|
@ -1237,7 +1237,7 @@ ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (NGX_STREAM_SSL)
|
||||
#if (NGX_STREAM_SSL && !NGX_SSL_DTLS)
|
||||
if (lsopt.ssl) {
|
||||
return "\"ssl\" parameter is incompatible with \"udp\"";
|
||||
}
|
||||
|
@ -53,6 +53,9 @@ typedef struct {
|
||||
ngx_array_t *ssl_conf_commands;
|
||||
|
||||
ngx_ssl_t *ssl;
|
||||
#if (NGX_SSL_DTLS)
|
||||
ngx_ssl_t *ssl_udp;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
ngx_stream_upstream_srv_conf_t *upstream;
|
||||
@ -822,9 +825,9 @@ ngx_stream_proxy_init_upstream(ngx_stream_session_t *s)
|
||||
|
||||
#if (NGX_STREAM_SSL)
|
||||
|
||||
if (pc->type == SOCK_STREAM && pscf->ssl_enable) {
|
||||
if (pscf->ssl_enable) {
|
||||
|
||||
if (u->proxy_protocol) {
|
||||
if (pc->type == SOCK_STREAM && u->proxy_protocol) {
|
||||
if (ngx_stream_proxy_send_proxy_protocol(s) != NGX_OK) {
|
||||
return;
|
||||
}
|
||||
@ -1068,6 +1071,7 @@ static void
|
||||
ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t *s)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
ngx_ssl_t *ssl;
|
||||
ngx_connection_t *pc;
|
||||
ngx_stream_upstream_t *u;
|
||||
ngx_stream_proxy_srv_conf_t *pscf;
|
||||
@ -1078,7 +1082,16 @@ ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t *s)
|
||||
|
||||
pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
|
||||
|
||||
if (ngx_ssl_create_connection(pscf->ssl, pc, NGX_SSL_BUFFER|NGX_SSL_CLIENT)
|
||||
#if (NGX_SSL_DTLS)
|
||||
if (pc->type == SOCK_DGRAM) {
|
||||
ssl = pscf->ssl_udp;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ssl = pscf->ssl;
|
||||
}
|
||||
|
||||
if (ngx_ssl_create_connection(ssl, pc, NGX_SSL_BUFFER|NGX_SSL_CLIENT)
|
||||
!= NGX_OK)
|
||||
{
|
||||
ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
|
||||
@ -2092,6 +2105,7 @@ ngx_stream_proxy_create_srv_conf(ngx_conf_t *cf)
|
||||
* conf->ssl_crl = { 0, NULL };
|
||||
*
|
||||
* conf->ssl = NULL;
|
||||
* conf->ssl_udp = NULL;
|
||||
* conf->upstream = NULL;
|
||||
* conf->upstream_value = NULL;
|
||||
*/
|
||||
@ -2215,6 +2229,13 @@ ngx_stream_proxy_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
if (ngx_stream_proxy_set_ssl(cf, conf, conf->ssl) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
#if (NGX_SSL_DTLS)
|
||||
conf->ssl_udp->udp = 1;
|
||||
if (ngx_stream_proxy_set_ssl(cf, conf, conf->ssl_udp) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -2245,6 +2266,9 @@ ngx_stream_proxy_merge_ssl(ngx_conf_t *cf, ngx_stream_proxy_srv_conf_t *conf,
|
||||
{
|
||||
if (prev->ssl) {
|
||||
conf->ssl = prev->ssl;
|
||||
#if (NGX_SSL_DTLS)
|
||||
conf->ssl_udp = prev->ssl_udp;
|
||||
#endif
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
@ -2261,6 +2285,15 @@ ngx_stream_proxy_merge_ssl(ngx_conf_t *cf, ngx_stream_proxy_srv_conf_t *conf,
|
||||
|
||||
conf->ssl->log = cf->log;
|
||||
|
||||
#if (NGX_SSL_DTLS)
|
||||
conf->ssl_udp = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
|
||||
if (conf->ssl_udp == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
conf->ssl_udp->log = cf->log;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* special handling to preserve conf->ssl
|
||||
* in the "stream" section to inherit it to all servers
|
||||
@ -2268,6 +2301,9 @@ ngx_stream_proxy_merge_ssl(ngx_conf_t *cf, ngx_stream_proxy_srv_conf_t *conf,
|
||||
|
||||
if (preserve) {
|
||||
prev->ssl = conf->ssl;
|
||||
#if (NGX_SSL_DTLS)
|
||||
prev->ssl_udp = conf->ssl_udp;
|
||||
#endif
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
|
@ -403,6 +403,7 @@ ngx_stream_ssl_handler(ngx_stream_session_t *s)
|
||||
{
|
||||
long rc;
|
||||
X509 *cert;
|
||||
ngx_ssl_t *ssl;
|
||||
ngx_int_t rv;
|
||||
ngx_connection_t *c;
|
||||
ngx_stream_ssl_srv_conf_t *sscf;
|
||||
@ -418,7 +419,16 @@ ngx_stream_ssl_handler(ngx_stream_session_t *s)
|
||||
if (c->ssl == NULL) {
|
||||
c->log->action = "SSL handshaking";
|
||||
|
||||
rv = ngx_stream_ssl_init_connection(&sscf->ssl, c);
|
||||
#if (NGX_SSL_DTLS)
|
||||
if (c->type == SOCK_DGRAM) {
|
||||
ssl = &sscf->ssl_udp;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ssl = &sscf->ssl;
|
||||
}
|
||||
|
||||
rv = ngx_stream_ssl_init_connection(ssl, c);
|
||||
|
||||
if (rv != NGX_OK) {
|
||||
return rv;
|
||||
@ -472,7 +482,9 @@ ngx_stream_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c)
|
||||
|
||||
cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module);
|
||||
|
||||
if (cscf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) {
|
||||
if (c->type == SOCK_STREAM
|
||||
&& cscf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
@ -529,6 +541,7 @@ ngx_stream_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
ngx_str_t host;
|
||||
ngx_ssl_t *ssl;
|
||||
const char *servername;
|
||||
ngx_connection_t *c;
|
||||
ngx_stream_session_t *s;
|
||||
@ -589,8 +602,17 @@ ngx_stream_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
||||
|
||||
sscf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module);
|
||||
|
||||
if (sscf->ssl.ctx) {
|
||||
if (SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx) == NULL) {
|
||||
#if (NGX_SSL_DTLS)
|
||||
if (c->type == SOCK_DGRAM) {
|
||||
ssl = &sscf->ssl_udp;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ssl = &sscf->ssl;
|
||||
}
|
||||
|
||||
if (ssl->ctx) {
|
||||
if (SSL_set_SSL_CTX(ssl_conn, ssl->ctx) == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -599,18 +621,18 @@ ngx_stream_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
||||
* adjust other things we care about
|
||||
*/
|
||||
|
||||
SSL_set_verify(ssl_conn, SSL_CTX_get_verify_mode(sscf->ssl.ctx),
|
||||
SSL_CTX_get_verify_callback(sscf->ssl.ctx));
|
||||
SSL_set_verify(ssl_conn, SSL_CTX_get_verify_mode(ssl->ctx),
|
||||
SSL_CTX_get_verify_callback(ssl->ctx));
|
||||
|
||||
SSL_set_verify_depth(ssl_conn, SSL_CTX_get_verify_depth(sscf->ssl.ctx));
|
||||
SSL_set_verify_depth(ssl_conn, SSL_CTX_get_verify_depth(ssl->ctx));
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x009080dfL
|
||||
/* only in 0.9.8m+ */
|
||||
SSL_clear_options(ssl_conn, SSL_get_options(ssl_conn) &
|
||||
~SSL_CTX_get_options(sscf->ssl.ctx));
|
||||
~SSL_CTX_get_options(ssl->ctx));
|
||||
#endif
|
||||
|
||||
SSL_set_options(ssl_conn, SSL_CTX_get_options(sscf->ssl.ctx));
|
||||
SSL_set_options(ssl_conn, SSL_CTX_get_options(ssl->ctx));
|
||||
|
||||
#ifdef SSL_OP_NO_RENEGOTIATION
|
||||
SSL_set_options(ssl_conn, SSL_OP_NO_RENEGOTIATION);
|
||||
@ -943,6 +965,13 @@ ngx_stream_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
#if (NGX_SSL_DTLS)
|
||||
conf->ssl_udp.udp = 1;
|
||||
if (ngx_stream_ssl_set_ssl(cf, conf, prev, &conf->ssl_udp) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
@ -1527,6 +1556,15 @@ ngx_stream_ssl_init(ngx_conf_t *cf)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
#if (NGX_SSL_DTLS)
|
||||
if (ngx_ssl_stapling_resolver(cf, &sscf->ssl_udp, cscf->resolver,
|
||||
cscf->resolver_timeout)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (sscf->ocsp) {
|
||||
@ -1536,6 +1574,15 @@ ngx_stream_ssl_init(ngx_conf_t *cf)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
#if (NGX_SSL_DTLS)
|
||||
if (ngx_ssl_ocsp_resolver(cf, &sscf->ssl_udp, cscf->resolver,
|
||||
cscf->resolver_timeout)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,9 @@ typedef struct {
|
||||
ngx_flag_t reject_handshake;
|
||||
|
||||
ngx_ssl_t ssl;
|
||||
#if (NGX_SSL_DTLS)
|
||||
ngx_ssl_t ssl_udp;
|
||||
#endif
|
||||
|
||||
ngx_uint_t protocols;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user