blob: 276b8eeb1f1360e5041df86f8fe8a736006646c8 [file] [log] [blame]
Igor Sysoev02c8d182007-03-19 13:36:56 +00001
2/*
3 * Copyright (C) Igor Sysoev
Maxim Konovalovf8d59e32012-01-18 15:07:43 +00004 * Copyright (C) Nginx, Inc.
Igor Sysoev02c8d182007-03-19 13:36:56 +00005 */
6
7
8#include <ngx_config.h>
9#include <ngx_core.h>
10#include <ngx_event.h>
11#include <ngx_mail.h>
12
13
14static void *ngx_mail_core_create_main_conf(ngx_conf_t *cf);
15static void *ngx_mail_core_create_srv_conf(ngx_conf_t *cf);
16static char *ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent,
17 void *child);
18static char *ngx_mail_core_server(ngx_conf_t *cf, ngx_command_t *cmd,
19 void *conf);
20static char *ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd,
21 void *conf);
Igor Sysoev48714082007-09-15 16:51:16 +000022static char *ngx_mail_core_protocol(ngx_conf_t *cf, ngx_command_t *cmd,
Igor Sysoev02c8d182007-03-19 13:36:56 +000023 void *conf);
Vladimir Homutov2b01f262015-02-20 15:31:37 +030024static char *ngx_mail_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd,
25 void *conf);
Igor Sysoev45450462008-02-13 13:50:04 +000026static char *ngx_mail_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd,
27 void *conf);
Igor Sysoev02c8d182007-03-19 13:36:56 +000028
29
Igor Sysoev02c8d182007-03-19 13:36:56 +000030static ngx_command_t ngx_mail_core_commands[] = {
31
32 { ngx_string("server"),
33 NGX_MAIL_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
34 ngx_mail_core_server,
35 0,
36 0,
37 NULL },
38
39 { ngx_string("listen"),
Valentin Bartenevc7efcf62014-08-20 13:13:27 +040040 NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
Igor Sysoev02c8d182007-03-19 13:36:56 +000041 ngx_mail_core_listen,
Igor Sysoev48714082007-09-15 16:51:16 +000042 NGX_MAIL_SRV_CONF_OFFSET,
Igor Sysoev02c8d182007-03-19 13:36:56 +000043 0,
44 NULL },
45
46 { ngx_string("protocol"),
47 NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
Igor Sysoev48714082007-09-15 16:51:16 +000048 ngx_mail_core_protocol,
Igor Sysoev02c8d182007-03-19 13:36:56 +000049 NGX_MAIL_SRV_CONF_OFFSET,
Igor Sysoev48714082007-09-15 16:51:16 +000050 0,
Igor Sysoev711c36b2007-09-14 13:58:49 +000051 NULL },
52
Igor Sysoev02c8d182007-03-19 13:36:56 +000053 { ngx_string("timeout"),
54 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
55 ngx_conf_set_msec_slot,
56 NGX_MAIL_SRV_CONF_OFFSET,
57 offsetof(ngx_mail_core_srv_conf_t, timeout),
58 NULL },
59
Igor Sysoev02c8d182007-03-19 13:36:56 +000060 { ngx_string("server_name"),
61 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
62 ngx_conf_set_str_slot,
63 NGX_MAIL_SRV_CONF_OFFSET,
64 offsetof(ngx_mail_core_srv_conf_t, server_name),
65 NULL },
66
Vladimir Homutov2b01f262015-02-20 15:31:37 +030067 { ngx_string("error_log"),
68 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
69 ngx_mail_core_error_log,
70 NGX_MAIL_SRV_CONF_OFFSET,
71 0,
72 NULL },
73
Igor Sysoev45450462008-02-13 13:50:04 +000074 { ngx_string("resolver"),
Igor Sysoev62071812011-10-24 16:09:05 +000075 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
Igor Sysoev45450462008-02-13 13:50:04 +000076 ngx_mail_core_resolver,
77 NGX_MAIL_SRV_CONF_OFFSET,
78 0,
79 NULL },
80
81 { ngx_string("resolver_timeout"),
82 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
83 ngx_conf_set_msec_slot,
84 NGX_MAIL_SRV_CONF_OFFSET,
85 offsetof(ngx_mail_core_srv_conf_t, resolver_timeout),
86 NULL },
87
Igor Sysoev02c8d182007-03-19 13:36:56 +000088 ngx_null_command
89};
90
91
92static ngx_mail_module_t ngx_mail_core_module_ctx = {
Igor Sysoev48714082007-09-15 16:51:16 +000093 NULL, /* protocol */
94
Igor Sysoev02c8d182007-03-19 13:36:56 +000095 ngx_mail_core_create_main_conf, /* create main configuration */
96 NULL, /* init main configuration */
97
98 ngx_mail_core_create_srv_conf, /* create server configuration */
99 ngx_mail_core_merge_srv_conf /* merge server configuration */
100};
101
102
103ngx_module_t ngx_mail_core_module = {
104 NGX_MODULE_V1,
105 &ngx_mail_core_module_ctx, /* module context */
106 ngx_mail_core_commands, /* module directives */
107 NGX_MAIL_MODULE, /* module type */
108 NULL, /* init master */
109 NULL, /* init module */
110 NULL, /* init process */
111 NULL, /* init thread */
112 NULL, /* exit thread */
113 NULL, /* exit process */
114 NULL, /* exit master */
115 NGX_MODULE_V1_PADDING
116};
117
118
119static void *
120ngx_mail_core_create_main_conf(ngx_conf_t *cf)
121{
122 ngx_mail_core_main_conf_t *cmcf;
123
124 cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_core_main_conf_t));
125 if (cmcf == NULL) {
Igor Sysoev260c4322009-06-02 16:09:44 +0000126 return NULL;
Igor Sysoev02c8d182007-03-19 13:36:56 +0000127 }
128
129 if (ngx_array_init(&cmcf->servers, cf->pool, 4,
130 sizeof(ngx_mail_core_srv_conf_t *))
131 != NGX_OK)
132 {
Igor Sysoev260c4322009-06-02 16:09:44 +0000133 return NULL;
Igor Sysoev02c8d182007-03-19 13:36:56 +0000134 }
135
136 if (ngx_array_init(&cmcf->listen, cf->pool, 4, sizeof(ngx_mail_listen_t))
137 != NGX_OK)
138 {
Igor Sysoev260c4322009-06-02 16:09:44 +0000139 return NULL;
Igor Sysoev02c8d182007-03-19 13:36:56 +0000140 }
141
142 return cmcf;
143}
144
145
146static void *
147ngx_mail_core_create_srv_conf(ngx_conf_t *cf)
148{
149 ngx_mail_core_srv_conf_t *cscf;
150
151 cscf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_core_srv_conf_t));
152 if (cscf == NULL) {
153 return NULL;
154 }
155
Igor Sysoev48714082007-09-15 16:51:16 +0000156 /*
157 * set by ngx_pcalloc():
158 *
159 * cscf->protocol = NULL;
Vladimir Homutov2b01f262015-02-20 15:31:37 +0300160 * cscf->error_log = NULL;
Igor Sysoev48714082007-09-15 16:51:16 +0000161 */
162
Igor Sysoev02c8d182007-03-19 13:36:56 +0000163 cscf->timeout = NGX_CONF_UNSET_MSEC;
Igor Sysoev45450462008-02-13 13:50:04 +0000164 cscf->resolver_timeout = NGX_CONF_UNSET_MSEC;
Igor Sysoev02c8d182007-03-19 13:36:56 +0000165
Igor Sysoev5fa11462008-02-16 13:46:33 +0000166 cscf->resolver = NGX_CONF_UNSET_PTR;
167
Igor Sysoev45450462008-02-13 13:50:04 +0000168 cscf->file_name = cf->conf_file->file.name.data;
169 cscf->line = cf->conf_file->line;
170
Igor Sysoev02c8d182007-03-19 13:36:56 +0000171 return cscf;
172}
173
174
175static char *
176ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
177{
178 ngx_mail_core_srv_conf_t *prev = parent;
179 ngx_mail_core_srv_conf_t *conf = child;
180
Igor Sysoev02c8d182007-03-19 13:36:56 +0000181 ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 60000);
Igor Sysoev45450462008-02-13 13:50:04 +0000182 ngx_conf_merge_msec_value(conf->resolver_timeout, prev->resolver_timeout,
183 30000);
Igor Sysoev711c36b2007-09-14 13:58:49 +0000184
Igor Sysoev02c8d182007-03-19 13:36:56 +0000185
186 ngx_conf_merge_str_value(conf->server_name, prev->server_name, "");
187
188 if (conf->server_name.len == 0) {
Igor Sysoev3be52572008-05-16 14:39:06 +0000189 conf->server_name = cf->cycle->hostname;
Igor Sysoev02c8d182007-03-19 13:36:56 +0000190 }
191
Igor Sysoev48714082007-09-15 16:51:16 +0000192 if (conf->protocol == NULL) {
193 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
194 "unknown mail protocol for server in %s:%ui",
195 conf->file_name, conf->line);
Igor Sysoev02c8d182007-03-19 13:36:56 +0000196 return NGX_CONF_ERROR;
197 }
198
Vladimir Homutov2b01f262015-02-20 15:31:37 +0300199 if (conf->error_log == NULL) {
200 if (prev->error_log) {
201 conf->error_log = prev->error_log;
202 } else {
203 conf->error_log = &cf->cycle->new_log;
204 }
205 }
206
Igor Sysoev5fa11462008-02-16 13:46:33 +0000207 ngx_conf_merge_ptr_value(conf->resolver, prev->resolver, NULL);
Igor Sysoev45450462008-02-13 13:50:04 +0000208
Igor Sysoev02c8d182007-03-19 13:36:56 +0000209 return NGX_CONF_OK;
210}
211
212
213static char *
214ngx_mail_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
215{
216 char *rv;
217 void *mconf;
218 ngx_uint_t m;
219 ngx_conf_t pcf;
220 ngx_mail_module_t *module;
221 ngx_mail_conf_ctx_t *ctx, *mail_ctx;
222 ngx_mail_core_srv_conf_t *cscf, **cscfp;
223 ngx_mail_core_main_conf_t *cmcf;
224
Igor Sysoev02c8d182007-03-19 13:36:56 +0000225 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_mail_conf_ctx_t));
226 if (ctx == NULL) {
227 return NGX_CONF_ERROR;
228 }
229
230 mail_ctx = cf->ctx;
231 ctx->main_conf = mail_ctx->main_conf;
232
233 /* the server{}'s srv_conf */
234
235 ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_mail_max_module);
236 if (ctx->srv_conf == NULL) {
237 return NGX_CONF_ERROR;
238 }
239
Maxim Dounin55c74592016-02-04 18:30:21 +0300240 for (m = 0; cf->cycle->modules[m]; m++) {
241 if (cf->cycle->modules[m]->type != NGX_MAIL_MODULE) {
Igor Sysoev02c8d182007-03-19 13:36:56 +0000242 continue;
243 }
244
Maxim Dounin55c74592016-02-04 18:30:21 +0300245 module = cf->cycle->modules[m]->ctx;
Igor Sysoev02c8d182007-03-19 13:36:56 +0000246
247 if (module->create_srv_conf) {
248 mconf = module->create_srv_conf(cf);
249 if (mconf == NULL) {
250 return NGX_CONF_ERROR;
251 }
252
Maxim Dounin55c74592016-02-04 18:30:21 +0300253 ctx->srv_conf[cf->cycle->modules[m]->ctx_index] = mconf;
Igor Sysoev02c8d182007-03-19 13:36:56 +0000254 }
255 }
256
257 /* the server configuration context */
258
259 cscf = ctx->srv_conf[ngx_mail_core_module.ctx_index];
260 cscf->ctx = ctx;
261
262 cmcf = ctx->main_conf[ngx_mail_core_module.ctx_index];
263
264 cscfp = ngx_array_push(&cmcf->servers);
265 if (cscfp == NULL) {
266 return NGX_CONF_ERROR;
267 }
268
269 *cscfp = cscf;
270
271
272 /* parse inside server{} */
273
274 pcf = *cf;
275 cf->ctx = ctx;
276 cf->cmd_type = NGX_MAIL_SRV_CONF;
277
278 rv = ngx_conf_parse(cf, NULL);
279
280 *cf = pcf;
281
Roman Arutyunyan10e151f2016-08-17 11:26:51 +0300282 if (rv == NGX_CONF_OK && !cscf->listen) {
283 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
284 "no \"listen\" is defined for server in %s:%ui",
285 cscf->file_name, cscf->line);
286 return NGX_CONF_ERROR;
287 }
288
Igor Sysoev02c8d182007-03-19 13:36:56 +0000289 return rv;
290}
291
292
Igor Sysoev02c8d182007-03-19 13:36:56 +0000293static char *
294ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
295{
Igor Sysoev48714082007-09-15 16:51:16 +0000296 ngx_mail_core_srv_conf_t *cscf = conf;
297
Vladimir Homutov76725a82017-04-03 17:30:34 +0300298 ngx_str_t *value, size;
Igor Sysoev02c8d182007-03-19 13:36:56 +0000299 ngx_url_t u;
Igor Sysoev48714082007-09-15 16:51:16 +0000300 ngx_uint_t i, m;
Igor Sysoev4c9d3672009-05-04 19:34:59 +0000301 ngx_mail_listen_t *ls;
Igor Sysoev48714082007-09-15 16:51:16 +0000302 ngx_mail_module_t *module;
Igor Sysoev02c8d182007-03-19 13:36:56 +0000303 ngx_mail_core_main_conf_t *cmcf;
Igor Sysoev02c8d182007-03-19 13:36:56 +0000304
Roman Arutyunyan10e151f2016-08-17 11:26:51 +0300305 cscf->listen = 1;
306
Igor Sysoev02c8d182007-03-19 13:36:56 +0000307 value = cf->args->elts;
308
309 ngx_memzero(&u, sizeof(ngx_url_t));
310
311 u.url = value[1];
312 u.listen = 1;
313
Igor Sysoev7ed63ee2007-10-08 08:55:12 +0000314 if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
Igor Sysoev02c8d182007-03-19 13:36:56 +0000315 if (u.err) {
316 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
317 "%s in \"%V\" of the \"listen\" directive",
318 u.err, &u.url);
319 }
320
321 return NGX_CONF_ERROR;
322 }
323
324 cmcf = ngx_mail_conf_get_module_main_conf(cf, ngx_mail_core_module);
325
Igor Sysoev4c9d3672009-05-04 19:34:59 +0000326 ls = cmcf->listen.elts;
Igor Sysoev02c8d182007-03-19 13:36:56 +0000327
328 for (i = 0; i < cmcf->listen.nelts; i++) {
329
Maxim Douninc47ead42016-05-23 16:37:28 +0300330 if (ngx_cmp_sockaddr(&ls[i].sockaddr.sockaddr, ls[i].socklen,
Ruslan Ermilovfdfe5022016-05-20 19:10:42 +0300331 (struct sockaddr *) &u.sockaddr, u.socklen, 1)
332 != NGX_OK)
Ruslan Ermilov63a5d452015-06-08 23:11:58 +0300333 {
Igor Sysoev610cbd42009-05-18 12:20:22 +0000334 continue;
335 }
336
Igor Sysoev02c8d182007-03-19 13:36:56 +0000337 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
338 "duplicate \"%V\" address and port pair", &u.url);
339 return NGX_CONF_ERROR;
340 }
341
Igor Sysoev4c9d3672009-05-04 19:34:59 +0000342 ls = ngx_array_push(&cmcf->listen);
343 if (ls == NULL) {
Igor Sysoev02c8d182007-03-19 13:36:56 +0000344 return NGX_CONF_ERROR;
345 }
346
Igor Sysoev4c9d3672009-05-04 19:34:59 +0000347 ngx_memzero(ls, sizeof(ngx_mail_listen_t));
Igor Sysoev02c8d182007-03-19 13:36:56 +0000348
Maxim Douninc47ead42016-05-23 16:37:28 +0300349 ngx_memcpy(&ls->sockaddr.sockaddr, &u.sockaddr, u.socklen);
Igor Sysoev610cbd42009-05-18 12:20:22 +0000350
351 ls->socklen = u.socklen;
Ruslan Ermilov67902c52015-06-08 23:13:56 +0300352 ls->backlog = NGX_LISTEN_BACKLOG;
Vladimir Homutov76725a82017-04-03 17:30:34 +0300353 ls->rcvbuf = -1;
354 ls->sndbuf = -1;
Igor Sysoev610cbd42009-05-18 12:20:22 +0000355 ls->wildcard = u.wildcard;
Igor Sysoev4c9d3672009-05-04 19:34:59 +0000356 ls->ctx = cf->ctx;
Igor Sysoev02c8d182007-03-19 13:36:56 +0000357
Maxim Douninc7689a82016-10-03 15:58:25 +0300358#if (NGX_HAVE_INET6)
Ruslan Ermilovdeaf22d2012-07-30 12:27:06 +0000359 ls->ipv6only = 1;
360#endif
361
Ruslan Ermilov9aac01a2012-08-15 11:30:24 +0000362 if (cscf->protocol == NULL) {
Maxim Dounin55c74592016-02-04 18:30:21 +0300363 for (m = 0; cf->cycle->modules[m]; m++) {
364 if (cf->cycle->modules[m]->type != NGX_MAIL_MODULE) {
Ruslan Ermilov9aac01a2012-08-15 11:30:24 +0000365 continue;
366 }
Maxim Dounin83e35f62012-08-18 23:04:39 +0000367
Maxim Dounin55c74592016-02-04 18:30:21 +0300368 module = cf->cycle->modules[m]->ctx;
Maxim Dounin83e35f62012-08-18 23:04:39 +0000369
Ruslan Ermilov9aac01a2012-08-15 11:30:24 +0000370 if (module->protocol == NULL) {
371 continue;
372 }
Maxim Dounin83e35f62012-08-18 23:04:39 +0000373
Ruslan Ermilov9aac01a2012-08-15 11:30:24 +0000374 for (i = 0; module->protocol->port[i]; i++) {
375 if (module->protocol->port[i] == u.port) {
376 cscf->protocol = module->protocol;
377 break;
378 }
Igor Sysoev48714082007-09-15 16:51:16 +0000379 }
380 }
381 }
382
Igor Sysoevf100c782008-09-01 14:19:01 +0000383 for (i = 2; i < cf->args->nelts; i++) {
384
385 if (ngx_strcmp(value[i].data, "bind") == 0) {
Igor Sysoev4c9d3672009-05-04 19:34:59 +0000386 ls->bind = 1;
Igor Sysoevf100c782008-09-01 14:19:01 +0000387 continue;
388 }
389
Ruslan Ermilov67902c52015-06-08 23:13:56 +0300390 if (ngx_strncmp(value[i].data, "backlog=", 8) == 0) {
391 ls->backlog = ngx_atoi(value[i].data + 8, value[i].len - 8);
392 ls->bind = 1;
393
394 if (ls->backlog == NGX_ERROR || ls->backlog == 0) {
395 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
396 "invalid backlog \"%V\"", &value[i]);
397 return NGX_CONF_ERROR;
398 }
399
400 continue;
401 }
402
Vladimir Homutov76725a82017-04-03 17:30:34 +0300403 if (ngx_strncmp(value[i].data, "rcvbuf=", 7) == 0) {
404 size.len = value[i].len - 7;
405 size.data = value[i].data + 7;
406
407 ls->rcvbuf = ngx_parse_size(&size);
408 ls->bind = 1;
409
410 if (ls->rcvbuf == NGX_ERROR) {
411 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
412 "invalid rcvbuf \"%V\"", &value[i]);
413 return NGX_CONF_ERROR;
414 }
415
416 continue;
417 }
418
419 if (ngx_strncmp(value[i].data, "sndbuf=", 7) == 0) {
420 size.len = value[i].len - 7;
421 size.data = value[i].data + 7;
422
423 ls->sndbuf = ngx_parse_size(&size);
424 ls->bind = 1;
425
426 if (ls->sndbuf == NGX_ERROR) {
427 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
428 "invalid sndbuf \"%V\"", &value[i]);
429 return NGX_CONF_ERROR;
430 }
431
432 continue;
433 }
434
Igor Sysoev610cbd42009-05-18 12:20:22 +0000435 if (ngx_strncmp(value[i].data, "ipv6only=o", 10) == 0) {
436#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
Ruslan Ermilovfdfe5022016-05-20 19:10:42 +0300437 size_t len;
Maxim Dounin46c5ecc2015-08-17 18:09:17 +0300438 u_char buf[NGX_SOCKADDR_STRLEN];
Igor Sysoev610cbd42009-05-18 12:20:22 +0000439
Maxim Douninc47ead42016-05-23 16:37:28 +0300440 if (ls->sockaddr.sockaddr.sa_family == AF_INET6) {
Igor Sysoev610cbd42009-05-18 12:20:22 +0000441
442 if (ngx_strcmp(&value[i].data[10], "n") == 0) {
443 ls->ipv6only = 1;
444
445 } else if (ngx_strcmp(&value[i].data[10], "ff") == 0) {
Ruslan Ermilovdeaf22d2012-07-30 12:27:06 +0000446 ls->ipv6only = 0;
Igor Sysoev610cbd42009-05-18 12:20:22 +0000447
448 } else {
449 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
450 "invalid ipv6only flags \"%s\"",
451 &value[i].data[9]);
452 return NGX_CONF_ERROR;
453 }
454
455 ls->bind = 1;
456
457 } else {
Maxim Douninc47ead42016-05-23 16:37:28 +0300458 len = ngx_sock_ntop(&ls->sockaddr.sockaddr, ls->socklen, buf,
Vladimir Homutovaf189462013-07-11 16:07:25 +0400459 NGX_SOCKADDR_STRLEN, 1);
Igor Sysoev610cbd42009-05-18 12:20:22 +0000460
461 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
462 "ipv6only is not supported "
463 "on addr \"%*s\", ignored", len, buf);
464 }
465
466 continue;
467#else
468 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
469 "bind ipv6only is not supported "
470 "on this platform");
471 return NGX_CONF_ERROR;
472#endif
473 }
474
Igor Sysoevf100c782008-09-01 14:19:01 +0000475 if (ngx_strcmp(value[i].data, "ssl") == 0) {
476#if (NGX_MAIL_SSL)
Igor Sysoev4c9d3672009-05-04 19:34:59 +0000477 ls->ssl = 1;
Igor Sysoevf100c782008-09-01 14:19:01 +0000478 continue;
479#else
480 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
481 "the \"ssl\" parameter requires "
482 "ngx_mail_ssl_module");
483 return NGX_CONF_ERROR;
484#endif
485 }
486
Valentin Bartenev92edf472011-12-05 08:06:15 +0000487 if (ngx_strncmp(value[i].data, "so_keepalive=", 13) == 0) {
488
489 if (ngx_strcmp(&value[i].data[13], "on") == 0) {
490 ls->so_keepalive = 1;
491
492 } else if (ngx_strcmp(&value[i].data[13], "off") == 0) {
493 ls->so_keepalive = 2;
494
495 } else {
496
497#if (NGX_HAVE_KEEPALIVE_TUNABLE)
498 u_char *p, *end;
499 ngx_str_t s;
500
501 end = value[i].data + value[i].len;
502 s.data = value[i].data + 13;
503
504 p = ngx_strlchr(s.data, end, ':');
505 if (p == NULL) {
506 p = end;
507 }
508
509 if (p > s.data) {
510 s.len = p - s.data;
511
512 ls->tcp_keepidle = ngx_parse_time(&s, 1);
Maxim Dounin9f38b202012-02-13 15:41:11 +0000513 if (ls->tcp_keepidle == (time_t) NGX_ERROR) {
Valentin Bartenev92edf472011-12-05 08:06:15 +0000514 goto invalid_so_keepalive;
515 }
516 }
517
518 s.data = (p < end) ? (p + 1) : end;
519
520 p = ngx_strlchr(s.data, end, ':');
521 if (p == NULL) {
522 p = end;
523 }
524
525 if (p > s.data) {
526 s.len = p - s.data;
527
528 ls->tcp_keepintvl = ngx_parse_time(&s, 1);
Maxim Dounin9f38b202012-02-13 15:41:11 +0000529 if (ls->tcp_keepintvl == (time_t) NGX_ERROR) {
Valentin Bartenev92edf472011-12-05 08:06:15 +0000530 goto invalid_so_keepalive;
531 }
532 }
533
534 s.data = (p < end) ? (p + 1) : end;
535
536 if (s.data < end) {
537 s.len = end - s.data;
538
539 ls->tcp_keepcnt = ngx_atoi(s.data, s.len);
540 if (ls->tcp_keepcnt == NGX_ERROR) {
541 goto invalid_so_keepalive;
542 }
543 }
544
545 if (ls->tcp_keepidle == 0 && ls->tcp_keepintvl == 0
546 && ls->tcp_keepcnt == 0)
547 {
548 goto invalid_so_keepalive;
549 }
550
551 ls->so_keepalive = 1;
552
553#else
554
555 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
556 "the \"so_keepalive\" parameter accepts "
557 "only \"on\" or \"off\" on this platform");
558 return NGX_CONF_ERROR;
559
560#endif
561 }
562
563 ls->bind = 1;
564
565 continue;
566
567#if (NGX_HAVE_KEEPALIVE_TUNABLE)
568 invalid_so_keepalive:
569
570 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
571 "invalid so_keepalive value: \"%s\"",
572 &value[i].data[13]);
573 return NGX_CONF_ERROR;
574#endif
575 }
576
Igor Sysoevf100c782008-09-01 14:19:01 +0000577 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
578 "the invalid \"%V\" parameter", &value[i]);
579 return NGX_CONF_ERROR;
Igor Sysoev02c8d182007-03-19 13:36:56 +0000580 }
581
Igor Sysoevf100c782008-09-01 14:19:01 +0000582 return NGX_CONF_OK;
Igor Sysoev02c8d182007-03-19 13:36:56 +0000583}
584
585
586static char *
Igor Sysoev48714082007-09-15 16:51:16 +0000587ngx_mail_core_protocol(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
588{
589 ngx_mail_core_srv_conf_t *cscf = conf;
590
591 ngx_str_t *value;
592 ngx_uint_t m;
593 ngx_mail_module_t *module;
594
595 value = cf->args->elts;
596
Maxim Dounin55c74592016-02-04 18:30:21 +0300597 for (m = 0; cf->cycle->modules[m]; m++) {
598 if (cf->cycle->modules[m]->type != NGX_MAIL_MODULE) {
Igor Sysoev48714082007-09-15 16:51:16 +0000599 continue;
600 }
601
Maxim Dounin55c74592016-02-04 18:30:21 +0300602 module = cf->cycle->modules[m]->ctx;
Igor Sysoev48714082007-09-15 16:51:16 +0000603
604 if (module->protocol
605 && ngx_strcmp(module->protocol->name.data, value[1].data) == 0)
606 {
607 cscf->protocol = module->protocol;
608
609 return NGX_CONF_OK;
610 }
611 }
612
613 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
614 "unknown protocol \"%V\"", &value[1]);
615 return NGX_CONF_ERROR;
616}
617
618
Igor Sysoev45450462008-02-13 13:50:04 +0000619static char *
Vladimir Homutov2b01f262015-02-20 15:31:37 +0300620ngx_mail_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
621{
622 ngx_mail_core_srv_conf_t *cscf = conf;
623
624 return ngx_log_set_log(cf, &cscf->error_log);
625}
626
627
628static char *
Igor Sysoev45450462008-02-13 13:50:04 +0000629ngx_mail_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
630{
631 ngx_mail_core_srv_conf_t *cscf = conf;
632
Igor Sysoev45450462008-02-13 13:50:04 +0000633 ngx_str_t *value;
634
635 value = cf->args->elts;
636
Igor Sysoev73eb97f2008-03-06 08:48:25 +0000637 if (cscf->resolver != NGX_CONF_UNSET_PTR) {
638 return "is duplicate";
639 }
640
Igor Sysoev5fa11462008-02-16 13:46:33 +0000641 if (ngx_strcmp(value[1].data, "off") == 0) {
642 cscf->resolver = NULL;
643 return NGX_CONF_OK;
644 }
645
Igor Sysoev62071812011-10-24 16:09:05 +0000646 cscf->resolver = ngx_resolver_create(cf, &value[1], cf->args->nelts - 1);
Igor Sysoev45450462008-02-13 13:50:04 +0000647 if (cscf->resolver == NULL) {
Igor Sysoev62071812011-10-24 16:09:05 +0000648 return NGX_CONF_ERROR;
Igor Sysoev45450462008-02-13 13:50:04 +0000649 }
650
651 return NGX_CONF_OK;
652}
653
654
Igor Sysoev48714082007-09-15 16:51:16 +0000655char *
656ngx_mail_capabilities(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev02c8d182007-03-19 13:36:56 +0000657{
658 char *p = conf;
659
660 ngx_str_t *c, *value;
661 ngx_uint_t i;
662 ngx_array_t *a;
663
664 a = (ngx_array_t *) (p + cmd->offset);
665
666 value = cf->args->elts;
667
668 for (i = 1; i < cf->args->nelts; i++) {
669 c = ngx_array_push(a);
670 if (c == NULL) {
671 return NGX_CONF_ERROR;
672 }
673
674 *c = value[i];
675 }
676
677 return NGX_CONF_OK;
678}