diff options
author | Maxim Dounin <mdounin@mdounin.ru> | 2022-11-23 17:30:08 +0300 |
---|---|---|
committer | Maxim Dounin <mdounin@mdounin.ru> | 2022-11-23 17:30:08 +0300 |
commit | 22223c75c9715e568f5710a8eed1fee9e7c2983f (patch) | |
tree | 09d21b13a921c385119565c107b15f0ae66a4578 /src/http/ngx_http_core_module.c | |
parent | 17066ac8600412eabb1fdf8360cf6ada13f02391 (diff) | |
download | nginx-22223c75c9715e568f5710a8eed1fee9e7c2983f.tar.gz nginx-22223c75c9715e568f5710a8eed1fee9e7c2983f.zip |
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
Diffstat (limited to 'src/http/ngx_http_core_module.c')
-rw-r--r-- | src/http/ngx_http_core_module.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index 28f7d99b4..2647e7cd0 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -3963,7 +3963,7 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ngx_str_t *value, size; ngx_url_t u; - ngx_uint_t n; + ngx_uint_t n, i; ngx_http_listen_opt_t lsopt; cscf->listen = 1; @@ -4289,6 +4289,16 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) } for (n = 0; n < u.naddrs; n++) { + + for (i = 0; i < n; i++) { + if (ngx_cmp_sockaddr(u.addrs[n].sockaddr, u.addrs[n].socklen, + u.addrs[i].sockaddr, u.addrs[i].socklen, 0) + == NGX_OK) + { + goto next; + } + } + lsopt.sockaddr = u.addrs[n].sockaddr; lsopt.socklen = u.addrs[n].socklen; lsopt.addr_text = u.addrs[n].name; @@ -4297,6 +4307,9 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) if (ngx_http_add_listen(cf, cscf, &lsopt) != NGX_OK) { return NGX_CONF_ERROR; } + + next: + continue; } return NGX_CONF_OK; |