Mercurial > hg > nginx
annotate src/stream/ngx_stream_handler.c @ 6679:40e8ce405859
Stream: postpone session initialization under accept mutex.
Previously, it was possible that some system calls could be
invoked while holding the accept mutex. This is clearly
wrong as it prevents incoming connections from being accepted
as quickly as possible.
author | Dmitry Volyntsev <xeioex@nginx.com> |
---|---|
date | Tue, 06 Sep 2016 21:28:13 +0300 |
parents | 0125b151c9a5 |
children | 7357abd1fa8c |
rev | line source |
---|---|
6115 | 1 |
2 /* | |
3 * Copyright (C) Roman Arutyunyan | |
4 * Copyright (C) Nginx, Inc. | |
5 */ | |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_event.h> | |
11 #include <ngx_stream.h> | |
12 | |
13 | |
6674
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
14 static void ngx_stream_close_connection(ngx_connection_t *c); |
6115 | 15 static u_char *ngx_stream_log_error(ngx_log_t *log, u_char *buf, size_t len); |
6679
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
16 static void ngx_stream_init_session_handler(ngx_event_t *rev); |
6115 | 17 static void ngx_stream_init_session(ngx_connection_t *c); |
18 | |
19 #if (NGX_STREAM_SSL) | |
20 static void ngx_stream_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c); | |
21 static void ngx_stream_ssl_handshake_handler(ngx_connection_t *c); | |
22 #endif | |
23 | |
24 | |
25 void | |
26 ngx_stream_init_connection(ngx_connection_t *c) | |
27 { | |
6175 | 28 u_char text[NGX_SOCKADDR_STRLEN]; |
29 size_t len; | |
30 ngx_uint_t i; | |
6669
164a0824ce20
Stream: the $session_time variable.
Vladimir Homutov <vl@nginx.com>
parents:
6607
diff
changeset
|
31 ngx_time_t *tp; |
6679
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
32 ngx_event_t *rev; |
6175 | 33 struct sockaddr *sa; |
34 ngx_stream_port_t *port; | |
35 struct sockaddr_in *sin; | |
36 ngx_stream_in_addr_t *addr; | |
37 ngx_stream_session_t *s; | |
38 ngx_stream_addr_conf_t *addr_conf; | |
6115 | 39 #if (NGX_HAVE_INET6) |
6175 | 40 struct sockaddr_in6 *sin6; |
41 ngx_stream_in6_addr_t *addr6; | |
6115 | 42 #endif |
6175 | 43 ngx_stream_core_srv_conf_t *cscf; |
44 ngx_stream_core_main_conf_t *cmcf; | |
6115 | 45 |
46 /* find the server configuration for the address:port */ | |
47 | |
48 port = c->listening->servers; | |
49 | |
50 if (port->naddrs > 1) { | |
51 | |
52 /* | |
53 * There are several addresses on this port and one of them | |
54 * is the "*:port" wildcard so getsockname() is needed to determine | |
55 * the server address. | |
56 * | |
6436 | 57 * AcceptEx() and recvmsg() already gave this address. |
6115 | 58 */ |
59 | |
60 if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) { | |
61 ngx_stream_close_connection(c); | |
62 return; | |
63 } | |
64 | |
65 sa = c->local_sockaddr; | |
66 | |
67 switch (sa->sa_family) { | |
68 | |
69 #if (NGX_HAVE_INET6) | |
70 case AF_INET6: | |
71 sin6 = (struct sockaddr_in6 *) sa; | |
72 | |
73 addr6 = port->addrs; | |
74 | |
75 /* the last address is "*" */ | |
76 | |
77 for (i = 0; i < port->naddrs - 1; i++) { | |
78 if (ngx_memcmp(&addr6[i].addr6, &sin6->sin6_addr, 16) == 0) { | |
79 break; | |
80 } | |
81 } | |
82 | |
83 addr_conf = &addr6[i].conf; | |
84 | |
85 break; | |
86 #endif | |
87 | |
88 default: /* AF_INET */ | |
89 sin = (struct sockaddr_in *) sa; | |
90 | |
91 addr = port->addrs; | |
92 | |
93 /* the last address is "*" */ | |
94 | |
95 for (i = 0; i < port->naddrs - 1; i++) { | |
96 if (addr[i].addr == sin->sin_addr.s_addr) { | |
97 break; | |
98 } | |
99 } | |
100 | |
101 addr_conf = &addr[i].conf; | |
102 | |
103 break; | |
104 } | |
105 | |
106 } else { | |
107 switch (c->local_sockaddr->sa_family) { | |
108 | |
109 #if (NGX_HAVE_INET6) | |
110 case AF_INET6: | |
111 addr6 = port->addrs; | |
112 addr_conf = &addr6[0].conf; | |
113 break; | |
114 #endif | |
115 | |
116 default: /* AF_INET */ | |
117 addr = port->addrs; | |
118 addr_conf = &addr[0].conf; | |
119 break; | |
120 } | |
121 } | |
122 | |
123 s = ngx_pcalloc(c->pool, sizeof(ngx_stream_session_t)); | |
124 if (s == NULL) { | |
125 ngx_stream_close_connection(c); | |
126 return; | |
127 } | |
128 | |
129 s->signature = NGX_STREAM_MODULE; | |
130 s->main_conf = addr_conf->ctx->main_conf; | |
131 s->srv_conf = addr_conf->ctx->srv_conf; | |
132 | |
6679
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
133 #if (NGX_STREAM_SSL) |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
134 s->ssl = addr_conf->ssl; |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
135 #endif |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
136 |
6115 | 137 s->connection = c; |
138 c->data = s; | |
139 | |
140 cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module); | |
141 | |
6129
187aa751ad62
Core: the ngx_set_connection_log() macro.
Vladimir Homutov <vl@nginx.com>
parents:
6115
diff
changeset
|
142 ngx_set_connection_log(c, cscf->error_log); |
6115 | 143 |
144 len = ngx_sock_ntop(c->sockaddr, c->socklen, text, NGX_SOCKADDR_STRLEN, 1); | |
145 | |
6461
a01e315b3a78
Stream: additional logging for UDP.
Vladimir Homutov <vl@nginx.com>
parents:
6436
diff
changeset
|
146 ngx_log_error(NGX_LOG_INFO, c->log, 0, "*%uA %sclient %*s connected to %V", |
a01e315b3a78
Stream: additional logging for UDP.
Vladimir Homutov <vl@nginx.com>
parents:
6436
diff
changeset
|
147 c->number, c->type == SOCK_DGRAM ? "udp " : "", |
a01e315b3a78
Stream: additional logging for UDP.
Vladimir Homutov <vl@nginx.com>
parents:
6436
diff
changeset
|
148 len, text, &addr_conf->addr_text); |
6115 | 149 |
150 c->log->connection = c->number; | |
151 c->log->handler = ngx_stream_log_error; | |
152 c->log->data = s; | |
153 c->log->action = "initializing connection"; | |
154 c->log_error = NGX_ERROR_INFO; | |
155 | |
6175 | 156 cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module); |
157 | |
6607
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6461
diff
changeset
|
158 s->variables = ngx_pcalloc(s->connection->pool, |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6461
diff
changeset
|
159 cmcf->variables.nelts |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6461
diff
changeset
|
160 * sizeof(ngx_stream_variable_value_t)); |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6461
diff
changeset
|
161 |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6461
diff
changeset
|
162 if (s->variables == NULL) { |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6461
diff
changeset
|
163 ngx_stream_close_connection(c); |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6461
diff
changeset
|
164 return; |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6461
diff
changeset
|
165 } |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6461
diff
changeset
|
166 |
6669
164a0824ce20
Stream: the $session_time variable.
Vladimir Homutov <vl@nginx.com>
parents:
6607
diff
changeset
|
167 tp = ngx_timeofday(); |
164a0824ce20
Stream: the $session_time variable.
Vladimir Homutov <vl@nginx.com>
parents:
6607
diff
changeset
|
168 s->start_sec = tp->sec; |
164a0824ce20
Stream: the $session_time variable.
Vladimir Homutov <vl@nginx.com>
parents:
6607
diff
changeset
|
169 s->start_msec = tp->msec; |
164a0824ce20
Stream: the $session_time variable.
Vladimir Homutov <vl@nginx.com>
parents:
6607
diff
changeset
|
170 |
6679
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
171 rev = c->read; |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
172 rev->handler = ngx_stream_init_session_handler; |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
173 |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
174 if (ngx_use_accept_mutex) { |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
175 ngx_post_event(rev, &ngx_posted_events); |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
176 return; |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
177 } |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
178 |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
179 rev->handler(rev); |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
180 } |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
181 |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
182 |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
183 static void |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
184 ngx_stream_init_session_handler(ngx_event_t *rev) |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
185 { |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
186 int tcp_nodelay; |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
187 ngx_int_t rc; |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
188 ngx_connection_t *c; |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
189 ngx_stream_session_t *s; |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
190 ngx_stream_core_srv_conf_t *cscf; |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
191 ngx_stream_core_main_conf_t *cmcf; |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
192 |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
193 c = rev->data; |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
194 s = c->data; |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
195 |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
196 c->log->action = "initializing session"; |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
197 |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
198 cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module); |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
199 |
6197
0dcef374b8bb
Stream: connection limiting module.
Vladimir Homutov <vl@nginx.com>
parents:
6175
diff
changeset
|
200 if (cmcf->limit_conn_handler) { |
0dcef374b8bb
Stream: connection limiting module.
Vladimir Homutov <vl@nginx.com>
parents:
6175
diff
changeset
|
201 rc = cmcf->limit_conn_handler(s); |
0dcef374b8bb
Stream: connection limiting module.
Vladimir Homutov <vl@nginx.com>
parents:
6175
diff
changeset
|
202 |
6674
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
203 if (rc == NGX_ERROR) { |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
204 ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
205 return; |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
206 } |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
207 |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
208 if (rc == NGX_ABORT) { |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
209 ngx_stream_finalize_session(s, NGX_STREAM_SERVICE_UNAVAILABLE); |
6197
0dcef374b8bb
Stream: connection limiting module.
Vladimir Homutov <vl@nginx.com>
parents:
6175
diff
changeset
|
210 return; |
0dcef374b8bb
Stream: connection limiting module.
Vladimir Homutov <vl@nginx.com>
parents:
6175
diff
changeset
|
211 } |
0dcef374b8bb
Stream: connection limiting module.
Vladimir Homutov <vl@nginx.com>
parents:
6175
diff
changeset
|
212 } |
0dcef374b8bb
Stream: connection limiting module.
Vladimir Homutov <vl@nginx.com>
parents:
6175
diff
changeset
|
213 |
6175 | 214 if (cmcf->access_handler) { |
215 rc = cmcf->access_handler(s); | |
216 | |
6674
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
217 if (rc == NGX_ERROR) { |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
218 ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
219 return; |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
220 } |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
221 |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
222 if (rc == NGX_ABORT) { |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
223 ngx_stream_finalize_session(s, NGX_STREAM_FORBIDDEN); |
6175 | 224 return; |
225 } | |
226 } | |
227 | |
6679
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
228 cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module); |
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
229 |
6436 | 230 if (c->type == SOCK_STREAM |
231 && cscf->tcp_nodelay | |
232 && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) | |
233 { | |
6221
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6197
diff
changeset
|
234 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, "tcp_nodelay"); |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6197
diff
changeset
|
235 |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6197
diff
changeset
|
236 tcp_nodelay = 1; |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6197
diff
changeset
|
237 |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6197
diff
changeset
|
238 if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6197
diff
changeset
|
239 (const void *) &tcp_nodelay, sizeof(int)) == -1) |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6197
diff
changeset
|
240 { |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6197
diff
changeset
|
241 ngx_connection_error(c, ngx_socket_errno, |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6197
diff
changeset
|
242 "setsockopt(TCP_NODELAY) failed"); |
6674
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
243 ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); |
6221
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6197
diff
changeset
|
244 return; |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6197
diff
changeset
|
245 } |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6197
diff
changeset
|
246 |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6197
diff
changeset
|
247 c->tcp_nodelay = NGX_TCP_NODELAY_SET; |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6197
diff
changeset
|
248 } |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6197
diff
changeset
|
249 |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6197
diff
changeset
|
250 |
6115 | 251 #if (NGX_STREAM_SSL) |
252 { | |
253 ngx_stream_ssl_conf_t *sslcf; | |
254 | |
255 sslcf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module); | |
256 | |
6679
40e8ce405859
Stream: postpone session initialization under accept mutex.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6678
diff
changeset
|
257 if (s->ssl) { |
6115 | 258 c->log->action = "SSL handshaking"; |
259 | |
260 if (sslcf->ssl.ctx == NULL) { | |
261 ngx_log_error(NGX_LOG_ERR, c->log, 0, | |
262 "no \"ssl_certificate\" is defined " | |
263 "in server listening on SSL port"); | |
6674
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
264 ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); |
6115 | 265 return; |
266 } | |
267 | |
268 ngx_stream_ssl_init_connection(&sslcf->ssl, c); | |
269 return; | |
270 } | |
271 } | |
272 #endif | |
273 | |
274 ngx_stream_init_session(c); | |
275 } | |
276 | |
277 | |
278 static void | |
279 ngx_stream_init_session(ngx_connection_t *c) | |
280 { | |
281 ngx_stream_session_t *s; | |
282 ngx_stream_core_srv_conf_t *cscf; | |
283 | |
284 s = c->data; | |
285 c->log->action = "handling client connection"; | |
286 | |
287 cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module); | |
288 | |
289 s->ctx = ngx_pcalloc(c->pool, sizeof(void *) * ngx_stream_max_module); | |
290 if (s->ctx == NULL) { | |
6674
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
291 ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); |
6115 | 292 return; |
293 } | |
294 | |
295 cscf->handler(s); | |
296 } | |
297 | |
298 | |
299 #if (NGX_STREAM_SSL) | |
300 | |
301 static void | |
302 ngx_stream_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c) | |
303 { | |
304 ngx_stream_session_t *s; | |
305 ngx_stream_ssl_conf_t *sslcf; | |
306 | |
6674
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
307 s = c->data; |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
308 |
6115 | 309 if (ngx_ssl_create_connection(ssl, c, 0) == NGX_ERROR) { |
6674
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
310 ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); |
6115 | 311 return; |
312 } | |
313 | |
314 if (ngx_ssl_handshake(c) == NGX_AGAIN) { | |
315 sslcf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module); | |
316 | |
317 ngx_add_timer(c->read, sslcf->handshake_timeout); | |
318 | |
319 c->ssl->handler = ngx_stream_ssl_handshake_handler; | |
320 | |
321 return; | |
322 } | |
323 | |
324 ngx_stream_ssl_handshake_handler(c); | |
325 } | |
326 | |
327 | |
328 static void | |
329 ngx_stream_ssl_handshake_handler(ngx_connection_t *c) | |
330 { | |
331 if (!c->ssl->handshaked) { | |
6674
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
332 ngx_stream_finalize_session(c->data, NGX_STREAM_INTERNAL_SERVER_ERROR); |
6115 | 333 return; |
334 } | |
335 | |
336 if (c->read->timer_set) { | |
337 ngx_del_timer(c->read); | |
338 } | |
339 | |
340 ngx_stream_init_session(c); | |
341 } | |
342 | |
343 #endif | |
344 | |
345 | |
346 void | |
6674
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
347 ngx_stream_finalize_session(ngx_stream_session_t *s, ngx_uint_t rc) |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
348 { |
6678 | 349 ngx_stream_core_main_conf_t *cmcf; |
350 | |
6674
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
351 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
352 "finalize stream session: %i", rc); |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
353 |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
354 s->status = rc; |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
355 |
6678 | 356 cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module); |
357 | |
358 if (cmcf->access_log_handler) { | |
359 (void) cmcf->access_log_handler(s); | |
360 } | |
361 | |
6674
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
362 ngx_stream_close_connection(s->connection); |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
363 } |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
364 |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
365 |
38143d1abdec
Stream: the $status variable.
Roman Arutyunyan <arut@nginx.com>
parents:
6669
diff
changeset
|
366 static void |
6115 | 367 ngx_stream_close_connection(ngx_connection_t *c) |
368 { | |
369 ngx_pool_t *pool; | |
370 | |
371 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, | |
372 "close stream connection: %d", c->fd); | |
373 | |
374 #if (NGX_STREAM_SSL) | |
375 | |
376 if (c->ssl) { | |
377 if (ngx_ssl_shutdown(c) == NGX_AGAIN) { | |
378 c->ssl->handler = ngx_stream_close_connection; | |
379 return; | |
380 } | |
381 } | |
382 | |
383 #endif | |
384 | |
385 #if (NGX_STAT_STUB) | |
386 (void) ngx_atomic_fetch_add(ngx_stat_active, -1); | |
387 #endif | |
388 | |
389 pool = c->pool; | |
390 | |
391 ngx_close_connection(c); | |
392 | |
393 ngx_destroy_pool(pool); | |
394 } | |
395 | |
396 | |
397 static u_char * | |
398 ngx_stream_log_error(ngx_log_t *log, u_char *buf, size_t len) | |
399 { | |
400 u_char *p; | |
401 ngx_stream_session_t *s; | |
402 | |
403 if (log->action) { | |
404 p = ngx_snprintf(buf, len, " while %s", log->action); | |
405 len -= p - buf; | |
406 buf = p; | |
407 } | |
408 | |
409 s = log->data; | |
410 | |
6461
a01e315b3a78
Stream: additional logging for UDP.
Vladimir Homutov <vl@nginx.com>
parents:
6436
diff
changeset
|
411 p = ngx_snprintf(buf, len, ", %sclient: %V, server: %V", |
a01e315b3a78
Stream: additional logging for UDP.
Vladimir Homutov <vl@nginx.com>
parents:
6436
diff
changeset
|
412 s->connection->type == SOCK_DGRAM ? "udp " : "", |
6115 | 413 &s->connection->addr_text, |
414 &s->connection->listening->addr_text); | |
6223
d1f94042c29c
Stream: fixed potential error log buffer overrun.
Vladimir Homutov <vl@nginx.com>
parents:
6221
diff
changeset
|
415 len -= p - buf; |
d1f94042c29c
Stream: fixed potential error log buffer overrun.
Vladimir Homutov <vl@nginx.com>
parents:
6221
diff
changeset
|
416 buf = p; |
6115 | 417 |
418 if (s->log_handler) { | |
6223
d1f94042c29c
Stream: fixed potential error log buffer overrun.
Vladimir Homutov <vl@nginx.com>
parents:
6221
diff
changeset
|
419 p = s->log_handler(log, buf, len); |
6115 | 420 } |
421 | |
422 return p; | |
423 } |