Mercurial > hg > nginx-quic
annotate src/stream/ngx_stream.c @ 7107:d4b031cf32cf
HTTP/2: fixed debug log about indexed headers.
Previously, "get indexed header" message was logged when in fact only
header name was obtained using an index, and "get indexed header name"
was logged when full header representation (name and value) was obtained
using an index. Fixed version logs "get indexed name" and "get indexed
header" respectively.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 14 Sep 2017 19:06:05 +0300 |
parents | d7ce41bdf050 |
children | e7b2b907c0f8 |
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 | |
14 static char *ngx_stream_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | |
6693 | 15 static ngx_int_t ngx_stream_init_phases(ngx_conf_t *cf, |
16 ngx_stream_core_main_conf_t *cmcf); | |
17 static ngx_int_t ngx_stream_init_phase_handlers(ngx_conf_t *cf, | |
18 ngx_stream_core_main_conf_t *cmcf); | |
6115 | 19 static ngx_int_t ngx_stream_add_ports(ngx_conf_t *cf, ngx_array_t *ports, |
20 ngx_stream_listen_t *listen); | |
21 static char *ngx_stream_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports); | |
22 static ngx_int_t ngx_stream_add_addrs(ngx_conf_t *cf, ngx_stream_port_t *stport, | |
23 ngx_stream_conf_addr_t *addr); | |
24 #if (NGX_HAVE_INET6) | |
25 static ngx_int_t ngx_stream_add_addrs6(ngx_conf_t *cf, | |
26 ngx_stream_port_t *stport, ngx_stream_conf_addr_t *addr); | |
27 #endif | |
28 static ngx_int_t ngx_stream_cmp_conf_addrs(const void *one, const void *two); | |
29 | |
30 | |
31 ngx_uint_t ngx_stream_max_module; | |
32 | |
33 | |
6692 | 34 ngx_stream_filter_pt ngx_stream_top_filter; |
35 | |
36 | |
6115 | 37 static ngx_command_t ngx_stream_commands[] = { |
38 | |
39 { ngx_string("stream"), | |
40 NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, | |
41 ngx_stream_block, | |
42 0, | |
43 0, | |
44 NULL }, | |
45 | |
46 ngx_null_command | |
47 }; | |
48 | |
49 | |
50 static ngx_core_module_t ngx_stream_module_ctx = { | |
51 ngx_string("stream"), | |
52 NULL, | |
53 NULL | |
54 }; | |
55 | |
56 | |
57 ngx_module_t ngx_stream_module = { | |
58 NGX_MODULE_V1, | |
59 &ngx_stream_module_ctx, /* module context */ | |
60 ngx_stream_commands, /* module directives */ | |
61 NGX_CORE_MODULE, /* module type */ | |
62 NULL, /* init master */ | |
63 NULL, /* init module */ | |
64 NULL, /* init process */ | |
65 NULL, /* init thread */ | |
66 NULL, /* exit thread */ | |
67 NULL, /* exit process */ | |
68 NULL, /* exit master */ | |
69 NGX_MODULE_V1_PADDING | |
70 }; | |
71 | |
72 | |
73 static char * | |
74 ngx_stream_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
75 { | |
76 char *rv; | |
77 ngx_uint_t i, m, mi, s; | |
78 ngx_conf_t pcf; | |
79 ngx_array_t ports; | |
80 ngx_stream_listen_t *listen; | |
81 ngx_stream_module_t *module; | |
82 ngx_stream_conf_ctx_t *ctx; | |
83 ngx_stream_core_srv_conf_t **cscfp; | |
84 ngx_stream_core_main_conf_t *cmcf; | |
85 | |
6193
78c06e5e1d76
Disabled duplicate http, mail, and stream blocks.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
86 if (*(ngx_stream_conf_ctx_t **) conf) { |
78c06e5e1d76
Disabled duplicate http, mail, and stream blocks.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
87 return "is duplicate"; |
78c06e5e1d76
Disabled duplicate http, mail, and stream blocks.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
88 } |
78c06e5e1d76
Disabled duplicate http, mail, and stream blocks.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
89 |
6115 | 90 /* the main stream context */ |
91 | |
92 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_stream_conf_ctx_t)); | |
93 if (ctx == NULL) { | |
94 return NGX_CONF_ERROR; | |
95 } | |
96 | |
97 *(ngx_stream_conf_ctx_t **) conf = ctx; | |
98 | |
99 /* count the number of the stream modules and set up their indices */ | |
100 | |
6378
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6193
diff
changeset
|
101 ngx_stream_max_module = ngx_count_modules(cf->cycle, NGX_STREAM_MODULE); |
6115 | 102 |
103 | |
104 /* the stream main_conf context, it's the same in the all stream contexts */ | |
105 | |
106 ctx->main_conf = ngx_pcalloc(cf->pool, | |
107 sizeof(void *) * ngx_stream_max_module); | |
108 if (ctx->main_conf == NULL) { | |
109 return NGX_CONF_ERROR; | |
110 } | |
111 | |
112 | |
113 /* | |
114 * the stream null srv_conf context, it is used to merge | |
115 * the server{}s' srv_conf's | |
116 */ | |
117 | |
118 ctx->srv_conf = ngx_pcalloc(cf->pool, | |
119 sizeof(void *) * ngx_stream_max_module); | |
120 if (ctx->srv_conf == NULL) { | |
121 return NGX_CONF_ERROR; | |
122 } | |
123 | |
124 | |
125 /* | |
126 * create the main_conf's and the null srv_conf's of the all stream modules | |
127 */ | |
128 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6378
diff
changeset
|
129 for (m = 0; cf->cycle->modules[m]; m++) { |
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6378
diff
changeset
|
130 if (cf->cycle->modules[m]->type != NGX_STREAM_MODULE) { |
6115 | 131 continue; |
132 } | |
133 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6378
diff
changeset
|
134 module = cf->cycle->modules[m]->ctx; |
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6378
diff
changeset
|
135 mi = cf->cycle->modules[m]->ctx_index; |
6115 | 136 |
137 if (module->create_main_conf) { | |
138 ctx->main_conf[mi] = module->create_main_conf(cf); | |
139 if (ctx->main_conf[mi] == NULL) { | |
140 return NGX_CONF_ERROR; | |
141 } | |
142 } | |
143 | |
144 if (module->create_srv_conf) { | |
145 ctx->srv_conf[mi] = module->create_srv_conf(cf); | |
146 if (ctx->srv_conf[mi] == NULL) { | |
147 return NGX_CONF_ERROR; | |
148 } | |
149 } | |
150 } | |
151 | |
152 | |
153 pcf = *cf; | |
154 cf->ctx = ctx; | |
155 | |
6606
2f41d383c9c7
Stream: added preconfiguration step.
Vladimir Homutov <vl@nginx.com>
parents:
6593
diff
changeset
|
156 for (m = 0; cf->cycle->modules[m]; m++) { |
2f41d383c9c7
Stream: added preconfiguration step.
Vladimir Homutov <vl@nginx.com>
parents:
6593
diff
changeset
|
157 if (cf->cycle->modules[m]->type != NGX_STREAM_MODULE) { |
2f41d383c9c7
Stream: added preconfiguration step.
Vladimir Homutov <vl@nginx.com>
parents:
6593
diff
changeset
|
158 continue; |
2f41d383c9c7
Stream: added preconfiguration step.
Vladimir Homutov <vl@nginx.com>
parents:
6593
diff
changeset
|
159 } |
2f41d383c9c7
Stream: added preconfiguration step.
Vladimir Homutov <vl@nginx.com>
parents:
6593
diff
changeset
|
160 |
2f41d383c9c7
Stream: added preconfiguration step.
Vladimir Homutov <vl@nginx.com>
parents:
6593
diff
changeset
|
161 module = cf->cycle->modules[m]->ctx; |
2f41d383c9c7
Stream: added preconfiguration step.
Vladimir Homutov <vl@nginx.com>
parents:
6593
diff
changeset
|
162 |
2f41d383c9c7
Stream: added preconfiguration step.
Vladimir Homutov <vl@nginx.com>
parents:
6593
diff
changeset
|
163 if (module->preconfiguration) { |
2f41d383c9c7
Stream: added preconfiguration step.
Vladimir Homutov <vl@nginx.com>
parents:
6593
diff
changeset
|
164 if (module->preconfiguration(cf) != NGX_OK) { |
2f41d383c9c7
Stream: added preconfiguration step.
Vladimir Homutov <vl@nginx.com>
parents:
6593
diff
changeset
|
165 return NGX_CONF_ERROR; |
2f41d383c9c7
Stream: added preconfiguration step.
Vladimir Homutov <vl@nginx.com>
parents:
6593
diff
changeset
|
166 } |
2f41d383c9c7
Stream: added preconfiguration step.
Vladimir Homutov <vl@nginx.com>
parents:
6593
diff
changeset
|
167 } |
2f41d383c9c7
Stream: added preconfiguration step.
Vladimir Homutov <vl@nginx.com>
parents:
6593
diff
changeset
|
168 } |
2f41d383c9c7
Stream: added preconfiguration step.
Vladimir Homutov <vl@nginx.com>
parents:
6593
diff
changeset
|
169 |
2f41d383c9c7
Stream: added preconfiguration step.
Vladimir Homutov <vl@nginx.com>
parents:
6593
diff
changeset
|
170 |
2f41d383c9c7
Stream: added preconfiguration step.
Vladimir Homutov <vl@nginx.com>
parents:
6593
diff
changeset
|
171 /* parse inside the stream{} block */ |
2f41d383c9c7
Stream: added preconfiguration step.
Vladimir Homutov <vl@nginx.com>
parents:
6593
diff
changeset
|
172 |
6115 | 173 cf->module_type = NGX_STREAM_MODULE; |
174 cf->cmd_type = NGX_STREAM_MAIN_CONF; | |
175 rv = ngx_conf_parse(cf, NULL); | |
176 | |
177 if (rv != NGX_CONF_OK) { | |
178 *cf = pcf; | |
179 return rv; | |
180 } | |
181 | |
182 | |
183 /* init stream{} main_conf's, merge the server{}s' srv_conf's */ | |
184 | |
185 cmcf = ctx->main_conf[ngx_stream_core_module.ctx_index]; | |
186 cscfp = cmcf->servers.elts; | |
187 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6378
diff
changeset
|
188 for (m = 0; cf->cycle->modules[m]; m++) { |
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6378
diff
changeset
|
189 if (cf->cycle->modules[m]->type != NGX_STREAM_MODULE) { |
6115 | 190 continue; |
191 } | |
192 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6378
diff
changeset
|
193 module = cf->cycle->modules[m]->ctx; |
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6378
diff
changeset
|
194 mi = cf->cycle->modules[m]->ctx_index; |
6115 | 195 |
196 /* init stream{} main_conf's */ | |
197 | |
198 cf->ctx = ctx; | |
199 | |
200 if (module->init_main_conf) { | |
201 rv = module->init_main_conf(cf, ctx->main_conf[mi]); | |
202 if (rv != NGX_CONF_OK) { | |
203 *cf = pcf; | |
204 return rv; | |
205 } | |
206 } | |
207 | |
208 for (s = 0; s < cmcf->servers.nelts; s++) { | |
209 | |
210 /* merge the server{}s' srv_conf's */ | |
211 | |
212 cf->ctx = cscfp[s]->ctx; | |
213 | |
214 if (module->merge_srv_conf) { | |
215 rv = module->merge_srv_conf(cf, | |
216 ctx->srv_conf[mi], | |
217 cscfp[s]->ctx->srv_conf[mi]); | |
218 if (rv != NGX_CONF_OK) { | |
219 *cf = pcf; | |
220 return rv; | |
221 } | |
222 } | |
223 } | |
224 } | |
225 | |
6693 | 226 if (ngx_stream_init_phases(cf, cmcf) != NGX_OK) { |
227 return NGX_CONF_ERROR; | |
228 } | |
229 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6378
diff
changeset
|
230 for (m = 0; cf->cycle->modules[m]; m++) { |
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6378
diff
changeset
|
231 if (cf->cycle->modules[m]->type != NGX_STREAM_MODULE) { |
6174
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
232 continue; |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
233 } |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
234 |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6378
diff
changeset
|
235 module = cf->cycle->modules[m]->ctx; |
6174
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
236 |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
237 if (module->postconfiguration) { |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
238 if (module->postconfiguration(cf) != NGX_OK) { |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
239 return NGX_CONF_ERROR; |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
240 } |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
241 } |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
242 } |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
243 |
6607
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
244 if (ngx_stream_variables_init_vars(cf) != NGX_OK) { |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
245 return NGX_CONF_ERROR; |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
246 } |
c70b7f4537e1
Stream: variables and script.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
247 |
6115 | 248 *cf = pcf; |
249 | |
6693 | 250 if (ngx_stream_init_phase_handlers(cf, cmcf) != NGX_OK) { |
251 return NGX_CONF_ERROR; | |
252 } | |
6115 | 253 |
254 if (ngx_array_init(&ports, cf->temp_pool, 4, sizeof(ngx_stream_conf_port_t)) | |
255 != NGX_OK) | |
256 { | |
257 return NGX_CONF_ERROR; | |
258 } | |
259 | |
260 listen = cmcf->listen.elts; | |
261 | |
262 for (i = 0; i < cmcf->listen.nelts; i++) { | |
263 if (ngx_stream_add_ports(cf, &ports, &listen[i]) != NGX_OK) { | |
264 return NGX_CONF_ERROR; | |
265 } | |
266 } | |
267 | |
268 return ngx_stream_optimize_servers(cf, &ports); | |
269 } | |
270 | |
271 | |
272 static ngx_int_t | |
6693 | 273 ngx_stream_init_phases(ngx_conf_t *cf, ngx_stream_core_main_conf_t *cmcf) |
274 { | |
275 if (ngx_array_init(&cmcf->phases[NGX_STREAM_POST_ACCEPT_PHASE].handlers, | |
276 cf->pool, 1, sizeof(ngx_stream_handler_pt)) | |
277 != NGX_OK) | |
278 { | |
279 return NGX_ERROR; | |
280 } | |
281 | |
282 if (ngx_array_init(&cmcf->phases[NGX_STREAM_PREACCESS_PHASE].handlers, | |
283 cf->pool, 1, sizeof(ngx_stream_handler_pt)) | |
284 != NGX_OK) | |
285 { | |
286 return NGX_ERROR; | |
287 } | |
288 | |
289 if (ngx_array_init(&cmcf->phases[NGX_STREAM_ACCESS_PHASE].handlers, | |
290 cf->pool, 1, sizeof(ngx_stream_handler_pt)) | |
291 != NGX_OK) | |
292 { | |
293 return NGX_ERROR; | |
294 } | |
295 | |
296 if (ngx_array_init(&cmcf->phases[NGX_STREAM_SSL_PHASE].handlers, | |
297 cf->pool, 1, sizeof(ngx_stream_handler_pt)) | |
298 != NGX_OK) | |
299 { | |
300 return NGX_ERROR; | |
301 } | |
302 | |
6694 | 303 if (ngx_array_init(&cmcf->phases[NGX_STREAM_PREREAD_PHASE].handlers, |
304 cf->pool, 1, sizeof(ngx_stream_handler_pt)) | |
305 != NGX_OK) | |
306 { | |
307 return NGX_ERROR; | |
308 } | |
309 | |
6693 | 310 if (ngx_array_init(&cmcf->phases[NGX_STREAM_LOG_PHASE].handlers, |
311 cf->pool, 1, sizeof(ngx_stream_handler_pt)) | |
312 != NGX_OK) | |
313 { | |
314 return NGX_ERROR; | |
315 } | |
316 | |
317 return NGX_OK; | |
318 } | |
319 | |
320 | |
321 static ngx_int_t | |
322 ngx_stream_init_phase_handlers(ngx_conf_t *cf, | |
323 ngx_stream_core_main_conf_t *cmcf) | |
324 { | |
325 ngx_int_t j; | |
326 ngx_uint_t i, n; | |
327 ngx_stream_handler_pt *h; | |
328 ngx_stream_phase_handler_t *ph; | |
329 ngx_stream_phase_handler_pt checker; | |
330 | |
331 n = 1 /* content phase */; | |
332 | |
333 for (i = 0; i < NGX_STREAM_LOG_PHASE; i++) { | |
334 n += cmcf->phases[i].handlers.nelts; | |
335 } | |
336 | |
337 ph = ngx_pcalloc(cf->pool, | |
338 n * sizeof(ngx_stream_phase_handler_t) + sizeof(void *)); | |
339 if (ph == NULL) { | |
340 return NGX_ERROR; | |
341 } | |
342 | |
343 cmcf->phase_engine.handlers = ph; | |
344 n = 0; | |
345 | |
346 for (i = 0; i < NGX_STREAM_LOG_PHASE; i++) { | |
347 h = cmcf->phases[i].handlers.elts; | |
348 | |
349 switch (i) { | |
350 | |
6694 | 351 case NGX_STREAM_PREREAD_PHASE: |
352 checker = ngx_stream_core_preread_phase; | |
353 break; | |
354 | |
6693 | 355 case NGX_STREAM_CONTENT_PHASE: |
356 ph->checker = ngx_stream_core_content_phase; | |
357 n++; | |
358 ph++; | |
359 | |
360 continue; | |
361 | |
362 default: | |
363 checker = ngx_stream_core_generic_phase; | |
364 } | |
365 | |
366 n += cmcf->phases[i].handlers.nelts; | |
367 | |
368 for (j = cmcf->phases[i].handlers.nelts - 1; j >= 0; j--) { | |
369 ph->checker = checker; | |
370 ph->handler = h[j]; | |
371 ph->next = n; | |
372 ph++; | |
373 } | |
374 } | |
375 | |
376 return NGX_OK; | |
377 } | |
378 | |
379 | |
380 static ngx_int_t | |
6115 | 381 ngx_stream_add_ports(ngx_conf_t *cf, ngx_array_t *ports, |
382 ngx_stream_listen_t *listen) | |
383 { | |
384 in_port_t p; | |
385 ngx_uint_t i; | |
386 struct sockaddr *sa; | |
387 ngx_stream_conf_port_t *port; | |
388 ngx_stream_conf_addr_t *addr; | |
389 | |
6560
c90cf79d0e1d
Renamed "u" to "sockaddr" in listen options types.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6436
diff
changeset
|
390 sa = &listen->sockaddr.sockaddr; |
6593
b3b7e33083ac
Introduced ngx_inet_get_port() and ngx_inet_set_port() functions.
Roman Arutyunyan <arut@nginx.com>
parents:
6560
diff
changeset
|
391 p = ngx_inet_get_port(sa); |
6115 | 392 |
393 port = ports->elts; | |
394 for (i = 0; i < ports->nelts; i++) { | |
395 | |
6436 | 396 if (p == port[i].port |
397 && listen->type == port[i].type | |
398 && sa->sa_family == port[i].family) | |
399 { | |
6115 | 400 /* a port is already in the port list */ |
401 | |
402 port = &port[i]; | |
403 goto found; | |
404 } | |
405 } | |
406 | |
407 /* add a port to the port list */ | |
408 | |
409 port = ngx_array_push(ports); | |
410 if (port == NULL) { | |
411 return NGX_ERROR; | |
412 } | |
413 | |
414 port->family = sa->sa_family; | |
6436 | 415 port->type = listen->type; |
6115 | 416 port->port = p; |
417 | |
418 if (ngx_array_init(&port->addrs, cf->temp_pool, 2, | |
419 sizeof(ngx_stream_conf_addr_t)) | |
420 != NGX_OK) | |
421 { | |
422 return NGX_ERROR; | |
423 } | |
424 | |
425 found: | |
426 | |
427 addr = ngx_array_push(&port->addrs); | |
428 if (addr == NULL) { | |
429 return NGX_ERROR; | |
430 } | |
431 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
432 addr->opt = *listen; |
6115 | 433 |
434 return NGX_OK; | |
435 } | |
436 | |
437 | |
438 static char * | |
439 ngx_stream_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports) | |
440 { | |
441 ngx_uint_t i, p, last, bind_wildcard; | |
442 ngx_listening_t *ls; | |
443 ngx_stream_port_t *stport; | |
444 ngx_stream_conf_port_t *port; | |
445 ngx_stream_conf_addr_t *addr; | |
446 ngx_stream_core_srv_conf_t *cscf; | |
447 | |
448 port = ports->elts; | |
449 for (p = 0; p < ports->nelts; p++) { | |
450 | |
451 ngx_sort(port[p].addrs.elts, (size_t) port[p].addrs.nelts, | |
452 sizeof(ngx_stream_conf_addr_t), ngx_stream_cmp_conf_addrs); | |
453 | |
454 addr = port[p].addrs.elts; | |
455 last = port[p].addrs.nelts; | |
456 | |
457 /* | |
458 * if there is the binding to the "*:port" then we need to bind() | |
459 * to the "*:port" only and ignore the other bindings | |
460 */ | |
461 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
462 if (addr[last - 1].opt.wildcard) { |
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
463 addr[last - 1].opt.bind = 1; |
6115 | 464 bind_wildcard = 1; |
465 | |
466 } else { | |
467 bind_wildcard = 0; | |
468 } | |
469 | |
470 i = 0; | |
471 | |
472 while (i < last) { | |
473 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
474 if (bind_wildcard && !addr[i].opt.bind) { |
6115 | 475 i++; |
476 continue; | |
477 } | |
478 | |
6560
c90cf79d0e1d
Renamed "u" to "sockaddr" in listen options types.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6436
diff
changeset
|
479 ls = ngx_create_listening(cf, &addr[i].opt.sockaddr.sockaddr, |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
480 addr[i].opt.socklen); |
6115 | 481 if (ls == NULL) { |
482 return NGX_CONF_ERROR; | |
483 } | |
484 | |
485 ls->addr_ntop = 1; | |
486 ls->handler = ngx_stream_init_connection; | |
487 ls->pool_size = 256; | |
6436 | 488 ls->type = addr[i].opt.type; |
6115 | 489 |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
490 cscf = addr->opt.ctx->srv_conf[ngx_stream_core_module.ctx_index]; |
6129
187aa751ad62
Core: the ngx_set_connection_log() macro.
Vladimir Homutov <vl@nginx.com>
parents:
6115
diff
changeset
|
491 |
6115 | 492 ls->logp = cscf->error_log; |
493 ls->log.data = &ls->addr_text; | |
494 ls->log.handler = ngx_accept_log_error; | |
495 | |
6172 | 496 ls->backlog = addr[i].opt.backlog; |
6975
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6736
diff
changeset
|
497 ls->rcvbuf = addr[i].opt.rcvbuf; |
d7ce41bdf050
Stream: configurable socket buffer sizes.
Vladimir Homutov <vl@nginx.com>
parents:
6736
diff
changeset
|
498 ls->sndbuf = addr[i].opt.sndbuf; |
6172 | 499 |
6436 | 500 ls->wildcard = addr[i].opt.wildcard; |
501 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
502 ls->keepalive = addr[i].opt.so_keepalive; |
6115 | 503 #if (NGX_HAVE_KEEPALIVE_TUNABLE) |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
504 ls->keepidle = addr[i].opt.tcp_keepidle; |
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
505 ls->keepintvl = addr[i].opt.tcp_keepintvl; |
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
506 ls->keepcnt = addr[i].opt.tcp_keepcnt; |
6115 | 507 #endif |
508 | |
6719
cebf5fed00bf
Modules compatibility: removed unneeded IPV6_V6ONLY checks.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6694
diff
changeset
|
509 #if (NGX_HAVE_INET6) |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
510 ls->ipv6only = addr[i].opt.ipv6only; |
6115 | 511 #endif |
512 | |
6169
f654addf0eea
Stream: fixed "reuseport" to actually work.
Ruslan Ermilov <ru@nginx.com>
parents:
6153
diff
changeset
|
513 #if (NGX_HAVE_REUSEPORT) |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
514 ls->reuseport = addr[i].opt.reuseport; |
6169
f654addf0eea
Stream: fixed "reuseport" to actually work.
Ruslan Ermilov <ru@nginx.com>
parents:
6153
diff
changeset
|
515 #endif |
f654addf0eea
Stream: fixed "reuseport" to actually work.
Ruslan Ermilov <ru@nginx.com>
parents:
6153
diff
changeset
|
516 |
6115 | 517 stport = ngx_palloc(cf->pool, sizeof(ngx_stream_port_t)); |
518 if (stport == NULL) { | |
519 return NGX_CONF_ERROR; | |
520 } | |
521 | |
522 ls->servers = stport; | |
523 | |
6152
3c344ea7d88b
Simplified ngx_http_init_listening().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6129
diff
changeset
|
524 stport->naddrs = i + 1; |
6115 | 525 |
526 switch (ls->sockaddr->sa_family) { | |
527 #if (NGX_HAVE_INET6) | |
528 case AF_INET6: | |
529 if (ngx_stream_add_addrs6(cf, stport, addr) != NGX_OK) { | |
530 return NGX_CONF_ERROR; | |
531 } | |
532 break; | |
533 #endif | |
534 default: /* AF_INET */ | |
535 if (ngx_stream_add_addrs(cf, stport, addr) != NGX_OK) { | |
536 return NGX_CONF_ERROR; | |
537 } | |
538 break; | |
539 } | |
540 | |
6153
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6152
diff
changeset
|
541 if (ngx_clone_listening(cf, ls) != NGX_OK) { |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6152
diff
changeset
|
542 return NGX_CONF_ERROR; |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6152
diff
changeset
|
543 } |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6152
diff
changeset
|
544 |
6115 | 545 addr++; |
546 last--; | |
547 } | |
548 } | |
549 | |
550 return NGX_CONF_OK; | |
551 } | |
552 | |
553 | |
554 static ngx_int_t | |
555 ngx_stream_add_addrs(ngx_conf_t *cf, ngx_stream_port_t *stport, | |
556 ngx_stream_conf_addr_t *addr) | |
557 { | |
558 u_char *p; | |
559 size_t len; | |
560 ngx_uint_t i; | |
561 struct sockaddr_in *sin; | |
562 ngx_stream_in_addr_t *addrs; | |
563 u_char buf[NGX_SOCKADDR_STRLEN]; | |
564 | |
565 stport->addrs = ngx_pcalloc(cf->pool, | |
566 stport->naddrs * sizeof(ngx_stream_in_addr_t)); | |
567 if (stport->addrs == NULL) { | |
568 return NGX_ERROR; | |
569 } | |
570 | |
571 addrs = stport->addrs; | |
572 | |
573 for (i = 0; i < stport->naddrs; i++) { | |
574 | |
6560
c90cf79d0e1d
Renamed "u" to "sockaddr" in listen options types.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6436
diff
changeset
|
575 sin = &addr[i].opt.sockaddr.sockaddr_in; |
6115 | 576 addrs[i].addr = sin->sin_addr.s_addr; |
577 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
578 addrs[i].conf.ctx = addr[i].opt.ctx; |
6115 | 579 #if (NGX_STREAM_SSL) |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
580 addrs[i].conf.ssl = addr[i].opt.ssl; |
6115 | 581 #endif |
6680
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6607
diff
changeset
|
582 addrs[i].conf.proxy_protocol = addr[i].opt.proxy_protocol; |
6115 | 583 |
6560
c90cf79d0e1d
Renamed "u" to "sockaddr" in listen options types.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6436
diff
changeset
|
584 len = ngx_sock_ntop(&addr[i].opt.sockaddr.sockaddr, addr[i].opt.socklen, |
c90cf79d0e1d
Renamed "u" to "sockaddr" in listen options types.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6436
diff
changeset
|
585 buf, NGX_SOCKADDR_STRLEN, 1); |
6115 | 586 |
587 p = ngx_pnalloc(cf->pool, len); | |
588 if (p == NULL) { | |
589 return NGX_ERROR; | |
590 } | |
591 | |
592 ngx_memcpy(p, buf, len); | |
593 | |
594 addrs[i].conf.addr_text.len = len; | |
595 addrs[i].conf.addr_text.data = p; | |
596 } | |
597 | |
598 return NGX_OK; | |
599 } | |
600 | |
601 | |
602 #if (NGX_HAVE_INET6) | |
603 | |
604 static ngx_int_t | |
605 ngx_stream_add_addrs6(ngx_conf_t *cf, ngx_stream_port_t *stport, | |
606 ngx_stream_conf_addr_t *addr) | |
607 { | |
608 u_char *p; | |
609 size_t len; | |
610 ngx_uint_t i; | |
611 struct sockaddr_in6 *sin6; | |
612 ngx_stream_in6_addr_t *addrs6; | |
613 u_char buf[NGX_SOCKADDR_STRLEN]; | |
614 | |
615 stport->addrs = ngx_pcalloc(cf->pool, | |
616 stport->naddrs * sizeof(ngx_stream_in6_addr_t)); | |
617 if (stport->addrs == NULL) { | |
618 return NGX_ERROR; | |
619 } | |
620 | |
621 addrs6 = stport->addrs; | |
622 | |
623 for (i = 0; i < stport->naddrs; i++) { | |
624 | |
6560
c90cf79d0e1d
Renamed "u" to "sockaddr" in listen options types.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6436
diff
changeset
|
625 sin6 = &addr[i].opt.sockaddr.sockaddr_in6; |
6115 | 626 addrs6[i].addr6 = sin6->sin6_addr; |
627 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
628 addrs6[i].conf.ctx = addr[i].opt.ctx; |
6115 | 629 #if (NGX_STREAM_SSL) |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
630 addrs6[i].conf.ssl = addr[i].opt.ssl; |
6115 | 631 #endif |
6680
7357abd1fa8c
Stream: the "proxy_protocol" parameter of the "listen" directive.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6607
diff
changeset
|
632 addrs6[i].conf.proxy_protocol = addr[i].opt.proxy_protocol; |
6115 | 633 |
6560
c90cf79d0e1d
Renamed "u" to "sockaddr" in listen options types.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6436
diff
changeset
|
634 len = ngx_sock_ntop(&addr[i].opt.sockaddr.sockaddr, addr[i].opt.socklen, |
c90cf79d0e1d
Renamed "u" to "sockaddr" in listen options types.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6436
diff
changeset
|
635 buf, NGX_SOCKADDR_STRLEN, 1); |
6115 | 636 |
637 p = ngx_pnalloc(cf->pool, len); | |
638 if (p == NULL) { | |
639 return NGX_ERROR; | |
640 } | |
641 | |
642 ngx_memcpy(p, buf, len); | |
643 | |
644 addrs6[i].conf.addr_text.len = len; | |
645 addrs6[i].conf.addr_text.data = p; | |
646 } | |
647 | |
648 return NGX_OK; | |
649 } | |
650 | |
651 #endif | |
652 | |
653 | |
654 static ngx_int_t | |
655 ngx_stream_cmp_conf_addrs(const void *one, const void *two) | |
656 { | |
657 ngx_stream_conf_addr_t *first, *second; | |
658 | |
659 first = (ngx_stream_conf_addr_t *) one; | |
660 second = (ngx_stream_conf_addr_t *) two; | |
661 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
662 if (first->opt.wildcard) { |
6115 | 663 /* a wildcard must be the last resort, shift it to the end */ |
664 return 1; | |
665 } | |
666 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
667 if (second->opt.wildcard) { |
6115 | 668 /* a wildcard must be the last resort, shift it to the end */ |
669 return -1; | |
670 } | |
671 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
672 if (first->opt.bind && !second->opt.bind) { |
6115 | 673 /* shift explicit bind()ed addresses to the start */ |
674 return -1; | |
675 } | |
676 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
677 if (!first->opt.bind && second->opt.bind) { |
6115 | 678 /* shift explicit bind()ed addresses to the start */ |
679 return 1; | |
680 } | |
681 | |
682 /* do not sort by default */ | |
683 | |
684 return 0; | |
685 } |