annotate src/stream/ngx_stream.c @ 6153:4f6efabcb09b

The "reuseport" option of the "listen" directive. When configured, an individual listen socket on a given address is created for each worker process. This allows to reduce in-kernel lock contention on configurations with high accept rates, resulting in better performance. As of now it works on Linux and DragonFly BSD. Note that on Linux incoming connection requests are currently tied up to a specific listen socket, and if some sockets are closed, connection requests will be reset, see https://lwn.net/Articles/542629/. With nginx, this may happen if the number of worker processes is reduced. There is no such problem on DragonFly BSD. Based on previous work by Sepherosa Ziehau and Yingqi Lu.
author Maxim Dounin <mdounin@mdounin.ru>
date Wed, 20 May 2015 15:51:56 +0300
parents 3c344ea7d88b
children f654addf0eea
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6115
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
1
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
2 /*
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
3 * Copyright (C) Roman Arutyunyan
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
4 * Copyright (C) Nginx, Inc.
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
5 */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
6
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
7
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
8 #include <ngx_config.h>
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
9 #include <ngx_core.h>
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
10 #include <ngx_event.h>
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
11 #include <ngx_stream.h>
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
12
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
13
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
14 static char *ngx_stream_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
15 static ngx_int_t ngx_stream_add_ports(ngx_conf_t *cf, ngx_array_t *ports,
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
16 ngx_stream_listen_t *listen);
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
17 static char *ngx_stream_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports);
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
18 static ngx_int_t ngx_stream_add_addrs(ngx_conf_t *cf, ngx_stream_port_t *stport,
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
19 ngx_stream_conf_addr_t *addr);
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
20 #if (NGX_HAVE_INET6)
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
21 static ngx_int_t ngx_stream_add_addrs6(ngx_conf_t *cf,
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
22 ngx_stream_port_t *stport, ngx_stream_conf_addr_t *addr);
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
23 #endif
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
24 static ngx_int_t ngx_stream_cmp_conf_addrs(const void *one, const void *two);
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
25
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
26
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
27 ngx_uint_t ngx_stream_max_module;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
28
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
29
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
30 static ngx_command_t ngx_stream_commands[] = {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
31
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
32 { ngx_string("stream"),
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
33 NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
34 ngx_stream_block,
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
35 0,
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
36 0,
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
37 NULL },
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
38
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
39 ngx_null_command
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
40 };
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
41
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
42
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
43 static ngx_core_module_t ngx_stream_module_ctx = {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
44 ngx_string("stream"),
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
45 NULL,
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
46 NULL
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
47 };
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
48
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
49
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
50 ngx_module_t ngx_stream_module = {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
51 NGX_MODULE_V1,
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
52 &ngx_stream_module_ctx, /* module context */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
53 ngx_stream_commands, /* module directives */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
54 NGX_CORE_MODULE, /* module type */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
55 NULL, /* init master */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
56 NULL, /* init module */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
57 NULL, /* init process */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
58 NULL, /* init thread */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
59 NULL, /* exit thread */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
60 NULL, /* exit process */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
61 NULL, /* exit master */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
62 NGX_MODULE_V1_PADDING
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
63 };
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
64
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
65
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
66 static char *
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
67 ngx_stream_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
68 {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
69 char *rv;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
70 ngx_uint_t i, m, mi, s;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
71 ngx_conf_t pcf;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
72 ngx_array_t ports;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
73 ngx_stream_listen_t *listen;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
74 ngx_stream_module_t *module;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
75 ngx_stream_conf_ctx_t *ctx;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
76 ngx_stream_core_srv_conf_t **cscfp;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
77 ngx_stream_core_main_conf_t *cmcf;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
78
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
79 /* the main stream context */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
80
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
81 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_stream_conf_ctx_t));
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
82 if (ctx == NULL) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
83 return NGX_CONF_ERROR;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
84 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
85
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
86 *(ngx_stream_conf_ctx_t **) conf = ctx;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
87
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
88 /* count the number of the stream modules and set up their indices */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
89
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
90 ngx_stream_max_module = 0;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
91 for (m = 0; ngx_modules[m]; m++) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
92 if (ngx_modules[m]->type != NGX_STREAM_MODULE) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
93 continue;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
94 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
95
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
96 ngx_modules[m]->ctx_index = ngx_stream_max_module++;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
97 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
98
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
99
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
100 /* the stream main_conf context, it's the same in the all stream contexts */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
101
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
102 ctx->main_conf = ngx_pcalloc(cf->pool,
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
103 sizeof(void *) * ngx_stream_max_module);
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
104 if (ctx->main_conf == NULL) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
105 return NGX_CONF_ERROR;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
106 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
107
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
108
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
109 /*
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
110 * the stream null srv_conf context, it is used to merge
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
111 * the server{}s' srv_conf's
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
112 */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
113
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
114 ctx->srv_conf = ngx_pcalloc(cf->pool,
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
115 sizeof(void *) * ngx_stream_max_module);
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
116 if (ctx->srv_conf == NULL) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
117 return NGX_CONF_ERROR;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
118 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
119
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
120
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
121 /*
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
122 * create the main_conf's and the null srv_conf's of the all stream modules
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
123 */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
124
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
125 for (m = 0; ngx_modules[m]; m++) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
126 if (ngx_modules[m]->type != NGX_STREAM_MODULE) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
127 continue;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
128 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
129
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
130 module = ngx_modules[m]->ctx;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
131 mi = ngx_modules[m]->ctx_index;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
132
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
133 if (module->create_main_conf) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
134 ctx->main_conf[mi] = module->create_main_conf(cf);
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
135 if (ctx->main_conf[mi] == NULL) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
136 return NGX_CONF_ERROR;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
137 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
138 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
139
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
140 if (module->create_srv_conf) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
141 ctx->srv_conf[mi] = module->create_srv_conf(cf);
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
142 if (ctx->srv_conf[mi] == NULL) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
143 return NGX_CONF_ERROR;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
144 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
145 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
146 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
147
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
148
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
149 /* parse inside the stream{} block */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
150
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
151 pcf = *cf;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
152 cf->ctx = ctx;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
153
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
154 cf->module_type = NGX_STREAM_MODULE;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
155 cf->cmd_type = NGX_STREAM_MAIN_CONF;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
156 rv = ngx_conf_parse(cf, NULL);
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
157
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
158 if (rv != NGX_CONF_OK) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
159 *cf = pcf;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
160 return rv;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
161 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
162
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
163
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
164 /* init stream{} main_conf's, merge the server{}s' srv_conf's */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
165
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
166 cmcf = ctx->main_conf[ngx_stream_core_module.ctx_index];
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
167 cscfp = cmcf->servers.elts;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
168
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
169 for (m = 0; ngx_modules[m]; m++) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
170 if (ngx_modules[m]->type != NGX_STREAM_MODULE) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
171 continue;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
172 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
173
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
174 module = ngx_modules[m]->ctx;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
175 mi = ngx_modules[m]->ctx_index;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
176
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
177 /* init stream{} main_conf's */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
178
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
179 cf->ctx = ctx;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
180
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
181 if (module->init_main_conf) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
182 rv = module->init_main_conf(cf, ctx->main_conf[mi]);
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
183 if (rv != NGX_CONF_OK) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
184 *cf = pcf;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
185 return rv;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
186 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
187 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
188
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
189 for (s = 0; s < cmcf->servers.nelts; s++) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
190
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
191 /* merge the server{}s' srv_conf's */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
192
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
193 cf->ctx = cscfp[s]->ctx;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
194
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
195 if (module->merge_srv_conf) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
196 rv = module->merge_srv_conf(cf,
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
197 ctx->srv_conf[mi],
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
198 cscfp[s]->ctx->srv_conf[mi]);
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
199 if (rv != NGX_CONF_OK) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
200 *cf = pcf;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
201 return rv;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
202 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
203 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
204 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
205 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
206
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
207 *cf = pcf;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
208
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
209
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
210 if (ngx_array_init(&ports, cf->temp_pool, 4, sizeof(ngx_stream_conf_port_t))
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
211 != NGX_OK)
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
212 {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
213 return NGX_CONF_ERROR;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
214 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
215
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
216 listen = cmcf->listen.elts;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
217
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
218 for (i = 0; i < cmcf->listen.nelts; i++) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
219 if (ngx_stream_add_ports(cf, &ports, &listen[i]) != NGX_OK) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
220 return NGX_CONF_ERROR;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
221 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
222 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
223
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
224 return ngx_stream_optimize_servers(cf, &ports);
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
225 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
226
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
227
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
228 static ngx_int_t
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
229 ngx_stream_add_ports(ngx_conf_t *cf, ngx_array_t *ports,
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
230 ngx_stream_listen_t *listen)
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
231 {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
232 in_port_t p;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
233 ngx_uint_t i;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
234 struct sockaddr *sa;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
235 struct sockaddr_in *sin;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
236 ngx_stream_conf_port_t *port;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
237 ngx_stream_conf_addr_t *addr;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
238 #if (NGX_HAVE_INET6)
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
239 struct sockaddr_in6 *sin6;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
240 #endif
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
241
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
242 sa = (struct sockaddr *) &listen->sockaddr;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
243
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
244 switch (sa->sa_family) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
245
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
246 #if (NGX_HAVE_INET6)
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
247 case AF_INET6:
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
248 sin6 = (struct sockaddr_in6 *) sa;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
249 p = sin6->sin6_port;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
250 break;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
251 #endif
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
252
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
253 #if (NGX_HAVE_UNIX_DOMAIN)
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
254 case AF_UNIX:
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
255 p = 0;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
256 break;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
257 #endif
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
258
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
259 default: /* AF_INET */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
260 sin = (struct sockaddr_in *) sa;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
261 p = sin->sin_port;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
262 break;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
263 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
264
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
265 port = ports->elts;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
266 for (i = 0; i < ports->nelts; i++) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
267 if (p == port[i].port && sa->sa_family == port[i].family) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
268
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
269 /* a port is already in the port list */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
270
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
271 port = &port[i];
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
272 goto found;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
273 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
274 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
275
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
276 /* add a port to the port list */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
277
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
278 port = ngx_array_push(ports);
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
279 if (port == NULL) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
280 return NGX_ERROR;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
281 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
282
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
283 port->family = sa->sa_family;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
284 port->port = p;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
285
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
286 if (ngx_array_init(&port->addrs, cf->temp_pool, 2,
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
287 sizeof(ngx_stream_conf_addr_t))
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
288 != NGX_OK)
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
289 {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
290 return NGX_ERROR;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
291 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
292
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
293 found:
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
294
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
295 addr = ngx_array_push(&port->addrs);
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
296 if (addr == NULL) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
297 return NGX_ERROR;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
298 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
299
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
300 addr->sockaddr = (struct sockaddr *) &listen->sockaddr;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
301 addr->socklen = listen->socklen;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
302 addr->ctx = listen->ctx;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
303 addr->bind = listen->bind;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
304 addr->wildcard = listen->wildcard;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
305 addr->so_keepalive = listen->so_keepalive;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
306 #if (NGX_HAVE_KEEPALIVE_TUNABLE)
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
307 addr->tcp_keepidle = listen->tcp_keepidle;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
308 addr->tcp_keepintvl = listen->tcp_keepintvl;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
309 addr->tcp_keepcnt = listen->tcp_keepcnt;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
310 #endif
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
311 #if (NGX_STREAM_SSL)
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
312 addr->ssl = listen->ssl;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
313 #endif
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
314 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
315 addr->ipv6only = listen->ipv6only;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
316 #endif
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
317
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
318 return NGX_OK;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
319 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
320
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
321
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
322 static char *
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
323 ngx_stream_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports)
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
324 {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
325 ngx_uint_t i, p, last, bind_wildcard;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
326 ngx_listening_t *ls;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
327 ngx_stream_port_t *stport;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
328 ngx_stream_conf_port_t *port;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
329 ngx_stream_conf_addr_t *addr;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
330 ngx_stream_core_srv_conf_t *cscf;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
331
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
332 port = ports->elts;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
333 for (p = 0; p < ports->nelts; p++) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
334
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
335 ngx_sort(port[p].addrs.elts, (size_t) port[p].addrs.nelts,
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
336 sizeof(ngx_stream_conf_addr_t), ngx_stream_cmp_conf_addrs);
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
337
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
338 addr = port[p].addrs.elts;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
339 last = port[p].addrs.nelts;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
340
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
341 /*
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
342 * if there is the binding to the "*:port" then we need to bind()
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
343 * to the "*:port" only and ignore the other bindings
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
344 */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
345
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
346 if (addr[last - 1].wildcard) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
347 addr[last - 1].bind = 1;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
348 bind_wildcard = 1;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
349
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
350 } else {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
351 bind_wildcard = 0;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
352 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
353
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
354 i = 0;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
355
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
356 while (i < last) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
357
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
358 if (bind_wildcard && !addr[i].bind) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
359 i++;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
360 continue;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
361 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
362
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
363 ls = ngx_create_listening(cf, addr[i].sockaddr, addr[i].socklen);
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
364 if (ls == NULL) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
365 return NGX_CONF_ERROR;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
366 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
367
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
368 ls->addr_ntop = 1;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
369 ls->handler = ngx_stream_init_connection;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
370 ls->pool_size = 256;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
371
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
372 cscf = addr->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
373
6115
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
374 ls->logp = cscf->error_log;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
375 ls->log.data = &ls->addr_text;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
376 ls->log.handler = ngx_accept_log_error;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
377
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
378 ls->keepalive = addr[i].so_keepalive;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
379 #if (NGX_HAVE_KEEPALIVE_TUNABLE)
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
380 ls->keepidle = addr[i].tcp_keepidle;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
381 ls->keepintvl = addr[i].tcp_keepintvl;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
382 ls->keepcnt = addr[i].tcp_keepcnt;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
383 #endif
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
384
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
385 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
386 ls->ipv6only = addr[i].ipv6only;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
387 #endif
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
388
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
389 stport = ngx_palloc(cf->pool, sizeof(ngx_stream_port_t));
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
390 if (stport == NULL) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
391 return NGX_CONF_ERROR;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
392 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
393
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
394 ls->servers = stport;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
395
6152
3c344ea7d88b Simplified ngx_http_init_listening().
Maxim Dounin <mdounin@mdounin.ru>
parents: 6129
diff changeset
396 stport->naddrs = i + 1;
6115
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
397
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
398 switch (ls->sockaddr->sa_family) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
399 #if (NGX_HAVE_INET6)
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
400 case AF_INET6:
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
401 if (ngx_stream_add_addrs6(cf, stport, addr) != NGX_OK) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
402 return NGX_CONF_ERROR;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
403 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
404 break;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
405 #endif
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
406 default: /* AF_INET */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
407 if (ngx_stream_add_addrs(cf, stport, addr) != NGX_OK) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
408 return NGX_CONF_ERROR;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
409 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
410 break;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
411 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
412
6153
4f6efabcb09b The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6152
diff changeset
413 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
414 return NGX_CONF_ERROR;
4f6efabcb09b The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6152
diff changeset
415 }
4f6efabcb09b The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6152
diff changeset
416
6115
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
417 addr++;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
418 last--;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
419 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
420 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
421
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
422 return NGX_CONF_OK;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
423 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
424
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
425
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
426 static ngx_int_t
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
427 ngx_stream_add_addrs(ngx_conf_t *cf, ngx_stream_port_t *stport,
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
428 ngx_stream_conf_addr_t *addr)
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
429 {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
430 u_char *p;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
431 size_t len;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
432 ngx_uint_t i;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
433 struct sockaddr_in *sin;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
434 ngx_stream_in_addr_t *addrs;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
435 u_char buf[NGX_SOCKADDR_STRLEN];
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
436
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
437 stport->addrs = ngx_pcalloc(cf->pool,
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
438 stport->naddrs * sizeof(ngx_stream_in_addr_t));
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
439 if (stport->addrs == NULL) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
440 return NGX_ERROR;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
441 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
442
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
443 addrs = stport->addrs;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
444
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
445 for (i = 0; i < stport->naddrs; i++) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
446
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
447 sin = (struct sockaddr_in *) addr[i].sockaddr;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
448 addrs[i].addr = sin->sin_addr.s_addr;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
449
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
450 addrs[i].conf.ctx = addr[i].ctx;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
451 #if (NGX_STREAM_SSL)
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
452 addrs[i].conf.ssl = addr[i].ssl;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
453 #endif
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
454
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
455 len = ngx_sock_ntop(addr[i].sockaddr, addr[i].socklen, buf,
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
456 NGX_SOCKADDR_STRLEN, 1);
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
457
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
458 p = ngx_pnalloc(cf->pool, len);
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
459 if (p == NULL) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
460 return NGX_ERROR;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
461 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
462
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
463 ngx_memcpy(p, buf, len);
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
464
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
465 addrs[i].conf.addr_text.len = len;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
466 addrs[i].conf.addr_text.data = p;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
467 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
468
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
469 return NGX_OK;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
470 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
471
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
472
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
473 #if (NGX_HAVE_INET6)
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
474
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
475 static ngx_int_t
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
476 ngx_stream_add_addrs6(ngx_conf_t *cf, ngx_stream_port_t *stport,
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
477 ngx_stream_conf_addr_t *addr)
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
478 {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
479 u_char *p;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
480 size_t len;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
481 ngx_uint_t i;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
482 struct sockaddr_in6 *sin6;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
483 ngx_stream_in6_addr_t *addrs6;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
484 u_char buf[NGX_SOCKADDR_STRLEN];
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
485
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
486 stport->addrs = ngx_pcalloc(cf->pool,
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
487 stport->naddrs * sizeof(ngx_stream_in6_addr_t));
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
488 if (stport->addrs == NULL) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
489 return NGX_ERROR;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
490 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
491
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
492 addrs6 = stport->addrs;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
493
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
494 for (i = 0; i < stport->naddrs; i++) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
495
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
496 sin6 = (struct sockaddr_in6 *) addr[i].sockaddr;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
497 addrs6[i].addr6 = sin6->sin6_addr;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
498
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
499 addrs6[i].conf.ctx = addr[i].ctx;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
500 #if (NGX_STREAM_SSL)
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
501 addrs6[i].conf.ssl = addr[i].ssl;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
502 #endif
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
503
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
504 len = ngx_sock_ntop(addr[i].sockaddr, addr[i].socklen, buf,
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
505 NGX_SOCKADDR_STRLEN, 1);
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
506
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
507 p = ngx_pnalloc(cf->pool, len);
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
508 if (p == NULL) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
509 return NGX_ERROR;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
510 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
511
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
512 ngx_memcpy(p, buf, len);
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
513
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
514 addrs6[i].conf.addr_text.len = len;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
515 addrs6[i].conf.addr_text.data = p;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
516 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
517
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
518 return NGX_OK;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
519 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
520
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
521 #endif
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
522
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
523
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
524 static ngx_int_t
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
525 ngx_stream_cmp_conf_addrs(const void *one, const void *two)
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
526 {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
527 ngx_stream_conf_addr_t *first, *second;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
528
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
529 first = (ngx_stream_conf_addr_t *) one;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
530 second = (ngx_stream_conf_addr_t *) two;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
531
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
532 if (first->wildcard) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
533 /* a wildcard must be the last resort, shift it to the end */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
534 return 1;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
535 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
536
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
537 if (second->wildcard) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
538 /* a wildcard must be the last resort, shift it to the end */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
539 return -1;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
540 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
541
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
542 if (first->bind && !second->bind) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
543 /* shift explicit bind()ed addresses to the start */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
544 return -1;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
545 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
546
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
547 if (!first->bind && second->bind) {
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
548 /* shift explicit bind()ed addresses to the start */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
549 return 1;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
550 }
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
551
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
552 /* do not sort by default */
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
553
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
554 return 0;
61d7ae76647d Stream: port from NGINX+.
Ruslan Ermilov <ru@nginx.com>
parents:
diff changeset
555 }