ngx_event_accept.c revision e18a033b
1
2/*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) Nginx, Inc.
5 */
6
7
8#include <ngx_config.h>
9#include <ngx_core.h>
10#include <ngx_event.h>
11
12
13static ngx_int_t ngx_enable_accept_events(ngx_cycle_t *cycle);
14static ngx_int_t ngx_disable_accept_events(ngx_cycle_t *cycle, ngx_uint_t all);
15static void ngx_close_accepted_connection(ngx_connection_t *c);
16#if (NGX_DEBUG)
17static void ngx_debug_accepted_connection(ngx_event_conf_t *ecf,
18    ngx_connection_t *c);
19#endif
20
21
22void
23ngx_event_accept(ngx_event_t *ev)
24{
25    socklen_t          socklen;
26    ngx_err_t          err;
27    ngx_log_t         *log;
28    ngx_uint_t         level;
29    ngx_socket_t       s;
30    ngx_event_t       *rev, *wev;
31    ngx_sockaddr_t     sa;
32    ngx_listening_t   *ls;
33    ngx_connection_t  *c, *lc;
34    ngx_event_conf_t  *ecf;
35#if (NGX_HAVE_ACCEPT4)
36    static ngx_uint_t  use_accept4 = 1;
37#endif
38
39    if (ev->timedout) {
40        if (ngx_enable_accept_events((ngx_cycle_t *) ngx_cycle) != NGX_OK) {
41            return;
42        }
43
44        ev->timedout = 0;
45    }
46
47    ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module);
48
49    if (!(ngx_event_flags & NGX_USE_KQUEUE_EVENT)) {
50        ev->available = ecf->multi_accept;
51    }
52
53    lc = ev->data;
54    ls = lc->listening;
55    ev->ready = 0;
56
57    ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
58                   "accept on %V, ready: %d", &ls->addr_text, ev->available);
59
60    do {
61        socklen = sizeof(ngx_sockaddr_t);
62
63#if (NGX_HAVE_ACCEPT4)
64        if (use_accept4) {
65            s = accept4(lc->fd, &sa.sockaddr, &socklen, SOCK_NONBLOCK);
66        } else {
67            s = accept(lc->fd, &sa.sockaddr, &socklen);
68        }
69#else
70        s = accept(lc->fd, &sa.sockaddr, &socklen);
71#endif
72
73        if (s == (ngx_socket_t) -1) {
74            err = ngx_socket_errno;
75
76            if (err == NGX_EAGAIN) {
77                ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, err,
78                               "accept() not ready");
79                return;
80            }
81
82            level = NGX_LOG_ALERT;
83
84            if (err == NGX_ECONNABORTED) {
85                level = NGX_LOG_ERR;
86
87            } else if (err == NGX_EMFILE || err == NGX_ENFILE) {
88                level = NGX_LOG_CRIT;
89            }
90
91#if (NGX_HAVE_ACCEPT4)
92            ngx_log_error(level, ev->log, err,
93                          use_accept4 ? "accept4() failed" : "accept() failed");
94
95            if (use_accept4 && err == NGX_ENOSYS) {
96                use_accept4 = 0;
97                ngx_inherited_nonblocking = 0;
98                continue;
99            }
100#else
101            ngx_log_error(level, ev->log, err, "accept() failed");
102#endif
103
104            if (err == NGX_ECONNABORTED) {
105                if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
106                    ev->available--;
107                }
108
109                if (ev->available) {
110                    continue;
111                }
112            }
113
114            if (err == NGX_EMFILE || err == NGX_ENFILE) {
115                if (ngx_disable_accept_events((ngx_cycle_t *) ngx_cycle, 1)
116                    != NGX_OK)
117                {
118                    return;
119                }
120
121                if (ngx_use_accept_mutex) {
122                    if (ngx_accept_mutex_held) {
123                        ngx_shmtx_unlock(&ngx_accept_mutex);
124                        ngx_accept_mutex_held = 0;
125                    }
126
127                    ngx_accept_disabled = 1;
128
129                } else {
130                    ngx_add_timer(ev, ecf->accept_mutex_delay);
131                }
132            }
133
134            return;
135        }
136
137#if (NGX_STAT_STUB)
138        (void) ngx_atomic_fetch_add(ngx_stat_accepted, 1);
139#endif
140
141        ngx_accept_disabled = ngx_cycle->connection_n / 8
142                              - ngx_cycle->free_connection_n;
143
144        c = ngx_get_connection(s, ev->log);
145
146        if (c == NULL) {
147            if (ngx_close_socket(s) == -1) {
148                ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
149                              ngx_close_socket_n " failed");
150            }
151
152            return;
153        }
154
155        c->type = SOCK_STREAM;
156
157#if (NGX_STAT_STUB)
158        (void) ngx_atomic_fetch_add(ngx_stat_active, 1);
159#endif
160
161        c->pool = ngx_create_pool(ls->pool_size, ev->log);
162        if (c->pool == NULL) {
163            ngx_close_accepted_connection(c);
164            return;
165        }
166
167        c->sockaddr = ngx_palloc(c->pool, socklen);
168        if (c->sockaddr == NULL) {
169            ngx_close_accepted_connection(c);
170            return;
171        }
172
173        ngx_memcpy(c->sockaddr, &sa, socklen);
174
175        log = ngx_palloc(c->pool, sizeof(ngx_log_t));
176        if (log == NULL) {
177            ngx_close_accepted_connection(c);
178            return;
179        }
180
181        /* set a blocking mode for iocp and non-blocking mode for others */
182
183        if (ngx_inherited_nonblocking) {
184            if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
185                if (ngx_blocking(s) == -1) {
186                    ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
187                                  ngx_blocking_n " failed");
188                    ngx_close_accepted_connection(c);
189                    return;
190                }
191            }
192
193        } else {
194            if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) {
195                if (ngx_nonblocking(s) == -1) {
196                    ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
197                                  ngx_nonblocking_n " failed");
198                    ngx_close_accepted_connection(c);
199                    return;
200                }
201            }
202        }
203
204        *log = ls->log;
205
206        c->recv = ngx_recv;
207        c->send = ngx_send;
208        c->recv_chain = ngx_recv_chain;
209        c->send_chain = ngx_send_chain;
210
211        c->log = log;
212        c->pool->log = log;
213
214        c->socklen = socklen;
215        c->listening = ls;
216        c->local_sockaddr = ls->sockaddr;
217        c->local_socklen = ls->socklen;
218
219#if (NGX_HAVE_UNIX_DOMAIN)
220        if (c->sockaddr->sa_family == AF_UNIX) {
221            c->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
222            c->tcp_nodelay = NGX_TCP_NODELAY_DISABLED;
223#if (NGX_SOLARIS)
224            /* Solaris's sendfilev() supports AF_NCA, AF_INET, and AF_INET6 */
225            c->sendfile = 0;
226#endif
227        }
228#endif
229
230        rev = c->read;
231        wev = c->write;
232
233        wev->ready = 1;
234
235        if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
236            rev->ready = 1;
237        }
238
239        if (ev->deferred_accept) {
240            rev->ready = 1;
241#if (NGX_HAVE_KQUEUE)
242            rev->available = 1;
243#endif
244        }
245
246        rev->log = log;
247        wev->log = log;
248
249        /*
250         * TODO: MT: - ngx_atomic_fetch_add()
251         *             or protection by critical section or light mutex
252         *
253         * TODO: MP: - allocated in a shared memory
254         *           - ngx_atomic_fetch_add()
255         *             or protection by critical section or light mutex
256         */
257
258        c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
259
260#if (NGX_STAT_STUB)
261        (void) ngx_atomic_fetch_add(ngx_stat_handled, 1);
262#endif
263
264        if (ls->addr_ntop) {
265            c->addr_text.data = ngx_pnalloc(c->pool, ls->addr_text_max_len);
266            if (c->addr_text.data == NULL) {
267                ngx_close_accepted_connection(c);
268                return;
269            }
270
271            c->addr_text.len = ngx_sock_ntop(c->sockaddr, c->socklen,
272                                             c->addr_text.data,
273                                             ls->addr_text_max_len, 0);
274            if (c->addr_text.len == 0) {
275                ngx_close_accepted_connection(c);
276                return;
277            }
278        }
279
280#if (NGX_DEBUG)
281        {
282        ngx_str_t  addr;
283        u_char     text[NGX_SOCKADDR_STRLEN];
284
285        ngx_debug_accepted_connection(ecf, c);
286
287        if (log->log_level & NGX_LOG_DEBUG_EVENT) {
288            addr.data = text;
289            addr.len = ngx_sock_ntop(c->sockaddr, c->socklen, text,
290                                     NGX_SOCKADDR_STRLEN, 1);
291
292            ngx_log_debug3(NGX_LOG_DEBUG_EVENT, log, 0,
293                           "*%uA accept: %V fd:%d", c->number, &addr, s);
294        }
295
296        }
297#endif
298
299        if (ngx_add_conn && (ngx_event_flags & NGX_USE_EPOLL_EVENT) == 0) {
300            if (ngx_add_conn(c) == NGX_ERROR) {
301                ngx_close_accepted_connection(c);
302                return;
303            }
304        }
305
306        log->data = NULL;
307        log->handler = NULL;
308
309        ls->handler(c);
310
311        if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
312            ev->available--;
313        }
314
315    } while (ev->available);
316}
317
318
319#if !(NGX_WIN32)
320
321void
322ngx_event_recvmsg(ngx_event_t *ev)
323{
324    ssize_t            n;
325    ngx_log_t         *log;
326    ngx_err_t          err;
327    ngx_event_t       *rev, *wev;
328    struct iovec       iov[1];
329    struct msghdr      msg;
330    ngx_sockaddr_t     sa;
331    ngx_listening_t   *ls;
332    ngx_event_conf_t  *ecf;
333    ngx_connection_t  *c, *lc;
334    static u_char      buffer[65535];
335
336#if (NGX_HAVE_MSGHDR_MSG_CONTROL)
337
338#if (NGX_HAVE_IP_RECVDSTADDR)
339    u_char             msg_control[CMSG_SPACE(sizeof(struct in_addr))];
340#elif (NGX_HAVE_IP_PKTINFO)
341    u_char             msg_control[CMSG_SPACE(sizeof(struct in_pktinfo))];
342#endif
343
344#if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO)
345    u_char             msg_control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
346#endif
347
348#endif
349
350    if (ev->timedout) {
351        if (ngx_enable_accept_events((ngx_cycle_t *) ngx_cycle) != NGX_OK) {
352            return;
353        }
354
355        ev->timedout = 0;
356    }
357
358    ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module);
359
360    if (!(ngx_event_flags & NGX_USE_KQUEUE_EVENT)) {
361        ev->available = ecf->multi_accept;
362    }
363
364    lc = ev->data;
365    ls = lc->listening;
366    ev->ready = 0;
367
368    ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
369                   "recvmsg on %V, ready: %d", &ls->addr_text, ev->available);
370
371    do {
372        ngx_memzero(&msg, sizeof(struct msghdr));
373
374        iov[0].iov_base = (void *) buffer;
375        iov[0].iov_len = sizeof(buffer);
376
377        msg.msg_name = &sa;
378        msg.msg_namelen = sizeof(ngx_sockaddr_t);
379        msg.msg_iov = iov;
380        msg.msg_iovlen = 1;
381
382#if (NGX_HAVE_MSGHDR_MSG_CONTROL)
383
384        if (ls->wildcard) {
385
386#if (NGX_HAVE_IP_RECVDSTADDR || NGX_HAVE_IP_PKTINFO)
387            if (ls->sockaddr->sa_family == AF_INET) {
388                msg.msg_control = &msg_control;
389                msg.msg_controllen = sizeof(msg_control);
390            }
391#endif
392
393#if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO)
394            if (ls->sockaddr->sa_family == AF_INET6) {
395                msg.msg_control = &msg_control6;
396                msg.msg_controllen = sizeof(msg_control6);
397            }
398#endif
399        }
400
401#endif
402
403        n = recvmsg(lc->fd, &msg, 0);
404
405        if (n == -1) {
406            err = ngx_socket_errno;
407
408            if (err == NGX_EAGAIN) {
409                ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, err,
410                               "recvmsg() not ready");
411                return;
412            }
413
414            ngx_log_error(NGX_LOG_ALERT, ev->log, err, "recvmsg() failed");
415
416            return;
417        }
418
419#if (NGX_STAT_STUB)
420        (void) ngx_atomic_fetch_add(ngx_stat_accepted, 1);
421#endif
422
423#if (NGX_HAVE_MSGHDR_MSG_CONTROL)
424        if (msg.msg_flags & (MSG_TRUNC|MSG_CTRUNC)) {
425            ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
426                          "recvmsg() truncated data");
427            continue;
428        }
429#endif
430
431        ngx_accept_disabled = ngx_cycle->connection_n / 8
432                              - ngx_cycle->free_connection_n;
433
434        c = ngx_get_connection(lc->fd, ev->log);
435        if (c == NULL) {
436            return;
437        }
438
439        c->shared = 1;
440        c->type = SOCK_DGRAM;
441        c->socklen = msg.msg_namelen;
442
443#if (NGX_STAT_STUB)
444        (void) ngx_atomic_fetch_add(ngx_stat_active, 1);
445#endif
446
447        c->pool = ngx_create_pool(ls->pool_size, ev->log);
448        if (c->pool == NULL) {
449            ngx_close_accepted_connection(c);
450            return;
451        }
452
453        c->sockaddr = ngx_palloc(c->pool, c->socklen);
454        if (c->sockaddr == NULL) {
455            ngx_close_accepted_connection(c);
456            return;
457        }
458
459        ngx_memcpy(c->sockaddr, msg.msg_name, c->socklen);
460
461        log = ngx_palloc(c->pool, sizeof(ngx_log_t));
462        if (log == NULL) {
463            ngx_close_accepted_connection(c);
464            return;
465        }
466
467        *log = ls->log;
468
469        c->send = ngx_udp_send;
470        c->send_chain = ngx_udp_send_chain;
471
472        c->log = log;
473        c->pool->log = log;
474
475        c->listening = ls;
476        c->local_sockaddr = ls->sockaddr;
477        c->local_socklen = ls->socklen;
478
479#if (NGX_HAVE_MSGHDR_MSG_CONTROL)
480
481        if (ls->wildcard) {
482            struct cmsghdr   *cmsg;
483            struct sockaddr  *sockaddr;
484
485            sockaddr = ngx_palloc(c->pool, c->local_socklen);
486            if (sockaddr == NULL) {
487                ngx_close_accepted_connection(c);
488                return;
489            }
490
491            ngx_memcpy(sockaddr, c->local_sockaddr, c->local_socklen);
492            c->local_sockaddr = sockaddr;
493
494            for (cmsg = CMSG_FIRSTHDR(&msg);
495                 cmsg != NULL;
496                 cmsg = CMSG_NXTHDR(&msg, cmsg))
497            {
498
499#if (NGX_HAVE_IP_RECVDSTADDR)
500
501                if (cmsg->cmsg_level == IPPROTO_IP
502                    && cmsg->cmsg_type == IP_RECVDSTADDR
503                    && sockaddr->sa_family == AF_INET)
504                {
505                    struct in_addr      *addr;
506                    struct sockaddr_in  *sin;
507
508                    addr = (struct in_addr *) CMSG_DATA(cmsg);
509                    sin = (struct sockaddr_in *) sockaddr;
510                    sin->sin_addr = *addr;
511
512                    break;
513                }
514
515#elif (NGX_HAVE_IP_PKTINFO)
516
517                if (cmsg->cmsg_level == IPPROTO_IP
518                    && cmsg->cmsg_type == IP_PKTINFO
519                    && sockaddr->sa_family == AF_INET)
520                {
521                    struct in_pktinfo   *pkt;
522                    struct sockaddr_in  *sin;
523
524                    pkt = (struct in_pktinfo *) CMSG_DATA(cmsg);
525                    sin = (struct sockaddr_in *) sockaddr;
526                    sin->sin_addr = pkt->ipi_addr;
527
528                    break;
529                }
530
531#endif
532
533#if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO)
534
535                if (cmsg->cmsg_level == IPPROTO_IPV6
536                    && cmsg->cmsg_type == IPV6_PKTINFO
537                    && sockaddr->sa_family == AF_INET6)
538                {
539                    struct in6_pktinfo   *pkt6;
540                    struct sockaddr_in6  *sin6;
541
542                    pkt6 = (struct in6_pktinfo *) CMSG_DATA(cmsg);
543                    sin6 = (struct sockaddr_in6 *) sockaddr;
544                    sin6->sin6_addr = pkt6->ipi6_addr;
545
546                    break;
547                }
548
549#endif
550
551            }
552        }
553
554#endif
555
556        c->buffer = ngx_create_temp_buf(c->pool, n);
557        if (c->buffer == NULL) {
558            ngx_close_accepted_connection(c);
559            return;
560        }
561
562        c->buffer->last = ngx_cpymem(c->buffer->last, buffer, n);
563
564        rev = c->read;
565        wev = c->write;
566
567        wev->ready = 1;
568
569        rev->log = log;
570        wev->log = log;
571
572        /*
573         * TODO: MT: - ngx_atomic_fetch_add()
574         *             or protection by critical section or light mutex
575         *
576         * TODO: MP: - allocated in a shared memory
577         *           - ngx_atomic_fetch_add()
578         *             or protection by critical section or light mutex
579         */
580
581        c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
582
583#if (NGX_STAT_STUB)
584        (void) ngx_atomic_fetch_add(ngx_stat_handled, 1);
585#endif
586
587        if (ls->addr_ntop) {
588            c->addr_text.data = ngx_pnalloc(c->pool, ls->addr_text_max_len);
589            if (c->addr_text.data == NULL) {
590                ngx_close_accepted_connection(c);
591                return;
592            }
593
594            c->addr_text.len = ngx_sock_ntop(c->sockaddr, c->socklen,
595                                             c->addr_text.data,
596                                             ls->addr_text_max_len, 0);
597            if (c->addr_text.len == 0) {
598                ngx_close_accepted_connection(c);
599                return;
600            }
601        }
602
603#if (NGX_DEBUG)
604        {
605        ngx_str_t  addr;
606        u_char     text[NGX_SOCKADDR_STRLEN];
607
608        ngx_debug_accepted_connection(ecf, c);
609
610        if (log->log_level & NGX_LOG_DEBUG_EVENT) {
611            addr.data = text;
612            addr.len = ngx_sock_ntop(c->sockaddr, c->socklen, text,
613                                     NGX_SOCKADDR_STRLEN, 1);
614
615            ngx_log_debug4(NGX_LOG_DEBUG_EVENT, log, 0,
616                           "*%uA recvmsg: %V fd:%d n:%z",
617                           c->number, &addr, c->fd, n);
618        }
619
620        }
621#endif
622
623        log->data = NULL;
624        log->handler = NULL;
625
626        ls->handler(c);
627
628        if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
629            ev->available -= n;
630        }
631
632    } while (ev->available);
633}
634
635#endif
636
637
638ngx_int_t
639ngx_trylock_accept_mutex(ngx_cycle_t *cycle)
640{
641    if (ngx_shmtx_trylock(&ngx_accept_mutex)) {
642
643        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
644                       "accept mutex locked");
645
646        if (ngx_accept_mutex_held && ngx_accept_events == 0) {
647            return NGX_OK;
648        }
649
650        if (ngx_enable_accept_events(cycle) == NGX_ERROR) {
651            ngx_shmtx_unlock(&ngx_accept_mutex);
652            return NGX_ERROR;
653        }
654
655        ngx_accept_events = 0;
656        ngx_accept_mutex_held = 1;
657
658        return NGX_OK;
659    }
660
661    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
662                   "accept mutex lock failed: %ui", ngx_accept_mutex_held);
663
664    if (ngx_accept_mutex_held) {
665        if (ngx_disable_accept_events(cycle, 0) == NGX_ERROR) {
666            return NGX_ERROR;
667        }
668
669        ngx_accept_mutex_held = 0;
670    }
671
672    return NGX_OK;
673}
674
675
676static ngx_int_t
677ngx_enable_accept_events(ngx_cycle_t *cycle)
678{
679    ngx_uint_t         i;
680    ngx_listening_t   *ls;
681    ngx_connection_t  *c;
682
683    ls = cycle->listening.elts;
684    for (i = 0; i < cycle->listening.nelts; i++) {
685
686        c = ls[i].connection;
687
688        if (c == NULL || c->read->active) {
689            continue;
690        }
691
692        if (ngx_add_event(c->read, NGX_READ_EVENT, 0) == NGX_ERROR) {
693            return NGX_ERROR;
694        }
695    }
696
697    return NGX_OK;
698}
699
700
701static ngx_int_t
702ngx_disable_accept_events(ngx_cycle_t *cycle, ngx_uint_t all)
703{
704    ngx_uint_t         i;
705    ngx_listening_t   *ls;
706    ngx_connection_t  *c;
707
708    ls = cycle->listening.elts;
709    for (i = 0; i < cycle->listening.nelts; i++) {
710
711        c = ls[i].connection;
712
713        if (c == NULL || !c->read->active) {
714            continue;
715        }
716
717#if (NGX_HAVE_REUSEPORT)
718
719        /*
720         * do not disable accept on worker's own sockets
721         * when disabling accept events due to accept mutex
722         */
723
724        if (ls[i].reuseport && !all) {
725            continue;
726        }
727
728#endif
729
730        if (ngx_del_event(c->read, NGX_READ_EVENT, NGX_DISABLE_EVENT)
731            == NGX_ERROR)
732        {
733            return NGX_ERROR;
734        }
735    }
736
737    return NGX_OK;
738}
739
740
741static void
742ngx_close_accepted_connection(ngx_connection_t *c)
743{
744    ngx_socket_t  fd;
745
746    ngx_free_connection(c);
747
748    fd = c->fd;
749    c->fd = (ngx_socket_t) -1;
750
751    if (!c->shared && ngx_close_socket(fd) == -1) {
752        ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno,
753                      ngx_close_socket_n " failed");
754    }
755
756    if (c->pool) {
757        ngx_destroy_pool(c->pool);
758    }
759
760#if (NGX_STAT_STUB)
761    (void) ngx_atomic_fetch_add(ngx_stat_active, -1);
762#endif
763}
764
765
766u_char *
767ngx_accept_log_error(ngx_log_t *log, u_char *buf, size_t len)
768{
769    return ngx_snprintf(buf, len, " while accepting new connection on %V",
770                        log->data);
771}
772
773
774#if (NGX_DEBUG)
775
776static void
777ngx_debug_accepted_connection(ngx_event_conf_t *ecf, ngx_connection_t *c)
778{
779    struct sockaddr_in   *sin;
780    ngx_cidr_t           *cidr;
781    ngx_uint_t            i;
782#if (NGX_HAVE_INET6)
783    struct sockaddr_in6  *sin6;
784    ngx_uint_t            n;
785#endif
786
787    cidr = ecf->debug_connection.elts;
788    for (i = 0; i < ecf->debug_connection.nelts; i++) {
789        if (cidr[i].family != (ngx_uint_t) c->sockaddr->sa_family) {
790            goto next;
791        }
792
793        switch (cidr[i].family) {
794
795#if (NGX_HAVE_INET6)
796        case AF_INET6:
797            sin6 = (struct sockaddr_in6 *) c->sockaddr;
798            for (n = 0; n < 16; n++) {
799                if ((sin6->sin6_addr.s6_addr[n]
800                    & cidr[i].u.in6.mask.s6_addr[n])
801                    != cidr[i].u.in6.addr.s6_addr[n])
802                {
803                    goto next;
804                }
805            }
806            break;
807#endif
808
809#if (NGX_HAVE_UNIX_DOMAIN)
810        case AF_UNIX:
811            break;
812#endif
813
814        default: /* AF_INET */
815            sin = (struct sockaddr_in *) c->sockaddr;
816            if ((sin->sin_addr.s_addr & cidr[i].u.in.mask)
817                != cidr[i].u.in.addr)
818            {
819                goto next;
820            }
821            break;
822        }
823
824        c->log->log_level = NGX_LOG_DEBUG_CONNECTION|NGX_LOG_DEBUG_ALL;
825        break;
826
827    next:
828        continue;
829    }
830}
831
832#endif
833