Mercurial > hg > nginx-quic
annotate src/stream/ngx_stream_core_module.c @ 6469:7cdf612fd58c
Win32: replaced NGX_EXDEV with more appropriate error code.
Correct error code for NGX_EXDEV on Windows is ERROR_NOT_SAME_DEVICE,
"The system cannot move the file to a different disk drive".
Previously used ERROR_WRONG_DISK is about wrong diskette in the drive and
is not appropriate.
There is no real difference though, as MoveFile() is able to copy files
between disk drives, and will fail with ERROR_ACCESS_DENIED when asked
to copy directories. The ERROR_NOT_SAME_DEVICE error is only used
by MoveFileEx() when called without the MOVEFILE_COPY_ALLOWED flag.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Tue, 29 Mar 2016 09:52:15 +0300 |
parents | 8f038068f4bc |
children | 6f8254ae61b8 |
rev | line source |
---|---|
6115 | 1 |
2 /* | |
3 * Copyright (C) Roman Arutyunyan | |
4 * Copyright (C) Nginx, Inc. | |
5 */ | |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_stream.h> | |
11 | |
12 | |
13 static void *ngx_stream_core_create_main_conf(ngx_conf_t *cf); | |
14 static void *ngx_stream_core_create_srv_conf(ngx_conf_t *cf); | |
15 static char *ngx_stream_core_merge_srv_conf(ngx_conf_t *cf, void *parent, | |
16 void *child); | |
17 static char *ngx_stream_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, | |
18 void *conf); | |
19 static char *ngx_stream_core_server(ngx_conf_t *cf, ngx_command_t *cmd, | |
20 void *conf); | |
21 static char *ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, | |
22 void *conf); | |
23 | |
24 | |
25 static ngx_command_t ngx_stream_core_commands[] = { | |
26 | |
27 { ngx_string("server"), | |
28 NGX_STREAM_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, | |
29 ngx_stream_core_server, | |
30 0, | |
31 0, | |
32 NULL }, | |
33 | |
34 { ngx_string("listen"), | |
35 NGX_STREAM_SRV_CONF|NGX_CONF_1MORE, | |
36 ngx_stream_core_listen, | |
37 NGX_STREAM_SRV_CONF_OFFSET, | |
38 0, | |
39 NULL }, | |
40 | |
41 { ngx_string("error_log"), | |
42 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE, | |
43 ngx_stream_core_error_log, | |
44 NGX_STREAM_SRV_CONF_OFFSET, | |
45 0, | |
46 NULL }, | |
47 | |
6221
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
48 { ngx_string("tcp_nodelay"), |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
49 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
50 ngx_conf_set_flag_slot, |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
51 NGX_STREAM_SRV_CONF_OFFSET, |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
52 offsetof(ngx_stream_core_srv_conf_t, tcp_nodelay), |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
53 NULL }, |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
54 |
6115 | 55 ngx_null_command |
56 }; | |
57 | |
58 | |
59 static ngx_stream_module_t ngx_stream_core_module_ctx = { | |
6174
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
60 NULL, /* postconfiguration */ |
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6172
diff
changeset
|
61 |
6115 | 62 ngx_stream_core_create_main_conf, /* create main configuration */ |
63 NULL, /* init main configuration */ | |
64 | |
65 ngx_stream_core_create_srv_conf, /* create server configuration */ | |
66 ngx_stream_core_merge_srv_conf /* merge server configuration */ | |
67 }; | |
68 | |
69 | |
70 ngx_module_t ngx_stream_core_module = { | |
71 NGX_MODULE_V1, | |
72 &ngx_stream_core_module_ctx, /* module context */ | |
73 ngx_stream_core_commands, /* module directives */ | |
74 NGX_STREAM_MODULE, /* module type */ | |
75 NULL, /* init master */ | |
76 NULL, /* init module */ | |
77 NULL, /* init process */ | |
78 NULL, /* init thread */ | |
79 NULL, /* exit thread */ | |
80 NULL, /* exit process */ | |
81 NULL, /* exit master */ | |
82 NGX_MODULE_V1_PADDING | |
83 }; | |
84 | |
85 | |
86 static void * | |
87 ngx_stream_core_create_main_conf(ngx_conf_t *cf) | |
88 { | |
89 ngx_stream_core_main_conf_t *cmcf; | |
90 | |
91 cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_core_main_conf_t)); | |
92 if (cmcf == NULL) { | |
93 return NULL; | |
94 } | |
95 | |
96 if (ngx_array_init(&cmcf->servers, cf->pool, 4, | |
97 sizeof(ngx_stream_core_srv_conf_t *)) | |
98 != NGX_OK) | |
99 { | |
100 return NULL; | |
101 } | |
102 | |
103 if (ngx_array_init(&cmcf->listen, cf->pool, 4, sizeof(ngx_stream_listen_t)) | |
104 != NGX_OK) | |
105 { | |
106 return NULL; | |
107 } | |
108 | |
109 return cmcf; | |
110 } | |
111 | |
112 | |
113 static void * | |
114 ngx_stream_core_create_srv_conf(ngx_conf_t *cf) | |
115 { | |
116 ngx_stream_core_srv_conf_t *cscf; | |
117 | |
118 cscf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_core_srv_conf_t)); | |
119 if (cscf == NULL) { | |
120 return NULL; | |
121 } | |
122 | |
123 /* | |
124 * set by ngx_pcalloc(): | |
125 * | |
126 * cscf->handler = NULL; | |
127 * cscf->error_log = NULL; | |
128 */ | |
129 | |
130 cscf->file_name = cf->conf_file->file.name.data; | |
131 cscf->line = cf->conf_file->line; | |
6221
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
132 cscf->tcp_nodelay = NGX_CONF_UNSET; |
6115 | 133 |
134 return cscf; | |
135 } | |
136 | |
137 | |
138 static char * | |
139 ngx_stream_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) | |
140 { | |
141 ngx_stream_core_srv_conf_t *prev = parent; | |
142 ngx_stream_core_srv_conf_t *conf = child; | |
143 | |
144 if (conf->handler == NULL) { | |
145 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
146 "no handler for server in %s:%ui", | |
147 conf->file_name, conf->line); | |
148 return NGX_CONF_ERROR; | |
149 } | |
150 | |
151 if (conf->error_log == NULL) { | |
152 if (prev->error_log) { | |
153 conf->error_log = prev->error_log; | |
154 } else { | |
155 conf->error_log = &cf->cycle->new_log; | |
156 } | |
157 } | |
158 | |
6221
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
159 ngx_conf_merge_value(conf->tcp_nodelay, prev->tcp_nodelay, 1); |
7565e056fad6
Stream: the "tcp_nodelay" directive.
Vladimir Homutov <vl@nginx.com>
parents:
6174
diff
changeset
|
160 |
6115 | 161 return NGX_CONF_OK; |
162 } | |
163 | |
164 | |
165 static char * | |
166 ngx_stream_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
167 { | |
168 ngx_stream_core_srv_conf_t *cscf = conf; | |
169 | |
170 return ngx_log_set_log(cf, &cscf->error_log); | |
171 } | |
172 | |
173 | |
174 static char * | |
175 ngx_stream_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
176 { | |
177 char *rv; | |
178 void *mconf; | |
179 ngx_uint_t m; | |
180 ngx_conf_t pcf; | |
181 ngx_stream_module_t *module; | |
182 ngx_stream_conf_ctx_t *ctx, *stream_ctx; | |
183 ngx_stream_core_srv_conf_t *cscf, **cscfp; | |
184 ngx_stream_core_main_conf_t *cmcf; | |
185 | |
186 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_stream_conf_ctx_t)); | |
187 if (ctx == NULL) { | |
188 return NGX_CONF_ERROR; | |
189 } | |
190 | |
191 stream_ctx = cf->ctx; | |
192 ctx->main_conf = stream_ctx->main_conf; | |
193 | |
194 /* the server{}'s srv_conf */ | |
195 | |
196 ctx->srv_conf = ngx_pcalloc(cf->pool, | |
197 sizeof(void *) * ngx_stream_max_module); | |
198 if (ctx->srv_conf == NULL) { | |
199 return NGX_CONF_ERROR; | |
200 } | |
201 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6230
diff
changeset
|
202 for (m = 0; cf->cycle->modules[m]; m++) { |
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6230
diff
changeset
|
203 if (cf->cycle->modules[m]->type != NGX_STREAM_MODULE) { |
6115 | 204 continue; |
205 } | |
206 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6230
diff
changeset
|
207 module = cf->cycle->modules[m]->ctx; |
6115 | 208 |
209 if (module->create_srv_conf) { | |
210 mconf = module->create_srv_conf(cf); | |
211 if (mconf == NULL) { | |
212 return NGX_CONF_ERROR; | |
213 } | |
214 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6230
diff
changeset
|
215 ctx->srv_conf[cf->cycle->modules[m]->ctx_index] = mconf; |
6115 | 216 } |
217 } | |
218 | |
219 /* the server configuration context */ | |
220 | |
221 cscf = ctx->srv_conf[ngx_stream_core_module.ctx_index]; | |
222 cscf->ctx = ctx; | |
223 | |
224 cmcf = ctx->main_conf[ngx_stream_core_module.ctx_index]; | |
225 | |
226 cscfp = ngx_array_push(&cmcf->servers); | |
227 if (cscfp == NULL) { | |
228 return NGX_CONF_ERROR; | |
229 } | |
230 | |
231 *cscfp = cscf; | |
232 | |
233 | |
234 /* parse inside server{} */ | |
235 | |
236 pcf = *cf; | |
237 cf->ctx = ctx; | |
238 cf->cmd_type = NGX_STREAM_SRV_CONF; | |
239 | |
240 rv = ngx_conf_parse(cf, NULL); | |
241 | |
242 *cf = pcf; | |
243 | |
244 return rv; | |
245 } | |
246 | |
247 | |
248 static char * | |
249 ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
250 { | |
251 size_t len, off; | |
252 in_port_t port; | |
253 ngx_str_t *value; | |
254 ngx_url_t u; | |
6436 | 255 ngx_uint_t i, backlog; |
6115 | 256 struct sockaddr *sa; |
257 struct sockaddr_in *sin; | |
258 ngx_stream_listen_t *ls; | |
259 ngx_stream_core_main_conf_t *cmcf; | |
260 #if (NGX_HAVE_INET6) | |
261 struct sockaddr_in6 *sin6; | |
262 #endif | |
263 | |
264 value = cf->args->elts; | |
265 | |
266 ngx_memzero(&u, sizeof(ngx_url_t)); | |
267 | |
268 u.url = value[1]; | |
269 u.listen = 1; | |
270 | |
271 if (ngx_parse_url(cf->pool, &u) != NGX_OK) { | |
272 if (u.err) { | |
273 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
274 "%s in \"%V\" of the \"listen\" directive", | |
275 u.err, &u.url); | |
276 } | |
277 | |
278 return NGX_CONF_ERROR; | |
279 } | |
280 | |
281 cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); | |
282 | |
283 ls = cmcf->listen.elts; | |
284 | |
285 for (i = 0; i < cmcf->listen.nelts; i++) { | |
286 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6153
diff
changeset
|
287 sa = &ls[i].u.sockaddr; |
6115 | 288 |
289 if (sa->sa_family != u.family) { | |
290 continue; | |
291 } | |
292 | |
293 switch (sa->sa_family) { | |
294 | |
295 #if (NGX_HAVE_INET6) | |
296 case AF_INET6: | |
297 off = offsetof(struct sockaddr_in6, sin6_addr); | |
298 len = 16; | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6153
diff
changeset
|
299 sin6 = &ls[i].u.sockaddr_in6; |
6115 | 300 port = sin6->sin6_port; |
301 break; | |
302 #endif | |
303 | |
304 #if (NGX_HAVE_UNIX_DOMAIN) | |
305 case AF_UNIX: | |
306 off = offsetof(struct sockaddr_un, sun_path); | |
307 len = sizeof(((struct sockaddr_un *) sa)->sun_path); | |
308 port = 0; | |
309 break; | |
310 #endif | |
311 | |
312 default: /* AF_INET */ | |
313 off = offsetof(struct sockaddr_in, sin_addr); | |
314 len = 4; | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6153
diff
changeset
|
315 sin = &ls[i].u.sockaddr_in; |
6115 | 316 port = sin->sin_port; |
317 break; | |
318 } | |
319 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6153
diff
changeset
|
320 if (ngx_memcmp(ls[i].u.sockaddr_data + off, u.sockaddr + off, len) |
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6153
diff
changeset
|
321 != 0) |
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6153
diff
changeset
|
322 { |
6115 | 323 continue; |
324 } | |
325 | |
326 if (port != u.port) { | |
327 continue; | |
328 } | |
329 | |
330 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
331 "duplicate \"%V\" address and port pair", &u.url); | |
332 return NGX_CONF_ERROR; | |
333 } | |
334 | |
335 ls = ngx_array_push(&cmcf->listen); | |
336 if (ls == NULL) { | |
337 return NGX_CONF_ERROR; | |
338 } | |
339 | |
340 ngx_memzero(ls, sizeof(ngx_stream_listen_t)); | |
341 | |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6153
diff
changeset
|
342 ngx_memcpy(&ls->u.sockaddr, u.sockaddr, u.socklen); |
6115 | 343 |
344 ls->socklen = u.socklen; | |
6172 | 345 ls->backlog = NGX_LISTEN_BACKLOG; |
6436 | 346 ls->type = SOCK_STREAM; |
6115 | 347 ls->wildcard = u.wildcard; |
348 ls->ctx = cf->ctx; | |
349 | |
350 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) | |
351 ls->ipv6only = 1; | |
352 #endif | |
353 | |
6436 | 354 backlog = 0; |
355 | |
6115 | 356 for (i = 2; i < cf->args->nelts; i++) { |
357 | |
6436 | 358 #if !(NGX_WIN32) |
359 if (ngx_strcmp(value[i].data, "udp") == 0) { | |
360 ls->type = SOCK_DGRAM; | |
361 continue; | |
362 } | |
363 #endif | |
364 | |
6115 | 365 if (ngx_strcmp(value[i].data, "bind") == 0) { |
366 ls->bind = 1; | |
367 continue; | |
368 } | |
369 | |
6172 | 370 if (ngx_strncmp(value[i].data, "backlog=", 8) == 0) { |
371 ls->backlog = ngx_atoi(value[i].data + 8, value[i].len - 8); | |
372 ls->bind = 1; | |
373 | |
374 if (ls->backlog == NGX_ERROR || ls->backlog == 0) { | |
375 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
376 "invalid backlog \"%V\"", &value[i]); | |
377 return NGX_CONF_ERROR; | |
378 } | |
379 | |
6436 | 380 backlog = 1; |
381 | |
6172 | 382 continue; |
383 } | |
384 | |
6115 | 385 if (ngx_strncmp(value[i].data, "ipv6only=o", 10) == 0) { |
386 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) | |
6230
2a621245f4cf
Win32: MSVC 2015 compatibility.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6221
diff
changeset
|
387 u_char buf[NGX_SOCKADDR_STRLEN]; |
6115 | 388 |
6170
c13091e6292c
Stream: embed ngx_stream_listen_t into ngx_stream_conf_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
6153
diff
changeset
|
389 sa = &ls->u.sockaddr; |
6115 | 390 |
391 if (sa->sa_family == AF_INET6) { | |
392 | |
393 if (ngx_strcmp(&value[i].data[10], "n") == 0) { | |
394 ls->ipv6only = 1; | |
395 | |
396 } else if (ngx_strcmp(&value[i].data[10], "ff") == 0) { | |
397 ls->ipv6only = 0; | |
398 | |
399 } else { | |
400 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
401 "invalid ipv6only flags \"%s\"", | |
402 &value[i].data[9]); | |
403 return NGX_CONF_ERROR; | |
404 } | |
405 | |
406 ls->bind = 1; | |
407 | |
408 } else { | |
409 len = ngx_sock_ntop(sa, ls->socklen, buf, | |
410 NGX_SOCKADDR_STRLEN, 1); | |
411 | |
412 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
413 "ipv6only is not supported " | |
414 "on addr \"%*s\", ignored", len, buf); | |
415 } | |
416 | |
417 continue; | |
418 #else | |
419 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
420 "bind ipv6only is not supported " | |
421 "on this platform"); | |
422 return NGX_CONF_ERROR; | |
423 #endif | |
424 } | |
425 | |
6153
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6115
diff
changeset
|
426 if (ngx_strcmp(value[i].data, "reuseport") == 0) { |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6115
diff
changeset
|
427 #if (NGX_HAVE_REUSEPORT) |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6115
diff
changeset
|
428 ls->reuseport = 1; |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6115
diff
changeset
|
429 ls->bind = 1; |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6115
diff
changeset
|
430 #else |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6115
diff
changeset
|
431 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6115
diff
changeset
|
432 "reuseport is not supported " |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6115
diff
changeset
|
433 "on this platform, ignored"); |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6115
diff
changeset
|
434 #endif |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6115
diff
changeset
|
435 continue; |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6115
diff
changeset
|
436 } |
4f6efabcb09b
The "reuseport" option of the "listen" directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6115
diff
changeset
|
437 |
6115 | 438 if (ngx_strcmp(value[i].data, "ssl") == 0) { |
439 #if (NGX_STREAM_SSL) | |
440 ls->ssl = 1; | |
441 continue; | |
442 #else | |
443 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
444 "the \"ssl\" parameter requires " | |
445 "ngx_stream_ssl_module"); | |
446 return NGX_CONF_ERROR; | |
447 #endif | |
448 } | |
449 | |
450 if (ngx_strncmp(value[i].data, "so_keepalive=", 13) == 0) { | |
451 | |
452 if (ngx_strcmp(&value[i].data[13], "on") == 0) { | |
453 ls->so_keepalive = 1; | |
454 | |
455 } else if (ngx_strcmp(&value[i].data[13], "off") == 0) { | |
456 ls->so_keepalive = 2; | |
457 | |
458 } else { | |
459 | |
460 #if (NGX_HAVE_KEEPALIVE_TUNABLE) | |
461 u_char *p, *end; | |
462 ngx_str_t s; | |
463 | |
464 end = value[i].data + value[i].len; | |
465 s.data = value[i].data + 13; | |
466 | |
467 p = ngx_strlchr(s.data, end, ':'); | |
468 if (p == NULL) { | |
469 p = end; | |
470 } | |
471 | |
472 if (p > s.data) { | |
473 s.len = p - s.data; | |
474 | |
475 ls->tcp_keepidle = ngx_parse_time(&s, 1); | |
476 if (ls->tcp_keepidle == (time_t) NGX_ERROR) { | |
477 goto invalid_so_keepalive; | |
478 } | |
479 } | |
480 | |
481 s.data = (p < end) ? (p + 1) : end; | |
482 | |
483 p = ngx_strlchr(s.data, end, ':'); | |
484 if (p == NULL) { | |
485 p = end; | |
486 } | |
487 | |
488 if (p > s.data) { | |
489 s.len = p - s.data; | |
490 | |
491 ls->tcp_keepintvl = ngx_parse_time(&s, 1); | |
492 if (ls->tcp_keepintvl == (time_t) NGX_ERROR) { | |
493 goto invalid_so_keepalive; | |
494 } | |
495 } | |
496 | |
497 s.data = (p < end) ? (p + 1) : end; | |
498 | |
499 if (s.data < end) { | |
500 s.len = end - s.data; | |
501 | |
502 ls->tcp_keepcnt = ngx_atoi(s.data, s.len); | |
503 if (ls->tcp_keepcnt == NGX_ERROR) { | |
504 goto invalid_so_keepalive; | |
505 } | |
506 } | |
507 | |
508 if (ls->tcp_keepidle == 0 && ls->tcp_keepintvl == 0 | |
509 && ls->tcp_keepcnt == 0) | |
510 { | |
511 goto invalid_so_keepalive; | |
512 } | |
513 | |
514 ls->so_keepalive = 1; | |
515 | |
516 #else | |
517 | |
518 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
519 "the \"so_keepalive\" parameter accepts " | |
520 "only \"on\" or \"off\" on this platform"); | |
521 return NGX_CONF_ERROR; | |
522 | |
523 #endif | |
524 } | |
525 | |
526 ls->bind = 1; | |
527 | |
528 continue; | |
529 | |
530 #if (NGX_HAVE_KEEPALIVE_TUNABLE) | |
531 invalid_so_keepalive: | |
532 | |
533 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
534 "invalid so_keepalive value: \"%s\"", | |
535 &value[i].data[13]); | |
536 return NGX_CONF_ERROR; | |
537 #endif | |
538 } | |
539 | |
540 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
541 "the invalid \"%V\" parameter", &value[i]); | |
542 return NGX_CONF_ERROR; | |
543 } | |
544 | |
6436 | 545 if (ls->type == SOCK_DGRAM) { |
546 if (backlog) { | |
547 return "\"backlog\" parameter is incompatible with \"udp\""; | |
548 } | |
549 | |
550 #if (NGX_STREAM_SSL) | |
551 if (ls->ssl) { | |
552 return "\"ssl\" parameter is incompatible with \"udp\""; | |
553 } | |
554 #endif | |
555 | |
556 if (ls->so_keepalive) { | |
557 return "\"so_keepalive\" parameter is incompatible with \"udp\""; | |
558 } | |
559 } | |
560 | |
6115 | 561 return NGX_CONF_OK; |
562 } |