Mercurial > hg > nginx
comparison src/stream/ngx_stream_core_module.c @ 8104:4cc2bfeff46c
Filtering duplicate addresses in listen (ticket #2400).
Due to the glibc bug[1], getaddrinfo("localhost") with AI_ADDRCONFIG
on a typical host with glibc and without IPv6 returns two 127.0.0.1
addresses, and therefore "listen localhost:80;" used to result in
"duplicate ... address and port pair" after 4f9b72a229c1.
Fix is to explicitly filter out duplicate addresses returned during
resolution of a name.
[1] https://sourceware.org/bugzilla/show_bug.cgi?id=14969
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Wed, 23 Nov 2022 17:30:08 +0300 |
parents | 2ab7b55ae4a0 |
children | 2af1287d2da7 91ad1abfb285 |
comparison
equal
deleted
inserted
replaced
8103:b809f53d3f5b | 8104:4cc2bfeff46c |
---|---|
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, n, backlog; | 580 ngx_uint_t i, n, backlog; |
581 ngx_stream_listen_t *ls, *als; | 581 ngx_stream_listen_t *ls, *als, *nls; |
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 |
586 value = cf->args->elts; | 586 value = cf->args->elts; |
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_n(&cmcf->listen, u.naddrs); | 605 ls = ngx_array_push(&cmcf->listen); |
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)); |
884 return "\"fastopen\" parameter is incompatible with \"udp\""; | 884 return "\"fastopen\" parameter is incompatible with \"udp\""; |
885 } | 885 } |
886 #endif | 886 #endif |
887 } | 887 } |
888 | 888 |
889 als = cmcf->listen.elts; | |
890 | |
891 for (n = 0; n < u.naddrs; n++) { | 889 for (n = 0; n < u.naddrs; n++) { |
892 ls[n] = ls[0]; | 890 |
893 | 891 for (i = 0; i < n; i++) { |
894 ls[n].sockaddr = u.addrs[n].sockaddr; | 892 if (ngx_cmp_sockaddr(u.addrs[n].sockaddr, u.addrs[n].socklen, |
895 ls[n].socklen = u.addrs[n].socklen; | 893 u.addrs[i].sockaddr, u.addrs[i].socklen, 0) |
896 ls[n].addr_text = u.addrs[n].name; | 894 == NGX_OK) |
897 ls[n].wildcard = ngx_inet_wildcard(ls[n].sockaddr); | 895 { |
898 | 896 goto next; |
899 for (i = 0; i < cmcf->listen.nelts - u.naddrs + n; i++) { | 897 } |
900 if (ls[n].type != als[i].type) { | 898 } |
899 | |
900 if (n != 0) { | |
901 nls = ngx_array_push(&cmcf->listen); | |
902 if (nls == NULL) { | |
903 return NGX_CONF_ERROR; | |
904 } | |
905 | |
906 *nls = *ls; | |
907 | |
908 } else { | |
909 nls = ls; | |
910 } | |
911 | |
912 nls->sockaddr = u.addrs[n].sockaddr; | |
913 nls->socklen = u.addrs[n].socklen; | |
914 nls->addr_text = u.addrs[n].name; | |
915 nls->wildcard = ngx_inet_wildcard(nls->sockaddr); | |
916 | |
917 als = cmcf->listen.elts; | |
918 | |
919 for (i = 0; i < cmcf->listen.nelts - 1; i++) { | |
920 if (nls->type != als[i].type) { | |
901 continue; | 921 continue; |
902 } | 922 } |
903 | 923 |
904 if (ngx_cmp_sockaddr(als[i].sockaddr, als[i].socklen, | 924 if (ngx_cmp_sockaddr(als[i].sockaddr, als[i].socklen, |
905 ls[n].sockaddr, ls[n].socklen, 1) | 925 nls->sockaddr, nls->socklen, 1) |
906 != NGX_OK) | 926 != NGX_OK) |
907 { | 927 { |
908 continue; | 928 continue; |
909 } | 929 } |
910 | 930 |
911 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 931 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
912 "duplicate \"%V\" address and port pair", | 932 "duplicate \"%V\" address and port pair", |
913 &ls[n].addr_text); | 933 &nls->addr_text); |
914 return NGX_CONF_ERROR; | 934 return NGX_CONF_ERROR; |
915 } | 935 } |
936 | |
937 next: | |
938 continue; | |
916 } | 939 } |
917 | 940 |
918 return NGX_CONF_OK; | 941 return NGX_CONF_OK; |
919 } | 942 } |
920 | 943 |