diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/event/ngx_event_accept.c | 153 |
1 files changed, 82 insertions, 71 deletions
diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c index 7e9f742a0..c988616ef 100644 --- a/src/event/ngx_event_accept.c +++ b/src/event/ngx_event_accept.c @@ -328,10 +328,12 @@ ngx_event_recvmsg(ngx_event_t *ev) ssize_t n; ngx_log_t *log; ngx_err_t err; + socklen_t socklen, local_socklen; ngx_event_t *rev, *wev; struct iovec iov[1]; struct msghdr msg; - ngx_sockaddr_t sa; + ngx_sockaddr_t sa, lsa; + struct sockaddr *sockaddr, *local_sockaddr; ngx_listening_t *ls; ngx_event_conf_t *ecf; ngx_connection_t *c, *lc; @@ -420,10 +422,6 @@ ngx_event_recvmsg(ngx_event_t *ev) return; } -#if (NGX_STAT_STUB) - (void) ngx_atomic_fetch_add(ngx_stat_accepted, 1); -#endif - #if (NGX_HAVE_MSGHDR_MSG_CONTROL) if (msg.msg_flags & (MSG_TRUNC|MSG_CTRUNC)) { ngx_log_error(NGX_LOG_ALERT, ev->log, 0, @@ -432,84 +430,35 @@ ngx_event_recvmsg(ngx_event_t *ev) } #endif - ngx_accept_disabled = ngx_cycle->connection_n / 8 - - ngx_cycle->free_connection_n; - - c = ngx_get_connection(lc->fd, ev->log); - if (c == NULL) { - return; - } - - c->shared = 1; - c->type = SOCK_DGRAM; - c->socklen = msg.msg_namelen; + sockaddr = msg.msg_name; + socklen = msg.msg_namelen; - if (c->socklen > (socklen_t) sizeof(ngx_sockaddr_t)) { - c->socklen = sizeof(ngx_sockaddr_t); + if (socklen > (socklen_t) sizeof(ngx_sockaddr_t)) { + socklen = sizeof(ngx_sockaddr_t); } - if (c->socklen == 0) { + if (socklen == 0) { /* * on Linux recvmsg() returns zero msg_namelen * when receiving packets from unbound AF_UNIX sockets */ - c->socklen = sizeof(struct sockaddr); + socklen = sizeof(struct sockaddr); ngx_memzero(&sa, sizeof(struct sockaddr)); sa.sockaddr.sa_family = ls->sockaddr->sa_family; } -#if (NGX_STAT_STUB) - (void) ngx_atomic_fetch_add(ngx_stat_active, 1); -#endif - - c->pool = ngx_create_pool(ls->pool_size, ev->log); - if (c->pool == NULL) { - ngx_close_accepted_connection(c); - return; - } - - c->sockaddr = ngx_palloc(c->pool, c->socklen); - if (c->sockaddr == NULL) { - ngx_close_accepted_connection(c); - return; - } - - ngx_memcpy(c->sockaddr, msg.msg_name, c->socklen); - - log = ngx_palloc(c->pool, sizeof(ngx_log_t)); - if (log == NULL) { - ngx_close_accepted_connection(c); - return; - } - - *log = ls->log; - - c->send = ngx_udp_send; - c->send_chain = ngx_udp_send_chain; - - c->log = log; - c->pool->log = log; - - c->listening = ls; - c->local_sockaddr = ls->sockaddr; - c->local_socklen = ls->socklen; + local_sockaddr = ls->sockaddr; + local_socklen = ls->socklen; #if (NGX_HAVE_MSGHDR_MSG_CONTROL) if (ls->wildcard) { - struct cmsghdr *cmsg; - struct sockaddr *sockaddr; - - sockaddr = ngx_palloc(c->pool, c->local_socklen); - if (sockaddr == NULL) { - ngx_close_accepted_connection(c); - return; - } + struct cmsghdr *cmsg; - ngx_memcpy(sockaddr, c->local_sockaddr, c->local_socklen); - c->local_sockaddr = sockaddr; + ngx_memcpy(&lsa, local_sockaddr, local_socklen); + local_sockaddr = &lsa.sockaddr; for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; @@ -520,13 +469,13 @@ ngx_event_recvmsg(ngx_event_t *ev) if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_RECVDSTADDR - && sockaddr->sa_family == AF_INET) + && local_sockaddr->sa_family == AF_INET) { struct in_addr *addr; struct sockaddr_in *sin; addr = (struct in_addr *) CMSG_DATA(cmsg); - sin = (struct sockaddr_in *) sockaddr; + sin = (struct sockaddr_in *) local_sockaddr; sin->sin_addr = *addr; break; @@ -536,13 +485,13 @@ ngx_event_recvmsg(ngx_event_t *ev) if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO - && sockaddr->sa_family == AF_INET) + && local_sockaddr->sa_family == AF_INET) { struct in_pktinfo *pkt; struct sockaddr_in *sin; pkt = (struct in_pktinfo *) CMSG_DATA(cmsg); - sin = (struct sockaddr_in *) sockaddr; + sin = (struct sockaddr_in *) local_sockaddr; sin->sin_addr = pkt->ipi_addr; break; @@ -554,13 +503,13 @@ ngx_event_recvmsg(ngx_event_t *ev) if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO - && sockaddr->sa_family == AF_INET6) + && local_sockaddr->sa_family == AF_INET6) { struct in6_pktinfo *pkt6; struct sockaddr_in6 *sin6; pkt6 = (struct in6_pktinfo *) CMSG_DATA(cmsg); - sin6 = (struct sockaddr_in6 *) sockaddr; + sin6 = (struct sockaddr_in6 *) local_sockaddr; sin6->sin6_addr = pkt6->ipi6_addr; break; @@ -573,6 +522,68 @@ ngx_event_recvmsg(ngx_event_t *ev) #endif +#if (NGX_STAT_STUB) + (void) ngx_atomic_fetch_add(ngx_stat_accepted, 1); +#endif + + ngx_accept_disabled = ngx_cycle->connection_n / 8 + - ngx_cycle->free_connection_n; + + c = ngx_get_connection(lc->fd, ev->log); + if (c == NULL) { + return; + } + + c->shared = 1; + c->type = SOCK_DGRAM; + c->socklen = socklen; + +#if (NGX_STAT_STUB) + (void) ngx_atomic_fetch_add(ngx_stat_active, 1); +#endif + + c->pool = ngx_create_pool(ls->pool_size, ev->log); + if (c->pool == NULL) { + ngx_close_accepted_connection(c); + return; + } + + c->sockaddr = ngx_palloc(c->pool, socklen); + if (c->sockaddr == NULL) { + ngx_close_accepted_connection(c); + return; + } + + ngx_memcpy(c->sockaddr, sockaddr, socklen); + + log = ngx_palloc(c->pool, sizeof(ngx_log_t)); + if (log == NULL) { + ngx_close_accepted_connection(c); + return; + } + + *log = ls->log; + + c->send = ngx_udp_send; + c->send_chain = ngx_udp_send_chain; + + c->log = log; + c->pool->log = log; + c->listening = ls; + + if (local_sockaddr == &lsa.sockaddr) { + local_sockaddr = ngx_palloc(c->pool, local_socklen); + if (local_sockaddr == NULL) { + ngx_close_accepted_connection(c); + return; + } + + ngx_memcpy(local_sockaddr, &lsa, local_socklen); + } + + c->local_sockaddr = local_sockaddr; + c->local_socklen = local_socklen; + c->buffer = ngx_create_temp_buf(c->pool, n); if (c->buffer == NULL) { ngx_close_accepted_connection(c); |