Mercurial > hg > nginx-quic
annotate src/stream/ngx_stream_core_module.c @ 7623:72b792bb3885
HTTP/2: fixed socket leak with an incomplete HEADERS frame.
A connection could get stuck without timers if a client has partially sent
the HEADERS frame such that it was split on the individual header boundary.
In this case, it cannot be processed without the rest of the HEADERS frame.
The fix is to call ngx_http_v2_state_headers_save() in this case. Normally,
it would be called from the ngx_http_v2_state_header_block() handler on the
next iteration, when there is not enough data to continue processing. This
isn't the case if recv_buffer became empty and there's no more data to read.
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Wed, 05 Feb 2020 16:29:23 +0300 |
parents | 4f9b72a229c1 |
children | 893b3313f53c 2ab7b55ae4a0 |
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_stream.h> | |
11 | |
12 | |
6607
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
13 static ngx_int_t ngx_stream_core_preconfiguration(ngx_conf_t *cf); |
6115 | 14 static void *ngx_stream_core_create_main_conf(ngx_conf_t *cf); |
6607
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
15 static char *ngx_stream_core_init_main_conf(ngx_conf_t *cf, void *conf); |
6115 | 16 static void *ngx_stream_core_create_srv_conf(ngx_conf_t *cf); |
17 static char *ngx_stream_core_merge_srv_conf(ngx_conf_t *cf, void *parent, | |
18 void *child); | |
19 static char *ngx_stream_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, | |
20 void *conf); | |
21 static char *ngx_stream_core_server(ngx_conf_t *cf, ngx_command_t *cmd, | |
22 void *conf); | |
23 static char *ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, | |
24 void *conf); | |
6618 | 25 static char *ngx_stream_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, |
26 void *conf); | |
6115 | 27 |
28 | |
29 static ngx_command_t ngx_stream_core_commands[] = { | |
30 | |
6607
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
31 { ngx_string("variables_hash_max_size"), |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
32 NGX_STREAM_MAIN_CONF|NGX_CONF_TAKE1, |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
33 ngx_conf_set_num_slot, |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
34 NGX_STREAM_MAIN_CONF_OFFSET, |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
35 offsetof(ngx_stream_core_main_conf_t, variables_hash_max_size), |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
36 NULL }, |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
37 |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
38 { ngx_string("variables_hash_bucket_size"), |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
39 NGX_STREAM_MAIN_CONF|NGX_CONF_TAKE1, |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
40 ngx_conf_set_num_slot, |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
41 NGX_STREAM_MAIN_CONF_OFFSET, |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
42 offsetof(ngx_stream_core_main_conf_t, variables_hash_bucket_size), |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
43 NULL }, |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
44 |
6115 | 45 { ngx_string("server"), |
46 NGX_STREAM_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, | |
47 ngx_stream_core_server, | |
48 0, | |
49 0, | |
50 NULL }, | |
51 | |
52 { ngx_string("listen"), | |
53 NGX_STREAM_SRV_CONF|NGX_CONF_1MORE, | |
54 ngx_stream_core_listen, | |
55 NGX_STREAM_SRV_CONF_OFFSET, | |
56 0, | |
57 NULL }, | |
58 | |
59 { ngx_string("error_log"), | |
60 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE, | |
61 ngx_stream_core_error_log, | |
62 NGX_STREAM_SRV_CONF_OFFSET, | |
63 0, | |
64 NULL }, | |
65 | |
6618 | 66 { ngx_string("resolver"), |
67 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE, | |
68 ngx_stream_core_resolver, | |
69 NGX_STREAM_SRV_CONF_OFFSET, | |
70 0, | |
71 NULL }, | |
72 | |
73 { ngx_string("resolver_timeout"), | |
74 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
75 ngx_conf_set_msec_slot, | |
76 NGX_STREAM_SRV_CONF_OFFSET, | |
77 offsetof(ngx_stream_core_srv_conf_t, resolver_timeout), | |
78 NULL }, | |
79 | |
6680
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6657
diff
changeset
|
80 { ngx_string("proxy_protocol_timeout"), |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6657
diff
changeset
|
81 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6657
diff
changeset
|
82 ngx_conf_set_msec_slot, |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6657
diff
changeset
|
83 NGX_STREAM_SRV_CONF_OFFSET, |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6657
diff
changeset
|
84 offsetof(ngx_stream_core_srv_conf_t, proxy_protocol_timeout), |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6657
diff
changeset
|
85 NULL }, |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6657
diff
changeset
|
86 |
6221
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
87 { ngx_string("tcp_nodelay"), |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
88 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
89 ngx_conf_set_flag_slot, |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
90 NGX_STREAM_SRV_CONF_OFFSET, |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
91 offsetof(ngx_stream_core_srv_conf_t, tcp_nodelay), |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
92 NULL }, |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
93 |
6694 | 94 { ngx_string("preread_buffer_size"), |
95 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
96 ngx_conf_set_size_slot, | |
97 NGX_STREAM_SRV_CONF_OFFSET, | |
98 offsetof(ngx_stream_core_srv_conf_t, preread_buffer_size), | |
99 NULL }, | |
100 | |
101 { ngx_string("preread_timeout"), | |
102 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
103 ngx_conf_set_msec_slot, | |
104 NGX_STREAM_SRV_CONF_OFFSET, | |
105 offsetof(ngx_stream_core_srv_conf_t, preread_timeout), | |
106 NULL }, | |
107 | |
6115 | 108 ngx_null_command |
109 }; | |
110 | |
111 | |
112 static ngx_stream_module_t ngx_stream_core_module_ctx = { | |
6607
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
113 ngx_stream_core_preconfiguration, /* preconfiguration */ |
6174
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
114 NULL, /* postconfiguration */ |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
115 |
6115 | 116 ngx_stream_core_create_main_conf, /* create main configuration */ |
6607
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
117 ngx_stream_core_init_main_conf, /* init main configuration */ |
6115 | 118 |
119 ngx_stream_core_create_srv_conf, /* create server configuration */ | |
120 ngx_stream_core_merge_srv_conf /* merge server configuration */ | |
121 }; | |
122 | |
123 | |
124 ngx_module_t ngx_stream_core_module = { | |
125 NGX_MODULE_V1, | |
126 &ngx_stream_core_module_ctx, /* module context */ | |
127 ngx_stream_core_commands, /* module directives */ | |
128 NGX_STREAM_MODULE, /* module type */ | |
129 NULL, /* init master */ | |
130 NULL, /* init module */ | |
131 NULL, /* init process */ | |
132 NULL, /* init thread */ | |
133 NULL, /* exit thread */ | |
134 NULL, /* exit process */ | |
135 NULL, /* exit master */ | |
136 NGX_MODULE_V1_PADDING | |
137 }; | |
138 | |
139 | |
6693 | 140 void |
141 ngx_stream_core_run_phases(ngx_stream_session_t *s) | |
142 { | |
143 ngx_int_t rc; | |
144 ngx_stream_phase_handler_t *ph; | |
145 ngx_stream_core_main_conf_t *cmcf; | |
146 | |
147 cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module); | |
148 | |
149 ph = cmcf->phase_engine.handlers; | |
150 | |
151 while (ph[s->phase_handler].checker) { | |
152 | |
153 rc = ph[s->phase_handler].checker(s, &ph[s->phase_handler]); | |
154 | |
155 if (rc == NGX_OK) { | |
156 return; | |
157 } | |
158 } | |
159 } | |
160 | |
161 | |
162 ngx_int_t | |
163 ngx_stream_core_generic_phase(ngx_stream_session_t *s, | |
164 ngx_stream_phase_handler_t *ph) | |
165 { | |
166 ngx_int_t rc; | |
167 | |
168 /* | |
169 * generic phase checker, | |
6694 | 170 * used by all phases, except for preread and content |
6693 | 171 */ |
172 | |
173 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, | |
174 "generic phase: %ui", s->phase_handler); | |
175 | |
176 rc = ph->handler(s); | |
177 | |
178 if (rc == NGX_OK) { | |
179 s->phase_handler = ph->next; | |
180 return NGX_AGAIN; | |
181 } | |
182 | |
183 if (rc == NGX_DECLINED) { | |
184 s->phase_handler++; | |
185 return NGX_AGAIN; | |
186 } | |
187 | |
188 if (rc == NGX_AGAIN || rc == NGX_DONE) { | |
189 return NGX_OK; | |
190 } | |
191 | |
192 if (rc == NGX_ERROR) { | |
193 rc = NGX_STREAM_INTERNAL_SERVER_ERROR; | |
194 } | |
195 | |
196 ngx_stream_finalize_session(s, rc); | |
197 | |
198 return NGX_OK; | |
199 } | |
200 | |
201 | |
202 ngx_int_t | |
6694 | 203 ngx_stream_core_preread_phase(ngx_stream_session_t *s, |
204 ngx_stream_phase_handler_t *ph) | |
205 { | |
206 size_t size; | |
207 ssize_t n; | |
208 ngx_int_t rc; | |
209 ngx_connection_t *c; | |
210 ngx_stream_core_srv_conf_t *cscf; | |
211 | |
212 c = s->connection; | |
213 | |
214 c->log->action = "prereading client data"; | |
215 | |
216 cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module); | |
217 | |
218 if (c->read->timedout) { | |
219 rc = NGX_STREAM_OK; | |
220 | |
221 } else if (c->read->timer_set) { | |
222 rc = NGX_AGAIN; | |
223 | |
224 } else { | |
225 rc = ph->handler(s); | |
226 } | |
227 | |
228 while (rc == NGX_AGAIN) { | |
229 | |
230 if (c->buffer == NULL) { | |
231 c->buffer = ngx_create_temp_buf(c->pool, cscf->preread_buffer_size); | |
232 if (c->buffer == NULL) { | |
233 rc = NGX_ERROR; | |
234 break; | |
235 } | |
236 } | |
237 | |
238 size = c->buffer->end - c->buffer->last; | |
239 | |
240 if (size == 0) { | |
241 ngx_log_error(NGX_LOG_ERR, c->log, 0, "preread buffer full"); | |
242 rc = NGX_STREAM_BAD_REQUEST; | |
243 break; | |
244 } | |
245 | |
246 if (c->read->eof) { | |
247 rc = NGX_STREAM_OK; | |
248 break; | |
249 } | |
250 | |
251 if (!c->read->ready) { | |
7345
fe767c99c2ad
Stream: avoid potential infinite loop at preread phase.
Roman Arutyunyan <arut@nginx.com>
parents:
7269
diff
changeset
|
252 break; |
6694 | 253 } |
254 | |
255 n = c->recv(c, c->buffer->last, size); | |
256 | |
7345
fe767c99c2ad
Stream: avoid potential infinite loop at preread phase.
Roman Arutyunyan <arut@nginx.com>
parents:
7269
diff
changeset
|
257 if (n == NGX_ERROR || n == 0) { |
6694 | 258 rc = NGX_STREAM_OK; |
259 break; | |
260 } | |
261 | |
7345
fe767c99c2ad
Stream: avoid potential infinite loop at preread phase.
Roman Arutyunyan <arut@nginx.com>
parents:
7269
diff
changeset
|
262 if (n == NGX_AGAIN) { |
fe767c99c2ad
Stream: avoid potential infinite loop at preread phase.
Roman Arutyunyan <arut@nginx.com>
parents:
7269
diff
changeset
|
263 break; |
6694 | 264 } |
265 | |
7345
fe767c99c2ad
Stream: avoid potential infinite loop at preread phase.
Roman Arutyunyan <arut@nginx.com>
parents:
7269
diff
changeset
|
266 c->buffer->last += n; |
fe767c99c2ad
Stream: avoid potential infinite loop at preread phase.
Roman Arutyunyan <arut@nginx.com>
parents:
7269
diff
changeset
|
267 |
6694 | 268 rc = ph->handler(s); |
269 } | |
270 | |
7345
fe767c99c2ad
Stream: avoid potential infinite loop at preread phase.
Roman Arutyunyan <arut@nginx.com>
parents:
7269
diff
changeset
|
271 if (rc == NGX_AGAIN) { |
fe767c99c2ad
Stream: avoid potential infinite loop at preread phase.
Roman Arutyunyan <arut@nginx.com>
parents:
7269
diff
changeset
|
272 if (ngx_handle_read_event(c->read, 0) != NGX_OK) { |
fe767c99c2ad
Stream: avoid potential infinite loop at preread phase.
Roman Arutyunyan <arut@nginx.com>
parents:
7269
diff
changeset
|
273 ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); |
fe767c99c2ad
Stream: avoid potential infinite loop at preread phase.
Roman Arutyunyan <arut@nginx.com>
parents:
7269
diff
changeset
|
274 return NGX_OK; |
fe767c99c2ad
Stream: avoid potential infinite loop at preread phase.
Roman Arutyunyan <arut@nginx.com>
parents:
7269
diff
changeset
|
275 } |
fe767c99c2ad
Stream: avoid potential infinite loop at preread phase.
Roman Arutyunyan <arut@nginx.com>
parents:
7269
diff
changeset
|
276 |
fe767c99c2ad
Stream: avoid potential infinite loop at preread phase.
Roman Arutyunyan <arut@nginx.com>
parents:
7269
diff
changeset
|
277 if (!c->read->timer_set) { |
fe767c99c2ad
Stream: avoid potential infinite loop at preread phase.
Roman Arutyunyan <arut@nginx.com>
parents:
7269
diff
changeset
|
278 ngx_add_timer(c->read, cscf->preread_timeout); |
fe767c99c2ad
Stream: avoid potential infinite loop at preread phase.
Roman Arutyunyan <arut@nginx.com>
parents:
7269
diff
changeset
|
279 } |
fe767c99c2ad
Stream: avoid potential infinite loop at preread phase.
Roman Arutyunyan <arut@nginx.com>
parents:
7269
diff
changeset
|
280 |
fe767c99c2ad
Stream: avoid potential infinite loop at preread phase.
Roman Arutyunyan <arut@nginx.com>
parents:
7269
diff
changeset
|
281 c->read->handler = ngx_stream_session_handler; |
fe767c99c2ad
Stream: avoid potential infinite loop at preread phase.
Roman Arutyunyan <arut@nginx.com>
parents:
7269
diff
changeset
|
282 |
fe767c99c2ad
Stream: avoid potential infinite loop at preread phase.
Roman Arutyunyan <arut@nginx.com>
parents:
7269
diff
changeset
|
283 return NGX_OK; |
fe767c99c2ad
Stream: avoid potential infinite loop at preread phase.
Roman Arutyunyan <arut@nginx.com>
parents:
7269
diff
changeset
|
284 } |
fe767c99c2ad
Stream: avoid potential infinite loop at preread phase.
Roman Arutyunyan <arut@nginx.com>
parents:
7269
diff
changeset
|
285 |
6694 | 286 if (c->read->timer_set) { |
287 ngx_del_timer(c->read); | |
288 } | |
289 | |
290 if (rc == NGX_OK) { | |
291 s->phase_handler = ph->next; | |
292 return NGX_AGAIN; | |
293 } | |
294 | |
295 if (rc == NGX_DECLINED) { | |
296 s->phase_handler++; | |
297 return NGX_AGAIN; | |
298 } | |
299 | |
300 if (rc == NGX_DONE) { | |
301 return NGX_OK; | |
302 } | |
303 | |
304 if (rc == NGX_ERROR) { | |
305 rc = NGX_STREAM_INTERNAL_SERVER_ERROR; | |
306 } | |
307 | |
308 ngx_stream_finalize_session(s, rc); | |
309 | |
310 return NGX_OK; | |
311 } | |
312 | |
313 | |
314 ngx_int_t | |
6693 | 315 ngx_stream_core_content_phase(ngx_stream_session_t *s, |
316 ngx_stream_phase_handler_t *ph) | |
317 { | |
318 ngx_connection_t *c; | |
319 ngx_stream_core_srv_conf_t *cscf; | |
320 | |
321 c = s->connection; | |
322 | |
323 c->log->action = NULL; | |
324 | |
325 cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module); | |
326 | |
327 if (c->type == SOCK_STREAM | |
328 && cscf->tcp_nodelay | |
7007
ed1101bbf19f
Introduced ngx_tcp_nodelay().
Ruslan Ermilov <ru@nginx.com>
parents:
6975
diff
changeset
|
329 && ngx_tcp_nodelay(c) != NGX_OK) |
6693 | 330 { |
7007
ed1101bbf19f
Introduced ngx_tcp_nodelay().
Ruslan Ermilov <ru@nginx.com>
parents:
6975
diff
changeset
|
331 ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); |
ed1101bbf19f
Introduced ngx_tcp_nodelay().
Ruslan Ermilov <ru@nginx.com>
parents:
6975
diff
changeset
|
332 return NGX_OK; |
6693 | 333 } |
334 | |
335 cscf->handler(s); | |
336 | |
337 return NGX_OK; | |
338 } | |
339 | |
340 | |
6607
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
341 static ngx_int_t |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
342 ngx_stream_core_preconfiguration(ngx_conf_t *cf) |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
343 { |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
344 return ngx_stream_variables_add_core_vars(cf); |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
345 } |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
346 |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
347 |
6115 | 348 static void * |
349 ngx_stream_core_create_main_conf(ngx_conf_t *cf) | |
350 { | |
351 ngx_stream_core_main_conf_t *cmcf; | |
352 | |
353 cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_core_main_conf_t)); | |
354 if (cmcf == NULL) { | |
355 return NULL; | |
356 } | |
357 | |
358 if (ngx_array_init(&cmcf->servers, cf->pool, 4, | |
359 sizeof(ngx_stream_core_srv_conf_t *)) | |
360 != NGX_OK) | |
361 { | |
362 return NULL; | |
363 } | |
364 | |
365 if (ngx_array_init(&cmcf->listen, cf->pool, 4, sizeof(ngx_stream_listen_t)) | |
366 != NGX_OK) | |
367 { | |
368 return NULL; | |
369 } | |
370 | |
6607
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
371 cmcf->variables_hash_max_size = NGX_CONF_UNSET_UINT; |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
372 cmcf->variables_hash_bucket_size = NGX_CONF_UNSET_UINT; |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
373 |
6115 | 374 return cmcf; |
375 } | |
376 | |
377 | |
6607
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
378 static char * |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
379 ngx_stream_core_init_main_conf(ngx_conf_t *cf, void *conf) |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
380 { |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
381 ngx_stream_core_main_conf_t *cmcf = conf; |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
382 |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
383 ngx_conf_init_uint_value(cmcf->variables_hash_max_size, 1024); |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
384 ngx_conf_init_uint_value(cmcf->variables_hash_bucket_size, 64); |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
385 |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
386 cmcf->variables_hash_bucket_size = |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
387 ngx_align(cmcf->variables_hash_bucket_size, ngx_cacheline_size); |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
388 |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
389 if (cmcf->ncaptures) { |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
390 cmcf->ncaptures = (cmcf->ncaptures + 1) * 3; |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
391 } |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
392 |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
393 return NGX_CONF_OK; |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
394 } |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
395 |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
396 |
6115 | 397 static void * |
398 ngx_stream_core_create_srv_conf(ngx_conf_t *cf) | |
399 { | |
400 ngx_stream_core_srv_conf_t *cscf; | |
401 | |
402 cscf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_core_srv_conf_t)); | |
403 if (cscf == NULL) { | |
404 return NULL; | |
405 } | |
406 | |
407 /* | |
408 * set by ngx_pcalloc(): | |
409 * | |
410 * cscf->handler = NULL; | |
411 * cscf->error_log = NULL; | |
412 */ | |
413 | |
414 cscf->file_name = cf->conf_file->file.name.data; | |
415 cscf->line = cf->conf_file->line; | |
6618 | 416 cscf->resolver_timeout = NGX_CONF_UNSET_MSEC; |
6680
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6657
diff
changeset
|
417 cscf->proxy_protocol_timeout = NGX_CONF_UNSET_MSEC; |
6221
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
418 cscf->tcp_nodelay = NGX_CONF_UNSET; |
6694 | 419 cscf->preread_buffer_size = NGX_CONF_UNSET_SIZE; |
420 cscf->preread_timeout = NGX_CONF_UNSET_MSEC; | |
6115 | 421 |
422 return cscf; | |
423 } | |
424 | |
425 | |
426 static char * | |
427 ngx_stream_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) | |
428 { | |
429 ngx_stream_core_srv_conf_t *prev = parent; | |
430 ngx_stream_core_srv_conf_t *conf = child; | |
431 | |
6618 | 432 ngx_conf_merge_msec_value(conf->resolver_timeout, |
433 prev->resolver_timeout, 30000); | |
434 | |
435 if (conf->resolver == NULL) { | |
436 | |
437 if (prev->resolver == NULL) { | |
438 | |
439 /* | |
440 * create dummy resolver in stream {} context | |
441 * to inherit it in all servers | |
442 */ | |
443 | |
444 prev->resolver = ngx_resolver_create(cf, NULL, 0); | |
445 if (prev->resolver == NULL) { | |
446 return NGX_CONF_ERROR; | |
447 } | |
448 } | |
449 | |
450 conf->resolver = prev->resolver; | |
451 } | |
452 | |
6115 | 453 if (conf->handler == NULL) { |
454 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
455 "no handler for server in %s:%ui", | |
456 conf->file_name, conf->line); | |
457 return NGX_CONF_ERROR; | |
458 } | |
459 | |
460 if (conf->error_log == NULL) { | |
461 if (prev->error_log) { | |
462 conf->error_log = prev->error_log; | |
463 } else { | |
464 conf->error_log = &cf->cycle->new_log; | |
465 } | |
466 } | |
467 | |
6680
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6657
diff
changeset
|
468 ngx_conf_merge_msec_value(conf->proxy_protocol_timeout, |
6685
4a16fceea03b
Stream: increase default value for proxy_protocol_timeout to 30s.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6680
diff
changeset
|
469 prev->proxy_protocol_timeout, 30000); |
6680
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6657
diff
changeset
|
470 |
6221
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
471 ngx_conf_merge_value(conf->tcp_nodelay, prev->tcp_nodelay, 1); |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
472 |
6694 | 473 ngx_conf_merge_size_value(conf->preread_buffer_size, |
474 prev->preread_buffer_size, 16384); | |
475 | |
476 ngx_conf_merge_msec_value(conf->preread_timeout, | |
477 prev->preread_timeout, 30000); | |
478 | |
6115 | 479 return NGX_CONF_OK; |
480 } | |
481 | |
482 | |
483 static char * | |
484 ngx_stream_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
485 { | |
486 ngx_stream_core_srv_conf_t *cscf = conf; | |
487 | |
488 return ngx_log_set_log(cf, &cscf->error_log); | |
489 } | |
490 | |
491 | |
492 static char * | |
493 ngx_stream_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
494 { | |
495 char *rv; | |
496 void *mconf; | |
497 ngx_uint_t m; | |
498 ngx_conf_t pcf; | |
499 ngx_stream_module_t *module; | |
500 ngx_stream_conf_ctx_t *ctx, *stream_ctx; | |
501 ngx_stream_core_srv_conf_t *cscf, **cscfp; | |
502 ngx_stream_core_main_conf_t *cmcf; | |
503 | |
504 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_stream_conf_ctx_t)); | |
505 if (ctx == NULL) { | |
506 return NGX_CONF_ERROR; | |
507 } | |
508 | |
509 stream_ctx = cf->ctx; | |
510 ctx->main_conf = stream_ctx->main_conf; | |
511 | |
512 /* the server{}'s srv_conf */ | |
513 | |
514 ctx->srv_conf = ngx_pcalloc(cf->pool, | |
515 sizeof(void *) * ngx_stream_max_module); | |
516 if (ctx->srv_conf == NULL) { | |
517 return NGX_CONF_ERROR; | |
518 } | |
519 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6230
diff
changeset
|
520 for (m = 0; cf->cycle->modules[m]; m++) { |
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6230
diff
changeset
|
521 if (cf->cycle->modules[m]->type != NGX_STREAM_MODULE) { |
6115 | 522 continue; |
523 } | |
524 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6230
diff
changeset
|
525 module = cf->cycle->modules[m]->ctx; |
6115 | 526 |
527 if (module->create_srv_conf) { | |
528 mconf = module->create_srv_conf(cf); | |
529 if (mconf == NULL) { | |
530 return NGX_CONF_ERROR; | |
531 } | |
532 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6230
diff
changeset
|
533 ctx->srv_conf[cf->cycle->modules[m]->ctx_index] = mconf; |
6115 | 534 } |
535 } | |
536 | |
537 /* the server configuration context */ | |
538 | |
539 cscf = ctx->srv_conf[ngx_stream_core_module.ctx_index]; | |
540 cscf->ctx = ctx; | |
541 | |
542 cmcf = ctx->main_conf[ngx_stream_core_module.ctx_index]; | |
543 | |
544 cscfp = ngx_array_push(&cmcf->servers); | |
545 if (cscfp == NULL) { | |
546 return NGX_CONF_ERROR; | |
547 } | |
548 | |
549 *cscfp = cscf; | |
550 | |
551 | |
552 /* parse inside server{} */ | |
553 | |
554 pcf = *cf; | |
555 cf->ctx = ctx; | |
556 cf->cmd_type = NGX_STREAM_SRV_CONF; | |
557 | |
558 rv = ngx_conf_parse(cf, NULL); | |
559 | |
560 *cf = pcf; | |
561 | |
6657
3d5202c71f94
Ensure "listen" exists in a mail or stream server (ticket #1049).
Roman Arutyunyan <arut@nginx.com>
parents:
6618
diff
changeset
|
562 if (rv == NGX_CONF_OK && !cscf->listen) { |
3d5202c71f94
Ensure "listen" exists in a mail or stream server (ticket #1049).
Roman Arutyunyan <arut@nginx.com>
parents:
6618
diff
changeset
|
563 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, |
3d5202c71f94
Ensure "listen" exists in a mail or stream server (ticket #1049).
Roman Arutyunyan <arut@nginx.com>
parents:
6618
diff
changeset
|
564 "no \"listen\" is defined for server in %s:%ui", |
3d5202c71f94
Ensure "listen" exists in a mail or stream server (ticket #1049).
Roman Arutyunyan <arut@nginx.com>
parents:
6618
diff
changeset
|
565 cscf->file_name, cscf->line); |
3d5202c71f94
Ensure "listen" exists in a mail or stream server (ticket #1049).
Roman Arutyunyan <arut@nginx.com>
parents:
6618
diff
changeset
|
566 return NGX_CONF_ERROR; |
3d5202c71f94
Ensure "listen" exists in a mail or stream server (ticket #1049).
Roman Arutyunyan <arut@nginx.com>
parents:
6618
diff
changeset
|
567 } |
3d5202c71f94
Ensure "listen" exists in a mail or stream server (ticket #1049).
Roman Arutyunyan <arut@nginx.com>
parents:
6618
diff
changeset
|
568 |
6115 | 569 return rv; |
570 } | |
571 | |
572 | |
573 static char * | |
574 ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
575 { | |
6657
3d5202c71f94
Ensure "listen" exists in a mail or stream server (ticket #1049).
Roman Arutyunyan <arut@nginx.com>
parents:
6618
diff
changeset
|
576 ngx_stream_core_srv_conf_t *cscf = conf; |
3d5202c71f94
Ensure "listen" exists in a mail or stream server (ticket #1049).
Roman Arutyunyan <arut@nginx.com>
parents:
6618
diff
changeset
|
577 |
6975
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
578 ngx_str_t *value, size; |
6115 | 579 ngx_url_t u; |
7478
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
580 ngx_uint_t i, n, backlog; |
6558
68854ce64ec7
Stream: fixed duplicate listen address detection.
Ruslan Ermilov <ru@nginx.com>
parents:
6557
diff
changeset
|
581 ngx_stream_listen_t *ls, *als; |
6115 | 582 ngx_stream_core_main_conf_t *cmcf; |
583 | |
6657
3d5202c71f94
Ensure "listen" exists in a mail or stream server (ticket #1049).
Roman Arutyunyan <arut@nginx.com>
parents:
6618
diff
changeset
|
584 cscf->listen = 1; |
3d5202c71f94
Ensure "listen" exists in a mail or stream server (ticket #1049).
Roman Arutyunyan <arut@nginx.com>
parents:
6618
diff
changeset
|
585 |
6115 | 586 value = cf->args->elts; |
587 | |
588 ngx_memzero(&u, sizeof(ngx_url_t)); | |
589 | |
590 u.url = value[1]; | |
591 u.listen = 1; | |
592 | |
593 if (ngx_parse_url(cf->pool, &u) != NGX_OK) { | |
594 if (u.err) { | |
595 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
596 "%s in \"%V\" of the \"listen\" directive", | |
597 u.err, &u.url); | |
598 } | |
599 | |
600 return NGX_CONF_ERROR; | |
601 } | |
602 | |
603 cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); | |
604 | |
7478
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
605 ls = ngx_array_push_n(&cmcf->listen, u.naddrs); |
6115 | 606 if (ls == NULL) { |
607 return NGX_CONF_ERROR; | |
608 } | |
609 | |
610 ngx_memzero(ls, sizeof(ngx_stream_listen_t)); | |
611 | |
6172 | 612 ls->backlog = NGX_LISTEN_BACKLOG; |
6975
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
613 ls->rcvbuf = -1; |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
614 ls->sndbuf = -1; |
6436 | 615 ls->type = SOCK_STREAM; |
6115 | 616 ls->ctx = cf->ctx; |
617 | |
6719
cebf5fed00bf
Modules compatibility: removed unneeded IPV6_V6ONLY checks.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6694
diff
changeset
|
618 #if (NGX_HAVE_INET6) |
6115 | 619 ls->ipv6only = 1; |
620 #endif | |
621 | |
6436 | 622 backlog = 0; |
623 | |
6115 | 624 for (i = 2; i < cf->args->nelts; i++) { |
625 | |
6436 | 626 #if !(NGX_WIN32) |
627 if (ngx_strcmp(value[i].data, "udp") == 0) { | |
628 ls->type = SOCK_DGRAM; | |
629 continue; | |
630 } | |
631 #endif | |
632 | |
6115 | 633 if (ngx_strcmp(value[i].data, "bind") == 0) { |
634 ls->bind = 1; | |
635 continue; | |
636 } | |
637 | |
6172 | 638 if (ngx_strncmp(value[i].data, "backlog=", 8) == 0) { |
639 ls->backlog = ngx_atoi(value[i].data + 8, value[i].len - 8); | |
640 ls->bind = 1; | |
641 | |
642 if (ls->backlog == NGX_ERROR || ls->backlog == 0) { | |
643 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
644 "invalid backlog \"%V\"", &value[i]); | |
645 return NGX_CONF_ERROR; | |
646 } | |
647 | |
6436 | 648 backlog = 1; |
649 | |
6172 | 650 continue; |
651 } | |
652 | |
6975
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
653 if (ngx_strncmp(value[i].data, "rcvbuf=", 7) == 0) { |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
654 size.len = value[i].len - 7; |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
655 size.data = value[i].data + 7; |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
656 |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
657 ls->rcvbuf = ngx_parse_size(&size); |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
658 ls->bind = 1; |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
659 |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
660 if (ls->rcvbuf == NGX_ERROR) { |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
661 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
662 "invalid rcvbuf \"%V\"", &value[i]); |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
663 return NGX_CONF_ERROR; |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
664 } |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
665 |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
666 continue; |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
667 } |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
668 |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
669 if (ngx_strncmp(value[i].data, "sndbuf=", 7) == 0) { |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
670 size.len = value[i].len - 7; |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
671 size.data = value[i].data + 7; |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
672 |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
673 ls->sndbuf = ngx_parse_size(&size); |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
674 ls->bind = 1; |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
675 |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
676 if (ls->sndbuf == NGX_ERROR) { |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
677 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
678 "invalid sndbuf \"%V\"", &value[i]); |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
679 return NGX_CONF_ERROR; |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
680 } |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
681 |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
682 continue; |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
683 } |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6719
diff
changeset
|
684 |
6115 | 685 if (ngx_strncmp(value[i].data, "ipv6only=o", 10) == 0) { |
686 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) | |
7478
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
687 if (ngx_strcmp(&value[i].data[10], "n") == 0) { |
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
688 ls->ipv6only = 1; |
6115 | 689 |
7478
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
690 } else if (ngx_strcmp(&value[i].data[10], "ff") == 0) { |
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
691 ls->ipv6only = 0; |
6115 | 692 |
693 } else { | |
694 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
7478
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
695 "invalid ipv6only flags \"%s\"", |
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
696 &value[i].data[9]); |
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
697 return NGX_CONF_ERROR; |
6115 | 698 } |
699 | |
7478
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
700 ls->bind = 1; |
6115 | 701 continue; |
702 #else | |
703 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
704 "bind ipv6only is not supported " | |
705 "on this platform"); | |
706 return NGX_CONF_ERROR; | |
707 #endif | |
708 } | |
709 | |
6153
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6115
diff
changeset
|
710 if (ngx_strcmp(value[i].data, "reuseport") == 0) { |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6115
diff
changeset
|
711 #if (NGX_HAVE_REUSEPORT) |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6115
diff
changeset
|
712 ls->reuseport = 1; |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6115
diff
changeset
|
713 ls->bind = 1; |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6115
diff
changeset
|
714 #else |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6115
diff
changeset
|
715 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6115
diff
changeset
|
716 "reuseport is not supported " |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6115
diff
changeset
|
717 "on this platform, ignored"); |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6115
diff
changeset
|
718 #endif |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6115
diff
changeset
|
719 continue; |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6115
diff
changeset
|
720 } |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6115
diff
changeset
|
721 |
6115 | 722 if (ngx_strcmp(value[i].data, "ssl") == 0) { |
723 #if (NGX_STREAM_SSL) | |
7269
7f955d3b9a0d
SSL: detect "listen ... ssl" without certificates (ticket #178).
Maxim Dounin <mdounin@mdounin.ru>
parents:
7007
diff
changeset
|
724 ngx_stream_ssl_conf_t *sslcf; |
7f955d3b9a0d
SSL: detect "listen ... ssl" without certificates (ticket #178).
Maxim Dounin <mdounin@mdounin.ru>
parents:
7007
diff
changeset
|
725 |
7f955d3b9a0d
SSL: detect "listen ... ssl" without certificates (ticket #178).
Maxim Dounin <mdounin@mdounin.ru>
parents:
7007
diff
changeset
|
726 sslcf = ngx_stream_conf_get_module_srv_conf(cf, |
7f955d3b9a0d
SSL: detect "listen ... ssl" without certificates (ticket #178).
Maxim Dounin <mdounin@mdounin.ru>
parents:
7007
diff
changeset
|
727 ngx_stream_ssl_module); |
7f955d3b9a0d
SSL: detect "listen ... ssl" without certificates (ticket #178).
Maxim Dounin <mdounin@mdounin.ru>
parents:
7007
diff
changeset
|
728 |
7f955d3b9a0d
SSL: detect "listen ... ssl" without certificates (ticket #178).
Maxim Dounin <mdounin@mdounin.ru>
parents:
7007
diff
changeset
|
729 sslcf->listen = 1; |
7f955d3b9a0d
SSL: detect "listen ... ssl" without certificates (ticket #178).
Maxim Dounin <mdounin@mdounin.ru>
parents:
7007
diff
changeset
|
730 sslcf->file = cf->conf_file->file.name.data; |
7f955d3b9a0d
SSL: detect "listen ... ssl" without certificates (ticket #178).
Maxim Dounin <mdounin@mdounin.ru>
parents:
7007
diff
changeset
|
731 sslcf->line = cf->conf_file->line; |
7f955d3b9a0d
SSL: detect "listen ... ssl" without certificates (ticket #178).
Maxim Dounin <mdounin@mdounin.ru>
parents:
7007
diff
changeset
|
732 |
6115 | 733 ls->ssl = 1; |
7269
7f955d3b9a0d
SSL: detect "listen ... ssl" without certificates (ticket #178).
Maxim Dounin <mdounin@mdounin.ru>
parents:
7007
diff
changeset
|
734 |
6115 | 735 continue; |
736 #else | |
737 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
738 "the \"ssl\" parameter requires " | |
739 "ngx_stream_ssl_module"); | |
740 return NGX_CONF_ERROR; | |
741 #endif | |
742 } | |
743 | |
744 if (ngx_strncmp(value[i].data, "so_keepalive=", 13) == 0) { | |
745 | |
746 if (ngx_strcmp(&value[i].data[13], "on") == 0) { | |
747 ls->so_keepalive = 1; | |
748 | |
749 } else if (ngx_strcmp(&value[i].data[13], "off") == 0) { | |
750 ls->so_keepalive = 2; | |
751 | |
752 } else { | |
753 | |
754 #if (NGX_HAVE_KEEPALIVE_TUNABLE) | |
755 u_char *p, *end; | |
756 ngx_str_t s; | |
757 | |
758 end = value[i].data + value[i].len; | |
759 s.data = value[i].data + 13; | |
760 | |
761 p = ngx_strlchr(s.data, end, ':'); | |
762 if (p == NULL) { | |
763 p = end; | |
764 } | |
765 | |
766 if (p > s.data) { | |
767 s.len = p - s.data; | |
768 | |
769 ls->tcp_keepidle = ngx_parse_time(&s, 1); | |
770 if (ls->tcp_keepidle == (time_t) NGX_ERROR) { | |
771 goto invalid_so_keepalive; | |
772 } | |
773 } | |
774 | |
775 s.data = (p < end) ? (p + 1) : end; | |
776 | |
777 p = ngx_strlchr(s.data, end, ':'); | |
778 if (p == NULL) { | |
779 p = end; | |
780 } | |
781 | |
782 if (p > s.data) { | |
783 s.len = p - s.data; | |
784 | |
785 ls->tcp_keepintvl = ngx_parse_time(&s, 1); | |
786 if (ls->tcp_keepintvl == (time_t) NGX_ERROR) { | |
787 goto invalid_so_keepalive; | |
788 } | |
789 } | |
790 | |
791 s.data = (p < end) ? (p + 1) : end; | |
792 | |
793 if (s.data < end) { | |
794 s.len = end - s.data; | |
795 | |
796 ls->tcp_keepcnt = ngx_atoi(s.data, s.len); | |
797 if (ls->tcp_keepcnt == NGX_ERROR) { | |
798 goto invalid_so_keepalive; | |
799 } | |
800 } | |
801 | |
802 if (ls->tcp_keepidle == 0 && ls->tcp_keepintvl == 0 | |
803 && ls->tcp_keepcnt == 0) | |
804 { | |
805 goto invalid_so_keepalive; | |
806 } | |
807 | |
808 ls->so_keepalive = 1; | |
809 | |
810 #else | |
811 | |
812 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
813 "the \"so_keepalive\" parameter accepts " | |
814 "only \"on\" or \"off\" on this platform"); | |
815 return NGX_CONF_ERROR; | |
816 | |
817 #endif | |
818 } | |
819 | |
820 ls->bind = 1; | |
821 | |
822 continue; | |
823 | |
824 #if (NGX_HAVE_KEEPALIVE_TUNABLE) | |
825 invalid_so_keepalive: | |
826 | |
827 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
828 "invalid so_keepalive value: \"%s\"", | |
829 &value[i].data[13]); | |
830 return NGX_CONF_ERROR; | |
831 #endif | |
832 } | |
833 | |
6680
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6657
diff
changeset
|
834 if (ngx_strcmp(value[i].data, "proxy_protocol") == 0) { |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6657
diff
changeset
|
835 ls->proxy_protocol = 1; |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6657
diff
changeset
|
836 continue; |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6657
diff
changeset
|
837 } |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6657
diff
changeset
|
838 |
6115 | 839 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
840 "the invalid \"%V\" parameter", &value[i]); | |
841 return NGX_CONF_ERROR; | |
842 } | |
843 | |
6436 | 844 if (ls->type == SOCK_DGRAM) { |
845 if (backlog) { | |
846 return "\"backlog\" parameter is incompatible with \"udp\""; | |
847 } | |
848 | |
849 #if (NGX_STREAM_SSL) | |
850 if (ls->ssl) { | |
851 return "\"ssl\" parameter is incompatible with \"udp\""; | |
852 } | |
853 #endif | |
854 | |
855 if (ls->so_keepalive) { | |
856 return "\"so_keepalive\" parameter is incompatible with \"udp\""; | |
857 } | |
6680
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6657
diff
changeset
|
858 |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6657
diff
changeset
|
859 if (ls->proxy_protocol) { |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6657
diff
changeset
|
860 return "\"proxy_protocol\" parameter is incompatible with \"udp\""; |
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6657
diff
changeset
|
861 } |
6436 | 862 } |
863 | |
6558
68854ce64ec7
Stream: fixed duplicate listen address detection.
Ruslan Ermilov <ru@nginx.com>
parents:
6557
diff
changeset
|
864 als = cmcf->listen.elts; |
68854ce64ec7
Stream: fixed duplicate listen address detection.
Ruslan Ermilov <ru@nginx.com>
parents:
6557
diff
changeset
|
865 |
7478
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
866 for (n = 0; n < u.naddrs; n++) { |
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
867 ls[n] = ls[0]; |
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
868 |
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
869 ls[n].sockaddr = u.addrs[n].sockaddr; |
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
870 ls[n].socklen = u.addrs[n].socklen; |
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
871 ls[n].addr_text = u.addrs[n].name; |
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
872 ls[n].wildcard = ngx_inet_wildcard(ls[n].sockaddr); |
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
873 |
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
874 for (i = 0; i < cmcf->listen.nelts - u.naddrs + n; i++) { |
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
875 if (ls[n].type != als[i].type) { |
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
876 continue; |
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
877 } |
6558
68854ce64ec7
Stream: fixed duplicate listen address detection.
Ruslan Ermilov <ru@nginx.com>
parents:
6557
diff
changeset
|
878 |
7478
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
879 if (ngx_cmp_sockaddr(als[i].sockaddr, als[i].socklen, |
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
880 ls[n].sockaddr, ls[n].socklen, 1) |
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
881 != NGX_OK) |
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
882 { |
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
883 continue; |
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
884 } |
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
885 |
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
886 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
887 "duplicate \"%V\" address and port pair", |
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
888 &ls[n].addr_text); |
4f9b72a229c1
Multiple addresses in "listen".
Roman Arutyunyan <arut@nginx.com>
parents:
7345
diff
changeset
|
889 return NGX_CONF_ERROR; |
6558
68854ce64ec7
Stream: fixed duplicate listen address detection.
Ruslan Ermilov <ru@nginx.com>
parents:
6557
diff
changeset
|
890 } |
68854ce64ec7
Stream: fixed duplicate listen address detection.
Ruslan Ermilov <ru@nginx.com>
parents:
6557
diff
changeset
|
891 } |
68854ce64ec7
Stream: fixed duplicate listen address detection.
Ruslan Ermilov <ru@nginx.com>
parents:
6557
diff
changeset
|
892 |
6115 | 893 return NGX_CONF_OK; |
894 } | |
6618 | 895 |
896 | |
897 static char * | |
898 ngx_stream_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
899 { | |
900 ngx_stream_core_srv_conf_t *cscf = conf; | |
901 | |
902 ngx_str_t *value; | |
903 | |
904 if (cscf->resolver) { | |
905 return "is duplicate"; | |
906 } | |
907 | |
908 value = cf->args->elts; | |
909 | |
910 cscf->resolver = ngx_resolver_create(cf, &value[1], cf->args->nelts - 1); | |
911 if (cscf->resolver == NULL) { | |
912 return NGX_CONF_ERROR; | |
913 } | |
914 | |
915 return NGX_CONF_OK; | |
916 } |