From 31951d1dabc6ed48f13a8ffb80d283b4e2f1b3bb Mon Sep 17 00:00:00 2001 From: Evgenii Sokolov <26638058+echolimazulu@users.noreply.github.com> Date: Wed, 20 Apr 2022 16:20:38 +0400 Subject: [PATCH 1/9] Socket: fixed parameter definition --- src/nxt_listen_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nxt_listen_socket.c b/src/nxt_listen_socket.c index f10abdef8..7aba6df44 100644 --- a/src/nxt_listen_socket.c +++ b/src/nxt_listen_socket.c @@ -8,7 +8,7 @@ static u_char *nxt_listen_socket_log_handler(void *ctx, u_char *pos, - u_char *last); + u_char *end); nxt_int_t From 440ecaf831517e73fba53b516c8f9644f3b6e81f Mon Sep 17 00:00:00 2001 From: Evgenii Sokolov <26638058+echolimazulu@users.noreply.github.com> Date: Wed, 20 Apr 2022 16:23:26 +0400 Subject: [PATCH 2/9] Socket: setting permissions for unix socket Access for unix sockets should be equal to 0666 and controlled by the rights set on the directory. Discussion: https://github.com/nginx/unit/pull/647 --- src/nxt_listen_socket.c | 2 +- src/nxt_listen_socket.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/nxt_listen_socket.c b/src/nxt_listen_socket.c index 7aba6df44..5c50d3c95 100644 --- a/src/nxt_listen_socket.c +++ b/src/nxt_listen_socket.c @@ -129,7 +129,7 @@ nxt_listen_socket_create(nxt_task_t *task, nxt_mp_t *mp, if (family == AF_UNIX) { name = (nxt_file_name_t *) sa->u.sockaddr_un.sun_path; - access = (S_IRUSR | S_IWUSR); + access = (ls->access) ? ls->access : (S_IRUSR | S_IWUSR); if (nxt_file_set_access(name, access) != NXT_OK) { goto listen_fail; diff --git a/src/nxt_listen_socket.h b/src/nxt_listen_socket.h index e2435b766..3030ee78a 100644 --- a/src/nxt_listen_socket.h +++ b/src/nxt_listen_socket.h @@ -29,6 +29,9 @@ typedef struct { #if (NXT_INET6 && defined IPV6_V6ONLY) uint8_t ipv6only; /* 2 bits */ #endif +#if (NXT_HAVE_UNIX_DOMAIN) + nxt_file_access_t access; +#endif uint8_t socklen; uint8_t address_length; From 6e3f50e2efcf72224815633c52e0af00cf62eb0d Mon Sep 17 00:00:00 2001 From: Evgenii Sokolov <26638058+echolimazulu@users.noreply.github.com> Date: Wed, 20 Apr 2022 16:26:26 +0400 Subject: [PATCH 3/9] Socket: checking socket file type before deleting Discussion: https://github.com/nginx/unit/pull/649#issuecomment-1043989667 --- src/nxt_file.h | 4 ++++ src/nxt_listen_socket.c | 6 +++++- src/nxt_socket.c | 26 ++++++++++++++++++++++++++ src/nxt_socket.h | 1 + 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/nxt_file.h b/src/nxt_file.h index 4846305b1..08203e1f8 100644 --- a/src/nxt_file.h +++ b/src/nxt_file.h @@ -176,6 +176,10 @@ nxt_is_dir(fi) \ nxt_is_file(fi) \ (S_ISREG((fi)->st_mode)) +#define \ +nxt_is_sock(fi) \ + (S_ISSOCK((fi)->st_mode)) + #define \ nxt_file_size(fi) \ (fi)->st_size diff --git a/src/nxt_listen_socket.c b/src/nxt_listen_socket.c index 5c50d3c95..843a10730 100644 --- a/src/nxt_listen_socket.c +++ b/src/nxt_listen_socket.c @@ -112,7 +112,11 @@ nxt_listen_socket_create(nxt_task_t *task, nxt_mp_t *mp, nxt_sockaddr_text(sa); - (void) unlink(sa->u.sockaddr_un.sun_path); + name = (nxt_file_name_t *) sa->u.sockaddr_un.sun_path; + + if (nxt_socket_release_by_path(name) != NXT_OK) { + goto fail; + } } else { orig_sa = NULL; diff --git a/src/nxt_socket.c b/src/nxt_socket.c index a8e0d5141..21ac8c750 100644 --- a/src/nxt_socket.c +++ b/src/nxt_socket.c @@ -358,3 +358,29 @@ nxt_socket_error_level(nxt_err_t err) return NXT_LOG_ALERT; } } + + +nxt_int_t +nxt_socket_release_by_path(nxt_file_name_t *name) +{ + nxt_file_t file; + nxt_file_info_t fi; + nxt_int_t ret; + + nxt_memzero(&file, sizeof(file)); + nxt_memzero(&fi, sizeof(fi)); + + file.fd = NXT_FILE_INVALID; + file.name = name; + + ret = nxt_file_info(&file, &fi); + + if (nxt_fast_path(ret == NXT_OK && nxt_is_sock(&fi))) { + return nxt_file_delete(file.name); + } else if (nxt_fast_path(ret == NXT_ERROR + && file.error == NXT_ENOENT)) { + return NXT_OK; + } + + return NXT_ERROR; +} diff --git a/src/nxt_socket.h b/src/nxt_socket.h index ec21d7791..7d49e6186 100644 --- a/src/nxt_socket.h +++ b/src/nxt_socket.h @@ -116,6 +116,7 @@ NXT_EXPORT ssize_t nxt_socketpair_send(nxt_fd_event_t *ev, nxt_fd_t *fd, nxt_iobuf_t *iob, nxt_uint_t niob); NXT_EXPORT ssize_t nxt_socketpair_recv(nxt_fd_event_t *ev, nxt_iobuf_t *iob, nxt_uint_t niob, void *oob); +NXT_EXPORT nxt_int_t nxt_socket_release_by_path(nxt_file_name_t *name); #define \ From 25faad707ddb344e0063a2385ed0186ff8fe7f78 Mon Sep 17 00:00:00 2001 From: Evgenii Sokolov <26638058+echolimazulu@users.noreply.github.com> Date: Wed, 20 Apr 2022 16:40:02 +0400 Subject: [PATCH 4/9] Socket: added the ability to get errno for further processing --- src/nxt_conn_connect.c | 4 ++-- src/nxt_listen_socket.c | 8 ++++---- src/nxt_socket.c | 20 ++++++++++++++++---- src/nxt_socket.h | 4 ++-- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/nxt_conn_connect.c b/src/nxt_conn_connect.c index 220fb5f9d..5c0ccb2b6 100644 --- a/src/nxt_conn_connect.c +++ b/src/nxt_conn_connect.c @@ -84,7 +84,7 @@ nxt_conn_socket(nxt_task_t *task, nxt_conn_t *c) family = c->remote->u.sockaddr.sa_family; - s = nxt_socket_create(task, family, c->remote->type, 0, NXT_NONBLOCK); + s = nxt_socket_create(task, family, c->remote->type, 0, NXT_NONBLOCK, NULL); if (nxt_slow_path(s == -1)) { return NXT_ERROR; @@ -108,7 +108,7 @@ nxt_conn_socket(nxt_task_t *task, nxt_conn_t *c) c->write_timer.task = task; if (c->local != NULL) { - if (nxt_slow_path(nxt_socket_bind(task, s, c->local) != NXT_OK)) { + if (nxt_slow_path(nxt_socket_bind(task, s, c->local, NULL) != NXT_OK)) { nxt_socket_close(task, s); return NXT_ERROR; } diff --git a/src/nxt_listen_socket.c b/src/nxt_listen_socket.c index 843a10730..c8f2fcccb 100644 --- a/src/nxt_listen_socket.c +++ b/src/nxt_listen_socket.c @@ -35,10 +35,10 @@ nxt_listen_socket_create(nxt_task_t *task, nxt_mp_t *mp, nxt_socket_t s; nxt_thread_t *thr; nxt_sockaddr_t *sa; + nxt_err_t err; #if (NXT_HAVE_UNIX_DOMAIN) int ret; u_char *p; - nxt_err_t err; nxt_socket_t ts; nxt_sockaddr_t *orig_sa; nxt_file_name_t *name, *tmp; @@ -56,7 +56,7 @@ nxt_listen_socket_create(nxt_task_t *task, nxt_mp_t *mp, family = sa->u.sockaddr.sa_family; - s = nxt_socket_create(task, family, sa->type, 0, ls->flags); + s = nxt_socket_create(task, family, sa->type, 0, ls->flags, &err); if (s == -1) { goto fail; } @@ -124,7 +124,7 @@ nxt_listen_socket_create(nxt_task_t *task, nxt_mp_t *mp, #endif - if (nxt_socket_bind(task, s, sa) != NXT_OK) { + if (nxt_socket_bind(task, s, sa, &err) != NXT_OK) { goto fail; } @@ -153,7 +153,7 @@ nxt_listen_socket_create(nxt_task_t *task, nxt_mp_t *mp, #if (NXT_HAVE_UNIX_DOMAIN) if (orig_sa != NULL) { - ts = nxt_socket_create(task, AF_UNIX, SOCK_STREAM, 0, 0); + ts = nxt_socket_create(task, AF_UNIX, SOCK_STREAM, 0, 0, NULL); if (ts == -1) { goto listen_fail; } diff --git a/src/nxt_socket.c b/src/nxt_socket.c index 21ac8c750..0f5b64e95 100644 --- a/src/nxt_socket.c +++ b/src/nxt_socket.c @@ -13,9 +13,10 @@ static const char *nxt_socket_sockopt_name(nxt_uint_t level, nxt_socket_t nxt_socket_create(nxt_task_t *task, nxt_uint_t domain, nxt_uint_t type, - nxt_uint_t protocol, nxt_uint_t flags) + nxt_uint_t protocol, nxt_uint_t flags, nxt_err_t *errnum) { nxt_socket_t s; + nxt_err_t err; #if (NXT_HAVE_SOCK_NONBLOCK) @@ -28,8 +29,12 @@ nxt_socket_create(nxt_task_t *task, nxt_uint_t domain, nxt_uint_t type, s = socket(domain, type, protocol); if (nxt_slow_path(s == -1)) { + err = nxt_socket_errno; + if (errnum != NULL) { + *errnum = err; + } nxt_alert(task, "socket(%ui, 0x%uXi, %ui) failed %E", - domain, type, protocol, nxt_socket_errno); + domain, type, protocol, err); return s; } @@ -172,8 +177,9 @@ nxt_socket_sockopt_name(nxt_uint_t level, nxt_uint_t sockopt) nxt_int_t -nxt_socket_bind(nxt_task_t *task, nxt_socket_t s, nxt_sockaddr_t *sa) +nxt_socket_bind(nxt_task_t *task, nxt_socket_t s, nxt_sockaddr_t *sa, nxt_err_t *errnum) { + nxt_err_t err; nxt_debug(task, "bind(%d, %*s)", s, (size_t) sa->length, nxt_sockaddr_start(sa)); @@ -181,8 +187,14 @@ nxt_socket_bind(nxt_task_t *task, nxt_socket_t s, nxt_sockaddr_t *sa) return NXT_OK; } + err = nxt_socket_errno; + + if (errnum != NULL) { + *errnum = err; + } + nxt_alert(task, "bind(%d, %*s) failed %E", - s, (size_t) sa->length, nxt_sockaddr_start(sa), nxt_socket_errno); + s, (size_t) sa->length, nxt_sockaddr_start(sa), err); return NXT_ERROR; } diff --git a/src/nxt_socket.h b/src/nxt_socket.h index 7d49e6186..44a417372 100644 --- a/src/nxt_socket.h +++ b/src/nxt_socket.h @@ -92,7 +92,7 @@ typedef union { NXT_EXPORT nxt_socket_t nxt_socket_create(nxt_task_t *task, nxt_uint_t family, - nxt_uint_t type, nxt_uint_t protocol, nxt_uint_t flags); + nxt_uint_t type, nxt_uint_t protocol, nxt_uint_t flags, nxt_err_t *errnum); NXT_EXPORT void nxt_socket_defer_accept(nxt_task_t *task, nxt_socket_t s, nxt_sockaddr_t *sa); NXT_EXPORT nxt_int_t nxt_socket_getsockopt(nxt_task_t *task, nxt_socket_t s, @@ -100,7 +100,7 @@ NXT_EXPORT nxt_int_t nxt_socket_getsockopt(nxt_task_t *task, nxt_socket_t s, NXT_EXPORT nxt_int_t nxt_socket_setsockopt(nxt_task_t *task, nxt_socket_t s, nxt_uint_t level, nxt_uint_t sockopt, int val); NXT_EXPORT nxt_int_t nxt_socket_bind(nxt_task_t *task, nxt_socket_t s, - nxt_sockaddr_t *sa); + nxt_sockaddr_t *sa, nxt_err_t *errnum); NXT_EXPORT nxt_int_t nxt_socket_connect(nxt_task_t *task, nxt_socket_t s, nxt_sockaddr_t *sa); NXT_EXPORT void nxt_socket_shutdown(nxt_task_t *task, nxt_socket_t s, From 2d46b175ab8356bcaab32447652b3c669aa6f996 Mon Sep 17 00:00:00 2001 From: Evgenii Sokolov <26638058+echolimazulu@users.noreply.github.com> Date: Wed, 20 Apr 2022 16:42:19 +0400 Subject: [PATCH 5/9] Controller: zeroing allocated memory --- src/nxt_controller.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nxt_controller.c b/src/nxt_controller.c index 7510d6f0a..21e49e402 100644 --- a/src/nxt_controller.c +++ b/src/nxt_controller.c @@ -631,7 +631,7 @@ nxt_runtime_controller_socket(nxt_task_t *task, nxt_runtime_t *rt) { nxt_listen_socket_t *ls; - ls = nxt_mp_alloc(rt->mem_pool, sizeof(nxt_listen_socket_t)); + ls = nxt_mp_zalloc(rt->mem_pool, sizeof(nxt_listen_socket_t)); if (ls == NULL) { return NXT_ERROR; } From 491fe57b37adf31a4aaf0cff39ca51f1bdae076f Mon Sep 17 00:00:00 2001 From: Evgenii Sokolov <26638058+echolimazulu@users.noreply.github.com> Date: Wed, 20 Apr 2022 16:44:29 +0400 Subject: [PATCH 6/9] Socket: transferring error codes to the appropriate file --- src/nxt_main_process.h | 11 ----------- src/nxt_socket.h | 11 +++++++++++ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/nxt_main_process.h b/src/nxt_main_process.h index ef083d630..5c748d136 100644 --- a/src/nxt_main_process.h +++ b/src/nxt_main_process.h @@ -8,17 +8,6 @@ #define _NXT_MAIN_PROCESS_H_INCLUDED_ -typedef enum { - NXT_SOCKET_ERROR_SYSTEM = 0, - NXT_SOCKET_ERROR_NOINET6, - NXT_SOCKET_ERROR_PORT, - NXT_SOCKET_ERROR_INUSE, - NXT_SOCKET_ERROR_NOADDR, - NXT_SOCKET_ERROR_ACCESS, - NXT_SOCKET_ERROR_PATH, -} nxt_socket_error_t; - - nxt_int_t nxt_main_process_start(nxt_thread_t *thr, nxt_task_t *task, nxt_runtime_t *runtime); diff --git a/src/nxt_socket.h b/src/nxt_socket.h index 44a417372..a63c8f062 100644 --- a/src/nxt_socket.h +++ b/src/nxt_socket.h @@ -10,6 +10,17 @@ typedef int nxt_socket_t; +typedef enum { + NXT_SOCKET_ERROR_SYSTEM = 0, + NXT_SOCKET_ERROR_NOINET6, + NXT_SOCKET_ERROR_PORT, + NXT_SOCKET_ERROR_INUSE, + NXT_SOCKET_ERROR_NOADDR, + NXT_SOCKET_ERROR_ACCESS, + NXT_SOCKET_ERROR_PATH, +} nxt_socket_error_t; + + #define NXT_NONBLOCK 1 From 2912b5463997edce360d3298783f3b1626fa70c8 Mon Sep 17 00:00:00 2001 From: Evgenii Sokolov <26638058+echolimazulu@users.noreply.github.com> Date: Wed, 20 Apr 2022 17:22:46 +0400 Subject: [PATCH 7/9] Socket: preparing to replace connect and rename for listening sockets --- src/nxt_listen_socket.c | 61 +++++++++++++++++++++++++++++++++++++++++ src/nxt_listen_socket.h | 5 ++++ 2 files changed, 66 insertions(+) diff --git a/src/nxt_listen_socket.c b/src/nxt_listen_socket.c index c8f2fcccb..618d4833f 100644 --- a/src/nxt_listen_socket.c +++ b/src/nxt_listen_socket.c @@ -219,6 +219,67 @@ nxt_listen_socket_create(nxt_task_t *task, nxt_mp_t *mp, } +nxt_int_t +nxt_listen_socket_saddr_check(nxt_task_t *task, nxt_sockaddr_t *sa) +{ + nxt_socket_t ts; + nxt_int_t ret; + nxt_err_t err; + + ts = nxt_socket_create(task, AF_UNIX, SOCK_STREAM, 0, 0, NULL); + if (ts == -1) { + return NXT_ERROR; + } + + ret = connect(ts, &sa->u.sockaddr, sa->socklen); + err = nxt_socket_errno; + + nxt_socket_close(task, ts); + + if (ret == 0) { + nxt_alert(task, "connect(%d, %*s) succeed, address already in use", + ts, (size_t) sa->length, + nxt_sockaddr_start(sa)); + return NXT_ERROR; + } + + if (err != NXT_ENOENT && err != NXT_ECONNREFUSED) { + nxt_alert(task, "connect(%d, %*s) failed %E", + ts, (size_t) sa->length, + nxt_sockaddr_start(sa), err); + return NXT_ERROR; + } + + return NXT_OK; +} + + +nxt_int_t +nxt_listen_socket_tmp_rename(nxt_task_t *task, nxt_sockaddr_t *sa) +{ + size_t TMP_EXT_SIZE = sizeof(NXT_TMP_EXT), + TMP_SIZE = sa->socklen + TMP_EXT_SIZE, + name_size; + nxt_file_name_t tmp[TMP_SIZE], *name; + + nxt_memzero(&tmp, TMP_SIZE); + + name = (nxt_file_name_t *) sa->u.sockaddr_un.sun_path; + name_size = nxt_strlen(name); + + nxt_memcpy(tmp, name, name_size); + nxt_memcpy(tmp + name_size, NXT_TMP_EXT, TMP_EXT_SIZE); + + if (nxt_file_rename(tmp, name) != NXT_OK) { + nxt_alert(task, "nxt_file_rename(%FN, %FN) failed", + tmp, name); + return NXT_ERROR; + } + + return NXT_OK; +} + + nxt_int_t nxt_listen_socket_update(nxt_task_t *task, nxt_listen_socket_t *ls, nxt_listen_socket_t *prev) diff --git a/src/nxt_listen_socket.h b/src/nxt_listen_socket.h index 3030ee78a..f5e8d25d1 100644 --- a/src/nxt_listen_socket.h +++ b/src/nxt_listen_socket.h @@ -8,6 +8,9 @@ #define _NXT_LISTEN_SOCKET_H_INCLUDED_ +#define NXT_TMP_EXT ".tmp" + + typedef struct { /* nxt_socket_t is int. */ nxt_socket_t socket; @@ -63,6 +66,8 @@ NXT_EXPORT nxt_int_t nxt_listen_socket_update(nxt_task_t *task, nxt_listen_socket_t *ls, nxt_listen_socket_t *prev); NXT_EXPORT void nxt_listen_socket_remote_size(nxt_listen_socket_t *ls); NXT_EXPORT size_t nxt_listen_socket_pool_min_size(nxt_listen_socket_t *ls); +NXT_EXPORT nxt_int_t nxt_listen_socket_saddr_check(nxt_task_t *task, nxt_sockaddr_t *sa); +NXT_EXPORT nxt_int_t nxt_listen_socket_tmp_rename(nxt_task_t *task, nxt_sockaddr_t *sa); #endif /* _NXT_LISTEN_SOCKET_H_INCLUDED_ */ From 867d4ec927c481d53504606059f2337a3d2f5a1a Mon Sep 17 00:00:00 2001 From: Evgenii Sokolov <26638058+echolimazulu@users.noreply.github.com> Date: Wed, 20 Apr 2022 17:33:24 +0400 Subject: [PATCH 8/9] Main: creating a new rcp handler for the main process --- src/nxt_main_process.c | 42 ++++++++++++++++++++++++++++++++++++++++-- src/nxt_port.h | 3 +++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/nxt_main_process.c b/src/nxt_main_process.c index 9883f04c2..b2ce43ea7 100644 --- a/src/nxt_main_process.c +++ b/src/nxt_main_process.c @@ -48,8 +48,8 @@ static void nxt_main_process_signal_handler(nxt_task_t *task, void *obj, static void nxt_main_process_cleanup(nxt_task_t *task, nxt_process_t *process); static void nxt_main_port_socket_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg); -static nxt_int_t nxt_main_listening_socket(nxt_sockaddr_t *sa, - nxt_listening_socket_t *ls); +static void nxt_main_port_socket_rename_handler(nxt_task_t *task, + nxt_port_recv_msg_t *msg); static void nxt_main_port_modules_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg); static int nxt_cdecl nxt_app_lang_compare(const void *v1, const void *v2); @@ -599,6 +599,7 @@ static nxt_port_handlers_t nxt_main_process_port_handlers = { .remove_pid = nxt_port_remove_pid_handler, .start_process = nxt_main_start_process_handler, .socket = nxt_main_port_socket_handler, + .socket_rename = nxt_main_port_socket_rename_handler, .modules = nxt_main_port_modules_handler, .conf_store = nxt_main_port_conf_store_handler, #if (NXT_TLS) @@ -1216,6 +1217,43 @@ nxt_main_listening_socket(nxt_sockaddr_t *sa, nxt_listening_socket_t *ls) } +static void +nxt_main_port_socket_rename_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) +{ + nxt_buf_t *b; + nxt_port_t *port; + nxt_sockaddr_t *sa; + nxt_port_msg_type_t type; + + port = nxt_runtime_port_find(task->thread->runtime, msg->port_msg.pid, + msg->port_msg.reply_port); + if (nxt_slow_path(port == NULL)) { + return; + } + + if (nxt_slow_path(port->type != NXT_PROCESS_ROUTER)) { + nxt_alert(task, "process %PI cannot rename listener sockets", + msg->port_msg.pid); + return; + } + + b = nxt_buf_chk_make_plain(task->thread->runtime->mem_pool, + msg->buf, msg->size); + sa = (nxt_sockaddr_t *) b->mem.pos; + + if (nxt_listen_socket_saddr_check(task, sa) != NXT_OK + || nxt_listen_socket_tmp_rename(task, sa) != NXT_OK) + { + type = NXT_PORT_MSG_RPC_ERROR; + } else { + type = NXT_PORT_MSG_RPC_READY_LAST; + } + + nxt_port_socket_write(task, port, type, -1, msg->port_msg.stream, + 0, NULL); +} + + static nxt_conf_map_t nxt_app_lang_module_map[] = { { nxt_string("type"), diff --git a/src/nxt_port.h b/src/nxt_port.h index 3b66edfd1..a743fee5c 100644 --- a/src/nxt_port.h +++ b/src/nxt_port.h @@ -16,6 +16,7 @@ struct nxt_port_handlers_s { /* Main process RPC requests. */ nxt_port_handler_t start_process; nxt_port_handler_t socket; + nxt_port_handler_t socket_rename; nxt_port_handler_t modules; nxt_port_handler_t conf_store; nxt_port_handler_t cert_get; @@ -78,6 +79,7 @@ typedef enum { _NXT_PORT_MSG_START_PROCESS = nxt_port_handler_idx(start_process), _NXT_PORT_MSG_SOCKET = nxt_port_handler_idx(socket), + _NXT_PORT_MSG_SOCKET_RENAME = nxt_port_handler_idx(socket_rename), _NXT_PORT_MSG_MODULES = nxt_port_handler_idx(modules), _NXT_PORT_MSG_CONF_STORE = nxt_port_handler_idx(conf_store), _NXT_PORT_MSG_CERT_GET = nxt_port_handler_idx(cert_get), @@ -118,6 +120,7 @@ typedef enum { NXT_PORT_MSG_RPC_ERROR = nxt_msg_last(_NXT_PORT_MSG_RPC_ERROR), NXT_PORT_MSG_START_PROCESS = nxt_msg_last(_NXT_PORT_MSG_START_PROCESS), NXT_PORT_MSG_SOCKET = nxt_msg_last(_NXT_PORT_MSG_SOCKET), + NXT_PORT_MSG_SOCKET_RENAME = nxt_msg_last(_NXT_PORT_MSG_SOCKET_RENAME), NXT_PORT_MSG_MODULES = nxt_msg_last(_NXT_PORT_MSG_MODULES), NXT_PORT_MSG_CONF_STORE = nxt_msg_last(_NXT_PORT_MSG_CONF_STORE), NXT_PORT_MSG_CERT_GET = nxt_msg_last(_NXT_PORT_MSG_CERT_GET), From 1497d198699db262e15cd0cb36d13023ee9cc849 Mon Sep 17 00:00:00 2001 From: Evgenii Sokolov <26638058+echolimazulu@users.noreply.github.com> Date: Thu, 21 Apr 2022 18:07:23 +0400 Subject: [PATCH 9/9] Main, Router, Socket: fixed unix socket reuse issue - set the access mode for listening sockets; - moving structure members and replacing the structure type `nxt_listening_socket_t` with `nxt_listen_socket_t`; - replacing unused `nxt_main_listening_socket` with `nxt_listen_socket_create`; - transfer of the system of codes and errors from `nxt_main_listening_socket` to `nxt_listen_socket_create`; - replacement of the existing `connect` and `rename` logic; - replacement of the string `tmp` with the constant `NXT_TMP_EXT`; - adding a separate `renaming_sockets` queue for router; - adding handler `nxt_router_listen_socket_rpc_rename`; - separation of execution logic `listen`, `connect`, `rename` for `Controller` and for `Router`. Issue: https://github.com/nginx/unit/issues/669. --- src/nxt_listen_socket.c | 157 ++++++++++++++++++++++++---------- src/nxt_listen_socket.h | 4 + src/nxt_main_process.c | 145 +++---------------------------- src/nxt_router.c | 183 ++++++++++++++++++++++++++++++++++++---- 4 files changed, 294 insertions(+), 195 deletions(-) diff --git a/src/nxt_listen_socket.c b/src/nxt_listen_socket.c index 618d4833f..94b2b604e 100644 --- a/src/nxt_listen_socket.c +++ b/src/nxt_listen_socket.c @@ -37,9 +37,7 @@ nxt_listen_socket_create(nxt_task_t *task, nxt_mp_t *mp, nxt_sockaddr_t *sa; nxt_err_t err; #if (NXT_HAVE_UNIX_DOMAIN) - int ret; u_char *p; - nxt_socket_t ts; nxt_sockaddr_t *orig_sa; nxt_file_name_t *name, *tmp; nxt_file_access_t access; @@ -58,10 +56,27 @@ nxt_listen_socket_create(nxt_task_t *task, nxt_mp_t *mp, s = nxt_socket_create(task, family, sa->type, 0, ls->flags, &err); if (s == -1) { + +#if (NXT_INET6) + + if (err == EAFNOSUPPORT && sa->u.sockaddr.sa_family == AF_INET6) { + ls->error = NXT_SOCKET_ERROR_NOINET6; + } + +#endif + + if (ls->start != NULL && ls->end != NULL) + ls->end = nxt_sprintf(ls->start, ls->end, + "nxt_socket_create(\"%*s\") failed %E", + (size_t) sa->length, nxt_sockaddr_start(sa), err); goto fail; } if (nxt_socket_setsockopt(task, s, SOL_SOCKET, SO_REUSEADDR, 1) != NXT_OK) { + if (ls->start != NULL && ls->end != NULL) + ls->end = nxt_sprintf(ls->start, ls->end, + "nxt_socket_setsockopt(\"%*s\", SO_REUSEADDR) failed", + (size_t) sa->length, nxt_sockaddr_start(sa)); goto fail; } @@ -72,9 +87,14 @@ nxt_listen_socket_create(nxt_task_t *task, nxt_mp_t *mp, ipv6only = (ls->ipv6only == 1); - /* Ignore possible error. TODO: why? */ - (void) nxt_socket_setsockopt(task, s, IPPROTO_IPV6, IPV6_V6ONLY, - ipv6only); + if (nxt_socket_setsockopt(task, s, IPPROTO_IPV6, IPV6_V6ONLY, + ipv6only) != NXT_OK) { + if (ls->start != NULL && ls->end != NULL) + ls->end = nxt_sprintf(ls->start, ls->end, + "nxt_socket_setsockopt(\"%*s\", IPV6_V6ONLY) failed", + (size_t) sa->length, nxt_sockaddr_start(sa)); + goto fail; + } } #endif @@ -100,6 +120,10 @@ nxt_listen_socket_create(nxt_task_t *task, nxt_mp_t *mp, sa = nxt_sockaddr_alloc(mp, sa->socklen + 4, sa->length + 4); if (sa == NULL) { + if (ls->start != NULL && ls->end != NULL) + ls->end = nxt_sprintf(ls->start, ls->end, + "nxt_sockaddr_alloc(%*s) failed", + (size_t) sa->length, nxt_sockaddr_start(sa)); goto fail; } @@ -108,13 +132,17 @@ nxt_listen_socket_create(nxt_task_t *task, nxt_mp_t *mp, p = nxt_cpystr((u_char *) sa->u.sockaddr_un.sun_path, (u_char *) orig_sa->u.sockaddr_un.sun_path); - nxt_memcpy(p, ".tmp", 4); + nxt_memcpy(p, NXT_TMP_EXT, 4); nxt_sockaddr_text(sa); name = (nxt_file_name_t *) sa->u.sockaddr_un.sun_path; if (nxt_socket_release_by_path(name) != NXT_OK) { + if (ls->start != NULL && ls->end != NULL) + ls->end = nxt_sprintf(ls->start, ls->end, + "nxt_socket_release_by_path(%FN) failed", + name); goto fail; } @@ -125,71 +153,114 @@ nxt_listen_socket_create(nxt_task_t *task, nxt_mp_t *mp, #endif if (nxt_socket_bind(task, s, sa, &err) != NXT_OK) { - goto fail; - } #if (NXT_HAVE_UNIX_DOMAIN) - if (family == AF_UNIX) { - name = (nxt_file_name_t *) sa->u.sockaddr_un.sun_path; + if (sa->u.sockaddr.sa_family == AF_UNIX) { + switch (err) { - access = (ls->access) ? ls->access : (S_IRUSR | S_IWUSR); + case EACCES: + ls->error = NXT_SOCKET_ERROR_ACCESS; + break; - if (nxt_file_set_access(name, access) != NXT_OK) { - goto listen_fail; - } - } + case ENOENT: + case ENOTDIR: + ls->error = NXT_SOCKET_ERROR_PATH; + break; + } + } else #endif + { + switch (err) { - nxt_debug(task, "listen(%d, %d)", s, ls->backlog); - - if (listen(s, ls->backlog) != 0) { - nxt_alert(task, "listen(%d, %d) failed %E", - s, ls->backlog, nxt_socket_errno); - goto listen_fail; - } + case EACCES: + ls->error = NXT_SOCKET_ERROR_PORT; + break; -#if (NXT_HAVE_UNIX_DOMAIN) + case EADDRINUSE: + ls->error = NXT_SOCKET_ERROR_INUSE; + break; - if (orig_sa != NULL) { - ts = nxt_socket_create(task, AF_UNIX, SOCK_STREAM, 0, 0, NULL); - if (ts == -1) { - goto listen_fail; + case EADDRNOTAVAIL: + ls->error = NXT_SOCKET_ERROR_NOADDR; + break; + } } - ret = connect(ts, &orig_sa->u.sockaddr, orig_sa->socklen); + if (ls->start != NULL && ls->end != NULL) + ls->end = nxt_sprintf(ls->start, ls->end, + "nxt_socket_bind(%d, %*s) failed %E", + s, (size_t) sa->length, nxt_sockaddr_start(sa), + err); + goto fail; + } - err = nxt_socket_errno; +#if (NXT_HAVE_UNIX_DOMAIN) - nxt_socket_close(task, ts); + if (family == AF_UNIX) { + name = (nxt_file_name_t *) sa->u.sockaddr_un.sun_path; - if (ret == 0) { - nxt_alert(task, "connect(%d, %*s) succeed, address already in use", - ts, (size_t) orig_sa->length, - nxt_sockaddr_start(orig_sa)); + access = (ls->access) ? ls->access : (S_IRUSR | S_IWUSR); + if (nxt_file_set_access(name, access) != NXT_OK) { + if (ls->start != NULL && ls->end != NULL) + ls->end = nxt_sprintf(ls->start, ls->end, + "nxt_file_set_access(%FN) failed", + name); goto listen_fail; } + } - if (err != NXT_ENOENT && err != NXT_ECONNREFUSED) { - nxt_alert(task, "connect(%d, %*s) failed %E", - ts, (size_t) orig_sa->length, - nxt_sockaddr_start(orig_sa), err); +#endif + if (ls->start == NULL) { + nxt_debug(task, "listen(%d, %d)", s, ls->backlog); + + if (listen(s, ls->backlog) != 0) { + err = nxt_socket_errno; + nxt_alert(task, "listen(%d, %d) failed %E", + s, ls->backlog, err); + if (ls->start != NULL && ls->end != NULL) + ls->end = nxt_sprintf(ls->start, ls->end, + "listen(%d, %d) failed %E", + s, ls->backlog, err); goto listen_fail; } - tmp = (nxt_file_name_t *) sa->u.sockaddr_un.sun_path; - name = (nxt_file_name_t *) orig_sa->u.sockaddr_un.sun_path; +#if (NXT_HAVE_UNIX_DOMAIN) + + if (orig_sa != NULL) { + + if (nxt_listen_socket_saddr_check(task, orig_sa) != NXT_OK) { + nxt_alert(task, "nxt_listen_socket_saddr_check(%*s) failed", + (size_t) sa->length, nxt_sockaddr_start(sa)); + if (ls->start != NULL && ls->end != NULL) + ls->end = nxt_sprintf(ls->start, ls->end, + "nxt_listen_socket_connect(%*s) failed", + (size_t) sa->length, nxt_sockaddr_start(sa)); + goto listen_fail; + } + + tmp = (nxt_file_name_t *) sa->u.sockaddr_un.sun_path; + name = (nxt_file_name_t *) orig_sa->u.sockaddr_un.sun_path; + + if (nxt_file_rename(tmp, name) != NXT_OK) { + nxt_alert(task, "nxt_file_rename(%FN, %FN) failed", + tmp, name); + if (ls->start != NULL && ls->end != NULL) + ls->end = nxt_sprintf(ls->start, ls->end, + "nxt_file_rename(%FN, %FN) failed", + tmp, name); + goto listen_fail; + } - if (nxt_file_rename(tmp, name) != NXT_OK) { - goto listen_fail; } - } #endif + } + ls->socket = s; thr->log = old; diff --git a/src/nxt_listen_socket.h b/src/nxt_listen_socket.h index f5e8d25d1..204c0bb82 100644 --- a/src/nxt_listen_socket.h +++ b/src/nxt_listen_socket.h @@ -38,6 +38,10 @@ typedef struct { uint8_t socklen; uint8_t address_length; + + nxt_socket_error_t error; + u_char *start; + u_char *end; } nxt_listen_socket_t; diff --git a/src/nxt_main_process.c b/src/nxt_main_process.c index b2ce43ea7..f27b56e36 100644 --- a/src/nxt_main_process.c +++ b/src/nxt_main_process.c @@ -18,14 +18,6 @@ #include -typedef struct { - nxt_socket_t socket; - nxt_socket_error_t error; - u_char *start; - u_char *end; -} nxt_listening_socket_t; - - typedef struct { nxt_uint_t size; nxt_conf_map_t *map; @@ -1032,7 +1024,7 @@ nxt_main_port_socket_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) nxt_port_t *port; nxt_sockaddr_t *sa; nxt_port_msg_type_t type; - nxt_listening_socket_t ls; + nxt_listen_socket_t ls; u_char message[2048]; port = nxt_runtime_port_find(task->thread->runtime, msg->port_msg.pid, @@ -1053,15 +1045,23 @@ nxt_main_port_socket_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) /* TODO check b size and make plain */ + ls.sockaddr = sa; + + nxt_listen_socket_remote_size(&ls); + ls.socket = -1; ls.error = NXT_SOCKET_ERROR_SYSTEM; ls.start = message; ls.end = message + sizeof(message); +#if (NXT_HAVE_UNIX_DOMAIN) + ls.access = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); +#endif + nxt_debug(task, "listening socket \"%*s\"", (size_t) sa->length, nxt_sockaddr_start(sa)); - ret = nxt_main_listening_socket(sa, &ls); + ret = nxt_listen_socket_create(task, task->thread->runtime->mem_pool, &ls); if (ret == NXT_OK) { nxt_debug(task, "socket(\"%*s\"): %d", @@ -1092,131 +1092,6 @@ nxt_main_port_socket_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) } -static nxt_int_t -nxt_main_listening_socket(nxt_sockaddr_t *sa, nxt_listening_socket_t *ls) -{ - nxt_err_t err; - nxt_socket_t s; - - const socklen_t length = sizeof(int); - static const int enable = 1; - - s = socket(sa->u.sockaddr.sa_family, sa->type, 0); - - if (nxt_slow_path(s == -1)) { - err = nxt_errno; - -#if (NXT_INET6) - - if (err == EAFNOSUPPORT && sa->u.sockaddr.sa_family == AF_INET6) { - ls->error = NXT_SOCKET_ERROR_NOINET6; - } - -#endif - - ls->end = nxt_sprintf(ls->start, ls->end, - "socket(\\\"%*s\\\") failed %E", - (size_t) sa->length, nxt_sockaddr_start(sa), err); - - return NXT_ERROR; - } - - if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &enable, length) != 0) { - ls->end = nxt_sprintf(ls->start, ls->end, - "setsockopt(\\\"%*s\\\", SO_REUSEADDR) failed %E", - (size_t) sa->length, nxt_sockaddr_start(sa), - nxt_errno); - goto fail; - } - -#if (NXT_INET6) - - if (sa->u.sockaddr.sa_family == AF_INET6) { - - if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &enable, length) != 0) { - ls->end = nxt_sprintf(ls->start, ls->end, - "setsockopt(\\\"%*s\\\", IPV6_V6ONLY) failed %E", - (size_t) sa->length, nxt_sockaddr_start(sa), - nxt_errno); - goto fail; - } - } - -#endif - - if (bind(s, &sa->u.sockaddr, sa->socklen) != 0) { - err = nxt_errno; - -#if (NXT_HAVE_UNIX_DOMAIN) - - if (sa->u.sockaddr.sa_family == AF_UNIX) { - switch (err) { - - case EACCES: - ls->error = NXT_SOCKET_ERROR_ACCESS; - break; - - case ENOENT: - case ENOTDIR: - ls->error = NXT_SOCKET_ERROR_PATH; - break; - } - - } else -#endif - { - switch (err) { - - case EACCES: - ls->error = NXT_SOCKET_ERROR_PORT; - break; - - case EADDRINUSE: - ls->error = NXT_SOCKET_ERROR_INUSE; - break; - - case EADDRNOTAVAIL: - ls->error = NXT_SOCKET_ERROR_NOADDR; - break; - } - } - - ls->end = nxt_sprintf(ls->start, ls->end, "bind(\\\"%*s\\\") failed %E", - (size_t) sa->length, nxt_sockaddr_start(sa), err); - goto fail; - } - -#if (NXT_HAVE_UNIX_DOMAIN) - - if (sa->u.sockaddr.sa_family == AF_UNIX) { - char *filename; - mode_t access; - - filename = sa->u.sockaddr_un.sun_path; - access = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); - - if (chmod(filename, access) != 0) { - ls->end = nxt_sprintf(ls->start, ls->end, - "chmod(\\\"%s\\\") failed %E", - filename, nxt_errno); - goto fail; - } - } - -#endif - - ls->socket = s; - - return NXT_OK; - -fail: - - (void) close(s); - - return NXT_ERROR; -} - - static void nxt_main_port_socket_rename_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) { diff --git a/src/nxt_router.c b/src/nxt_router.c index 52ea0f373..29ee05dc0 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -103,6 +103,8 @@ static void nxt_router_conf_error(nxt_task_t *task, nxt_router_temp_conf_t *tmcf); static void nxt_router_conf_send(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_port_msg_type_t type); +static void nxt_router_conf_flush_sockets(nxt_task_t *task, + nxt_queue_t *queue); static nxt_int_t nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, u_char *start, u_char *end); @@ -133,6 +135,14 @@ static void nxt_router_listen_socket_ready(nxt_task_t *task, nxt_port_recv_msg_t *msg, void *data); static void nxt_router_listen_socket_error(nxt_task_t *task, nxt_port_recv_msg_t *msg, void *data); +#if (NXT_HAVE_UNIX_DOMAIN) +static void nxt_router_listen_socket_rpc_rename(nxt_task_t *task, + nxt_router_temp_conf_t *tmcf, nxt_socket_conf_t *skcf); +static void nxt_router_listen_socket_rename_ready(nxt_task_t *task, + nxt_port_recv_msg_t *msg, void *data); +static void nxt_router_listen_socket_rename_error(nxt_task_t *task, + nxt_port_recv_msg_t *msg, void *data); +#endif #if (NXT_TLS) static void nxt_router_tls_rpc_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg, void *data); @@ -315,6 +325,9 @@ const nxt_process_init_t nxt_router_process = { /* Queues of nxt_socket_conf_t */ +#if (NXT_HAVE_UNIX_DOMAIN) +nxt_queue_t renaming_sockets; +#endif nxt_queue_t creating_sockets; nxt_queue_t pending_sockets; nxt_queue_t updating_sockets; @@ -1024,6 +1037,9 @@ nxt_router_temp_conf(nxt_task_t *task) goto temp_fail; } +#if (NXT_HAVE_UNIX_DOMAIN) + nxt_queue_init(&renaming_sockets); +#endif nxt_queue_init(&creating_sockets); nxt_queue_init(&pending_sockets); nxt_queue_init(&updating_sockets); @@ -1081,6 +1097,9 @@ nxt_router_conf_apply(nxt_task_t *task, void *obj, void *data) nxt_router_conf_t *rtcf; nxt_router_temp_conf_t *tmcf; const nxt_event_interface_t *interface; +#if (NXT_HAVE_UNIX_DOMAIN) + nxt_sockaddr_t *sa; +#endif #if (NXT_TLS) nxt_router_tlssock_t *tls; #endif @@ -1091,15 +1110,44 @@ nxt_router_conf_apply(nxt_task_t *task, void *obj, void *data) if (qlk != nxt_queue_tail(&pending_sockets)) { nxt_queue_remove(qlk); - nxt_queue_insert_tail(&creating_sockets, qlk); skcf = nxt_queue_link_data(qlk, nxt_socket_conf_t, link); +#if (NXT_HAVE_UNIX_DOMAIN) + sa = skcf->listen->sockaddr; + if (sa->u.sockaddr.sa_family == AF_UNIX + && sa->type == SOCK_STREAM + && sa->u.sockaddr_un.sun_path[0] != '\0') + { + nxt_queue_insert_tail(&renaming_sockets, qlk); + } else +#endif + { + nxt_queue_insert_tail(&creating_sockets, qlk); + } + nxt_router_listen_socket_rpc_create(task, tmcf, skcf); return; } +#if (NXT_HAVE_UNIX_DOMAIN) + + qlk = nxt_queue_first(&renaming_sockets); + + if (qlk != nxt_queue_tail(&renaming_sockets)) { + nxt_queue_remove(qlk); + nxt_queue_insert_tail(&creating_sockets, qlk); + + skcf = nxt_queue_link_data(qlk, nxt_socket_conf_t, link); + + nxt_router_listen_socket_rpc_rename(task, tmcf, skcf); + + return; + } + +#endif + #if (NXT_TLS) qlk = nxt_queue_last(&tmcf->tls); @@ -1230,31 +1278,22 @@ nxt_router_conf_error(nxt_task_t *task, nxt_router_temp_conf_t *tmcf) { nxt_app_t *app; nxt_queue_t new_socket_confs; - nxt_socket_t s; nxt_router_t *router; - nxt_queue_link_t *qlk; - nxt_socket_conf_t *skcf; nxt_router_conf_t *rtcf; nxt_alert(task, "failed to apply new conf"); - for (qlk = nxt_queue_first(&creating_sockets); - qlk != nxt_queue_tail(&creating_sockets); - qlk = nxt_queue_next(qlk)) - { - skcf = nxt_queue_link_data(qlk, nxt_socket_conf_t, link); - s = skcf->listen->socket; - - if (s != -1) { - nxt_socket_close(task, s); - } - - nxt_free(skcf->listen); - } +#if (NXT_HAVE_UNIX_DOMAIN) + nxt_router_conf_flush_sockets(task, &renaming_sockets); +#endif + nxt_router_conf_flush_sockets(task, &creating_sockets); nxt_queue_init(&new_socket_confs); nxt_queue_add(&new_socket_confs, &updating_sockets); nxt_queue_add(&new_socket_confs, &pending_sockets); +#if (NXT_HAVE_UNIX_DOMAIN) + nxt_queue_add(&new_socket_confs, &renaming_sockets); +#endif nxt_queue_add(&new_socket_confs, &creating_sockets); rtcf = tmcf->router_conf; @@ -1296,6 +1335,29 @@ nxt_router_conf_send(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, } +static void +nxt_router_conf_flush_sockets(nxt_task_t *task, nxt_queue_t *queue) +{ + nxt_socket_t s; + nxt_socket_conf_t *skcf; + nxt_queue_link_t *qlk; + + for (qlk = nxt_queue_first(queue); + qlk != nxt_queue_tail(queue); + qlk = nxt_queue_next(qlk)) + { + skcf = nxt_queue_link_data(qlk, nxt_socket_conf_t, link); + s = skcf->listen->socket; + + if (s != -1) { + nxt_socket_close(task, s); + } + + nxt_free(skcf->listen); + } +} + + static nxt_conf_map_t nxt_router_conf[] = { { nxt_string("listeners_threads"), @@ -2707,6 +2769,93 @@ nxt_router_listen_socket_error(nxt_task_t *task, nxt_port_recv_msg_t *msg, } +#if (NXT_HAVE_UNIX_DOMAIN) + +static void +nxt_router_listen_socket_rpc_rename(nxt_task_t *task, + nxt_router_temp_conf_t *tmcf, nxt_socket_conf_t *skcf) +{ + size_t size; + uint32_t stream; + nxt_int_t ret; + nxt_buf_t *b; + nxt_port_t *main_port, *router_port; + nxt_runtime_t *rt; + nxt_socket_rpc_t *rpc; + + rpc = nxt_mp_alloc(tmcf->mem_pool, sizeof(nxt_socket_rpc_t)); + if (rpc == NULL) { + goto fail; + } + + rpc->socket_conf = skcf; + rpc->temp_conf = tmcf; + + size = nxt_sockaddr_size(skcf->listen->sockaddr); + + b = nxt_buf_mem_alloc(tmcf->mem_pool, size, 0); + if (b == NULL) { + goto fail; + } + + b->completion_handler = nxt_buf_dummy_completion; + + b->mem.free = nxt_cpymem(b->mem.free, skcf->listen->sockaddr, size); + + rt = task->thread->runtime; + main_port = rt->port_by_type[NXT_PROCESS_MAIN]; + router_port = rt->port_by_type[NXT_PROCESS_ROUTER]; + + stream = nxt_port_rpc_register_handler(task, router_port, + nxt_router_listen_socket_rename_ready, + nxt_router_listen_socket_rename_error, + main_port->pid, rpc); + if (nxt_slow_path(stream == 0)) { + goto fail; + } + + ret = nxt_port_socket_write(task, main_port, NXT_PORT_MSG_SOCKET_RENAME, -1, + stream, router_port->id, b); + + if (nxt_slow_path(ret != NXT_OK)) { + nxt_port_rpc_cancel(task, router_port, stream); + goto fail; + } + + return; + +fail: + + nxt_router_conf_error(task, tmcf); +} + + +static void +nxt_router_listen_socket_rename_ready(nxt_task_t *task, nxt_port_recv_msg_t *msg, + void *data) +{ + nxt_socket_rpc_t *rpc; + + rpc = data; + + nxt_work_queue_add(&task->thread->engine->fast_work_queue, + nxt_router_conf_apply, task, rpc->temp_conf, NULL); +} + + +static void +nxt_router_listen_socket_rename_error(nxt_task_t *task, nxt_port_recv_msg_t *msg, + void *data) +{ + nxt_socket_rpc_t *rpc; + + rpc = data; + + nxt_router_conf_error(task, rpc->temp_conf); +} + +#endif + #if (NXT_TLS) static void