diff options
-rw-r--r-- | src/nxt_conn_accept.c | 30 | ||||
-rw-r--r-- | src/nxt_controller.c | 5 | ||||
-rw-r--r-- | src/nxt_epoll_engine.c | 20 | ||||
-rw-r--r-- | src/nxt_kqueue_engine.c | 20 | ||||
-rw-r--r-- | src/nxt_listen_socket.c | 41 | ||||
-rw-r--r-- | src/nxt_listen_socket.h | 2 | ||||
-rw-r--r-- | src/nxt_router.c | 4 |
7 files changed, 79 insertions, 43 deletions
diff --git a/src/nxt_conn_accept.c b/src/nxt_conn_accept.c index 1f620d76..660b41ff 100644 --- a/src/nxt_conn_accept.c +++ b/src/nxt_conn_accept.c @@ -117,8 +117,9 @@ nxt_conn_accept_alloc(nxt_task_t *task, nxt_listen_event_t *lev) sa = ls->sockaddr; remote->type = sa->type; /* - * Set address family for unspecified Unix domain, - * because these sockaddr's are not be passed to accept(). + * Set address family for unspecified Unix domain socket, + * because these sockaddr's are not updated by old BSD systems, + * see comment in nxt_conn_io_accept(). */ remote->u.sockaddr.sa_family = sa->u.sockaddr.sa_family; @@ -149,7 +150,7 @@ nxt_conn_listen_handler(nxt_task_t *task, void *obj, void *data) void nxt_conn_io_accept(nxt_task_t *task, void *obj, void *data) { - socklen_t len; + socklen_t socklen; nxt_conn_t *c; nxt_socket_t s; struct sockaddr *sa; @@ -161,17 +162,18 @@ nxt_conn_io_accept(nxt_task_t *task, void *obj, void *data) lev->ready--; lev->socket.read_ready = (lev->ready != 0); - len = c->remote->socklen; - - if (len >= sizeof(struct sockaddr)) { - sa = &c->remote->u.sockaddr; - - } else { - sa = NULL; - len = 0; - } - - s = accept(lev->socket.fd, sa, &len); + sa = &c->remote->u.sockaddr; + socklen = c->remote->socklen; + /* + * The returned socklen is ignored here, because sockaddr_in and + * sockaddr_in6 socklens are not changed. As to unspecified sockaddr_un + * it is 3 byte length and already prepared, because old BSDs return zero + * socklen and do not update the sockaddr_un at all; Linux returns 2 byte + * socklen and updates only the sa_family part; other systems copy 3 bytes + * and truncate surplus zero part. Only bound sockaddr_un will be really + * truncated here. + */ + s = accept(lev->socket.fd, sa, &socklen); if (s == -1) { nxt_conn_accept_error(task, lev, "accept", nxt_socket_errno); diff --git a/src/nxt_controller.c b/src/nxt_controller.c index 7305b3d5..e41452a3 100644 --- a/src/nxt_controller.c +++ b/src/nxt_controller.c @@ -281,11 +281,10 @@ nxt_runtime_controller_socket(nxt_task_t *task, nxt_runtime_t *rt) } ls->sockaddr->type = sa->type; - ls->socklen = sa->socklen; - ls->address_length = sa->length; - nxt_sockaddr_text(ls->sockaddr); + nxt_listen_socket_remote_size(ls, sa); + ls->socket = -1; ls->backlog = NXT_LISTEN_BACKLOG; ls->read_after_accept = 1; diff --git a/src/nxt_epoll_engine.c b/src/nxt_epoll_engine.c index 4e2dd5c0..7e9a0b1c 100644 --- a/src/nxt_epoll_engine.c +++ b/src/nxt_epoll_engine.c @@ -985,7 +985,7 @@ nxt_epoll_poll(nxt_event_engine_t *engine, nxt_msec_t timeout) static void nxt_epoll_conn_io_accept4(nxt_task_t *task, void *obj, void *data) { - socklen_t len; + socklen_t socklen; nxt_conn_t *c; nxt_socket_t s; struct sockaddr *sa; @@ -997,17 +997,13 @@ nxt_epoll_conn_io_accept4(nxt_task_t *task, void *obj, void *data) lev->ready--; lev->socket.read_ready = (lev->ready != 0); - len = c->remote->socklen; - - if (len >= sizeof(struct sockaddr)) { - sa = &c->remote->u.sockaddr; - - } else { - sa = NULL; - len = 0; - } - - s = accept4(lev->socket.fd, sa, &len, SOCK_NONBLOCK); + sa = &c->remote->u.sockaddr; + socklen = c->remote->socklen; + /* + * The returned socklen is ignored here, + * see comment in nxt_conn_io_accept(). + */ + s = accept4(lev->socket.fd, sa, &socklen, SOCK_NONBLOCK); if (s != -1) { c->socket.fd = s; diff --git a/src/nxt_kqueue_engine.c b/src/nxt_kqueue_engine.c index 4582b314..c8585063 100644 --- a/src/nxt_kqueue_engine.c +++ b/src/nxt_kqueue_engine.c @@ -929,7 +929,7 @@ nxt_kqueue_listen_handler(nxt_task_t *task, void *obj, void *data) static void nxt_kqueue_conn_io_accept(nxt_task_t *task, void *obj, void *data) { - socklen_t len; + socklen_t socklen; nxt_conn_t *c; nxt_socket_t s; struct sockaddr *sa; @@ -944,17 +944,13 @@ nxt_kqueue_conn_io_accept(nxt_task_t *task, void *obj, void *data) lev->socket.kq_available--; lev->socket.read_ready = (lev->socket.kq_available != 0); - len = c->remote->socklen; - - if (len >= sizeof(struct sockaddr)) { - sa = &c->remote->u.sockaddr; - - } else { - sa = NULL; - len = 0; - } - - s = accept(lev->socket.fd, sa, &len); + sa = &c->remote->u.sockaddr; + socklen = c->remote->socklen; + /* + * The returned socklen is ignored here, + * see comment in nxt_conn_io_accept(). + */ + s = accept(lev->socket.fd, sa, &socklen); if (s != -1) { c->socket.fd = s; diff --git a/src/nxt_listen_socket.c b/src/nxt_listen_socket.c index 4141c206..4d4a8c5e 100644 --- a/src/nxt_listen_socket.c +++ b/src/nxt_listen_socket.c @@ -176,6 +176,47 @@ fail: } +void +nxt_listen_socket_remote_size(nxt_listen_socket_t *ls, nxt_sockaddr_t *sa) +{ + switch (sa->u.sockaddr.sa_family) { + +#if (NXT_INET6) + + case AF_INET6: + ls->socklen = sizeof(struct sockaddr_in6); + ls->address_length = NXT_INET6_ADDR_STR_LEN; + + break; + +#endif + +#if (NXT_HAVE_UNIX_DOMAIN) + + case AF_UNIX: + /* + * A remote socket is usually unbound and thus has unspecified Unix + * domain sockaddr_un which can be shortcut to 3 bytes. To handle + * a bound remote socket correctly ls->socklen should be larger, see + * comment in nxt_socket.h. + */ + ls->socklen = offsetof(struct sockaddr_un, sun_path) + 1; + ls->address_length = sizeof("unix:") - 1; + + break; + +#endif + + default: + case AF_INET: + ls->socklen = sizeof(struct sockaddr_in); + ls->address_length = NXT_INET_ADDR_STR_LEN; + + break; + } +} + + size_t nxt_listen_socket_pool_min_size(nxt_listen_socket_t *ls) { diff --git a/src/nxt_listen_socket.h b/src/nxt_listen_socket.h index c872f27d..84e4cf71 100644 --- a/src/nxt_listen_socket.h +++ b/src/nxt_listen_socket.h @@ -56,6 +56,8 @@ NXT_EXPORT nxt_int_t nxt_listen_socket_create(nxt_task_t *task, nxt_listen_socket_t *ls, nxt_bool_t bind_test); 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_sockaddr_t *sa); NXT_EXPORT size_t nxt_listen_socket_pool_min_size(nxt_listen_socket_t *ls); diff --git a/src/nxt_router.c b/src/nxt_router.c index d62c536f..1a18ffa3 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -943,8 +943,8 @@ nxt_router_socket_conf(nxt_task_t *task, nxt_mp_t *mp, nxt_sockaddr_t *sa) skcf->sockaddr = sa; skcf->listen.sockaddr = sa; - skcf->listen.socklen = sa->socklen; - skcf->listen.address_length = sa->length; + + nxt_listen_socket_remote_size(&skcf->listen, sa); skcf->listen.socket = -1; skcf->listen.backlog = NXT_LISTEN_BACKLOG; |