summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/nxt_conn_accept.c30
-rw-r--r--src/nxt_controller.c5
-rw-r--r--src/nxt_epoll_engine.c20
-rw-r--r--src/nxt_kqueue_engine.c20
-rw-r--r--src/nxt_listen_socket.c41
-rw-r--r--src/nxt_listen_socket.h2
-rw-r--r--src/nxt_router.c4
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;