ПРОЕКТЫ 


  АРХИВ 


Apache-Talk @lexa.ru 

Inet-Admins @info.east.ru 

Filmscanners @halftone.co.uk 

Security-alerts @yandex-team.ru 

nginx-ru @sysoev.ru 


  СТАТЬИ 


  ПЕРСОНАЛЬНОЕ 


  ПРОГРАММЫ 



ПИШИТЕ
ПИСЬМА












     АРХИВ :: nginx-ru
Nginx-ru mailing list archive (nginx-ru@sysoev.ru)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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



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.

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



 




Copyright © Lexa Software, 1996-2009.