Mercurial > hg > nginx-quic
annotate src/stream/ngx_stream.c @ 6603:9eefb38f0005
Internal md5 and sha1 implementations are now always used.
This reduces the number of moving parts in ABI compatibility checks.
Additionally, it also allows to use OpenSSL in FIPS mode while still
using md5 for non-security tasks.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 30 Jun 2016 18:57:39 +0300 |
parents | b3b7e33083ac |
children | 2f41d383c9c7 |
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); | |
15 static ngx_int_t ngx_stream_add_ports(ngx_conf_t *cf, ngx_array_t *ports, | |
16 ngx_stream_listen_t *listen); | |
17 static char *ngx_stream_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports); | |
18 static ngx_int_t ngx_stream_add_addrs(ngx_conf_t *cf, ngx_stream_port_t *stport, | |
19 ngx_stream_conf_addr_t *addr); | |
20 #if (NGX_HAVE_INET6) | |
21 static ngx_int_t ngx_stream_add_addrs6(ngx_conf_t *cf, | |
22 ngx_stream_port_t *stport, ngx_stream_conf_addr_t *addr); | |
23 #endif | |
24 static ngx_int_t ngx_stream_cmp_conf_addrs(const void *one, const void *two); | |
25 | |
26 | |
27 ngx_uint_t ngx_stream_max_module; | |
28 | |
29 | |
30 static ngx_command_t ngx_stream_commands[] = { | |
31 | |
32 { ngx_string("stream"), | |
33 NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, | |
34 ngx_stream_block, | |
35 0, | |
36 0, | |
37 NULL }, | |
38 | |
39 ngx_null_command | |
40 }; | |
41 | |
42 | |
43 static ngx_core_module_t ngx_stream_module_ctx = { | |
44 ngx_string("stream"), | |
45 NULL, | |
46 NULL | |
47 }; | |
48 | |
49 | |
50 ngx_module_t ngx_stream_module = { | |
51 NGX_MODULE_V1, | |
52 &ngx_stream_module_ctx, /* module context */ | |
53 ngx_stream_commands, /* module directives */ | |
54 NGX_CORE_MODULE, /* module type */ | |
55 NULL, /* init master */ | |
56 NULL, /* init module */ | |
57 NULL, /* init process */ | |
58 NULL, /* init thread */ | |
59 NULL, /* exit thread */ | |
60 NULL, /* exit process */ | |
61 NULL, /* exit master */ | |
62 NGX_MODULE_V1_PADDING | |
63 }; | |
64 | |
65 | |
66 static char * | |
67 ngx_stream_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
68 { | |
69 char *rv; | |
70 ngx_uint_t i, m, mi, s; | |
71 ngx_conf_t pcf; | |
72 ngx_array_t ports; | |
73 ngx_stream_listen_t *listen; | |
74 ngx_stream_module_t *module; | |
75 ngx_stream_conf_ctx_t *ctx; | |
76 ngx_stream_core_srv_conf_t **cscfp; | |
77 ngx_stream_core_main_conf_t *cmcf; | |
78 | |
6193
78c06e5e1d76
Disabled duplicate http, mail, and stream blocks.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
79 if (*(ngx_stream_conf_ctx_t **) conf) { |
78c06e5e1d76
Disabled duplicate http, mail, and stream blocks.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
80 return "is duplicate"; |
78c06e5e1d76
Disabled duplicate http, mail, and stream blocks.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
81 } |
78c06e5e1d76
Disabled duplicate http, mail, and stream blocks.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
82 |
6115 | 83 /* the main stream context */ |
84 | |
85 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_stream_conf_ctx_t)); | |
86 if (ctx == NULL) { | |
87 return NGX_CONF_ERROR; | |
88 } | |
89 | |
90 *(ngx_stream_conf_ctx_t **) conf = ctx; | |
91 | |
92 /* count the number of the stream modules and set up their indices */ | |
93 | |
6378
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6193
diff
changeset
|
94 ngx_stream_max_module = ngx_count_modules(cf->cycle, NGX_STREAM_MODULE); |
6115 | 95 |
96 | |
97 /* the stream main_conf context, it's the same in the all stream contexts */ | |
98 | |
99 ctx->main_conf = ngx_pcalloc(cf->pool, | |
100 sizeof(void *) * ngx_stream_max_module); | |
101 if (ctx->main_conf == NULL) { | |
102 return NGX_CONF_ERROR; | |
103 } | |
104 | |
105 | |
106 /* | |
107 * the stream null srv_conf context, it is used to merge | |
108 * the server{}s' srv_conf's | |
109 */ | |
110 | |
111 ctx->srv_conf = ngx_pcalloc(cf->pool, | |
112 sizeof(void *) * ngx_stream_max_module); | |
113 if (ctx->srv_conf == NULL) { | |
114 return NGX_CONF_ERROR; | |
115 } | |
116 | |
117 | |
118 /* | |
119 * create the main_conf's and the null srv_conf's of the all stream modules | |
120 */ | |
121 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6378
diff
changeset
|
122 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
|
123 if (cf->cycle->modules[m]->type != NGX_STREAM_MODULE) { |
6115 | 124 continue; |
125 } | |
126 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6378
diff
changeset
|
127 module = cf->cycle->modules[m]->ctx; |
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6378
diff
changeset
|
128 mi = cf->cycle->modules[m]->ctx_index; |
6115 | 129 |
130 if (module->create_main_conf) { | |
131 ctx->main_conf[mi] = module->create_main_conf(cf); | |
132 if (ctx->main_conf[mi] == NULL) { | |
133 return NGX_CONF_ERROR; | |
134 } | |
135 } | |
136 | |
137 if (module->create_srv_conf) { | |
138 ctx->srv_conf[mi] = module->create_srv_conf(cf); | |
139 if (ctx->srv_conf[mi] == NULL) { | |
140 return NGX_CONF_ERROR; | |
141 } | |
142 } | |
143 } | |
144 | |
145 | |
146 /* parse inside the stream{} block */ | |
147 | |
148 pcf = *cf; | |
149 cf->ctx = ctx; | |
150 | |
151 cf->module_type = NGX_STREAM_MODULE; | |
152 cf->cmd_type = NGX_STREAM_MAIN_CONF; | |
153 rv = ngx_conf_parse(cf, NULL); | |
154 | |
155 if (rv != NGX_CONF_OK) { | |
156 *cf = pcf; | |
157 return rv; | |
158 } | |
159 | |
160 | |
161 /* init stream{} main_conf's, merge the server{}s' srv_conf's */ | |
162 | |
163 cmcf = ctx->main_conf[ngx_stream_core_module.ctx_index]; | |
164 cscfp = cmcf->servers.elts; | |
165 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6378
diff
changeset
|
166 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
|
167 if (cf->cycle->modules[m]->type != NGX_STREAM_MODULE) { |
6115 | 168 continue; |
169 } | |
170 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6378
diff
changeset
|
171 module = cf->cycle->modules[m]->ctx; |
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6378
diff
changeset
|
172 mi = cf->cycle->modules[m]->ctx_index; |
6115 | 173 |
174 /* init stream{} main_conf's */ | |
175 | |
176 cf->ctx = ctx; | |
177 | |
178 if (module->init_main_conf) { | |
179 rv = module->init_main_conf(cf, ctx->main_conf[mi]); | |
180 if (rv != NGX_CONF_OK) { | |
181 *cf = pcf; | |
182 return rv; | |
183 } | |
184 } | |
185 | |
186 for (s = 0; s < cmcf->servers.nelts; s++) { | |
187 | |
188 /* merge the server{}s' srv_conf's */ | |
189 | |
190 cf->ctx = cscfp[s]->ctx; | |
191 | |
192 if (module->merge_srv_conf) { | |
193 rv = module->merge_srv_conf(cf, | |
194 ctx->srv_conf[mi], | |
195 cscfp[s]->ctx->srv_conf[mi]); | |
196 if (rv != NGX_CONF_OK) { | |
197 *cf = pcf; | |
198 return rv; | |
199 } | |
200 } | |
201 } | |
202 } | |
203 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6378
diff
changeset
|
204 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
|
205 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
|
206 continue; |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
207 } |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
208 |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6378
diff
changeset
|
209 module = cf->cycle->modules[m]->ctx; |
6174
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
210 |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
211 if (module->postconfiguration) { |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
212 if (module->postconfiguration(cf) != NGX_OK) { |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
213 return NGX_CONF_ERROR; |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
214 } |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
215 } |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
216 } |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
217 |
6115 | 218 *cf = pcf; |
219 | |
220 | |
221 if (ngx_array_init(&ports, cf->temp_pool, 4, sizeof(ngx_stream_conf_port_t)) | |
222 != NGX_OK) | |
223 { | |
224 return NGX_CONF_ERROR; | |
225 } | |
226 | |
227 listen = cmcf->listen.elts; | |
228 | |
229 for (i = 0; i < cmcf->listen.nelts; i++) { | |
230 if (ngx_stream_add_ports(cf, &ports, &listen[i]) != NGX_OK) { | |
231 return NGX_CONF_ERROR; | |
232 } | |
233 } | |
234 | |
235 return ngx_stream_optimize_servers(cf, &ports); | |
236 } | |
237 | |
238 | |
239 static ngx_int_t | |
240 ngx_stream_add_ports(ngx_conf_t *cf, ngx_array_t *ports, | |
241 ngx_stream_listen_t *listen) | |
242 { | |
243 in_port_t p; | |
244 ngx_uint_t i; | |
245 struct sockaddr *sa; | |
246 ngx_stream_conf_port_t *port; | |
247 ngx_stream_conf_addr_t *addr; | |
248 | |
6560
c90cf79d0e1d
Renamed "u" to "sockaddr" in listen options types.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6436
diff
changeset
|
249 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
|
250 p = ngx_inet_get_port(sa); |
6115 | 251 |
252 port = ports->elts; | |
253 for (i = 0; i < ports->nelts; i++) { | |
254 | |
6436 | 255 if (p == port[i].port |
256 && listen->type == port[i].type | |
257 && sa->sa_family == port[i].family) | |
258 { | |
6115 | 259 /* a port is already in the port list */ |
260 | |
261 port = &port[i]; | |
262 goto found; | |
263 } | |
264 } | |
265 | |
266 /* add a port to the port list */ | |
267 | |
268 port = ngx_array_push(ports); | |
269 if (port == NULL) { | |
270 return NGX_ERROR; | |
271 } | |
272 | |
273 port->family = sa->sa_family; | |
6436 | 274 port->type = listen->type; |
6115 | 275 port->port = p; |
276 | |
277 if (ngx_array_init(&port->addrs, cf->temp_pool, 2, | |
278 sizeof(ngx_stream_conf_addr_t)) | |
279 != NGX_OK) | |
280 { | |
281 return NGX_ERROR; | |
282 } | |
283 | |
284 found: | |
285 | |
286 addr = ngx_array_push(&port->addrs); | |
287 if (addr == NULL) { | |
288 return NGX_ERROR; | |
289 } | |
290 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
291 addr->opt = *listen; |
6115 | 292 |
293 return NGX_OK; | |
294 } | |
295 | |
296 | |
297 static char * | |
298 ngx_stream_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports) | |
299 { | |
300 ngx_uint_t i, p, last, bind_wildcard; | |
301 ngx_listening_t *ls; | |
302 ngx_stream_port_t *stport; | |
303 ngx_stream_conf_port_t *port; | |
304 ngx_stream_conf_addr_t *addr; | |
305 ngx_stream_core_srv_conf_t *cscf; | |
306 | |
307 port = ports->elts; | |
308 for (p = 0; p < ports->nelts; p++) { | |
309 | |
310 ngx_sort(port[p].addrs.elts, (size_t) port[p].addrs.nelts, | |
311 sizeof(ngx_stream_conf_addr_t), ngx_stream_cmp_conf_addrs); | |
312 | |
313 addr = port[p].addrs.elts; | |
314 last = port[p].addrs.nelts; | |
315 | |
316 /* | |
317 * if there is the binding to the "*:port" then we need to bind() | |
318 * to the "*:port" only and ignore the other bindings | |
319 */ | |
320 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
321 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
|
322 addr[last - 1].opt.bind = 1; |
6115 | 323 bind_wildcard = 1; |
324 | |
325 } else { | |
326 bind_wildcard = 0; | |
327 } | |
328 | |
329 i = 0; | |
330 | |
331 while (i < last) { | |
332 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
333 if (bind_wildcard && !addr[i].opt.bind) { |
6115 | 334 i++; |
335 continue; | |
336 } | |
337 | |
6560
c90cf79d0e1d
Renamed "u" to "sockaddr" in listen options types.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6436
diff
changeset
|
338 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
|
339 addr[i].opt.socklen); |
6115 | 340 if (ls == NULL) { |
341 return NGX_CONF_ERROR; | |
342 } | |
343 | |
344 ls->addr_ntop = 1; | |
345 ls->handler = ngx_stream_init_connection; | |
346 ls->pool_size = 256; | |
6436 | 347 ls->type = addr[i].opt.type; |
6115 | 348 |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
349 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
|
350 |
6115 | 351 ls->logp = cscf->error_log; |
352 ls->log.data = &ls->addr_text; | |
353 ls->log.handler = ngx_accept_log_error; | |
354 | |
6172 | 355 ls->backlog = addr[i].opt.backlog; |
356 | |
6436 | 357 ls->wildcard = addr[i].opt.wildcard; |
358 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
359 ls->keepalive = addr[i].opt.so_keepalive; |
6115 | 360 #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
|
361 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
|
362 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
|
363 ls->keepcnt = addr[i].opt.tcp_keepcnt; |
6115 | 364 #endif |
365 | |
366 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
367 ls->ipv6only = addr[i].opt.ipv6only; |
6115 | 368 #endif |
369 | |
6169
f654addf0eea
Stream: fixed "reuseport" to actually work.
Ruslan Ermilov <ru@nginx.com>
parents:
6153
diff
changeset
|
370 #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
|
371 ls->reuseport = addr[i].opt.reuseport; |
6169
f654addf0eea
Stream: fixed "reuseport" to actually work.
Ruslan Ermilov <ru@nginx.com>
parents:
6153
diff
changeset
|
372 #endif |
f654addf0eea
Stream: fixed "reuseport" to actually work.
Ruslan Ermilov <ru@nginx.com>
parents:
6153
diff
changeset
|
373 |
6115 | 374 stport = ngx_palloc(cf->pool, sizeof(ngx_stream_port_t)); |
375 if (stport == NULL) { | |
376 return NGX_CONF_ERROR; | |
377 } | |
378 | |
379 ls->servers = stport; | |
380 | |
6152
3c344ea7d88b
Simplified ngx_http_init_listening().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6129
diff
changeset
|
381 stport->naddrs = i + 1; |
6115 | 382 |
383 switch (ls->sockaddr->sa_family) { | |
384 #if (NGX_HAVE_INET6) | |
385 case AF_INET6: | |
386 if (ngx_stream_add_addrs6(cf, stport, addr) != NGX_OK) { | |
387 return NGX_CONF_ERROR; | |
388 } | |
389 break; | |
390 #endif | |
391 default: /* AF_INET */ | |
392 if (ngx_stream_add_addrs(cf, stport, addr) != NGX_OK) { | |
393 return NGX_CONF_ERROR; | |
394 } | |
395 break; | |
396 } | |
397 | |
6153
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6152
diff
changeset
|
398 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
|
399 return NGX_CONF_ERROR; |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6152
diff
changeset
|
400 } |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6152
diff
changeset
|
401 |
6115 | 402 addr++; |
403 last--; | |
404 } | |
405 } | |
406 | |
407 return NGX_CONF_OK; | |
408 } | |
409 | |
410 | |
411 static ngx_int_t | |
412 ngx_stream_add_addrs(ngx_conf_t *cf, ngx_stream_port_t *stport, | |
413 ngx_stream_conf_addr_t *addr) | |
414 { | |
415 u_char *p; | |
416 size_t len; | |
417 ngx_uint_t i; | |
418 struct sockaddr_in *sin; | |
419 ngx_stream_in_addr_t *addrs; | |
420 u_char buf[NGX_SOCKADDR_STRLEN]; | |
421 | |
422 stport->addrs = ngx_pcalloc(cf->pool, | |
423 stport->naddrs * sizeof(ngx_stream_in_addr_t)); | |
424 if (stport->addrs == NULL) { | |
425 return NGX_ERROR; | |
426 } | |
427 | |
428 addrs = stport->addrs; | |
429 | |
430 for (i = 0; i < stport->naddrs; i++) { | |
431 | |
6560
c90cf79d0e1d
Renamed "u" to "sockaddr" in listen options types.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6436
diff
changeset
|
432 sin = &addr[i].opt.sockaddr.sockaddr_in; |
6115 | 433 addrs[i].addr = sin->sin_addr.s_addr; |
434 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
435 addrs[i].conf.ctx = addr[i].opt.ctx; |
6115 | 436 #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
|
437 addrs[i].conf.ssl = addr[i].opt.ssl; |
6115 | 438 #endif |
439 | |
6560
c90cf79d0e1d
Renamed "u" to "sockaddr" in listen options types.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6436
diff
changeset
|
440 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
|
441 buf, NGX_SOCKADDR_STRLEN, 1); |
6115 | 442 |
443 p = ngx_pnalloc(cf->pool, len); | |
444 if (p == NULL) { | |
445 return NGX_ERROR; | |
446 } | |
447 | |
448 ngx_memcpy(p, buf, len); | |
449 | |
450 addrs[i].conf.addr_text.len = len; | |
451 addrs[i].conf.addr_text.data = p; | |
452 } | |
453 | |
454 return NGX_OK; | |
455 } | |
456 | |
457 | |
458 #if (NGX_HAVE_INET6) | |
459 | |
460 static ngx_int_t | |
461 ngx_stream_add_addrs6(ngx_conf_t *cf, ngx_stream_port_t *stport, | |
462 ngx_stream_conf_addr_t *addr) | |
463 { | |
464 u_char *p; | |
465 size_t len; | |
466 ngx_uint_t i; | |
467 struct sockaddr_in6 *sin6; | |
468 ngx_stream_in6_addr_t *addrs6; | |
469 u_char buf[NGX_SOCKADDR_STRLEN]; | |
470 | |
471 stport->addrs = ngx_pcalloc(cf->pool, | |
472 stport->naddrs * sizeof(ngx_stream_in6_addr_t)); | |
473 if (stport->addrs == NULL) { | |
474 return NGX_ERROR; | |
475 } | |
476 | |
477 addrs6 = stport->addrs; | |
478 | |
479 for (i = 0; i < stport->naddrs; i++) { | |
480 | |
6560
c90cf79d0e1d
Renamed "u" to "sockaddr" in listen options types.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6436
diff
changeset
|
481 sin6 = &addr[i].opt.sockaddr.sockaddr_in6; |
6115 | 482 addrs6[i].addr6 = sin6->sin6_addr; |
483 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
484 addrs6[i].conf.ctx = addr[i].opt.ctx; |
6115 | 485 #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
|
486 addrs6[i].conf.ssl = addr[i].opt.ssl; |
6115 | 487 #endif |
488 | |
6560
c90cf79d0e1d
Renamed "u" to "sockaddr" in listen options types.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6436
diff
changeset
|
489 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
|
490 buf, NGX_SOCKADDR_STRLEN, 1); |
6115 | 491 |
492 p = ngx_pnalloc(cf->pool, len); | |
493 if (p == NULL) { | |
494 return NGX_ERROR; | |
495 } | |
496 | |
497 ngx_memcpy(p, buf, len); | |
498 | |
499 addrs6[i].conf.addr_text.len = len; | |
500 addrs6[i].conf.addr_text.data = p; | |
501 } | |
502 | |
503 return NGX_OK; | |
504 } | |
505 | |
506 #endif | |
507 | |
508 | |
509 static ngx_int_t | |
510 ngx_stream_cmp_conf_addrs(const void *one, const void *two) | |
511 { | |
512 ngx_stream_conf_addr_t *first, *second; | |
513 | |
514 first = (ngx_stream_conf_addr_t *) one; | |
515 second = (ngx_stream_conf_addr_t *) two; | |
516 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
517 if (first->opt.wildcard) { |
6115 | 518 /* a wildcard must be the last resort, shift it to the end */ |
519 return 1; | |
520 } | |
521 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
522 if (second->opt.wildcard) { |
6115 | 523 /* a wildcard must be the last resort, shift it to the end */ |
524 return -1; | |
525 } | |
526 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
527 if (first->opt.bind && !second->opt.bind) { |
6115 | 528 /* shift explicit bind()ed addresses to the start */ |
529 return -1; | |
530 } | |
531 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
532 if (!first->opt.bind && second->opt.bind) { |
6115 | 533 /* shift explicit bind()ed addresses to the start */ |
534 return 1; | |
535 } | |
536 | |
537 /* do not sort by default */ | |
538 | |
539 return 0; | |
540 } |