Mercurial > hg > nginx
annotate src/stream/ngx_stream.c @ 6230:2a621245f4cf
Win32: MSVC 2015 compatibility.
Resolved warnings about declarations that hide previous local declarations.
Warnings about WSASocketA() being deprecated resolved by explicit use of
WSASocketW() instead of WSASocket(). When compiling without IPv6 support,
WinSock deprecated warnings are disabled to allow use of gethostbyname().
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 17 Aug 2015 18:09:17 +0300 |
parents | 78c06e5e1d76 |
children | 0f203a2af17c |
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 | |
94 ngx_stream_max_module = 0; | |
95 for (m = 0; ngx_modules[m]; m++) { | |
96 if (ngx_modules[m]->type != NGX_STREAM_MODULE) { | |
97 continue; | |
98 } | |
99 | |
100 ngx_modules[m]->ctx_index = ngx_stream_max_module++; | |
101 } | |
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 | |
129 for (m = 0; ngx_modules[m]; m++) { | |
130 if (ngx_modules[m]->type != NGX_STREAM_MODULE) { | |
131 continue; | |
132 } | |
133 | |
134 module = ngx_modules[m]->ctx; | |
135 mi = ngx_modules[m]->ctx_index; | |
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 /* parse inside the stream{} block */ | |
154 | |
155 pcf = *cf; | |
156 cf->ctx = ctx; | |
157 | |
158 cf->module_type = NGX_STREAM_MODULE; | |
159 cf->cmd_type = NGX_STREAM_MAIN_CONF; | |
160 rv = ngx_conf_parse(cf, NULL); | |
161 | |
162 if (rv != NGX_CONF_OK) { | |
163 *cf = pcf; | |
164 return rv; | |
165 } | |
166 | |
167 | |
168 /* init stream{} main_conf's, merge the server{}s' srv_conf's */ | |
169 | |
170 cmcf = ctx->main_conf[ngx_stream_core_module.ctx_index]; | |
171 cscfp = cmcf->servers.elts; | |
172 | |
173 for (m = 0; ngx_modules[m]; m++) { | |
174 if (ngx_modules[m]->type != NGX_STREAM_MODULE) { | |
175 continue; | |
176 } | |
177 | |
178 module = ngx_modules[m]->ctx; | |
179 mi = ngx_modules[m]->ctx_index; | |
180 | |
181 /* init stream{} main_conf's */ | |
182 | |
183 cf->ctx = ctx; | |
184 | |
185 if (module->init_main_conf) { | |
186 rv = module->init_main_conf(cf, ctx->main_conf[mi]); | |
187 if (rv != NGX_CONF_OK) { | |
188 *cf = pcf; | |
189 return rv; | |
190 } | |
191 } | |
192 | |
193 for (s = 0; s < cmcf->servers.nelts; s++) { | |
194 | |
195 /* merge the server{}s' srv_conf's */ | |
196 | |
197 cf->ctx = cscfp[s]->ctx; | |
198 | |
199 if (module->merge_srv_conf) { | |
200 rv = module->merge_srv_conf(cf, | |
201 ctx->srv_conf[mi], | |
202 cscfp[s]->ctx->srv_conf[mi]); | |
203 if (rv != NGX_CONF_OK) { | |
204 *cf = pcf; | |
205 return rv; | |
206 } | |
207 } | |
208 } | |
209 } | |
210 | |
6174
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
211 for (m = 0; ngx_modules[m]; m++) { |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
212 if (ngx_modules[m]->type != NGX_STREAM_MODULE) { |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
213 continue; |
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 module = ngx_modules[m]->ctx; |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
217 |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
218 if (module->postconfiguration) { |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
219 if (module->postconfiguration(cf) != NGX_OK) { |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
220 return NGX_CONF_ERROR; |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
221 } |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
222 } |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
223 } |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
224 |
6115 | 225 *cf = pcf; |
226 | |
227 | |
228 if (ngx_array_init(&ports, cf->temp_pool, 4, sizeof(ngx_stream_conf_port_t)) | |
229 != NGX_OK) | |
230 { | |
231 return NGX_CONF_ERROR; | |
232 } | |
233 | |
234 listen = cmcf->listen.elts; | |
235 | |
236 for (i = 0; i < cmcf->listen.nelts; i++) { | |
237 if (ngx_stream_add_ports(cf, &ports, &listen[i]) != NGX_OK) { | |
238 return NGX_CONF_ERROR; | |
239 } | |
240 } | |
241 | |
242 return ngx_stream_optimize_servers(cf, &ports); | |
243 } | |
244 | |
245 | |
246 static ngx_int_t | |
247 ngx_stream_add_ports(ngx_conf_t *cf, ngx_array_t *ports, | |
248 ngx_stream_listen_t *listen) | |
249 { | |
250 in_port_t p; | |
251 ngx_uint_t i; | |
252 struct sockaddr *sa; | |
253 struct sockaddr_in *sin; | |
254 ngx_stream_conf_port_t *port; | |
255 ngx_stream_conf_addr_t *addr; | |
256 #if (NGX_HAVE_INET6) | |
257 struct sockaddr_in6 *sin6; | |
258 #endif | |
259 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
260 sa = &listen->u.sockaddr; |
6115 | 261 |
262 switch (sa->sa_family) { | |
263 | |
264 #if (NGX_HAVE_INET6) | |
265 case AF_INET6: | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
266 sin6 = &listen->u.sockaddr_in6; |
6115 | 267 p = sin6->sin6_port; |
268 break; | |
269 #endif | |
270 | |
271 #if (NGX_HAVE_UNIX_DOMAIN) | |
272 case AF_UNIX: | |
273 p = 0; | |
274 break; | |
275 #endif | |
276 | |
277 default: /* AF_INET */ | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
278 sin = &listen->u.sockaddr_in; |
6115 | 279 p = sin->sin_port; |
280 break; | |
281 } | |
282 | |
283 port = ports->elts; | |
284 for (i = 0; i < ports->nelts; i++) { | |
285 if (p == port[i].port && sa->sa_family == port[i].family) { | |
286 | |
287 /* a port is already in the port list */ | |
288 | |
289 port = &port[i]; | |
290 goto found; | |
291 } | |
292 } | |
293 | |
294 /* add a port to the port list */ | |
295 | |
296 port = ngx_array_push(ports); | |
297 if (port == NULL) { | |
298 return NGX_ERROR; | |
299 } | |
300 | |
301 port->family = sa->sa_family; | |
302 port->port = p; | |
303 | |
304 if (ngx_array_init(&port->addrs, cf->temp_pool, 2, | |
305 sizeof(ngx_stream_conf_addr_t)) | |
306 != NGX_OK) | |
307 { | |
308 return NGX_ERROR; | |
309 } | |
310 | |
311 found: | |
312 | |
313 addr = ngx_array_push(&port->addrs); | |
314 if (addr == NULL) { | |
315 return NGX_ERROR; | |
316 } | |
317 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
318 addr->opt = *listen; |
6115 | 319 |
320 return NGX_OK; | |
321 } | |
322 | |
323 | |
324 static char * | |
325 ngx_stream_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports) | |
326 { | |
327 ngx_uint_t i, p, last, bind_wildcard; | |
328 ngx_listening_t *ls; | |
329 ngx_stream_port_t *stport; | |
330 ngx_stream_conf_port_t *port; | |
331 ngx_stream_conf_addr_t *addr; | |
332 ngx_stream_core_srv_conf_t *cscf; | |
333 | |
334 port = ports->elts; | |
335 for (p = 0; p < ports->nelts; p++) { | |
336 | |
337 ngx_sort(port[p].addrs.elts, (size_t) port[p].addrs.nelts, | |
338 sizeof(ngx_stream_conf_addr_t), ngx_stream_cmp_conf_addrs); | |
339 | |
340 addr = port[p].addrs.elts; | |
341 last = port[p].addrs.nelts; | |
342 | |
343 /* | |
344 * if there is the binding to the "*:port" then we need to bind() | |
345 * to the "*:port" only and ignore the other bindings | |
346 */ | |
347 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
348 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
|
349 addr[last - 1].opt.bind = 1; |
6115 | 350 bind_wildcard = 1; |
351 | |
352 } else { | |
353 bind_wildcard = 0; | |
354 } | |
355 | |
356 i = 0; | |
357 | |
358 while (i < last) { | |
359 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
360 if (bind_wildcard && !addr[i].opt.bind) { |
6115 | 361 i++; |
362 continue; | |
363 } | |
364 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
365 ls = ngx_create_listening(cf, &addr[i].opt.u.sockaddr, |
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
366 addr[i].opt.socklen); |
6115 | 367 if (ls == NULL) { |
368 return NGX_CONF_ERROR; | |
369 } | |
370 | |
371 ls->addr_ntop = 1; | |
372 ls->handler = ngx_stream_init_connection; | |
373 ls->pool_size = 256; | |
374 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
375 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
|
376 |
6115 | 377 ls->logp = cscf->error_log; |
378 ls->log.data = &ls->addr_text; | |
379 ls->log.handler = ngx_accept_log_error; | |
380 | |
6172 | 381 ls->backlog = addr[i].opt.backlog; |
382 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
383 ls->keepalive = addr[i].opt.so_keepalive; |
6115 | 384 #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
|
385 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
|
386 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
|
387 ls->keepcnt = addr[i].opt.tcp_keepcnt; |
6115 | 388 #endif |
389 | |
390 #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
|
391 ls->ipv6only = addr[i].opt.ipv6only; |
6115 | 392 #endif |
393 | |
6169
f654addf0eea
Stream: fixed "reuseport" to actually work.
Ruslan Ermilov <ru@nginx.com>
parents:
6153
diff
changeset
|
394 #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
|
395 ls->reuseport = addr[i].opt.reuseport; |
6169
f654addf0eea
Stream: fixed "reuseport" to actually work.
Ruslan Ermilov <ru@nginx.com>
parents:
6153
diff
changeset
|
396 #endif |
f654addf0eea
Stream: fixed "reuseport" to actually work.
Ruslan Ermilov <ru@nginx.com>
parents:
6153
diff
changeset
|
397 |
6115 | 398 stport = ngx_palloc(cf->pool, sizeof(ngx_stream_port_t)); |
399 if (stport == NULL) { | |
400 return NGX_CONF_ERROR; | |
401 } | |
402 | |
403 ls->servers = stport; | |
404 | |
6152
3c344ea7d88b
Simplified ngx_http_init_listening().
Maxim Dounin <mdounin@mdounin.ru>
parents:
6129
diff
changeset
|
405 stport->naddrs = i + 1; |
6115 | 406 |
407 switch (ls->sockaddr->sa_family) { | |
408 #if (NGX_HAVE_INET6) | |
409 case AF_INET6: | |
410 if (ngx_stream_add_addrs6(cf, stport, addr) != NGX_OK) { | |
411 return NGX_CONF_ERROR; | |
412 } | |
413 break; | |
414 #endif | |
415 default: /* AF_INET */ | |
416 if (ngx_stream_add_addrs(cf, stport, addr) != NGX_OK) { | |
417 return NGX_CONF_ERROR; | |
418 } | |
419 break; | |
420 } | |
421 | |
6153
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6152
diff
changeset
|
422 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
|
423 return NGX_CONF_ERROR; |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6152
diff
changeset
|
424 } |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6152
diff
changeset
|
425 |
6115 | 426 addr++; |
427 last--; | |
428 } | |
429 } | |
430 | |
431 return NGX_CONF_OK; | |
432 } | |
433 | |
434 | |
435 static ngx_int_t | |
436 ngx_stream_add_addrs(ngx_conf_t *cf, ngx_stream_port_t *stport, | |
437 ngx_stream_conf_addr_t *addr) | |
438 { | |
439 u_char *p; | |
440 size_t len; | |
441 ngx_uint_t i; | |
442 struct sockaddr_in *sin; | |
443 ngx_stream_in_addr_t *addrs; | |
444 u_char buf[NGX_SOCKADDR_STRLEN]; | |
445 | |
446 stport->addrs = ngx_pcalloc(cf->pool, | |
447 stport->naddrs * sizeof(ngx_stream_in_addr_t)); | |
448 if (stport->addrs == NULL) { | |
449 return NGX_ERROR; | |
450 } | |
451 | |
452 addrs = stport->addrs; | |
453 | |
454 for (i = 0; i < stport->naddrs; i++) { | |
455 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
456 sin = &addr[i].opt.u.sockaddr_in; |
6115 | 457 addrs[i].addr = sin->sin_addr.s_addr; |
458 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
459 addrs[i].conf.ctx = addr[i].opt.ctx; |
6115 | 460 #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
|
461 addrs[i].conf.ssl = addr[i].opt.ssl; |
6115 | 462 #endif |
463 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
464 len = ngx_sock_ntop(&addr[i].opt.u.sockaddr, addr[i].opt.socklen, buf, |
6115 | 465 NGX_SOCKADDR_STRLEN, 1); |
466 | |
467 p = ngx_pnalloc(cf->pool, len); | |
468 if (p == NULL) { | |
469 return NGX_ERROR; | |
470 } | |
471 | |
472 ngx_memcpy(p, buf, len); | |
473 | |
474 addrs[i].conf.addr_text.len = len; | |
475 addrs[i].conf.addr_text.data = p; | |
476 } | |
477 | |
478 return NGX_OK; | |
479 } | |
480 | |
481 | |
482 #if (NGX_HAVE_INET6) | |
483 | |
484 static ngx_int_t | |
485 ngx_stream_add_addrs6(ngx_conf_t *cf, ngx_stream_port_t *stport, | |
486 ngx_stream_conf_addr_t *addr) | |
487 { | |
488 u_char *p; | |
489 size_t len; | |
490 ngx_uint_t i; | |
491 struct sockaddr_in6 *sin6; | |
492 ngx_stream_in6_addr_t *addrs6; | |
493 u_char buf[NGX_SOCKADDR_STRLEN]; | |
494 | |
495 stport->addrs = ngx_pcalloc(cf->pool, | |
496 stport->naddrs * sizeof(ngx_stream_in6_addr_t)); | |
497 if (stport->addrs == NULL) { | |
498 return NGX_ERROR; | |
499 } | |
500 | |
501 addrs6 = stport->addrs; | |
502 | |
503 for (i = 0; i < stport->naddrs; i++) { | |
504 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
505 sin6 = &addr[i].opt.u.sockaddr_in6; |
6115 | 506 addrs6[i].addr6 = sin6->sin6_addr; |
507 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
508 addrs6[i].conf.ctx = addr[i].opt.ctx; |
6115 | 509 #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
|
510 addrs6[i].conf.ssl = addr[i].opt.ssl; |
6115 | 511 #endif |
512 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
513 len = ngx_sock_ntop(&addr[i].opt.u.sockaddr, addr[i].opt.socklen, buf, |
6115 | 514 NGX_SOCKADDR_STRLEN, 1); |
515 | |
516 p = ngx_pnalloc(cf->pool, len); | |
517 if (p == NULL) { | |
518 return NGX_ERROR; | |
519 } | |
520 | |
521 ngx_memcpy(p, buf, len); | |
522 | |
523 addrs6[i].conf.addr_text.len = len; | |
524 addrs6[i].conf.addr_text.data = p; | |
525 } | |
526 | |
527 return NGX_OK; | |
528 } | |
529 | |
530 #endif | |
531 | |
532 | |
533 static ngx_int_t | |
534 ngx_stream_cmp_conf_addrs(const void *one, const void *two) | |
535 { | |
536 ngx_stream_conf_addr_t *first, *second; | |
537 | |
538 first = (ngx_stream_conf_addr_t *) one; | |
539 second = (ngx_stream_conf_addr_t *) two; | |
540 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
541 if (first->opt.wildcard) { |
6115 | 542 /* a wildcard must be the last resort, shift it to the end */ |
543 return 1; | |
544 } | |
545 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
546 if (second->opt.wildcard) { |
6115 | 547 /* a wildcard must be the last resort, shift it to the end */ |
548 return -1; | |
549 } | |
550 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
551 if (first->opt.bind && !second->opt.bind) { |
6115 | 552 /* shift explicit bind()ed addresses to the start */ |
553 return -1; | |
554 } | |
555 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6169
diff
changeset
|
556 if (!first->opt.bind && second->opt.bind) { |
6115 | 557 /* shift explicit bind()ed addresses to the start */ |
558 return 1; | |
559 } | |
560 | |
561 /* do not sort by default */ | |
562 | |
563 return 0; | |
564 } |