From 113afb09ea7ddeebf2376cf6df3af212705e6128 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Thu, 22 Apr 2021 13:13:06 +0800 Subject: Router: grouped app and share fields in nxt_http_action_t. This is a prerequisite for further introduction of openat2() features. No functional changes. --- src/nxt_router.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nxt_router.c') diff --git a/src/nxt_router.c b/src/nxt_router.c index 8524b358..a20e4ede 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -2144,7 +2144,7 @@ nxt_router_listener_application(nxt_router_conf_t *rtcf, nxt_str_t *name, return NXT_DECLINED; } - action->u.application = app; + action->u.app.application = app; action->handler = nxt_http_application_handler; return NXT_OK; -- cgit From c216f26d3040beef46ca25f73e580153c4c59d02 Mon Sep 17 00:00:00 2001 From: Max Romanov Date: Mon, 17 May 2021 17:34:15 +0300 Subject: Fixing racing condition on listen socket close in router. Listen socket is actually closed in the instant timer handler. This patch moves the "configuration has been applied" notification to the timer handler to avoid a situation when the user gets the response from the controller, but the listen socket is still open in the router. --- src/nxt_router.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'src/nxt_router.c') diff --git a/src/nxt_router.c b/src/nxt_router.c index a20e4ede..da38aac0 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -3223,12 +3223,11 @@ nxt_router_listen_socket_update(nxt_task_t *task, void *obj, void *data) static void nxt_router_listen_socket_delete(nxt_task_t *task, void *obj, void *data) { - nxt_joint_job_t *job; - nxt_socket_conf_t *skcf; - nxt_listen_event_t *lev; - nxt_event_engine_t *engine; + nxt_socket_conf_t *skcf; + nxt_listen_event_t *lev; + nxt_event_engine_t *engine; + nxt_socket_conf_joint_t *joint; - job = obj; skcf = data; engine = task->thread->engine; @@ -3240,15 +3239,13 @@ nxt_router_listen_socket_delete(nxt_task_t *task, void *obj, void *data) nxt_debug(task, "engine %p: listen socket delete: %d", engine, lev->socket.fd); + joint = lev->socket.data; + joint->close_job = obj; + lev->timer.handler = nxt_router_listen_socket_close; lev->timer.work_queue = &engine->fast_work_queue; nxt_timer_add(engine, &lev->timer, 0); - - job->work.next = NULL; - job->work.handler = nxt_router_conf_wait; - - nxt_event_engine_post(job->tmcf->engine, &job->work); } @@ -3273,6 +3270,7 @@ static void nxt_router_listen_socket_close(nxt_task_t *task, void *obj, void *data) { nxt_timer_t *timer; + nxt_joint_job_t *job; nxt_listen_event_t *lev; nxt_socket_conf_joint_t *joint; @@ -3287,6 +3285,12 @@ nxt_router_listen_socket_close(nxt_task_t *task, void *obj, void *data) joint = lev->socket.data; lev->socket.data = NULL; + job = joint->close_job; + job->work.next = NULL; + job->work.handler = nxt_router_conf_wait; + + nxt_event_engine_post(job->tmcf->engine, &job->work); + /* 'task' refers to lev->task and we cannot use after nxt_free() */ task = &task->thread->engine->task; -- cgit From 19dfeba86b9dda6f1960ba9b3dba4708565d27ad Mon Sep 17 00:00:00 2001 From: Andrey Suvorov Date: Mon, 17 May 2021 14:28:38 -0700 Subject: Fixing a crash after applying the wrong TLS configuration. When an invalid TLS configuration is applied (such as the conf_commands feature), nxt_cert_store_get() creates a buffer to send a certificate request to the main process and adds its default completion handler to an asynchronous queue to free the allocated buffer. However, if configuration fails, nxt_router_conf_error() removes the memory pool used to allocate the buffer, causing a crash when the completion handler is dispatched. Assertion "src/nxt_buf.c:208 assertion failed: data == b->parent" is triggered when is NXT_DEBUG enabled in the configure script. This patch uses a reference counter to retain the memory pool and redefines the completion handler to free the buffer before releasing the memory pool. --- src/nxt_router.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/nxt_router.c') diff --git a/src/nxt_router.c b/src/nxt_router.c index da38aac0..2bbe87b8 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -773,7 +773,7 @@ fail: msg->port_msg.stream, 0, NULL); if (tmcf != NULL) { - nxt_mp_destroy(tmcf->mem_pool); + nxt_mp_release(tmcf->mem_pool); } cleanup: @@ -1061,7 +1061,7 @@ nxt_router_conf_ready(nxt_task_t *task, nxt_router_temp_conf_t *tmcf) nxt_mp_destroy(rtcf->mem_pool); } - nxt_mp_destroy(tmcf->mem_pool); + nxt_mp_release(tmcf->mem_pool); } @@ -1120,7 +1120,7 @@ nxt_router_conf_error(nxt_task_t *task, nxt_router_temp_conf_t *tmcf) nxt_router_conf_send(task, tmcf, NXT_PORT_MSG_RPC_ERROR); - nxt_mp_destroy(tmcf->mem_pool); + nxt_mp_release(tmcf->mem_pool); } -- cgit From 24905c1a00dbf8f62c902d1b248279c5a31cf199 Mon Sep 17 00:00:00 2001 From: Max Romanov Date: Tue, 25 May 2021 18:01:00 +0300 Subject: Fixing racing condition on listen socket close in router (v2). This patch fixes a possible race between the nxt_router_conf_wait() and nxt_router_listen_socket_release() function calls and improves the 7f1b2eaa2d58 commit fix. --- src/nxt_router.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/nxt_router.c') diff --git a/src/nxt_router.c b/src/nxt_router.c index 2bbe87b8..c597863e 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -3285,17 +3285,17 @@ nxt_router_listen_socket_close(nxt_task_t *task, void *obj, void *data) joint = lev->socket.data; lev->socket.data = NULL; + /* 'task' refers to lev->task and we cannot use after nxt_free() */ + task = &task->thread->engine->task; + + nxt_router_listen_socket_release(task, joint->socket_conf); + job = joint->close_job; job->work.next = NULL; job->work.handler = nxt_router_conf_wait; nxt_event_engine_post(job->tmcf->engine, &job->work); - /* 'task' refers to lev->task and we cannot use after nxt_free() */ - task = &task->thread->engine->task; - - nxt_router_listen_socket_release(task, joint->socket_conf); - nxt_router_listen_event_release(task, lev, joint); } -- cgit From 3efffddd95e564fe10f59e1de45afc2b551a5cba Mon Sep 17 00:00:00 2001 From: Andrey Suvorov Date: Wed, 26 May 2021 11:11:58 -0700 Subject: Fixing crash during TLS connection shutdown. A crash was caused by an incorrect timer handler nxt_h1p_idle_timeout() if SSL_shutdown() returned SSL_ERROR_WANT_READ/SSL_ERROR_WANT_WRITE. The flag SSL_RECEIVED_SHUTDOWN is used to avoid getting SSL_ERROR_WANT_READ, so the server won't wait for a close notification from a client. For SSL_ERROR_WANT_WRITE, a correct timer handler is set up. --- src/nxt_router.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nxt_router.c') diff --git a/src/nxt_router.c b/src/nxt_router.c index c597863e..122fd523 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -2477,6 +2477,7 @@ nxt_router_tls_rpc_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg, goto fail; } + tlscf->no_wait_shutdown = 1; rpc->socket_conf->tls = tlscf; } else { -- cgit From 3f7ccf142ff4d1a11b807a344bcb1e3cb6c3284b Mon Sep 17 00:00:00 2001 From: Andrey Suvorov Date: Wed, 26 May 2021 11:19:47 -0700 Subject: Enabling SSL_CTX configuration by using SSL_CONF_cmd(). To perform various configuration operations on SSL_CTX, OpenSSL provides SSL_CONF_cmd(). Specifically, to configure ciphers for a listener, "CipherString" and "Ciphersuites" file commands are used: https://www.openssl.org/docs/man1.1.1/man3/SSL_CONF_cmd.html This feature can be configured in the "tls/conf_commands" section. --- src/nxt_router.c | 90 ++++++++++++++++++++++++-------------------------------- 1 file changed, 38 insertions(+), 52 deletions(-) (limited to 'src/nxt_router.c') diff --git a/src/nxt_router.c b/src/nxt_router.c index 122fd523..015ae226 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -41,8 +41,11 @@ typedef struct { #if (NXT_TLS) typedef struct { - nxt_str_t name; - nxt_socket_conf_t *conf; + nxt_str_t name; + nxt_socket_conf_t *socket_conf; + nxt_router_temp_conf_t *temp_conf; + nxt_conf_value_t *conf_cmds; + nxt_bool_t last; nxt_queue_link_t link; /* for nxt_socket_conf_t.tls */ } nxt_router_tlssock_t; @@ -117,12 +120,11 @@ static void nxt_router_listen_socket_ready(nxt_task_t *task, static void nxt_router_listen_socket_error(nxt_task_t *task, nxt_port_recv_msg_t *msg, void *data); #if (NXT_TLS) -static void nxt_router_tls_rpc_create(nxt_task_t *task, - nxt_router_temp_conf_t *tmcf, nxt_router_tlssock_t *tls, nxt_bool_t last); static void nxt_router_tls_rpc_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg, void *data); static nxt_int_t nxt_router_conf_tls_insert(nxt_router_temp_conf_t *tmcf, - nxt_conf_value_t *value, nxt_socket_conf_t *skcf); + nxt_conf_value_t *value, nxt_socket_conf_t *skcf, + nxt_conf_value_t * conf_cmds); #endif static void nxt_router_app_rpc_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_app_t *app); @@ -954,8 +956,10 @@ nxt_router_conf_apply(nxt_task_t *task, void *obj, void *data) tls = nxt_queue_link_data(qlk, nxt_router_tlssock_t, link); - nxt_router_tls_rpc_create(task, tmcf, tls, - nxt_queue_is_empty(&tmcf->tls)); + tls->last = nxt_queue_is_empty(&tmcf->tls); + + nxt_cert_store_get(task, &tls->name, tmcf->mem_pool, + nxt_router_tls_rpc_handler, tls); return; } #endif @@ -1337,7 +1341,7 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_router_t *router; nxt_app_joint_t *app_joint; #if (NXT_TLS) - nxt_conf_value_t *certificate; + nxt_conf_value_t *certificate, *conf_cmds; #endif nxt_conf_value_t *conf, *http, *value, *websocket; nxt_conf_value_t *applications, *application; @@ -1358,6 +1362,7 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, static nxt_str_t access_log_path = nxt_string("/access_log"); #if (NXT_TLS) static nxt_str_t certificate_path = nxt_string("/tls/certificate"); + static nxt_str_t conf_commands_path = nxt_string("/tls/conf_commands"); #endif static nxt_str_t static_path = nxt_string("/settings/http/static"); static nxt_str_t websocket_path = nxt_string("/settings/http/websocket"); @@ -1736,6 +1741,8 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, certificate = nxt_conf_get_path(listener, &certificate_path); if (certificate != NULL) { + conf_cmds = nxt_conf_get_path(listener, &conf_commands_path); + if (nxt_conf_type(certificate) == NXT_CONF_ARRAY) { n = nxt_conf_array_elements_count(certificate); @@ -1744,7 +1751,8 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_assert(value != NULL); - ret = nxt_router_conf_tls_insert(tmcf, value, skcf); + ret = nxt_router_conf_tls_insert(tmcf, value, skcf, + conf_cmds); if (nxt_slow_path(ret != NXT_OK)) { goto fail; } @@ -1752,7 +1760,8 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, } else { /* NXT_CONF_STRING */ - ret = nxt_router_conf_tls_insert(tmcf, certificate, skcf); + ret = nxt_router_conf_tls_insert(tmcf, certificate, skcf, + conf_cmds); if (nxt_slow_path(ret != NXT_OK)) { goto fail; } @@ -1846,25 +1855,20 @@ fail: static nxt_int_t nxt_router_conf_tls_insert(nxt_router_temp_conf_t *tmcf, - nxt_conf_value_t *value, nxt_socket_conf_t *skcf) + nxt_conf_value_t *value, nxt_socket_conf_t *skcf, + nxt_conf_value_t *conf_cmds) { - nxt_mp_t *mp; - nxt_str_t str; nxt_router_tlssock_t *tls; - mp = tmcf->router_conf->mem_pool; - - tls = nxt_mp_get(mp, sizeof(nxt_router_tlssock_t)); + tls = nxt_mp_get(tmcf->mem_pool, sizeof(nxt_router_tlssock_t)); if (nxt_slow_path(tls == NULL)) { return NXT_ERROR; } - tls->conf = skcf; - nxt_conf_get_string(value, &str); - - if (nxt_slow_path(nxt_str_dup(mp, &tls->name, &str) == NULL)) { - return NXT_ERROR; - } + tls->socket_conf = skcf; + tls->conf_cmds = conf_cmds; + tls->temp_conf = tmcf; + nxt_conf_get_string(value, &tls->name); nxt_queue_insert_tail(&tmcf->tls, &tls->link); @@ -2427,28 +2431,6 @@ nxt_router_listen_socket_error(nxt_task_t *task, nxt_port_recv_msg_t *msg, #if (NXT_TLS) -static void -nxt_router_tls_rpc_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, - nxt_router_tlssock_t *tls, nxt_bool_t last) -{ - nxt_socket_rpc_t *rpc; - - rpc = nxt_mp_alloc(tmcf->mem_pool, sizeof(nxt_socket_rpc_t)); - if (rpc == NULL) { - nxt_router_conf_error(task, tmcf); - return; - } - - rpc->name = &tls->name; - rpc->socket_conf = tls->conf; - rpc->temp_conf = tmcf; - rpc->last = last; - - nxt_cert_store_get(task, &tls->name, tmcf->mem_pool, - nxt_router_tls_rpc_handler, rpc); -} - - static void nxt_router_tls_rpc_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg, void *data) @@ -2456,14 +2438,14 @@ nxt_router_tls_rpc_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg, nxt_mp_t *mp; nxt_int_t ret; nxt_tls_conf_t *tlscf; - nxt_socket_rpc_t *rpc; + nxt_router_tlssock_t *tls; nxt_tls_bundle_conf_t *bundle; nxt_router_temp_conf_t *tmcf; nxt_debug(task, "tls rpc handler"); - rpc = data; - tmcf = rpc->temp_conf; + tls = data; + tmcf = tls->temp_conf; if (msg == NULL || msg->port_msg.type == _NXT_PORT_MSG_RPC_ERROR) { goto fail; @@ -2471,17 +2453,17 @@ nxt_router_tls_rpc_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg, mp = tmcf->router_conf->mem_pool; - if (rpc->socket_conf->tls == NULL){ + if (tls->socket_conf->tls == NULL){ tlscf = nxt_mp_zget(mp, sizeof(nxt_tls_conf_t)); if (nxt_slow_path(tlscf == NULL)) { goto fail; } tlscf->no_wait_shutdown = 1; - rpc->socket_conf->tls = tlscf; + tls->socket_conf->tls = tlscf; } else { - tlscf = rpc->socket_conf->tls; + tlscf = tls->socket_conf->tls; } bundle = nxt_mp_get(mp, sizeof(nxt_tls_bundle_conf_t)); @@ -2489,12 +2471,16 @@ nxt_router_tls_rpc_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg, goto fail; } - bundle->name = rpc->name; + if (nxt_slow_path(nxt_str_dup(mp, &bundle->name, &tls->name) == NULL)) { + goto fail; + } + bundle->chain_file = msg->fd[0]; bundle->next = tlscf->bundle; tlscf->bundle = bundle; - ret = task->thread->runtime->tls->server_init(task, tlscf, mp, rpc->last); + ret = task->thread->runtime->tls->server_init(task, tlscf, mp, + tls->conf_cmds, tls->last); if (nxt_slow_path(ret != NXT_OK)) { goto fail; } -- cgit