diff options
Diffstat (limited to '')
-rw-r--r-- | src/nxt_conn_accept.c | 30 |
1 files changed, 16 insertions, 14 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); |