comparison src/mail/ngx_mail_core_module.c @ 7478:4f9b72a229c1

Multiple addresses in "listen". Previously only one address was used by the listen directive handler even if host name resolved to multiple addresses. Now a separate listening socket is created for each address.
author Roman Arutyunyan <arut@nginx.com>
date Fri, 15 Mar 2019 15:45:56 +0300
parents 7f955d3b9a0d
children 12ea1de7d87c
comparison
equal deleted inserted replaced
7477:c74904a17021 7478:4f9b72a229c1
295 { 295 {
296 ngx_mail_core_srv_conf_t *cscf = conf; 296 ngx_mail_core_srv_conf_t *cscf = conf;
297 297
298 ngx_str_t *value, size; 298 ngx_str_t *value, size;
299 ngx_url_t u; 299 ngx_url_t u;
300 ngx_uint_t i, m; 300 ngx_uint_t i, n, m;
301 ngx_mail_listen_t *ls; 301 ngx_mail_listen_t *ls, *als;
302 ngx_mail_module_t *module; 302 ngx_mail_module_t *module;
303 ngx_mail_core_main_conf_t *cmcf; 303 ngx_mail_core_main_conf_t *cmcf;
304 304
305 cscf->listen = 1; 305 cscf->listen = 1;
306 306
321 return NGX_CONF_ERROR; 321 return NGX_CONF_ERROR;
322 } 322 }
323 323
324 cmcf = ngx_mail_conf_get_module_main_conf(cf, ngx_mail_core_module); 324 cmcf = ngx_mail_conf_get_module_main_conf(cf, ngx_mail_core_module);
325 325
326 ls = cmcf->listen.elts; 326 ls = ngx_array_push_n(&cmcf->listen, u.naddrs);
327
328 for (i = 0; i < cmcf->listen.nelts; i++) {
329
330 if (ngx_cmp_sockaddr(&ls[i].sockaddr.sockaddr, ls[i].socklen,
331 (struct sockaddr *) &u.sockaddr, u.socklen, 1)
332 != NGX_OK)
333 {
334 continue;
335 }
336
337 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
342 ls = ngx_array_push(&cmcf->listen);
343 if (ls == NULL) { 327 if (ls == NULL) {
344 return NGX_CONF_ERROR; 328 return NGX_CONF_ERROR;
345 } 329 }
346 330
347 ngx_memzero(ls, sizeof(ngx_mail_listen_t)); 331 ngx_memzero(ls, sizeof(ngx_mail_listen_t));
348 332
349 ngx_memcpy(&ls->sockaddr.sockaddr, &u.sockaddr, u.socklen);
350
351 ls->socklen = u.socklen;
352 ls->backlog = NGX_LISTEN_BACKLOG; 333 ls->backlog = NGX_LISTEN_BACKLOG;
353 ls->rcvbuf = -1; 334 ls->rcvbuf = -1;
354 ls->sndbuf = -1; 335 ls->sndbuf = -1;
355 ls->wildcard = u.wildcard;
356 ls->ctx = cf->ctx; 336 ls->ctx = cf->ctx;
357 337
358 #if (NGX_HAVE_INET6) 338 #if (NGX_HAVE_INET6)
359 ls->ipv6only = 1; 339 ls->ipv6only = 1;
360 #endif 340 #endif
432 continue; 412 continue;
433 } 413 }
434 414
435 if (ngx_strncmp(value[i].data, "ipv6only=o", 10) == 0) { 415 if (ngx_strncmp(value[i].data, "ipv6only=o", 10) == 0) {
436 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) 416 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
437 size_t len; 417 if (ngx_strcmp(&value[i].data[10], "n") == 0) {
438 u_char buf[NGX_SOCKADDR_STRLEN]; 418 ls->ipv6only = 1;
439 419
440 if (ls->sockaddr.sockaddr.sa_family == AF_INET6) { 420 } else if (ngx_strcmp(&value[i].data[10], "ff") == 0) {
441 421 ls->ipv6only = 0;
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) {
446 ls->ipv6only = 0;
447
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 422
457 } else { 423 } else {
458 len = ngx_sock_ntop(&ls->sockaddr.sockaddr, ls->socklen, buf,
459 NGX_SOCKADDR_STRLEN, 1);
460
461 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 424 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
462 "ipv6only is not supported " 425 "invalid ipv6only flags \"%s\"",
463 "on addr \"%*s\", ignored", len, buf); 426 &value[i].data[9]);
464 } 427 return NGX_CONF_ERROR;
465 428 }
429
430 ls->bind = 1;
466 continue; 431 continue;
467 #else 432 #else
468 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 433 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
469 "bind ipv6only is not supported " 434 "bind ipv6only is not supported "
470 "on this platform"); 435 "on this platform");
586 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 551 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
587 "the invalid \"%V\" parameter", &value[i]); 552 "the invalid \"%V\" parameter", &value[i]);
588 return NGX_CONF_ERROR; 553 return NGX_CONF_ERROR;
589 } 554 }
590 555
556 als = cmcf->listen.elts;
557
558 for (n = 0; n < u.naddrs; n++) {
559 ls[n] = ls[0];
560
561 ls[n].sockaddr = u.addrs[n].sockaddr;
562 ls[n].socklen = u.addrs[n].socklen;
563 ls[n].addr_text = u.addrs[n].name;
564 ls[n].wildcard = ngx_inet_wildcard(ls[n].sockaddr);
565
566 for (i = 0; i < cmcf->listen.nelts - u.naddrs + n; i++) {
567
568 if (ngx_cmp_sockaddr(als[i].sockaddr, als[i].socklen,
569 ls[n].sockaddr, ls[n].socklen, 1)
570 != NGX_OK)
571 {
572 continue;
573 }
574
575 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
576 "duplicate \"%V\" address and port pair",
577 &ls[n].addr_text);
578 return NGX_CONF_ERROR;
579 }
580 }
581
591 return NGX_CONF_OK; 582 return NGX_CONF_OK;
592 } 583 }
593 584
594 585
595 static char * 586 static char *