comparison src/core/ngx_connection.c @ 665:0b460e61bdcd default tip

Merge with nginx 1.0.0.
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 25 Apr 2011 04:22:17 +0400
parents b9763778e212
children
comparison
equal deleted inserted replaced
572:06419a2298a9 665:0b460e61bdcd
10 10
11 11
12 ngx_os_io_t ngx_io; 12 ngx_os_io_t ngx_io;
13 13
14 14
15 static void ngx_drain_connections(void);
16
17
15 ngx_listening_t * 18 ngx_listening_t *
16 ngx_create_listening(ngx_conf_t *cf, void *sockaddr, socklen_t socklen) 19 ngx_create_listening(ngx_conf_t *cf, void *sockaddr, socklen_t socklen)
17 { 20 {
21 size_t len;
18 ngx_listening_t *ls; 22 ngx_listening_t *ls;
19 struct sockaddr *sa; 23 struct sockaddr *sa;
20 u_char text[NGX_SOCKADDR_STRLEN]; 24 u_char text[NGX_SOCKADDR_STRLEN];
21 25
22 ls = ngx_array_push(&cf->cycle->listening); 26 ls = ngx_array_push(&cf->cycle->listening);
34 ngx_memcpy(sa, sockaddr, socklen); 38 ngx_memcpy(sa, sockaddr, socklen);
35 39
36 ls->sockaddr = sa; 40 ls->sockaddr = sa;
37 ls->socklen = socklen; 41 ls->socklen = socklen;
38 42
39 ls->addr_text.len = ngx_sock_ntop(sa, text, NGX_SOCKADDR_STRLEN, 1); 43 len = ngx_sock_ntop(sa, text, NGX_SOCKADDR_STRLEN, 1);
40 44 ls->addr_text.len = len;
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 45
51 switch (ls->sockaddr->sa_family) { 46 switch (ls->sockaddr->sa_family) {
52 #if (NGX_HAVE_INET6) 47 #if (NGX_HAVE_INET6)
53 case AF_INET6: 48 case AF_INET6:
54 ls->addr_text_max_len = NGX_INET6_ADDRSTRLEN; 49 ls->addr_text_max_len = NGX_INET6_ADDRSTRLEN;
50 break;
51 #endif
52 #if (NGX_HAVE_UNIX_DOMAIN)
53 case AF_UNIX:
54 ls->addr_text_max_len = NGX_UNIX_ADDRSTRLEN;
55 len++;
55 break; 56 break;
56 #endif 57 #endif
57 case AF_INET: 58 case AF_INET:
58 ls->addr_text_max_len = NGX_INET_ADDRSTRLEN; 59 ls->addr_text_max_len = NGX_INET_ADDRSTRLEN;
59 break; 60 break;
60 default: 61 default:
61 ls->addr_text_max_len = NGX_SOCKADDR_STRLEN; 62 ls->addr_text_max_len = NGX_SOCKADDR_STRLEN;
62 break; 63 break;
63 } 64 }
64 65
66 ls->addr_text.data = ngx_pnalloc(cf->pool, len);
67 if (ls->addr_text.data == NULL) {
68 return NULL;
69 }
70
71 ngx_memcpy(ls->addr_text.data, text, len);
72
73 ls->fd = (ngx_socket_t) -1;
74 ls->type = SOCK_STREAM;
75
65 ls->backlog = NGX_LISTEN_BACKLOG; 76 ls->backlog = NGX_LISTEN_BACKLOG;
66 ls->rcvbuf = -1; 77 ls->rcvbuf = -1;
67 ls->sndbuf = -1; 78 ls->sndbuf = -1;
79
80 #if (NGX_HAVE_SETFIB)
81 ls->setfib = -1;
82 #endif
68 83
69 return ls; 84 return ls;
70 } 85 }
71 86
72 87
86 #endif 101 #endif
87 102
88 ls = cycle->listening.elts; 103 ls = cycle->listening.elts;
89 for (i = 0; i < cycle->listening.nelts; i++) { 104 for (i = 0; i < cycle->listening.nelts; i++) {
90 105
91 /* AF_INET only */ 106 ls[i].sockaddr = ngx_palloc(cycle->pool, NGX_SOCKADDRLEN);
92
93 ls[i].sockaddr = ngx_palloc(cycle->pool, sizeof(struct sockaddr_in));
94 if (ls[i].sockaddr == NULL) { 107 if (ls[i].sockaddr == NULL) {
95 return NGX_ERROR; 108 return NGX_ERROR;
96 } 109 }
97 110
98 ls[i].socklen = sizeof(struct sockaddr_in); 111 ls[i].socklen = NGX_SOCKADDRLEN;
99 if (getsockname(ls[i].fd, ls[i].sockaddr, &ls[i].socklen) == -1) { 112 if (getsockname(ls[i].fd, ls[i].sockaddr, &ls[i].socklen) == -1) {
100 ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno, 113 ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
101 "getsockname() of the inherited " 114 "getsockname() of the inherited "
102 "socket #%d failed", ls[i].fd); 115 "socket #%d failed", ls[i].fd);
103 ls[i].ignore = 1; 116 ls[i].ignore = 1;
107 switch (ls[i].sockaddr->sa_family) { 120 switch (ls[i].sockaddr->sa_family) {
108 121
109 #if (NGX_HAVE_INET6) 122 #if (NGX_HAVE_INET6)
110 case AF_INET6: 123 case AF_INET6:
111 ls[i].addr_text_max_len = NGX_INET6_ADDRSTRLEN; 124 ls[i].addr_text_max_len = NGX_INET6_ADDRSTRLEN;
125 len = NGX_INET6_ADDRSTRLEN + sizeof(":65535") - 1;
126 break;
127 #endif
128
129 #if (NGX_HAVE_UNIX_DOMAIN)
130 case AF_UNIX:
131 ls[i].addr_text_max_len = NGX_UNIX_ADDRSTRLEN;
132 len = NGX_UNIX_ADDRSTRLEN;
112 break; 133 break;
113 #endif 134 #endif
114 135
115 case AF_INET: 136 case AF_INET:
116 ls[i].addr_text_max_len = NGX_INET_ADDRSTRLEN; 137 ls[i].addr_text_max_len = NGX_INET_ADDRSTRLEN;
138 len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
117 break; 139 break;
118 140
119 default: 141 default:
120 ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno, 142 ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
121 "the inherited socket #%d has " 143 "the inherited socket #%d has "
122 "an unsupported protocol family", ls[i].fd); 144 "an unsupported protocol family", ls[i].fd);
123 ls[i].ignore = 1; 145 ls[i].ignore = 1;
124 continue; 146 continue;
125 } 147 }
126
127 len = ls[i].addr_text_max_len + sizeof(":65535") - 1;
128 148
129 ls[i].addr_text.data = ngx_pnalloc(cycle->pool, len); 149 ls[i].addr_text.data = ngx_pnalloc(cycle->pool, len);
130 if (ls[i].addr_text.data == NULL) { 150 if (ls[i].addr_text.data == NULL) {
131 return NGX_ERROR; 151 return NGX_ERROR;
132 } 152 }
163 "getsockopt(SO_SNDBUF) %V failed, ignored", 183 "getsockopt(SO_SNDBUF) %V failed, ignored",
164 &ls[i].addr_text); 184 &ls[i].addr_text);
165 185
166 ls[i].sndbuf = -1; 186 ls[i].sndbuf = -1;
167 } 187 }
188
189 #if 0
190 /* SO_SETFIB is currently a set only option */
191
192 #if (NGX_HAVE_SETFIB)
193
194 if (getsockopt(ls[i].setfib, SOL_SOCKET, SO_SETFIB,
195 (void *) &ls[i].setfib, &olen)
196 == -1)
197 {
198 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
199 "getsockopt(SO_SETFIB) %V failed, ignored",
200 &ls[i].addr_text);
201
202 ls[i].setfib = -1;
203 }
204
205 #endif
206 #endif
168 207
169 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) 208 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
170 209
171 ngx_memzero(&af, sizeof(struct accept_filter_arg)); 210 ngx_memzero(&af, sizeof(struct accept_filter_arg));
172 olen = sizeof(struct accept_filter_arg); 211 olen = sizeof(struct accept_filter_arg);
355 failed = 1; 394 failed = 1;
356 395
357 continue; 396 continue;
358 } 397 }
359 398
399 #if (NGX_HAVE_UNIX_DOMAIN)
400
401 if (ls[i].sockaddr->sa_family == AF_UNIX) {
402 mode_t mode;
403 u_char *name;
404
405 name = ls[i].addr_text.data + sizeof("unix:") - 1;
406 mode = (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
407
408 if (chmod((char *) name, mode) == -1) {
409 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
410 "chmod() \"%s\" failed", name);
411 }
412
413 if (ngx_test_config) {
414 if (ngx_delete_file(name) == -1) {
415 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
416 ngx_delete_file_n " %s failed", name);
417 }
418 }
419 }
420 #endif
421
360 if (listen(s, ls[i].backlog) == -1) { 422 if (listen(s, ls[i].backlog) == -1) {
361 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, 423 ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
362 "listen() to %V, backlog %d failed", 424 "listen() to %V, backlog %d failed",
363 &ls[i].addr_text, ls[i].backlog); 425 &ls[i].addr_text, ls[i].backlog);
364 426
434 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, 496 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
435 "setsockopt(SO_SNDBUF, %d) %V failed, ignored", 497 "setsockopt(SO_SNDBUF, %d) %V failed, ignored",
436 ls[i].sndbuf, &ls[i].addr_text); 498 ls[i].sndbuf, &ls[i].addr_text);
437 } 499 }
438 } 500 }
501
502 #if (NGX_HAVE_SETFIB)
503 if (ls[i].setfib != -1) {
504 if (setsockopt(ls[i].fd, SOL_SOCKET, SO_SETFIB,
505 (const void *) &ls[i].setfib, sizeof(int))
506 == -1)
507 {
508 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
509 "setsockopt(SO_SETFIB, %d) %V failed, ignored",
510 ls[i].setfib, &ls[i].addr_text);
511 }
512 }
513 #endif
439 514
440 #if 0 515 #if 0
441 if (1) { 516 if (1) {
442 int tcp_nodelay = 1; 517 int tcp_nodelay = 1;
443 518
602 if (ngx_close_socket(ls[i].fd) == -1) { 677 if (ngx_close_socket(ls[i].fd) == -1) {
603 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno, 678 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
604 ngx_close_socket_n " %V failed", &ls[i].addr_text); 679 ngx_close_socket_n " %V failed", &ls[i].addr_text);
605 } 680 }
606 681
682 #if (NGX_HAVE_UNIX_DOMAIN)
683
684 if (ls[i].sockaddr->sa_family == AF_UNIX
685 && ngx_process <= NGX_PROCESS_MASTER
686 && ngx_new_binary == 0)
687 {
688 u_char *name = ls[i].addr_text.data + sizeof("unix:") - 1;
689
690 if (ngx_delete_file(name) == -1) {
691 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
692 ngx_delete_file_n " %s failed", name);
693 }
694 }
695
696 #endif
697
607 ls[i].fd = (ngx_socket_t) -1; 698 ls[i].fd = (ngx_socket_t) -1;
608 } 699 }
609 } 700 }
610 701
611 702
629 /* ngx_mutex_lock */ 720 /* ngx_mutex_lock */
630 721
631 c = ngx_cycle->free_connections; 722 c = ngx_cycle->free_connections;
632 723
633 if (c == NULL) { 724 if (c == NULL) {
725 ngx_drain_connections();
726 c = ngx_cycle->free_connections;
727 }
728
729 if (c == NULL) {
634 ngx_log_error(NGX_LOG_ALERT, log, 0, 730 ngx_log_error(NGX_LOG_ALERT, log, 0,
635 "%ui worker_connections are not enough", 731 "%ui worker_connections are not enough",
636 ngx_cycle->connection_n); 732 ngx_cycle->connection_n);
637 733
638 /* ngx_mutex_unlock */ 734 /* ngx_mutex_unlock */
771 c->read->closed = 1; 867 c->read->closed = 1;
772 c->write->closed = 1; 868 c->write->closed = 1;
773 869
774 #endif 870 #endif
775 871
872 ngx_reusable_connection(c, 0);
873
776 log_error = c->log_error; 874 log_error = c->log_error;
777 875
778 ngx_free_connection(c); 876 ngx_free_connection(c);
779 877
780 fd = c->fd; 878 fd = c->fd;
806 904
807 /* we use ngx_cycle->log because c->log was in c->pool */ 905 /* we use ngx_cycle->log because c->log was in c->pool */
808 906
809 ngx_log_error(level, ngx_cycle->log, err, 907 ngx_log_error(level, ngx_cycle->log, err,
810 ngx_close_socket_n " %d failed", fd); 908 ngx_close_socket_n " %d failed", fd);
909 }
910 }
911
912
913 void
914 ngx_reusable_connection(ngx_connection_t *c, ngx_uint_t reusable)
915 {
916 ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
917 "reusable connection: %ui", reusable);
918
919 if (c->reusable) {
920 ngx_queue_remove(&c->queue);
921 }
922
923 c->reusable = reusable;
924
925 if (reusable) {
926 /* need cast as ngx_cycle is volatile */
927
928 ngx_queue_insert_head(
929 (ngx_queue_t *) &ngx_cycle->reusable_connections_queue, &c->queue);
930 }
931 }
932
933
934 static void
935 ngx_drain_connections(void)
936 {
937 ngx_int_t i;
938 ngx_queue_t *q;
939 ngx_connection_t *c;
940
941 for (i = 0; i < 32; i++) {
942 if (ngx_queue_empty(&ngx_cycle->reusable_connections_queue)) {
943 break;
944 }
945
946 q = ngx_queue_last(&ngx_cycle->reusable_connections_queue);
947 c = ngx_queue_data(q, ngx_connection_t, queue);
948
949 ngx_log_debug0(NGX_LOG_DEBUG_CORE, c->log, 0,
950 "reusing connection");
951
952 c->close = 1;
953 c->read->handler(c->read);
811 } 954 }
812 } 955 }
813 956
814 957
815 ngx_int_t 958 ngx_int_t
856 c->local_sockaddr = ngx_palloc(c->pool, len); 999 c->local_sockaddr = ngx_palloc(c->pool, len);
857 if (c->local_sockaddr == NULL) { 1000 if (c->local_sockaddr == NULL) {
858 return NGX_ERROR; 1001 return NGX_ERROR;
859 } 1002 }
860 1003
861 c->local_socklen = len;
862 ngx_memcpy(c->local_sockaddr, &sa, len); 1004 ngx_memcpy(c->local_sockaddr, &sa, len);
863 } 1005 }
864 1006
865 if (s == NULL) { 1007 if (s == NULL) {
866 return NGX_OK; 1008 return NGX_OK;
915 case NGX_ERROR_IGNORE_ECONNRESET: 1057 case NGX_ERROR_IGNORE_ECONNRESET:
916 case NGX_ERROR_INFO: 1058 case NGX_ERROR_INFO:
917 level = NGX_LOG_INFO; 1059 level = NGX_LOG_INFO;
918 break; 1060 break;
919 1061
920 case NGX_ERROR_ERR: 1062 default:
921 level = NGX_LOG_ERR; 1063 level = NGX_LOG_ERR;
922 break;
923
924 default:
925 level = NGX_LOG_ALERT;
926 } 1064 }
927 1065
928 } else { 1066 } else {
929 level = NGX_LOG_ALERT; 1067 level = NGX_LOG_ALERT;
930 } 1068 }