Revert "l4p/tcp: introduce tle_tcp_stream_establish() API"
[tldk.git] / app / nginx / src / event / ngx_event_accept.c
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
13 static ngx_int_t ngx_enable_accept_events(ngx_cycle_t *cycle);
14 static ngx_int_t ngx_disable_accept_events(ngx_cycle_t *cycle, ngx_uint_t all);
15 static void ngx_close_accepted_connection(ngx_connection_t *c);
16 #if (NGX_DEBUG)
17 static void ngx_debug_accepted_connection(ngx_event_conf_t *ecf,
18     ngx_connection_t *c);
19 #endif
20
21
22 void
23 ngx_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
321 void
322 ngx_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
638 ngx_int_t
639 ngx_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
676 static ngx_int_t
677 ngx_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
701 static ngx_int_t
702 ngx_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
741 static void
742 ngx_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
766 u_char *
767 ngx_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
776 static void
777 ngx_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