Annotation of embedaddon/nginx/src/core/ngx_connection.c, revision 1.1.1.1
1.1 misho 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: ngx_os_io_t ngx_io;
14:
15:
16: static void ngx_drain_connections(void);
17:
18:
19: ngx_listening_t *
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:
50: ls->addr_text_max_len = NGX_INET6_ADDRSTRLEN;
51: break;
52: #endif
53: #if (NGX_HAVE_UNIX_DOMAIN)
54: case AF_UNIX:
55: ls->addr_text_max_len = NGX_UNIX_ADDRSTRLEN;
56: len++;
57: break;
58: #endif
59: case AF_INET:
60: ls->addr_text_max_len = NGX_INET_ADDRSTRLEN;
61: break;
62: default:
63: ls->addr_text_max_len = NGX_SOCKADDR_STRLEN;
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:
77: ls->backlog = NGX_LISTEN_BACKLOG;
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:
89: ngx_int_t
90: ngx_set_inherited_sockets(ngx_cycle_t *cycle)
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) {
114: ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
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:
125: ls[i].addr_text_max_len = NGX_INET6_ADDRSTRLEN;
126: len = NGX_INET6_ADDRSTRLEN + sizeof(":65535") - 1;
127: break;
128: #endif
129:
130: #if (NGX_HAVE_UNIX_DOMAIN)
131: case AF_UNIX:
132: ls[i].addr_text_max_len = NGX_UNIX_ADDRSTRLEN;
133: len = NGX_UNIX_ADDRSTRLEN;
134: break;
135: #endif
136:
137: case AF_INET:
138: ls[i].addr_text_max_len = NGX_INET_ADDRSTRLEN;
139: len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
140: break;
141:
142: default:
143: ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
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:
162: ls[i].backlog = NGX_LISTEN_BACKLOG;
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: {
170: ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
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: {
183: ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
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: {
199: ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
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: {
250: ngx_log_error(NGX_LOG_NOTICE, cycle->log, ngx_errno,
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
269: ngx_open_listening_sockets(ngx_cycle_t *cycle)
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) {
315: ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
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: {
324: ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
325: "setsockopt(SO_REUSEADDR) %V failed",
326: &ls[i].addr_text);
327:
328: if (ngx_close_socket(s) == -1) {
329: ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
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: {
348: ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
349: "setsockopt(IPV6_V6ONLY) %V failed, ignored",
350: &ls[i].addr_text);
351: }
352: }
353: #endif
354: /* TODO: close on exit */
355:
356: if (!(ngx_event_flags & NGX_USE_AIO_EVENT)) {
357: if (ngx_nonblocking(s) == -1) {
358: ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
359: ngx_nonblocking_n " %V failed",
360: &ls[i].addr_text);
361:
362: if (ngx_close_socket(s) == -1) {
363: ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
364: ngx_close_socket_n " %V failed",
365: &ls[i].addr_text);
366: }
367:
368: return NGX_ERROR;
369: }
370: }
371:
372: ngx_log_debug2(NGX_LOG_DEBUG_CORE, log, 0,
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) {
386: ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
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) {
410: ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
411: "chmod() \"%s\" failed", name);
412: }
413:
414: if (ngx_test_config) {
415: if (ngx_delete_file(name) == NGX_FILE_ERROR) {
416: ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
417: ngx_delete_file_n " %s failed", name);
418: }
419: }
420: }
421: #endif
422:
423: if (listen(s, ls[i].backlog) == -1) {
424: ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
425: "listen() to %V, backlog %d failed",
426: &ls[i].addr_text, ls[i].backlog);
427:
428: if (ngx_close_socket(s) == -1) {
429: ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
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:
448: ngx_log_error(NGX_LOG_NOTICE, log, 0,
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
464: ngx_configure_listening_sockets(ngx_cycle_t *cycle)
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: {
487: ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
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: {
498: ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
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: {
511: ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
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: {
524: ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
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: {
535: ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
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: {
546: ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
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: {
560: ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
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: {
575: ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
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) {
587: ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
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: {
606: ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
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: {
633: ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
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: {
660: ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
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
683: ngx_close_listening_sockets(ngx_cycle_t *cycle)
684: {
685: ngx_uint_t i;
686: ngx_listening_t *ls;
687: ngx_connection_t *c;
688:
689: if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
690: return;
691: }
692:
693: ngx_accept_mutex_held = 0;
694: ngx_use_accept_mutex = 0;
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) {
703: if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
704: ngx_del_conn(c, NGX_CLOSE_EVENT);
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:
714: ngx_del_event(c->read, NGX_READ_EVENT, 0);
715:
716: } else {
717: ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
718: }
719: }
720:
721: ngx_free_connection(c);
722:
723: c->fd = (ngx_socket_t) -1;
724: }
725:
726: ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,
727: "close listening %V #%d ", &ls[i].addr_text, ls[i].fd);
728:
729: if (ngx_close_socket(ls[i].fd) == -1) {
730: ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
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
737: && ngx_process <= NGX_PROCESS_MASTER
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) {
743: ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
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:
757: ngx_connection_t *
758: ngx_get_connection(ngx_socket_t s, ngx_log_t *log)
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) {
767: ngx_log_error(NGX_LOG_ALERT, log, 0,
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:
776: c = ngx_cycle->free_connections;
777:
778: if (c == NULL) {
779: ngx_drain_connections();
780: c = ngx_cycle->free_connections;
781: }
782:
783: if (c == NULL) {
784: ngx_log_error(NGX_LOG_ALERT, log, 0,
785: "%ui worker_connections are not enough",
786: ngx_cycle->connection_n);
787:
788: /* ngx_mutex_unlock */
789:
790: return NULL;
791: }
792:
793: ngx_cycle->free_connections = c->data;
794: ngx_cycle->free_connection_n--;
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
833: ngx_free_connection(ngx_connection_t *c)
834: {
835: /* ngx_mutex_lock */
836:
837: c->data = ngx_cycle->free_connections;
838: ngx_cycle->free_connections = c;
839: ngx_cycle->free_connection_n++;
840:
841: /* ngx_mutex_unlock */
842:
843: if (ngx_cycle->files) {
844: ngx_cycle->files[c->fd] = NULL;
845: }
846: }
847:
848:
849: void
850: ngx_close_connection(ngx_connection_t *c)
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) {
870: ngx_del_conn(c, NGX_CLOSE_EVENT);
871:
872: } else {
873: if (c->read->active || c->read->disabled) {
874: ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
875: }
876:
877: if (c->write->active || c->write->disabled) {
878: ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT);
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) {
893: ngx_delete_posted_event(c->read);
894: }
895:
896: if (c->write->prev) {
897: ngx_delete_posted_event(c->write);
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) {
912: ngx_delete_posted_event(c->read);
913: }
914:
915: if (c->write->prev) {
916: ngx_delete_posted_event(c->write);
917: }
918:
919: c->read->closed = 1;
920: c->write->closed = 1;
921:
922: #endif
923:
924: ngx_reusable_connection(c, 0);
925:
926: log_error = c->log_error;
927:
928: ngx_free_connection(c);
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
966: ngx_reusable_connection(ngx_connection_t *c, ngx_uint_t reusable)
967: {
968: ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
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:
984: ngx_queue_insert_head(
985: (ngx_queue_t *) &ngx_cycle->reusable_connections_queue, &c->queue);
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++) {
1002: if (ngx_queue_empty(&ngx_cycle->reusable_connections_queue)) {
1003: break;
1004: }
1005:
1006: q = ngx_queue_last(&ngx_cycle->reusable_connections_queue);
1007: c = ngx_queue_data(q, ngx_connection_t, queue);
1008:
1009: ngx_log_debug0(NGX_LOG_DEBUG_CORE, c->log, 0,
1010: "reusing connection");
1011:
1012: c->close = 1;
1013: c->read->handler(c->read);
1014: }
1015: }
1016:
1017:
1018: ngx_int_t
1019: ngx_connection_local_sockaddr(ngx_connection_t *c, ngx_str_t *s,
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
1078: ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text)
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
1088: ) && c->log_error == NGX_ERROR_IGNORE_ECONNRESET)
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:
1116: case NGX_ERROR_IGNORE_EINVAL:
1117: case NGX_ERROR_IGNORE_ECONNRESET:
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: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>