Mercurial > hg > nginx
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 |