Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ngx_connection.c
Go to the documentation of this file.
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 
14 
15 
16 static void ngx_drain_connections(void);
17 
18 
20 ngx_create_listening(ngx_conf_t *cf, void *sockaddr, socklen_t socklen)
21 {
22  size_t len;
23  ngx_listening_t *ls;
24  struct sockaddr *sa;
25  u_char text[NGX_SOCKADDR_STRLEN];
26 
27  ls = ngx_array_push(&cf->cycle->listening);
28  if (ls == NULL) {
29  return NULL;
30  }
31 
32  ngx_memzero(ls, sizeof(ngx_listening_t));
33 
34  sa = ngx_palloc(cf->pool, socklen);
35  if (sa == NULL) {
36  return NULL;
37  }
38 
39  ngx_memcpy(sa, sockaddr, socklen);
40 
41  ls->sockaddr = sa;
42  ls->socklen = socklen;
43 
44  len = ngx_sock_ntop(sa, text, NGX_SOCKADDR_STRLEN, 1);
45  ls->addr_text.len = len;
46 
47  switch (ls->sockaddr->sa_family) {
48 #if (NGX_HAVE_INET6)
49  case AF_INET6:
51  break;
52 #endif
53 #if (NGX_HAVE_UNIX_DOMAIN)
54  case AF_UNIX:
56  len++;
57  break;
58 #endif
59  case AF_INET:
61  break;
62  default:
64  break;
65  }
66 
67  ls->addr_text.data = ngx_pnalloc(cf->pool, len);
68  if (ls->addr_text.data == NULL) {
69  return NULL;
70  }
71 
72  ngx_memcpy(ls->addr_text.data, text, len);
73 
74  ls->fd = (ngx_socket_t) -1;
75  ls->type = SOCK_STREAM;
76 
78  ls->rcvbuf = -1;
79  ls->sndbuf = -1;
80 
81 #if (NGX_HAVE_SETFIB)
82  ls->setfib = -1;
83 #endif
84 
85  return ls;
86 }
87 
88 
91 {
92  size_t len;
93  ngx_uint_t i;
94  ngx_listening_t *ls;
95  socklen_t olen;
96 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
97  ngx_err_t err;
98  struct accept_filter_arg af;
99 #endif
100 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
101  int timeout;
102 #endif
103 
104  ls = cycle->listening.elts;
105  for (i = 0; i < cycle->listening.nelts; i++) {
106 
107  ls[i].sockaddr = ngx_palloc(cycle->pool, NGX_SOCKADDRLEN);
108  if (ls[i].sockaddr == NULL) {
109  return NGX_ERROR;
110  }
111 
112  ls[i].socklen = NGX_SOCKADDRLEN;
113  if (getsockname(ls[i].fd, ls[i].sockaddr, &ls[i].socklen) == -1) {
115  "getsockname() of the inherited "
116  "socket #%d failed", ls[i].fd);
117  ls[i].ignore = 1;
118  continue;
119  }
120 
121  switch (ls[i].sockaddr->sa_family) {
122 
123 #if (NGX_HAVE_INET6)
124  case AF_INET6:
126  len = NGX_INET6_ADDRSTRLEN + sizeof(":65535") - 1;
127  break;
128 #endif
129 
130 #if (NGX_HAVE_UNIX_DOMAIN)
131  case AF_UNIX:
133  len = NGX_UNIX_ADDRSTRLEN;
134  break;
135 #endif
136 
137  case AF_INET:
139  len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
140  break;
141 
142  default:
144  "the inherited socket #%d has "
145  "an unsupported protocol family", ls[i].fd);
146  ls[i].ignore = 1;
147  continue;
148  }
149 
150  ls[i].addr_text.data = ngx_pnalloc(cycle->pool, len);
151  if (ls[i].addr_text.data == NULL) {
152  return NGX_ERROR;
153  }
154 
155  len = ngx_sock_ntop(ls[i].sockaddr, ls[i].addr_text.data, len, 1);
156  if (len == 0) {
157  return NGX_ERROR;
158  }
159 
160  ls[i].addr_text.len = len;
161 
163 
164  olen = sizeof(int);
165 
166  if (getsockopt(ls[i].fd, SOL_SOCKET, SO_RCVBUF, (void *) &ls[i].rcvbuf,
167  &olen)
168  == -1)
169  {
171  "getsockopt(SO_RCVBUF) %V failed, ignored",
172  &ls[i].addr_text);
173 
174  ls[i].rcvbuf = -1;
175  }
176 
177  olen = sizeof(int);
178 
179  if (getsockopt(ls[i].fd, SOL_SOCKET, SO_SNDBUF, (void *) &ls[i].sndbuf,
180  &olen)
181  == -1)
182  {
184  "getsockopt(SO_SNDBUF) %V failed, ignored",
185  &ls[i].addr_text);
186 
187  ls[i].sndbuf = -1;
188  }
189 
190 #if 0
191  /* SO_SETFIB is currently a set only option */
192 
193 #if (NGX_HAVE_SETFIB)
194 
195  if (getsockopt(ls[i].setfib, SOL_SOCKET, SO_SETFIB,
196  (void *) &ls[i].setfib, &olen)
197  == -1)
198  {
200  "getsockopt(SO_SETFIB) %V failed, ignored",
201  &ls[i].addr_text);
202 
203  ls[i].setfib = -1;
204  }
205 
206 #endif
207 #endif
208 
209 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
210 
211  ngx_memzero(&af, sizeof(struct accept_filter_arg));
212  olen = sizeof(struct accept_filter_arg);
213 
214  if (getsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER, &af, &olen)
215  == -1)
216  {
217  err = ngx_errno;
218 
219  if (err == NGX_EINVAL) {
220  continue;
221  }
222 
223  ngx_log_error(NGX_LOG_NOTICE, cycle->log, err,
224  "getsockopt(SO_ACCEPTFILTER) for %V failed, ignored",
225  &ls[i].addr_text);
226  continue;
227  }
228 
229  if (olen < sizeof(struct accept_filter_arg) || af.af_name[0] == '\0') {
230  continue;
231  }
232 
233  ls[i].accept_filter = ngx_palloc(cycle->pool, 16);
234  if (ls[i].accept_filter == NULL) {
235  return NGX_ERROR;
236  }
237 
238  (void) ngx_cpystrn((u_char *) ls[i].accept_filter,
239  (u_char *) af.af_name, 16);
240 #endif
241 
242 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
243 
244  timeout = 0;
245  olen = sizeof(int);
246 
247  if (getsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &timeout, &olen)
248  == -1)
249  {
251  "getsockopt(TCP_DEFER_ACCEPT) for %V failed, ignored",
252  &ls[i].addr_text);
253  continue;
254  }
255 
256  if (olen < sizeof(int) || timeout == 0) {
257  continue;
258  }
259 
260  ls[i].deferred_accept = 1;
261 #endif
262  }
263 
264  return NGX_OK;
265 }
266 
267 
268 ngx_int_t
270 {
271  int reuseaddr;
272  ngx_uint_t i, tries, failed;
273  ngx_err_t err;
274  ngx_log_t *log;
275  ngx_socket_t s;
276  ngx_listening_t *ls;
277 
278  reuseaddr = 1;
279 #if (NGX_SUPPRESS_WARN)
280  failed = 0;
281 #endif
282 
283  log = cycle->log;
284 
285  /* TODO: configurable try number */
286 
287  for (tries = 5; tries; tries--) {
288  failed = 0;
289 
290  /* for each listening socket */
291 
292  ls = cycle->listening.elts;
293  for (i = 0; i < cycle->listening.nelts; i++) {
294 
295  if (ls[i].ignore) {
296  continue;
297  }
298 
299  if (ls[i].fd != -1) {
300  continue;
301  }
302 
303  if (ls[i].inherited) {
304 
305  /* TODO: close on exit */
306  /* TODO: nonblocking */
307  /* TODO: deferred accept */
308 
309  continue;
310  }
311 
312  s = ngx_socket(ls[i].sockaddr->sa_family, ls[i].type, 0);
313 
314  if (s == -1) {
316  ngx_socket_n " %V failed", &ls[i].addr_text);
317  return NGX_ERROR;
318  }
319 
320  if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
321  (const void *) &reuseaddr, sizeof(int))
322  == -1)
323  {
325  "setsockopt(SO_REUSEADDR) %V failed",
326  &ls[i].addr_text);
327 
328  if (ngx_close_socket(s) == -1) {
330  ngx_close_socket_n " %V failed",
331  &ls[i].addr_text);
332  }
333 
334  return NGX_ERROR;
335  }
336 
337 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
338 
339  if (ls[i].sockaddr->sa_family == AF_INET6) {
340  int ipv6only;
341 
342  ipv6only = ls[i].ipv6only;
343 
344  if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
345  (const void *) &ipv6only, sizeof(int))
346  == -1)
347  {
349  "setsockopt(IPV6_V6ONLY) %V failed, ignored",
350  &ls[i].addr_text);
351  }
352  }
353 #endif
354  /* TODO: close on exit */
355 
357  if (ngx_nonblocking(s) == -1) {
359  ngx_nonblocking_n " %V failed",
360  &ls[i].addr_text);
361 
362  if (ngx_close_socket(s) == -1) {
364  ngx_close_socket_n " %V failed",
365  &ls[i].addr_text);
366  }
367 
368  return NGX_ERROR;
369  }
370  }
371 
373  "bind() %V #%d ", &ls[i].addr_text, s);
374 
375  if (bind(s, ls[i].sockaddr, ls[i].socklen) == -1) {
376  err = ngx_socket_errno;
377 
378  if (err == NGX_EADDRINUSE && ngx_test_config) {
379  continue;
380  }
381 
382  ngx_log_error(NGX_LOG_EMERG, log, err,
383  "bind() to %V failed", &ls[i].addr_text);
384 
385  if (ngx_close_socket(s) == -1) {
387  ngx_close_socket_n " %V failed",
388  &ls[i].addr_text);
389  }
390 
391  if (err != NGX_EADDRINUSE) {
392  return NGX_ERROR;
393  }
394 
395  failed = 1;
396 
397  continue;
398  }
399 
400 #if (NGX_HAVE_UNIX_DOMAIN)
401 
402  if (ls[i].sockaddr->sa_family == AF_UNIX) {
403  mode_t mode;
404  u_char *name;
405 
406  name = ls[i].addr_text.data + sizeof("unix:") - 1;
407  mode = (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
408 
409  if (chmod((char *) name, mode) == -1) {
411  "chmod() \"%s\" failed", name);
412  }
413 
414  if (ngx_test_config) {
415  if (ngx_delete_file(name) == NGX_FILE_ERROR) {
417  ngx_delete_file_n " %s failed", name);
418  }
419  }
420  }
421 #endif
422 
423  if (listen(s, ls[i].backlog) == -1) {
425  "listen() to %V, backlog %d failed",
426  &ls[i].addr_text, ls[i].backlog);
427 
428  if (ngx_close_socket(s) == -1) {
430  ngx_close_socket_n " %V failed",
431  &ls[i].addr_text);
432  }
433 
434  return NGX_ERROR;
435  }
436 
437  ls[i].listen = 1;
438 
439  ls[i].fd = s;
440  }
441 
442  if (!failed) {
443  break;
444  }
445 
446  /* TODO: delay configurable */
447 
449  "try again to bind() after 500ms");
450 
451  ngx_msleep(500);
452  }
453 
454  if (failed) {
455  ngx_log_error(NGX_LOG_EMERG, log, 0, "still could not bind()");
456  return NGX_ERROR;
457  }
458 
459  return NGX_OK;
460 }
461 
462 
463 void
465 {
466  int keepalive;
467  ngx_uint_t i;
468  ngx_listening_t *ls;
469 
470 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
471  struct accept_filter_arg af;
472 #endif
473 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
474  int timeout;
475 #endif
476 
477  ls = cycle->listening.elts;
478  for (i = 0; i < cycle->listening.nelts; i++) {
479 
480  ls[i].log = *ls[i].logp;
481 
482  if (ls[i].rcvbuf != -1) {
483  if (setsockopt(ls[i].fd, SOL_SOCKET, SO_RCVBUF,
484  (const void *) &ls[i].rcvbuf, sizeof(int))
485  == -1)
486  {
488  "setsockopt(SO_RCVBUF, %d) %V failed, ignored",
489  ls[i].rcvbuf, &ls[i].addr_text);
490  }
491  }
492 
493  if (ls[i].sndbuf != -1) {
494  if (setsockopt(ls[i].fd, SOL_SOCKET, SO_SNDBUF,
495  (const void *) &ls[i].sndbuf, sizeof(int))
496  == -1)
497  {
499  "setsockopt(SO_SNDBUF, %d) %V failed, ignored",
500  ls[i].sndbuf, &ls[i].addr_text);
501  }
502  }
503 
504  if (ls[i].keepalive) {
505  keepalive = (ls[i].keepalive == 1) ? 1 : 0;
506 
507  if (setsockopt(ls[i].fd, SOL_SOCKET, SO_KEEPALIVE,
508  (const void *) &keepalive, sizeof(int))
509  == -1)
510  {
512  "setsockopt(SO_KEEPALIVE, %d) %V failed, ignored",
513  keepalive, &ls[i].addr_text);
514  }
515  }
516 
517 #if (NGX_HAVE_KEEPALIVE_TUNABLE)
518 
519  if (ls[i].keepidle) {
520  if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_KEEPIDLE,
521  (const void *) &ls[i].keepidle, sizeof(int))
522  == -1)
523  {
525  "setsockopt(TCP_KEEPIDLE, %d) %V failed, ignored",
526  ls[i].keepidle, &ls[i].addr_text);
527  }
528  }
529 
530  if (ls[i].keepintvl) {
531  if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_KEEPINTVL,
532  (const void *) &ls[i].keepintvl, sizeof(int))
533  == -1)
534  {
536  "setsockopt(TCP_KEEPINTVL, %d) %V failed, ignored",
537  ls[i].keepintvl, &ls[i].addr_text);
538  }
539  }
540 
541  if (ls[i].keepcnt) {
542  if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_KEEPCNT,
543  (const void *) &ls[i].keepcnt, sizeof(int))
544  == -1)
545  {
547  "setsockopt(TCP_KEEPCNT, %d) %V failed, ignored",
548  ls[i].keepcnt, &ls[i].addr_text);
549  }
550  }
551 
552 #endif
553 
554 #if (NGX_HAVE_SETFIB)
555  if (ls[i].setfib != -1) {
556  if (setsockopt(ls[i].fd, SOL_SOCKET, SO_SETFIB,
557  (const void *) &ls[i].setfib, sizeof(int))
558  == -1)
559  {
561  "setsockopt(SO_SETFIB, %d) %V failed, ignored",
562  ls[i].setfib, &ls[i].addr_text);
563  }
564  }
565 #endif
566 
567 #if 0
568  if (1) {
569  int tcp_nodelay = 1;
570 
571  if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_NODELAY,
572  (const void *) &tcp_nodelay, sizeof(int))
573  == -1)
574  {
576  "setsockopt(TCP_NODELAY) %V failed, ignored",
577  &ls[i].addr_text);
578  }
579  }
580 #endif
581 
582  if (ls[i].listen) {
583 
584  /* change backlog via listen() */
585 
586  if (listen(ls[i].fd, ls[i].backlog) == -1) {
588  "listen() to %V, backlog %d failed, ignored",
589  &ls[i].addr_text, ls[i].backlog);
590  }
591  }
592 
593  /*
594  * setting deferred mode should be last operation on socket,
595  * because code may prematurely continue cycle on failure
596  */
597 
598 #if (NGX_HAVE_DEFERRED_ACCEPT)
599 
600 #ifdef SO_ACCEPTFILTER
601 
602  if (ls[i].delete_deferred) {
603  if (setsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER, NULL, 0)
604  == -1)
605  {
607  "setsockopt(SO_ACCEPTFILTER, NULL) "
608  "for %V failed, ignored",
609  &ls[i].addr_text);
610 
611  if (ls[i].accept_filter) {
612  ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
613  "could not change the accept filter "
614  "to \"%s\" for %V, ignored",
615  ls[i].accept_filter, &ls[i].addr_text);
616  }
617 
618  continue;
619  }
620 
621  ls[i].deferred_accept = 0;
622  }
623 
624  if (ls[i].add_deferred) {
625  ngx_memzero(&af, sizeof(struct accept_filter_arg));
626  (void) ngx_cpystrn((u_char *) af.af_name,
627  (u_char *) ls[i].accept_filter, 16);
628 
629  if (setsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER,
630  &af, sizeof(struct accept_filter_arg))
631  == -1)
632  {
634  "setsockopt(SO_ACCEPTFILTER, \"%s\") "
635  "for %V failed, ignored",
636  ls[i].accept_filter, &ls[i].addr_text);
637  continue;
638  }
639 
640  ls[i].deferred_accept = 1;
641  }
642 
643 #endif
644 
645 #ifdef TCP_DEFER_ACCEPT
646 
647  if (ls[i].add_deferred || ls[i].delete_deferred) {
648 
649  if (ls[i].add_deferred) {
650  timeout = (int) (ls[i].post_accept_timeout / 1000);
651 
652  } else {
653  timeout = 0;
654  }
655 
656  if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT,
657  &timeout, sizeof(int))
658  == -1)
659  {
661  "setsockopt(TCP_DEFER_ACCEPT, %d) for %V failed, "
662  "ignored",
663  timeout, &ls[i].addr_text);
664 
665  continue;
666  }
667  }
668 
669  if (ls[i].add_deferred) {
670  ls[i].deferred_accept = 1;
671  }
672 
673 #endif
674 
675 #endif /* NGX_HAVE_DEFERRED_ACCEPT */
676  }
677 
678  return;
679 }
680 
681 
682 void
684 {
685  ngx_uint_t i;
686  ngx_listening_t *ls;
687  ngx_connection_t *c;
688 
690  return;
691  }
692 
695 
696  ls = cycle->listening.elts;
697  for (i = 0; i < cycle->listening.nelts; i++) {
698 
699  c = ls[i].connection;
700 
701  if (c) {
702  if (c->read->active) {
705 
706  } else if (ngx_event_flags & NGX_USE_EPOLL_EVENT) {
707 
708  /*
709  * it seems that Linux-2.6.x OpenVZ sends events
710  * for closed shared listening sockets unless
711  * the events was explicitly deleted
712  */
713 
715 
716  } else {
718  }
719  }
720 
722 
723  c->fd = (ngx_socket_t) -1;
724  }
725 
727  "close listening %V #%d ", &ls[i].addr_text, ls[i].fd);
728 
729  if (ngx_close_socket(ls[i].fd) == -1) {
731  ngx_close_socket_n " %V failed", &ls[i].addr_text);
732  }
733 
734 #if (NGX_HAVE_UNIX_DOMAIN)
735 
736  if (ls[i].sockaddr->sa_family == AF_UNIX
738  && ngx_new_binary == 0)
739  {
740  u_char *name = ls[i].addr_text.data + sizeof("unix:") - 1;
741 
742  if (ngx_delete_file(name) == NGX_FILE_ERROR) {
744  ngx_delete_file_n " %s failed", name);
745  }
746  }
747 
748 #endif
749 
750  ls[i].fd = (ngx_socket_t) -1;
751  }
752 
753  cycle->listening.nelts = 0;
754 }
755 
756 
759 {
760  ngx_uint_t instance;
761  ngx_event_t *rev, *wev;
762  ngx_connection_t *c;
763 
764  /* disable warning: Win32 SOCKET is u_int while UNIX socket is int */
765 
766  if (ngx_cycle->files && (ngx_uint_t) s >= ngx_cycle->files_n) {
768  "the new socket has number %d, "
769  "but only %ui files are available",
770  s, ngx_cycle->files_n);
771  return NULL;
772  }
773 
774  /* ngx_mutex_lock */
775 
777 
778  if (c == NULL) {
779  ngx_drain_connections();
781  }
782 
783  if (c == NULL) {
785  "%ui worker_connections are not enough",
787 
788  /* ngx_mutex_unlock */
789 
790  return NULL;
791  }
792 
795 
796  /* ngx_mutex_unlock */
797 
798  if (ngx_cycle->files) {
799  ngx_cycle->files[s] = c;
800  }
801 
802  rev = c->read;
803  wev = c->write;
804 
805  ngx_memzero(c, sizeof(ngx_connection_t));
806 
807  c->read = rev;
808  c->write = wev;
809  c->fd = s;
810  c->log = log;
811 
812  instance = rev->instance;
813 
814  ngx_memzero(rev, sizeof(ngx_event_t));
815  ngx_memzero(wev, sizeof(ngx_event_t));
816 
817  rev->instance = !instance;
818  wev->instance = !instance;
819 
820  rev->index = NGX_INVALID_INDEX;
821  wev->index = NGX_INVALID_INDEX;
822 
823  rev->data = c;
824  wev->data = c;
825 
826  wev->write = 1;
827 
828  return c;
829 }
830 
831 
832 void
834 {
835  /* ngx_mutex_lock */
836 
840 
841  /* ngx_mutex_unlock */
842 
843  if (ngx_cycle->files) {
844  ngx_cycle->files[c->fd] = NULL;
845  }
846 }
847 
848 
849 void
851 {
852  ngx_err_t err;
853  ngx_uint_t log_error, level;
854  ngx_socket_t fd;
855 
856  if (c->fd == -1) {
857  ngx_log_error(NGX_LOG_ALERT, c->log, 0, "connection already closed");
858  return;
859  }
860 
861  if (c->read->timer_set) {
862  ngx_del_timer(c->read);
863  }
864 
865  if (c->write->timer_set) {
866  ngx_del_timer(c->write);
867  }
868 
869  if (ngx_del_conn) {
871 
872  } else {
873  if (c->read->active || c->read->disabled) {
875  }
876 
877  if (c->write->active || c->write->disabled) {
879  }
880  }
881 
882 #if (NGX_THREADS)
883 
884  /*
885  * we have to clean the connection information before the closing
886  * because another thread may reopen the same file descriptor
887  * before we clean the connection
888  */
889 
890  ngx_mutex_lock(ngx_posted_events_mutex);
891 
892  if (c->read->prev) {
894  }
895 
896  if (c->write->prev) {
898  }
899 
900  c->read->closed = 1;
901  c->write->closed = 1;
902 
903  ngx_unlock(&c->lock);
904  c->read->locked = 0;
905  c->write->locked = 0;
906 
907  ngx_mutex_unlock(ngx_posted_events_mutex);
908 
909 #else
910 
911  if (c->read->prev) {
913  }
914 
915  if (c->write->prev) {
917  }
918 
919  c->read->closed = 1;
920  c->write->closed = 1;
921 
922 #endif
923 
925 
926  log_error = c->log_error;
927 
929 
930  fd = c->fd;
931  c->fd = (ngx_socket_t) -1;
932 
933  if (ngx_close_socket(fd) == -1) {
934 
935  err = ngx_socket_errno;
936 
937  if (err == NGX_ECONNRESET || err == NGX_ENOTCONN) {
938 
939  switch (log_error) {
940 
941  case NGX_ERROR_INFO:
942  level = NGX_LOG_INFO;
943  break;
944 
945  case NGX_ERROR_ERR:
946  level = NGX_LOG_ERR;
947  break;
948 
949  default:
950  level = NGX_LOG_CRIT;
951  }
952 
953  } else {
954  level = NGX_LOG_CRIT;
955  }
956 
957  /* we use ngx_cycle->log because c->log was in c->pool */
958 
959  ngx_log_error(level, ngx_cycle->log, err,
960  ngx_close_socket_n " %d failed", fd);
961  }
962 }
963 
964 
965 void
967 {
969  "reusable connection: %ui", reusable);
970 
971  if (c->reusable) {
972  ngx_queue_remove(&c->queue);
973 
974 #if (NGX_STAT_STUB)
975  (void) ngx_atomic_fetch_add(ngx_stat_waiting, -1);
976 #endif
977  }
978 
979  c->reusable = reusable;
980 
981  if (reusable) {
982  /* need cast as ngx_cycle is volatile */
983 
986 
987 #if (NGX_STAT_STUB)
988  (void) ngx_atomic_fetch_add(ngx_stat_waiting, 1);
989 #endif
990  }
991 }
992 
993 
994 static void
995 ngx_drain_connections(void)
996 {
997  ngx_int_t i;
998  ngx_queue_t *q;
999  ngx_connection_t *c;
1000 
1001  for (i = 0; i < 32; i++) {
1003  break;
1004  }
1005 
1007  c = ngx_queue_data(q, ngx_connection_t, queue);
1008 
1010  "reusing connection");
1011 
1012  c->close = 1;
1013  c->read->handler(c->read);
1014  }
1015 }
1016 
1017 
1018 ngx_int_t
1020  ngx_uint_t port)
1021 {
1022  socklen_t len;
1023  ngx_uint_t addr;
1024  u_char sa[NGX_SOCKADDRLEN];
1025  struct sockaddr_in *sin;
1026 #if (NGX_HAVE_INET6)
1027  ngx_uint_t i;
1028  struct sockaddr_in6 *sin6;
1029 #endif
1030 
1031  switch (c->local_sockaddr->sa_family) {
1032 
1033 #if (NGX_HAVE_INET6)
1034  case AF_INET6:
1035  sin6 = (struct sockaddr_in6 *) c->local_sockaddr;
1036 
1037  for (addr = 0, i = 0; addr == 0 && i < 16; i++) {
1038  addr |= sin6->sin6_addr.s6_addr[i];
1039  }
1040 
1041  break;
1042 #endif
1043 
1044  default: /* AF_INET */
1045  sin = (struct sockaddr_in *) c->local_sockaddr;
1046  addr = sin->sin_addr.s_addr;
1047  break;
1048  }
1049 
1050  if (addr == 0) {
1051 
1052  len = NGX_SOCKADDRLEN;
1053 
1054  if (getsockname(c->fd, (struct sockaddr *) &sa, &len) == -1) {
1055  ngx_connection_error(c, ngx_socket_errno, "getsockname() failed");
1056  return NGX_ERROR;
1057  }
1058 
1059  c->local_sockaddr = ngx_palloc(c->pool, len);
1060  if (c->local_sockaddr == NULL) {
1061  return NGX_ERROR;
1062  }
1063 
1064  ngx_memcpy(c->local_sockaddr, &sa, len);
1065  }
1066 
1067  if (s == NULL) {
1068  return NGX_OK;
1069  }
1070 
1071  s->len = ngx_sock_ntop(c->local_sockaddr, s->data, s->len, port);
1072 
1073  return NGX_OK;
1074 }
1075 
1076 
1077 ngx_int_t
1079 {
1080  ngx_uint_t level;
1081 
1082  /* Winsock may return NGX_ECONNABORTED instead of NGX_ECONNRESET */
1083 
1084  if ((err == NGX_ECONNRESET
1085 #if (NGX_WIN32)
1086  || err == NGX_ECONNABORTED
1087 #endif
1089  {
1090  return 0;
1091  }
1092 
1093 #if (NGX_SOLARIS)
1094  if (err == NGX_EINVAL && c->log_error == NGX_ERROR_IGNORE_EINVAL) {
1095  return 0;
1096  }
1097 #endif
1098 
1099  if (err == 0
1100  || err == NGX_ECONNRESET
1101 #if (NGX_WIN32)
1102  || err == NGX_ECONNABORTED
1103 #else
1104  || err == NGX_EPIPE
1105 #endif
1106  || err == NGX_ENOTCONN
1107  || err == NGX_ETIMEDOUT
1108  || err == NGX_ECONNREFUSED
1109  || err == NGX_ENETDOWN
1110  || err == NGX_ENETUNREACH
1111  || err == NGX_EHOSTDOWN
1112  || err == NGX_EHOSTUNREACH)
1113  {
1114  switch (c->log_error) {
1115 
1118  case NGX_ERROR_INFO:
1119  level = NGX_LOG_INFO;
1120  break;
1121 
1122  default:
1123  level = NGX_LOG_ERR;
1124  }
1125 
1126  } else {
1127  level = NGX_LOG_ALERT;
1128  }
1129 
1130  ngx_log_error(level, c->log, err, text);
1131 
1132  return NGX_ERROR;
1133 }