summaryrefslogtreecommitdiffhomepage
path: root/src/nxt_conn_accept.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/nxt_conn_accept.c30
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);