diff options
Diffstat (limited to '')
-rw-r--r-- | src/nxt_sockaddr.c | 181 |
1 files changed, 142 insertions, 39 deletions
diff --git a/src/nxt_sockaddr.c b/src/nxt_sockaddr.c index 2bb85730..742cb0ba 100644 --- a/src/nxt_sockaddr.c +++ b/src/nxt_sockaddr.c @@ -17,10 +17,13 @@ static nxt_int_t nxt_job_sockaddr_inet_parse(nxt_job_sockaddr_parse_t *jbs); nxt_sockaddr_t * -nxt_sockaddr_alloc(nxt_mem_pool_t *mp, socklen_t length) +nxt_sockaddr_alloc(nxt_mem_pool_t *mp, socklen_t socklen, size_t address_length) { + size_t size; nxt_sockaddr_t *sa; + size = offsetof(nxt_sockaddr_t, u) + socklen + address_length; + /* * The current struct sockaddr's define 32-bit fields at maximum * and may define 64-bit AF_INET6 fields in the future. Alignment @@ -28,10 +31,13 @@ nxt_sockaddr_alloc(nxt_mem_pool_t *mp, socklen_t length) * If 128-bit alignment will be required then nxt_mem_malloc() and * nxt_memzero() should be used instead. */ - sa = nxt_mem_zalloc(mp, offsetof(nxt_sockaddr_t, u) + length); + + sa = nxt_mem_zalloc(mp, size); if (nxt_fast_path(sa != NULL)) { - nxt_socklen_set(sa, length); + sa->socklen = socklen; + sa->length = address_length; + sa->sockaddr_size = size; } return sa; @@ -40,7 +46,7 @@ nxt_sockaddr_alloc(nxt_mem_pool_t *mp, socklen_t length) nxt_sockaddr_t * nxt_sockaddr_create(nxt_mem_pool_t *mp, struct sockaddr *sockaddr, - socklen_t length) + socklen_t length, size_t address_length) { size_t size, copy; nxt_sockaddr_t *sa; @@ -95,19 +101,11 @@ nxt_sockaddr_create(nxt_mem_pool_t *mp, struct sockaddr *sockaddr, #endif /* NXT_HAVE_UNIX_DOMAIN */ - sa = nxt_sockaddr_alloc(mp, size); + sa = nxt_sockaddr_alloc(mp, size, address_length); if (nxt_fast_path(sa != NULL)) { - nxt_memcpy(&sa->u.sockaddr, sockaddr, copy); -#if (NXT_SOCKADDR_SA_LEN) - - /* Update shortcut sockaddr length overwritten by nxt_memcpy(). */ - nxt_socklen_set(sa, size); - -#endif - #if (NXT_HAVE_UNIX_DOMAIN && NXT_OPENBSD) if (length == 0) { @@ -127,7 +125,7 @@ nxt_sockaddr_copy(nxt_mem_pool_t *mp, nxt_sockaddr_t *src) size_t length; nxt_sockaddr_t *dst; - length = offsetof(nxt_sockaddr_t, u) + nxt_socklen(src); + length = offsetof(nxt_sockaddr_t, u) + src->socklen; dst = nxt_mem_alloc(mp, length); @@ -140,9 +138,10 @@ nxt_sockaddr_copy(nxt_mem_pool_t *mp, nxt_sockaddr_t *src) nxt_sockaddr_t * -nxt_getsockname(nxt_mem_pool_t *mp, nxt_socket_t s) +nxt_getsockname(nxt_task_t *task, nxt_mem_pool_t *mp, nxt_socket_t s) { int ret; + size_t length; socklen_t socklen; nxt_sockaddr_buf_t sockaddr; @@ -151,44 +150,148 @@ nxt_getsockname(nxt_mem_pool_t *mp, nxt_socket_t s) ret = getsockname(s, &sockaddr.buf, &socklen); if (nxt_fast_path(ret == 0)) { - return nxt_sockaddr_create(mp, &sockaddr.buf, socklen); + + switch (sockaddr.buf.sa_family) { +#if (NXT_INET6) + case AF_INET6: + length = NXT_INET6_ADDR_STR_LEN; + break; +#endif + +#if (NXT_HAVE_UNIX_DOMAIN) + case AF_UNIX: + length = sizeof("unix:") - 1 + socklen; +#endif + break; + + case AF_INET: + length = NXT_INET_ADDR_STR_LEN; + break; + + default: + length = 0; + break; + } + + return nxt_sockaddr_create(mp, &sockaddr.buf, socklen, length); } - nxt_thread_log_error(NXT_LOG_ERR, "getsockname(%d) failed %E", - s, nxt_errno); + nxt_log(task, NXT_LOG_ERR, "getsockname(%d) failed %E", s, nxt_errno); return NULL; } -nxt_int_t -nxt_sockaddr_text(nxt_mem_pool_t *mp, nxt_sockaddr_t *sa, nxt_bool_t port) +void +nxt_sockaddr_text(nxt_sockaddr_t *sa) { - size_t length; - u_char *p; - u_char buf[NXT_SOCKADDR_STR_LEN + NXT_SOCKPORT_STR_LEN]; + size_t offset; + u_char *p, *start, *end, *octet; + uint32_t port; - length = NXT_SOCKADDR_STR_LEN + NXT_SOCKPORT_STR_LEN; + end = (u_char *) sa + sa->sockaddr_size; - length = nxt_sockaddr_ntop(sa, buf, buf + length, port); + switch (sa->u.sockaddr.sa_family) { - p = nxt_mem_alloc(mp, length); + case AF_INET: + offset = offsetof(nxt_sockaddr_t, u) + sizeof(struct sockaddr_in); - if (nxt_fast_path(p != NULL)) { + sa->start = offset; + sa->address_start = offset; - sa->text = p; - sa->text_len = length; - nxt_memcpy(p, buf, length); + start = (u_char *) sa + offset; + octet = (u_char *) &sa->u.sockaddr_in.sin_addr; - return NXT_OK; + p = nxt_sprintf(start, end, "%ud.%ud.%ud.%ud", + octet[0], octet[1], octet[2], octet[3]); + + sa->address_length = p - start; + sa->port_start = sa->address_length + 1; + + port = sa->u.sockaddr_in.sin_port; + + break; + +#if (NXT_INET6) + + case AF_INET6: + offset = offsetof(nxt_sockaddr_t, u) + sizeof(struct sockaddr_in6); + + sa->start = offset; + sa->address_start = offset; + + start = (u_char *) sa + offset; + p = start; + + *p++ = '['; + + p = nxt_inet6_ntop(sa->u.sockaddr_in6.sin6_addr.s6_addr, p, end); + + sa->address_length = p - (start + 1); + sa->port_start = sa->address_length + 2; + + *p++ = ']'; + + port = sa->u.sockaddr_in6.sin6_port; + + break; + +#endif + +#if (NXT_HAVE_UNIX_DOMAIN) + + case AF_UNIX: + + offset = offsetof(nxt_sockaddr_t, u) + sizeof(struct sockaddr_un); + + sa->start = offset; + sa->address_start = offset; + + start = (u_char *) sa + offset; + p = start; + +#if (NXT_LINUX) + + p = (u_char *) sa->u.sockaddr_un.sun_path; + + if (p[0] == '\0') { + int length; + + /* Linux abstract socket address has no trailing zero. */ + length = sa->socklen - offsetof(struct sockaddr_un, sun_path); + + p = nxt_sprintf(start, end, "unix:@%*s", length - 1, p + 1); + + } else { + p = nxt_sprintf(start, end, "unix:%s", p); + } + +#else /* !(NXT_LINUX) */ + + p = nxt_sprintf(start, end, "unix:%s", p); + +#endif + + sa->address_length = p - start; + sa->port_start = sa->address_length; + sa->length = p - start; + + return; + +#endif /* NXT_HAVE_UNIX_DOMAIN */ + + default: + return; } - return NXT_ERROR; + p = nxt_sprintf(p, end, ":%d", ntohs(port)); + + sa->length = p - start; } uint32_t -nxt_sockaddr_port(nxt_sockaddr_t *sa) +nxt_sockaddr_port_number(nxt_sockaddr_t *sa) { uint32_t port; @@ -221,7 +324,7 @@ nxt_sockaddr_port(nxt_sockaddr_t *sa) nxt_bool_t nxt_sockaddr_cmp(nxt_sockaddr_t *sa1, nxt_sockaddr_t *sa2) { - if (nxt_socklen(sa1) != nxt_socklen(sa2)) { + if (sa1->socklen != sa2->socklen) { return 0; } @@ -264,7 +367,7 @@ nxt_sockaddr_cmp(nxt_sockaddr_t *sa1, nxt_sockaddr_t *sa2) { size_t length; - length = nxt_socklen(sa1) - offsetof(struct sockaddr_un, sun_path); + length = sa1->socklen - offsetof(struct sockaddr_un, sun_path); if (nxt_memcmp(&sa1->u.sockaddr_un.sun_path, &sa2->u.sockaddr_un.sun_path, length) @@ -347,8 +450,7 @@ nxt_sockaddr_ntop(nxt_sockaddr_t *sa, u_char *buf, u_char *end, nxt_bool_t port) /* Linux abstract socket address has no trailing zero. */ - length = nxt_socklen(sa) - - offsetof(struct sockaddr_un, sun_path) - 1; + length = sa->socklen - offsetof(struct sockaddr_un, sun_path) - 1; p = nxt_sprintf(buf, end, "unix:\\0%*s", length, p + 1); } else { @@ -556,7 +658,7 @@ nxt_job_sockaddr_unix_parse(nxt_job_sockaddr_parse_t *jbs) jbs->resolve.sockaddrs = nxt_mem_alloc(mp, sizeof(void *)); if (nxt_fast_path(jbs->resolve.sockaddrs != NULL)) { - sa = nxt_sockaddr_alloc(mp, socklen); + sa = nxt_sockaddr_alloc(mp, socklen, jbs->addr.length); if (nxt_fast_path(sa != NULL)) { jbs->resolve.count = 1; @@ -763,7 +865,8 @@ nxt_job_sockaddr_inet_parse(nxt_job_sockaddr_parse_t *jbs) return NXT_ERROR; } - sa = nxt_sockaddr_alloc(mp, sizeof(struct sockaddr_in)); + sa = nxt_sockaddr_alloc(mp, sizeof(struct sockaddr_in), + NXT_INET_ADDR_STR_LEN); if (nxt_fast_path(sa != NULL)) { jbs->resolve.count = 1; |