comparison src/mail/ngx_mail_core_module.c @ 570:9773720b845e

Merge with 0.8.16.
author Maxim Dounin <mdounin@mdounin.ru>
date Sat, 26 Sep 2009 01:25:07 +0400
parents 1e91f9968443 f39b9e29530d
children
comparison
equal deleted inserted replaced
511:1e91f9968443 570:9773720b845e
118 { 118 {
119 ngx_mail_core_main_conf_t *cmcf; 119 ngx_mail_core_main_conf_t *cmcf;
120 120
121 cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_core_main_conf_t)); 121 cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_core_main_conf_t));
122 if (cmcf == NULL) { 122 if (cmcf == NULL) {
123 return NGX_CONF_ERROR; 123 return NULL;
124 } 124 }
125 125
126 if (ngx_array_init(&cmcf->servers, cf->pool, 4, 126 if (ngx_array_init(&cmcf->servers, cf->pool, 4,
127 sizeof(ngx_mail_core_srv_conf_t *)) 127 sizeof(ngx_mail_core_srv_conf_t *))
128 != NGX_OK) 128 != NGX_OK)
129 { 129 {
130 return NGX_CONF_ERROR; 130 return NULL;
131 } 131 }
132 132
133 if (ngx_array_init(&cmcf->listen, cf->pool, 4, sizeof(ngx_mail_listen_t)) 133 if (ngx_array_init(&cmcf->listen, cf->pool, 4, sizeof(ngx_mail_listen_t))
134 != NGX_OK) 134 != NGX_OK)
135 { 135 {
136 return NGX_CONF_ERROR; 136 return NULL;
137 } 137 }
138 138
139 return cmcf; 139 return cmcf;
140 } 140 }
141 141
272 272
273 return rv; 273 return rv;
274 } 274 }
275 275
276 276
277 /* AF_INET only */
278
279 static char * 277 static char *
280 ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 278 ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
281 { 279 {
282 ngx_mail_core_srv_conf_t *cscf = conf; 280 ngx_mail_core_srv_conf_t *cscf = conf;
283 281
282 size_t len, off;
283 in_port_t port;
284 ngx_str_t *value; 284 ngx_str_t *value;
285 ngx_url_t u; 285 ngx_url_t u;
286 ngx_uint_t i, m; 286 ngx_uint_t i, m;
287 ngx_mail_listen_t *imls; 287 struct sockaddr *sa;
288 ngx_mail_listen_t *ls;
288 ngx_mail_module_t *module; 289 ngx_mail_module_t *module;
290 struct sockaddr_in *sin;
289 ngx_mail_core_main_conf_t *cmcf; 291 ngx_mail_core_main_conf_t *cmcf;
292 #if (NGX_HAVE_INET6)
293 struct sockaddr_in6 *sin6;
294 #endif
290 295
291 value = cf->args->elts; 296 value = cf->args->elts;
292 297
293 ngx_memzero(&u, sizeof(ngx_url_t)); 298 ngx_memzero(&u, sizeof(ngx_url_t));
294 299
303 } 308 }
304 309
305 return NGX_CONF_ERROR; 310 return NGX_CONF_ERROR;
306 } 311 }
307 312
308 if (u.family != AF_INET) {
309 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "listen supports IPv4 only");
310 return NGX_CONF_ERROR;
311 }
312
313 cmcf = ngx_mail_conf_get_module_main_conf(cf, ngx_mail_core_module); 313 cmcf = ngx_mail_conf_get_module_main_conf(cf, ngx_mail_core_module);
314 314
315 imls = cmcf->listen.elts; 315 ls = cmcf->listen.elts;
316 316
317 for (i = 0; i < cmcf->listen.nelts; i++) { 317 for (i = 0; i < cmcf->listen.nelts; i++) {
318 318
319 if (imls[i].addr != u.addr.in_addr || imls[i].port != u.port) { 319 sa = (struct sockaddr *) ls[i].sockaddr;
320
321 if (sa->sa_family != u.family) {
322 continue;
323 }
324
325 switch (sa->sa_family) {
326
327 #if (NGX_HAVE_INET6)
328 case AF_INET6:
329 off = offsetof(struct sockaddr_in6, sin6_addr);
330 len = 16;
331 sin6 = (struct sockaddr_in6 *) sa;
332 port = sin6->sin6_port;
333 break;
334 #endif
335
336 default: /* AF_INET */
337 off = offsetof(struct sockaddr_in, sin_addr);
338 len = 4;
339 sin = (struct sockaddr_in *) sa;
340 port = sin->sin_port;
341 break;
342 }
343
344 if (ngx_memcmp(ls[i].sockaddr + off, u.sockaddr + off, len) != 0) {
345 continue;
346 }
347
348 if (port != u.port) {
320 continue; 349 continue;
321 } 350 }
322 351
323 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 352 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
324 "duplicate \"%V\" address and port pair", &u.url); 353 "duplicate \"%V\" address and port pair", &u.url);
325 return NGX_CONF_ERROR; 354 return NGX_CONF_ERROR;
326 } 355 }
327 356
328 imls = ngx_array_push(&cmcf->listen); 357 ls = ngx_array_push(&cmcf->listen);
329 if (imls == NULL) { 358 if (ls == NULL) {
330 return NGX_CONF_ERROR; 359 return NGX_CONF_ERROR;
331 } 360 }
332 361
333 ngx_memzero(imls, sizeof(ngx_mail_listen_t)); 362 ngx_memzero(ls, sizeof(ngx_mail_listen_t));
334 363
335 imls->addr = u.addr.in_addr; 364 ngx_memcpy(ls->sockaddr, u.sockaddr, u.socklen);
336 imls->port = u.port; 365
337 imls->family = u.family; 366 ls->socklen = u.socklen;
338 imls->ctx = cf->ctx; 367 ls->wildcard = u.wildcard;
368 ls->ctx = cf->ctx;
339 369
340 for (m = 0; ngx_modules[m]; m++) { 370 for (m = 0; ngx_modules[m]; m++) {
341 if (ngx_modules[m]->type != NGX_MAIL_MODULE) { 371 if (ngx_modules[m]->type != NGX_MAIL_MODULE) {
342 continue; 372 continue;
343 } 373 }
357 } 387 }
358 388
359 for (i = 2; i < cf->args->nelts; i++) { 389 for (i = 2; i < cf->args->nelts; i++) {
360 390
361 if (ngx_strcmp(value[i].data, "bind") == 0) { 391 if (ngx_strcmp(value[i].data, "bind") == 0) {
362 imls->bind = 1; 392 ls->bind = 1;
363 continue; 393 continue;
394 }
395
396 if (ngx_strncmp(value[i].data, "ipv6only=o", 10) == 0) {
397 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
398 struct sockaddr *sa;
399 u_char buf[NGX_SOCKADDR_STRLEN];
400
401 sa = (struct sockaddr *) ls->sockaddr;
402
403 if (sa->sa_family == AF_INET6) {
404
405 if (ngx_strcmp(&value[i].data[10], "n") == 0) {
406 ls->ipv6only = 1;
407
408 } else if (ngx_strcmp(&value[i].data[10], "ff") == 0) {
409 ls->ipv6only = 2;
410
411 } else {
412 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
413 "invalid ipv6only flags \"%s\"",
414 &value[i].data[9]);
415 return NGX_CONF_ERROR;
416 }
417
418 ls->bind = 1;
419
420 } else {
421 len = ngx_sock_ntop(sa, buf, NGX_SOCKADDR_STRLEN, 1);
422
423 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
424 "ipv6only is not supported "
425 "on addr \"%*s\", ignored", len, buf);
426 }
427
428 continue;
429 #else
430 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
431 "bind ipv6only is not supported "
432 "on this platform");
433 return NGX_CONF_ERROR;
434 #endif
364 } 435 }
365 436
366 if (ngx_strcmp(value[i].data, "ssl") == 0) { 437 if (ngx_strcmp(value[i].data, "ssl") == 0) {
367 #if (NGX_MAIL_SSL) 438 #if (NGX_MAIL_SSL)
368 imls->ssl = 1; 439 ls->ssl = 1;
369 continue; 440 continue;
370 #else 441 #else
371 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 442 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
372 "the \"ssl\" parameter requires " 443 "the \"ssl\" parameter requires "
373 "ngx_mail_ssl_module"); 444 "ngx_mail_ssl_module");