nginx + default {deferred|bind} = корки

Alex Vorona voron at amhost.net
Wed May 30 02:14:26 MSD 2007


Igor Sysoev пишет:
> On Tue, May 29, 2007 at 07:57:56PM +0400, Александр Ворона wrote:
> 
>> Igor Sysoev пишет:
>>
>>> FreeBSD позволяет bind() to 127.0.0.1:80 и *:80 в любом порядке.
>>> Насчёт Линукса - нужно проверить.
>>>
>> netstat -tnepl|grep cfg.txt
>> tcp        0      0 0.0.0.0:82                  0.0.0.0:* 
>>     LISTEN      0          85904536   19582/cfg.txt
>>
>> нет bind() на 127.0.0.1:82
> 
> У меня воспроизводится эта ошибка, причём даже для такого непересекающегося
> варианта:
> 
>       listen  127.0.0.1:8000 default bind;
>       listen  192.168.1.1:8000 default bind;
> 
> Второй listen всегда вылетает с ошибкой (98: Address already in use).
> Проверялось на ядре 2.6.16.13.

2.6.9 с ipv6 - на разных ИП без проблем.
Попробовал

        server {
            listen     127.0.0.1:82 default bind;
        }

        server{
            listen     82 default bind;
        }
вообще хорошо - воркер быстренько нагнал мне 300М логов вида

accept() failed (22: Invalid argument) while accepting new connection on 0.0.0.0:82
Причём первой строчкой была
2007/05/29 16:30:40 [alert] 23161#0: changing the listen() backlog to -1 for 
0.0.0.0:82 failed, ignored (98: Address already in use)

strace
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 9
setsockopt(9, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
ioctl(9, FIONBIO, [1])                  = 0
bind(9, {sa_family=AF_INET, sin_port=htons(82), 
sin_addr=inet_addr("127.0.0.1")}, 16) = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 10
setsockopt(10, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
ioctl(10, FIONBIO, [1])                 = 0
bind(10, {sa_family=AF_INET, sin_port=htons(82), sin_addr=inet_addr("0.0.0.0")}, 
16) = 0
listen(9, 4294967295)                   = 0
listen(10, 4294967295)                  = -1 EADDRINUSE (Address already in use)
write(4, "2007/05/29 16:38:45 [alert] 2327"..., 133) = 133

те 2 default bind на пересекающихся диапазонах IP:port не привели ни к чему 
хорошему, кроме того, listen на 127.0.0.1:port блокирует последующий listen на 
*:port

> Здесь есть две странности:
> 1) эта ошибка должна по идее выдаваться ещё на стадии bind(),
> 2) эта ошибка не должна выдаваться для непересекающихся адресов (по крайней
>    мере, во FreeBSD с этим не возникает никаких проблем).
> 
> Есть подозрение на присутствие в ядре ipv6 (хотя nginx о нём не подозревает).
> 
> Можно попробовать собрать ядро без ipv6 ?
> 

2.6.20.3 x86_64 и было без ipv6

на непересекающихся ИП ошибки нет

А во FreeBSD при listen на пересекающихся ИП подключение приходит на более 
точный bind из двух возможных?

man 7 socket в Linux
SO_REUSEADDR
Indicates that the rules used in validating addresses supplied in a bind(2) call 
should allow reuse of  local addresses. For PF_INET sockets this means that a 
socket may bind, except when there is an active listening socket bound to the 
address.  When the listening socket  is  bound  to  INADDR_ANY with a specific 
port then it is not possible to bind to this port for any local address.

Вот как раз и имеем ту ситуацию, с которой начался тред.





More information about the nginx-ru mailing list