comparison src/stream/ngx_stream_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 fe767c99c2ad
children 2ab7b55ae4a0 893b3313f53c
comparison
equal deleted inserted replaced
7477:c74904a17021 7478:4f9b72a229c1
575 { 575 {
576 ngx_stream_core_srv_conf_t *cscf = conf; 576 ngx_stream_core_srv_conf_t *cscf = conf;
577 577
578 ngx_str_t *value, size; 578 ngx_str_t *value, size;
579 ngx_url_t u; 579 ngx_url_t u;
580 ngx_uint_t i, backlog; 580 ngx_uint_t i, n, backlog;
581 ngx_stream_listen_t *ls, *als; 581 ngx_stream_listen_t *ls, *als;
582 ngx_stream_core_main_conf_t *cmcf; 582 ngx_stream_core_main_conf_t *cmcf;
583 583
584 cscf->listen = 1; 584 cscf->listen = 1;
585 585
600 return NGX_CONF_ERROR; 600 return NGX_CONF_ERROR;
601 } 601 }
602 602
603 cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); 603 cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module);
604 604
605 ls = ngx_array_push(&cmcf->listen); 605 ls = ngx_array_push_n(&cmcf->listen, u.naddrs);
606 if (ls == NULL) { 606 if (ls == NULL) {
607 return NGX_CONF_ERROR; 607 return NGX_CONF_ERROR;
608 } 608 }
609 609
610 ngx_memzero(ls, sizeof(ngx_stream_listen_t)); 610 ngx_memzero(ls, sizeof(ngx_stream_listen_t));
611 611
612 ngx_memcpy(&ls->sockaddr.sockaddr, &u.sockaddr, u.socklen);
613
614 ls->socklen = u.socklen;
615 ls->backlog = NGX_LISTEN_BACKLOG; 612 ls->backlog = NGX_LISTEN_BACKLOG;
616 ls->rcvbuf = -1; 613 ls->rcvbuf = -1;
617 ls->sndbuf = -1; 614 ls->sndbuf = -1;
618 ls->type = SOCK_STREAM; 615 ls->type = SOCK_STREAM;
619 ls->wildcard = u.wildcard;
620 ls->ctx = cf->ctx; 616 ls->ctx = cf->ctx;
621 617
622 #if (NGX_HAVE_INET6) 618 #if (NGX_HAVE_INET6)
623 ls->ipv6only = 1; 619 ls->ipv6only = 1;
624 #endif 620 #endif
686 continue; 682 continue;
687 } 683 }
688 684
689 if (ngx_strncmp(value[i].data, "ipv6only=o", 10) == 0) { 685 if (ngx_strncmp(value[i].data, "ipv6only=o", 10) == 0) {
690 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) 686 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
691 size_t len; 687 if (ngx_strcmp(&value[i].data[10], "n") == 0) {
692 u_char buf[NGX_SOCKADDR_STRLEN]; 688 ls->ipv6only = 1;
693 689
694 if (ls->sockaddr.sockaddr.sa_family == AF_INET6) { 690 } else if (ngx_strcmp(&value[i].data[10], "ff") == 0) {
695 691 ls->ipv6only = 0;
696 if (ngx_strcmp(&value[i].data[10], "n") == 0) {
697 ls->ipv6only = 1;
698
699 } else if (ngx_strcmp(&value[i].data[10], "ff") == 0) {
700 ls->ipv6only = 0;
701
702 } else {
703 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
704 "invalid ipv6only flags \"%s\"",
705 &value[i].data[9]);
706 return NGX_CONF_ERROR;
707 }
708
709 ls->bind = 1;
710 692
711 } else { 693 } else {
712 len = ngx_sock_ntop(&ls->sockaddr.sockaddr, ls->socklen, buf,
713 NGX_SOCKADDR_STRLEN, 1);
714
715 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 694 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
716 "ipv6only is not supported " 695 "invalid ipv6only flags \"%s\"",
717 "on addr \"%*s\", ignored", len, buf); 696 &value[i].data[9]);
697 return NGX_CONF_ERROR;
718 } 698 }
719 699
700 ls->bind = 1;
720 continue; 701 continue;
721 #else 702 #else
722 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 703 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
723 "bind ipv6only is not supported " 704 "bind ipv6only is not supported "
724 "on this platform"); 705 "on this platform");
880 } 861 }
881 } 862 }
882 863
883 als = cmcf->listen.elts; 864 als = cmcf->listen.elts;
884 865
885 for (i = 0; i < cmcf->listen.nelts - 1; i++) { 866 for (n = 0; n < u.naddrs; n++) {
886 if (ls->type != als[i].type) { 867 ls[n] = ls[0];
887 continue; 868
888 } 869 ls[n].sockaddr = u.addrs[n].sockaddr;
889 870 ls[n].socklen = u.addrs[n].socklen;
890 if (ngx_cmp_sockaddr(&als[i].sockaddr.sockaddr, als[i].socklen, 871 ls[n].addr_text = u.addrs[n].name;
891 &ls->sockaddr.sockaddr, ls->socklen, 1) 872 ls[n].wildcard = ngx_inet_wildcard(ls[n].sockaddr);
892 != NGX_OK) 873
893 { 874 for (i = 0; i < cmcf->listen.nelts - u.naddrs + n; i++) {
894 continue; 875 if (ls[n].type != als[i].type) {
895 } 876 continue;
896 877 }
897 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 878
898 "duplicate \"%V\" address and port pair", &u.url); 879 if (ngx_cmp_sockaddr(als[i].sockaddr, als[i].socklen,
899 return NGX_CONF_ERROR; 880 ls[n].sockaddr, ls[n].socklen, 1)
881 != NGX_OK)
882 {
883 continue;
884 }
885
886 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
887 "duplicate \"%V\" address and port pair",
888 &ls[n].addr_text);
889 return NGX_CONF_ERROR;
890 }
900 } 891 }
901 892
902 return NGX_CONF_OK; 893 return NGX_CONF_OK;
903 } 894 }
904 895