~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Nginx/core/ngx_connection.c

Version: ~ [ nginx-0.8.20 ] ~ [ nginx-0.7.62 ] ~ [ nginx-0.6.39 ] ~

  1 
  2 /*
  3  * Copyright (C) Igor Sysoev
  4  */
  5 
  6 
  7 #include <ngx_config.h>
  8 #include <ngx_core.h>
  9 #include <ngx_event.h>
 10 
 11 
 12 ngx_os_io_t  ngx_io;
 13 
 14 
 15 ngx_listening_t *
 16 ngx_create_listening(ngx_conf_t *cf, void *sockaddr, socklen_t socklen)
 17 {
 18     ngx_listening_t  *ls;
 19     struct sockaddr  *sa;
 20     u_char            text[NGX_SOCKADDR_STRLEN];
 21 
 22     ls = ngx_array_push(&cf->cycle->listening);
 23     if (ls == NULL) {
 24         return NULL;
 25     }
 26 
 27     ngx_memzero(ls, sizeof(ngx_listening_t));
 28 
 29     sa = ngx_palloc(cf->pool, socklen);
 30     if (sa == NULL) {
 31         return NULL;
 32     }
 33 
 34     ngx_memcpy(sa, sockaddr, socklen);
 35 
 36     ls->sockaddr = sa;
 37     ls->socklen = socklen;
 38 
 39     ls->addr_text.len = ngx_sock_ntop(sa, text, NGX_SOCKADDR_STRLEN, 1);
 40 
 41     ls->addr_text.data = ngx_pnalloc(cf->pool, ls->addr_text.len);
 42     if (ls->addr_text.data == NULL) {
 43         return NULL;
 44     }
 45 
 46     ngx_memcpy(ls->addr_text.data, text, ls->addr_text.len);
 47 
 48     ls->fd = (ngx_socket_t) -1;
 49     ls->type = SOCK_STREAM;
 50 
 51     switch (ls->sockaddr->sa_family) {
 52 #if (NGX_HAVE_INET6)
 53     case AF_INET6:
 54          ls->addr_text_max_len = NGX_INET6_ADDRSTRLEN;
 55          break;
 56 #endif
 57     case AF_INET:
 58          ls->addr_text_max_len = NGX_INET_ADDRSTRLEN;
 59          break;
 60     default:
 61          ls->addr_text_max_len = NGX_SOCKADDR_STRLEN;
 62          break;
 63     }
 64 
 65     ls->backlog = NGX_LISTEN_BACKLOG;
 66     ls->rcvbuf = -1;
 67     ls->sndbuf = -1;
 68 
 69     return ls;
 70 }
 71 
 72 
 73 ngx_int_t
 74 ngx_set_inherited_sockets(ngx_cycle_t *cycle)
 75 {
 76     size_t                     len;
 77     ngx_uint_t                 i;
 78     ngx_listening_t           *ls;
 79     socklen_t                  olen;
 80 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
 81     ngx_err_t                  err;
 82     struct accept_filter_arg   af;
 83 #endif
 84 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
 85     int                        timeout;
 86 #endif
 87 
 88     ls = cycle->listening.elts;
 89     for (i = 0; i < cycle->listening.nelts; i++) {
 90 
 91         /* AF_INET only */
 92 
 93         ls[i].sockaddr = ngx_palloc(cycle->pool, sizeof(struct sockaddr_in));
 94         if (ls[i].sockaddr == NULL) {
 95             return NGX_ERROR;
 96         }
 97 
 98         ls[i].socklen = sizeof(struct sockaddr_in);
 99         if (getsockname(ls[i].fd, ls[i].sockaddr, &ls[i].socklen) == -1) {
100             ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
101                           "getsockname() of the inherited "
102                           "socket #%d failed", ls[i].fd);
103             ls[i].ignore = 1;
104             continue;
105         }
106 
107         switch (ls[i].sockaddr->sa_family) {
108 
109 #if (NGX_HAVE_INET6)
110         case AF_INET6:
111              ls[i].addr_text_max_len = NGX_INET6_ADDRSTRLEN;
112              break;
113 #endif
114 
115         case AF_INET:
116              ls[i].addr_text_max_len = NGX_INET_ADDRSTRLEN;
117              break;
118 
119         default:
120             ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
121                           "the inherited socket #%d has "
122                           "an unsupported protocol family", ls[i].fd);
123             ls[i].ignore = 1;
124             continue;
125         }
126 
127         len = ls[i].addr_text_max_len + sizeof(":65535") - 1;
128 
129         ls[i].addr_text.data = ngx_pnalloc(cycle->pool, len);
130         if (ls[i].addr_text.data == NULL) {
131             return NGX_ERROR;
132         }
133 
134         len = ngx_sock_ntop(ls[i].sockaddr, ls[i].addr_text.data, len, 1);
135         if (len == 0) {
136             return NGX_ERROR;
137         }
138 
139         ls[i].addr_text.len = len;
140 
141         ls[i].backlog = NGX_LISTEN_BACKLOG;
142 
143         olen = sizeof(int);
144 
145         if (getsockopt(ls[i].fd, SOL_SOCKET, SO_RCVBUF, (void *) &ls[i].rcvbuf,
146                        &olen)
147             == -1)
148         {
149             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
150                           "getsockopt(SO_RCVBUF) %V failed, ignored",
151                           &ls[i].addr_text);
152 
153             ls[i].rcvbuf = -1;
154         }
155 
156         olen = sizeof(int);
157 
158         if (getsockopt(ls[i].fd, SOL_SOCKET, SO_SNDBUF, (void *) &ls[i].sndbuf,
159                        &olen)
160             == -1)
161         {
162             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
163                           "getsockopt(SO_SNDBUF) %V failed, ignored",
164                           &ls[i].addr_text);
165 
166             ls[i].sndbuf = -1;
167         }
168 
169 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
170 
171         ngx_memzero(&af, sizeof(struct accept_filter_arg));
172         olen = sizeof(struct accept_filter_arg);
173 
174         if (getsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER, &af, &olen)
175             == -1)
176         {
177             err = ngx_errno;
178 
179             if (err == NGX_EINVAL) {
180                 continue;
181             }
182 
183             ngx_log_error(NGX_LOG_NOTICE, cycle->log, err,
184                           "getsockopt(SO_ACCEPTFILTER) for %V failed, ignored",
185                           &ls[i].addr_text);
186             continue;
187         }
188 
189         if (olen < sizeof(struct accept_filter_arg) || af.af_name[0] == '\0') {
190             continue;
191         }
192 
193         ls[i].accept_filter = ngx_palloc(cycle->pool, 16);
194         if (ls[i].accept_filter == NULL) {
195             return NGX_ERROR;
196         }
197 
198         (void) ngx_cpystrn((u_char *) ls[i].accept_filter,
199                            (u_char *) af.af_name, 16);
200 #endif
201 
202 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
203 
204         timeout = 0;
205         olen = sizeof(int);
206 
207         if (getsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &timeout, &olen)
208             == -1)
209         {
210             ngx_log_error(NGX_LOG_NOTICE, cycle->log, ngx_errno,
211                           "getsockopt(TCP_DEFER_ACCEPT) for %V failed, ignored",
212                           &ls[i].addr_text);
213             continue;
214         }
215 
216         if (olen < sizeof(int) || timeout == 0) {
217             continue;
218         }
219 
220         ls[i].deferred_accept = 1;
221 #endif
222     }
223 
224     return NGX_OK;
225 }
226 
227 
228 ngx_int_t
229 ngx_open_listening_sockets(ngx_cycle_t *cycle)
230 {
231     int               reuseaddr;
232     ngx_uint_t        i, tries, failed;
233     ngx_err_t         err;
234     ngx_log_t        *log;
235     ngx_socket_t      s;
236     ngx_listening_t  *ls;
237 
238     reuseaddr = 1;
239 #if (NGX_SUPPRESS_WARN)
240     failed = 0;
241 #endif
242 
243     log = cycle->log;
244 
245     /* TODO: configurable try number */
246 
247     for (tries = 5; tries; tries--) {
248         failed = 0;
249 
250         /* for each listening socket */
251 
252         ls = cycle->listening.elts;
253         for (i = 0; i < cycle->listening.nelts; i++) {
254 
255             if (ls[i].ignore) {
256                 continue;
257             }
258 
259             if (ls[i].fd != -1) {
260                 continue;
261             }
262 
263             if (ls[i].inherited) {
264 
265                 /* TODO: close on exit */
266                 /* TODO: nonblocking */
267                 /* TODO: deferred accept */
268 
269                 continue;
270             }
271 
272             s = ngx_socket(ls[i].sockaddr->sa_family, ls[i].type, 0);
273 
274             if (s == -1) {
275                 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
276                               ngx_socket_n " %V failed", &ls[i].addr_text);
277                 return NGX_ERROR;
278             }
279 
280             if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
281                            (const void *) &reuseaddr, sizeof(int))
282                 == -1)
283             {
284                 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
285                               "setsockopt(SO_REUSEADDR) %V failed",
286                               &ls[i].addr_text);
287 
288                 if (ngx_close_socket(s) == -1) {
289                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
290                                   ngx_close_socket_n " %V failed",
291                                   &ls[i].addr_text);
292                 }
293 
294                 return NGX_ERROR;
295             }
296 
297 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
298 
299             if (ls[i].sockaddr->sa_family == AF_INET6 && ls[i].ipv6only) {
300                 int  ipv6only;
301 
302                 ipv6only = (ls[i].ipv6only == 1);
303 
304                 if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
305                                (const void *) &ipv6only, sizeof(int))
306                     == -1)
307                 {
308                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
309                                   "setsockopt(IPV6_V6ONLY) %V failed, ignored",
310                                   &ls[i].addr_text);
311                 }
312             }
313 #endif
314             /* TODO: close on exit */
315 
316             if (!(ngx_event_flags & NGX_USE_AIO_EVENT)) {
317                 if (ngx_nonblocking(s) == -1) {
318                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
319                                   ngx_nonblocking_n " %V failed",
320                                   &ls[i].addr_text);
321 
322                     if (ngx_close_socket(s) == -1) {
323                         ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
324                                       ngx_close_socket_n " %V failed",
325                                       &ls[i].addr_text);
326                     }
327 
328                     return NGX_ERROR;
329                 }
330             }
331 
332             ngx_log_debug2(NGX_LOG_DEBUG_CORE, log, 0,
333                            "bind() %V #%d ", &ls[i].addr_text, s);
334 
335             if (bind(s, ls[i].sockaddr, ls[i].socklen) == -1) {
336                 err = ngx_socket_errno;
337 
338                 if (err == NGX_EADDRINUSE && ngx_test_config) {
339                     continue;
340                 }
341 
342                 ngx_log_error(NGX_LOG_EMERG, log, err,
343                               "bind() to %V failed", &ls[i].addr_text);
344 
345                 if (ngx_close_socket(s) == -1) {
346                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
347                                   ngx_close_socket_n " %V failed",
348                                   &ls[i].addr_text);
349                 }
350 
351                 if (err != NGX_EADDRINUSE) {
352                     return NGX_ERROR;
353                 }
354 
355                 failed = 1;
356 
357                 continue;
358             }
359 
360             if (listen(s, ls[i].backlog) == -1) {
361                 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
362                               "listen() to %V, backlog %d failed",
363                               &ls[i].addr_text, ls[i].backlog);
364 
365                 if (ngx_close_socket(s) == -1) {
366                     ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
367                                   ngx_close_socket_n " %V failed",
368                                   &ls[i].addr_text);
369                 }
370 
371                 return NGX_ERROR;
372             }
373 
374             ls[i].listen = 1;
375 
376             ls[i].fd = s;
377         }
378 
379         if (!failed) {
380             break;
381         }
382 
383         /* TODO: delay configurable */
384 
385         ngx_log_error(NGX_LOG_NOTICE, log, 0,
386                       "try again to bind() after 500ms");
387 
388         ngx_msleep(500);
389     }
390 
391     if (failed) {
392         ngx_log_error(NGX_LOG_EMERG, log, 0, "still could not bind()");
393         return NGX_ERROR;
394     }
395 
396     return NGX_OK;
397 }
398 
399 
400 void
401 ngx_configure_listening_sockets(ngx_cycle_t *cycle)
402 {
403     ngx_uint_t                 i;
404     ngx_listening_t           *ls;
405 
406 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
407     struct accept_filter_arg   af;
408 #endif
409 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
410     int                        timeout;
411 #endif
412 
413     ls = cycle->listening.elts;
414     for (i = 0; i < cycle->listening.nelts; i++) {
415 
416         ls[i].log = *ls[i].logp;
417 
418         if (ls[i].rcvbuf != -1) {
419             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_RCVBUF,
420                            (const void *) &ls[i].rcvbuf, sizeof(int))
421                 == -1)
422             {
423                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
424                               "setsockopt(SO_RCVBUF, %d) %V failed, ignored",
425                               ls[i].rcvbuf, &ls[i].addr_text);
426             }
427         }
428 
429         if (ls[i].sndbuf != -1) {
430             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_SNDBUF,
431                            (const void *) &ls[i].sndbuf, sizeof(int))
432                 == -1)
433             {
434                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
435                               "setsockopt(SO_SNDBUF, %d) %V failed, ignored",
436                               ls[i].sndbuf, &ls[i].addr_text);
437             }
438         }
439 
440 #if 0
441         if (1) {
442             int tcp_nodelay = 1;
443 
444             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_NODELAY,
445                        (const void *) &tcp_nodelay, sizeof(int))
446                 == -1)
447             {
448                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
449                               "setsockopt(TCP_NODELAY) %V failed, ignored",
450                               &ls[i].addr_text);
451             }
452         }
453 #endif
454 
455         if (ls[i].listen) {
456 
457             /* change backlog via listen() */
458 
459             if (listen(ls[i].fd, ls[i].backlog) == -1) {
460                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
461                               "listen() to %V, backlog %d failed, ignored",
462                               &ls[i].addr_text, ls[i].backlog);
463             }
464         }
465 
466         /*
467          * setting deferred mode should be last operation on socket,
468          * because code may prematurely continue cycle on failure
469          */
470 
471 #if (NGX_HAVE_DEFERRED_ACCEPT)
472 
473 #ifdef SO_ACCEPTFILTER
474 
475         if (ls[i].delete_deferred) {
476             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER, NULL, 0)
477                 == -1)
478             {
479                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
480                               "setsockopt(SO_ACCEPTFILTER, NULL) "
481                               "for %V failed, ignored",
482                               &ls[i].addr_text);
483 
484                 if (ls[i].accept_filter) {
485                     ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
486                                   "could not change the accept filter "
487                                   "to \"%s\" for %V, ignored",
488                                   ls[i].accept_filter, &ls[i].addr_text);
489                 }
490 
491                 continue;
492             }
493 
494             ls[i].deferred_accept = 0;
495         }
496 
497         if (ls[i].add_deferred) {
498             ngx_memzero(&af, sizeof(struct accept_filter_arg));
499             (void) ngx_cpystrn((u_char *) af.af_name,
500                                (u_char *) ls[i].accept_filter, 16);
501 
502             if (setsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER,
503                            &af, sizeof(struct accept_filter_arg))
504                 == -1)
505             {
506                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
507                               "setsockopt(SO_ACCEPTFILTER, \"%s\") "
508                               " for %V failed, ignored",
509                               ls[i].accept_filter, &ls[i].addr_text);
510                 continue;
511             }
512 
513             ls[i].deferred_accept = 1;
514         }
515 
516 #endif
517 
518 #ifdef TCP_DEFER_ACCEPT
519 
520         if (ls[i].add_deferred || ls[i].delete_deferred) {
521 
522             if (ls[i].add_deferred) {
523                 timeout = (int) (ls[i].post_accept_timeout / 1000);
524 
525             } else {
526                 timeout = 0;
527             }
528 
529             if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT,
530                            &timeout, sizeof(int))
531                 == -1)
532             {
533                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
534                               "setsockopt(TCP_DEFER_ACCEPT, %d) for %V failed, "
535                               "ignored",
536                               timeout, &ls[i].addr_text);
537 
538                 continue;
539             }
540         }
541 
542         if (ls[i].add_deferred) {
543             ls[i].deferred_accept = 1;
544         }
545 
546 #endif
547 
548 #endif /* NGX_HAVE_DEFERRED_ACCEPT */
549     }
550 
551     return;
552 }
553 
554 
555 void
556 ngx_close_listening_sockets(ngx_cycle_t *cycle)
557 {
558     ngx_uint_t         i;
559     ngx_listening_t   *ls;
560     ngx_connection_t  *c;
561 
562     if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
563         return;
564     }
565 
566     ngx_accept_mutex_held = 0;
567     ngx_use_accept_mutex = 0;
568 
569     ls = cycle->listening.elts;
570     for (i = 0; i < cycle->listening.nelts; i++) {
571 
572         c = ls[i].connection;
573 
574         if (c) {
575             if (c->read->active) {
576                 if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
577                     ngx_del_conn(c, NGX_CLOSE_EVENT);
578 
579                 } else if (ngx_event_flags & NGX_USE_EPOLL_EVENT) {
580 
581                     /*
582                      * it seems that Linux-2.6.x OpenVZ sends events
583                      * for closed shared listening sockets unless
584                      * the events was explicity deleted
585                      */
586 
587                     ngx_del_event(c->read, NGX_READ_EVENT, 0);
588 
589                 } else {
590                     ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
591                 }
592             }
593 
594             ngx_free_connection(c);
595 
596             c->fd = (ngx_socket_t) -1;
597         }
598 
599         ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,
600                        "close listening %V #%d ", &ls[i].addr_text, ls[i].fd);
601 
602         if (ngx_close_socket(ls[i].fd) == -1) {
603             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
604                           ngx_close_socket_n " %V failed", &ls[i].addr_text);
605         }
606 
607         ls[i].fd = (ngx_socket_t) -1;
608     }
609 }
610 
611 
612 ngx_connection_t *
613 ngx_get_connection(ngx_socket_t s, ngx_log_t *log)
614 {
615     ngx_uint_t         instance;
616     ngx_event_t       *rev, *wev;
617     ngx_connection_t  *c;
618 
619     /* disable warning: Win32 SOCKET is u_int while UNIX socket is int */
620 
621     if (ngx_cycle->files && (ngx_uint_t) s >= ngx_cycle->files_n) {
622         ngx_log_error(NGX_LOG_ALERT, log, 0,
623                       "the new socket has number %d, "
624                       "but only %ui files are available",
625                       s, ngx_cycle->files_n);
626         return NULL;
627     }
628 
629     /* ngx_mutex_lock */
630 
631     c = ngx_cycle->free_connections;
632 
633     if (c == NULL) {
634         ngx_log_error(NGX_LOG_ALERT, log, 0,
635                       "%ui worker_connections are not enough",
636                       ngx_cycle->connection_n);
637 
638         /* ngx_mutex_unlock */
639 
640         return NULL;
641     }
642 
643     ngx_cycle->free_connections = c->data;
644     ngx_cycle->free_connection_n--;
645 
646     /* ngx_mutex_unlock */
647 
648     if (ngx_cycle->files) {
649         ngx_cycle->files[s] = c;
650     }
651 
652     rev = c->read;
653     wev = c->write;
654 
655     ngx_memzero(c, sizeof(ngx_connection_t));
656 
657     c->read = rev;
658     c->write = wev;
659     c->fd = s;
660     c->log = log;
661 
662     instance = rev->instance;
663 
664     ngx_memzero(rev, sizeof(ngx_event_t));
665     ngx_memzero(wev, sizeof(ngx_event_t));
666 
667     rev->instance = !instance;
668     wev->instance = !instance;
669 
670     rev->index = NGX_INVALID_INDEX;
671     wev->index = NGX_INVALID_INDEX;
672 
673     rev->data = c;
674     wev->data = c;
675 
676     wev->write = 1;
677 
678     return c;
679 }
680 
681 
682 void
683 ngx_free_connection(ngx_connection_t *c)
684 {
685     /* ngx_mutex_lock */
686 
687     c->data = ngx_cycle->free_connections;
688     ngx_cycle->free_connections = c;
689     ngx_cycle->free_connection_n++;
690 
691     /* ngx_mutex_unlock */
692 
693     if (ngx_cycle->files) {
694         ngx_cycle->files[c->fd] = NULL;
695     }
696 }
697 
698 
699 void
700 ngx_close_connection(ngx_connection_t *c)
701 {
702     ngx_err_t     err;
703     ngx_uint_t    log_error, level;
704     ngx_socket_t  fd;
705 
706     if (c->fd == -1) {
707         ngx_log_error(NGX_LOG_ALERT, c->log, 0, "connection already closed");
708         return;
709     }
710 
711     if (c->read->timer_set) {
712         ngx_del_timer(c->read);
713     }
714 
715     if (c->write->timer_set) {
716         ngx_del_timer(c->write);
717     }
718 
719     if (ngx_del_conn) {
720         ngx_del_conn(c, NGX_CLOSE_EVENT);
721 
722     } else {
723         if (c->read->active || c->read->disabled) {
724             ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
725         }
726 
727         if (c->write->active || c->write->disabled) {
728             ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT);
729         }
730     }
731 
732 #if (NGX_THREADS)
733 
734     /*
735      * we have to clean the connection information before the closing
736      * because another thread may reopen the same file descriptor
737      * before we clean the connection
738      */
739 
740     ngx_mutex_lock(ngx_posted_events_mutex);
741 
742     if (c->read->prev) {
743         ngx_delete_posted_event(c->read);
744     }
745 
746     if (c->write->prev) {
747         ngx_delete_posted_event(c->write);
748     }
749 
750     c->read->closed = 1;
751     c->write->closed = 1;
752 
753     if (c->single_connection) {
754         ngx_unlock(&c->lock);
755         c->read->locked = 0;
756         c->write->locked = 0;
757     }
758 
759     ngx_mutex_unlock(ngx_posted_events_mutex);
760 
761 #else
762 
763     if (c->read->prev) {
764         ngx_delete_posted_event(c->read);
765     }
766 
767     if (c->write->prev) {
768         ngx_delete_posted_event(c->write);
769     }
770 
771     c->read->closed = 1;
772     c->write->closed = 1;
773 
774 #endif
775 
776     log_error = c->log_error;
777 
778     ngx_free_connection(c);
779 
780     fd = c->fd;
781     c->fd = (ngx_socket_t) -1;
782 
783     if (ngx_close_socket(fd) == -1) {
784 
785         err = ngx_socket_errno;
786 
787         if (err == NGX_ECONNRESET || err == NGX_ENOTCONN) {
788 
789             switch (log_error) {
790 
791             case NGX_ERROR_INFO:
792                 level = NGX_LOG_INFO;
793                 break;
794 
795             case NGX_ERROR_ERR:
796                 level = NGX_LOG_ERR;
797                 break;
798 
799             default:
800                 level = NGX_LOG_CRIT;
801             }
802 
803         } else {
804             level = NGX_LOG_CRIT;
805         }
806 
807         /* we use ngx_cycle->log because c->log was in c->pool */
808 
809         ngx_log_error(level, ngx_cycle->log, err,
810                       ngx_close_socket_n " %d failed", fd);
811     }
812 }
813 
814 
815 ngx_int_t
816 ngx_connection_local_sockaddr(ngx_connection_t *c, ngx_str_t *s,
817     ngx_uint_t port)
818 {
819     socklen_t             len;
820     ngx_uint_t            addr;
821     u_char                sa[NGX_SOCKADDRLEN];
822     struct sockaddr_in   *sin;
823 #if (NGX_HAVE_INET6)
824     ngx_uint_t            i;
825     struct sockaddr_in6  *sin6;
826 #endif
827 
828     switch (c->local_sockaddr->sa_family) {
829 
830 #if (NGX_HAVE_INET6)
831     case AF_INET6:
832         sin6 = (struct sockaddr_in6 *) c->local_sockaddr;
833 
834         for (addr = 0, i = 0; addr == 0 && i < 16; i++) {
835             addr |= sin6->sin6_addr.s6_addr[i];
836         }
837 
838         break;
839 #endif
840 
841     default: /* AF_INET */
842         sin = (struct sockaddr_in *) c->local_sockaddr;
843         addr = sin->sin_addr.s_addr;
844         break;
845     }
846 
847     if (addr == 0) {
848 
849         len = NGX_SOCKADDRLEN;
850 
851         if (getsockname(c->fd, (struct sockaddr *) &sa, &len) == -1) {
852             ngx_connection_error(c, ngx_socket_errno, "getsockname() failed");
853             return NGX_ERROR;
854         }
855 
856         c->local_sockaddr = ngx_palloc(c->pool, len);
857         if (c->local_sockaddr == NULL) {
858             return NGX_ERROR;
859         }
860 
861         c->local_socklen = len;
862         ngx_memcpy(c->local_sockaddr, &sa, len);
863     }
864 
865     if (s == NULL) {
866         return NGX_OK;
867     }
868 
869     s->len = ngx_sock_ntop(c->local_sockaddr, s->data, s->len, port);
870 
871     return NGX_OK;
872 }
873 
874 
875 ngx_int_t
876 ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text)
877 {
878     ngx_uint_t  level;
879 
880     /* Winsock may return NGX_ECONNABORTED instead of NGX_ECONNRESET */
881 
882     if ((err == NGX_ECONNRESET
883 #if (NGX_WIN32)
884          || err == NGX_ECONNABORTED
885 #endif
886         ) && c->log_error == NGX_ERROR_IGNORE_ECONNRESET)
887     {
888         return 0;
889     }
890 
891 #if (NGX_SOLARIS)
892     if (err == NGX_EINVAL && c->log_error == NGX_ERROR_IGNORE_EINVAL) {
893         return 0;
894     }
895 #endif
896 
897     if (err == 0
898         || err == NGX_ECONNRESET
899 #if (NGX_WIN32)
900         || err == NGX_ECONNABORTED
901 #else
902         || err == NGX_EPIPE
903 #endif
904         || err == NGX_ENOTCONN
905         || err == NGX_ETIMEDOUT
906         || err == NGX_ECONNREFUSED
907         || err == NGX_ENETDOWN
908         || err == NGX_ENETUNREACH
909         || err == NGX_EHOSTDOWN
910         || err == NGX_EHOSTUNREACH)
911     {
912         switch (c->log_error) {
913 
914         case NGX_ERROR_IGNORE_EINVAL:
915         case NGX_ERROR_IGNORE_ECONNRESET:
916         case NGX_ERROR_INFO:
917             level = NGX_LOG_INFO;
918             break;
919 
920         default:
921             level = NGX_LOG_ERR;
922         }
923 
924     } else {
925         level = NGX_LOG_ALERT;
926     }
927 
928     ngx_log_error(level, c->log, err, text);
929 
930     return NGX_ERROR;
931 }
932 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.