Сокеты-зомби?
От: Linuxoid  
Дата: 26.08.04 14:45
Оценка:
Кто-нибудь может обяъянить, почему после подключения к серверу и последующего отключения от него socklist (Linux) еще некоторое время показывает "мертвый" сокет? Если интенсивно подключаться к серверу и отключаться от него, число таких "сокетов-зомби" растет. Может ли это привести к Deny Of Service? (новые сокеты создаются accept()-ом, close() по окончанию работы с новым сокетом вызываю)


./socklist
type  port      inode     uid    pid   fd  name
tcp   3306       1367       0    862    3  mysqld
tcp   2002       1365       0   2447   17  httpd
tcp   2037    1490181     503    524    6  sender
tcp     21       1169       0    693    5  xinetd
tcp   2038    1470126     503    359    4  controld
tcp     22       1103       0    660    3  sshd
tcp     25     209910       0    721    4  sendmail
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2002          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2002          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp     22    1461092       0  32581    4  sshd
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2038    1541520     503    359    5  controld
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp     22    1438197       0  32190    4  sshd
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
tcp   2037          0       0      0    0
udp  32821    1490182     503    524    7  sender
Re: Сокеты-зомби?
От: jedi Мухосранск  
Дата: 26.08.04 14:54
Оценка:
Здравствуйте, Linuxoid, Вы писали:

L>Кто-нибудь может обяъянить, почему после подключения к серверу и последующего отключения от него socklist (Linux) еще некоторое время показывает "мертвый" сокет? Если интенсивно подключаться к серверу и отключаться от него, число таких "сокетов-зомби" растет. Может ли это привести к Deny Of Service? (новые сокеты создаются accept()-ом, close() по окончанию работы с новым сокетом вызываю)



После закрытия соединения сокет переходит в состояние TIMED_WAIT2 и находится в нем 75 — 300 секунд (в зависимости от настроек ОС, а вообще не меньше чем 2*ВРЕМЯ ЖИЗНИ ПАКЕТА В СЕТИ). Это сделано для того, чтобы пакеты из предыдущего соединения, затерявшиеся в сети не попали в новое. Более подробно об этом можно прочитать в книжке Стивенса "Unix Network Programming".
Re[2]: Сокеты-зомби?
От: Linuxoid  
Дата: 26.08.04 15:06
Оценка: :)
Здравствуйте, jedi, Вы писали:

J>После закрытия соединения сокет переходит в состояние TIMED_WAIT2 и находится в нем 75 — 300 секунд.


А это может привести к DOS? (например если за 300 секунд успеет наплодиться 65000 сокетов, или сколько их там может быть по максимуму)
Можно как-то убрать эти 300 секунд?
Re[3]: Сокеты-зомби?
От: jedi Мухосранск  
Дата: 26.08.04 15:38
Оценка:
Здравствуйте, Linuxoid, Вы писали:

L>А это может привести к DOS? (например если за 300 секунд успеет наплодиться 65000 сокетов, или сколько их там может быть по максимуму)


Конечно, и приводит (при хакерских атаках).

L>Можно как-то убрать эти 300 секунд?


Убрать наверно можно как-то административным путем (в зависимости от ОС).
Но надо ли ? Наверное так не зря сделано, иначе будешь какую-то фигню в новом сокете получать
при плохой связи.
Re[3]: Сокеты-зомби?
От: NavuhodonosoR Россия  
Дата: 26.08.04 17:23
Оценка:
Здравствуйте, Linuxoid, Вы писали:

J>>После закрытия соединения сокет переходит в состояние TIMED_WAIT2 и находится в нем 75 — 300 секунд.

L>Можно как-то убрать эти 300 секунд?

Кажется можно, но не уверен. Смотреть в сторону setsockopt(SO_LINGER)
Re: Сокеты-зомби?
От: aka50 Россия  
Дата: 26.08.04 20:54
Оценка: 9 (1)
Здравствуйте, Linuxoid, Вы писали:

L>Кто-нибудь может обяъянить, почему после подключения к серверу и последующего отключения от него socklist (Linux) еще некоторое время показывает "мертвый" сокет? Если интенсивно подключаться к серверу и отключаться от него, число таких "сокетов-зомби" растет. Может ли это привести к Deny Of Service? (новые сокеты создаются accept()-ом, close() по окончанию работы с новым сокетом вызываю)


Вот диаграмма fsm для TCP.

                              +---------+ ---------\      active OPEN  
                              |  CLOSED |            \    -----------  
                              +---------+<---------\   \   create TCB  
                                |     ^              \   \  snd SYN    
                   passive OPEN |     |   CLOSE        \   \           
                   ------------ |     | ----------       \   \         
                    create TCB  |     | delete TCB         \   \       
                                V     |                      \   \     
                              +---------+            CLOSE    |    \   
                              |  LISTEN |          ---------- |     |  
                              +---------+          delete TCB |     |  
                   rcv SYN      |     |     SEND              |     |  
                  -----------   |     |    -------            |     V  
 +---------+      snd SYN,ACK  /       \   snd SYN          +---------+
 |         |<-----------------           ------------------>|         |
 |   SYN   |                    rcv SYN                     |   SYN   |
 |   RCVD  |<-----------------------------------------------|   SENT  |
 |         |                    snd ACK                     |         |
 |         |------------------           -------------------|         |
 +---------+   rcv ACK of SYN  \       /  rcv SYN,ACK       +---------+
   |           --------------   |     |   -----------                  
   |                  x         |     |     snd ACK                    
   |                            V     V                                
   |  CLOSE                   +---------+                              
   | -------                  |  ESTAB  |                              
   | snd FIN                  +---------+                              
   |                   CLOSE    |     |    rcv FIN                     
   V                  -------   |     |    -------                     
 +---------+          snd FIN  /       \   snd ACK          +---------+
 |  FIN    |<-----------------           ------------------>|  CLOSE  |
 | WAIT-1  |------------------                              |   WAIT  |
 +---------+          rcv FIN  \                            +---------+
   | rcv ACK of FIN   -------   |                            CLOSE  |  
   | --------------   snd ACK   |                           ------- |  
   V        x                   V                           snd FIN V  
 +---------+                  +---------+                   +---------+
 |FINWAIT-2|                  | CLOSING |                   | LAST-ACK|
 +---------+                  +---------+                   +---------+
   |                rcv ACK of FIN |                 rcv ACK of FIN |  
   |  rcv FIN       -------------- |    Timeout=2MSL -------------- |  
   |  -------              x       V    ------------        x       V  
    \ snd ACK                 +---------+delete TCB         +---------+
     ------------------------>|TIME WAIT|------------------>| CLOSED  |
                              +---------+                   +---------+

                      TCP Connection State Diagram


Как видно TIME_WAIT возникает на закрывающей стороне. Т.е.
в Вашем случае Вы вызывая close() переводите fsm в состояние
FIN WAIT-1. После этого fsm обязательно перейдет в TIME WAIT и будет
в нем висеть 2MSL (4 минуты). А в случае, если соединение закрыл клиент
(rcv FIN) такого не возникает. (RFC-793 Section 3.5 хотя ИМХО надуманно,
но таков стандарт).
При этом некторые реализации позволяют переоткрывать сокет в
TIME_WAIT при условии, что seq будет больше, чем любое из предыдущего
соединения.
Re[3]: Сокеты-зомби?
От: Александр Россия  
Дата: 27.08.04 07:51
Оценка:
Здравствуйте, Linuxoid, Вы писали:

L>Здравствуйте, jedi, Вы писали:


J>>После закрытия соединения сокет переходит в состояние TIMED_WAIT2 и находится в нем 75 — 300 секунд.


L>А это может привести к DOS? (например если за 300 секунд успеет наплодиться 65000 сокетов, или сколько их там может быть по максимуму)

L>Можно как-то убрать эти 300 секунд?
Убрать конечно можно, но делать этого не в коем слечае нельзя!
а чтоб это немешало тебе открывать новые соединения есть такая опция SO_REUSEADDR
правда еще есть ситуёвина, что закончатся все доступные хенжлы, вроде в линуксах их не шибко много на процесс, но тут уж ничаго не поделаеш, можеш считать кол-во соединений и посылать клиентам что-нить типа попробуй позже
... << RSDN@Home 1.1.4 @@subversion >>
Re[4]: Сокеты-зомби?
От: aka50 Россия  
Дата: 27.08.04 13:08
Оценка:
Здравствуйте, Александр, Вы писали:

А>Здравствуйте, Linuxoid, Вы писали:


L>>Здравствуйте, jedi, Вы писали:


J>>>После закрытия соединения сокет переходит в состояние TIMED_WAIT2 и находится в нем 75 — 300 секунд.


L>>А это может привести к DOS? (например если за 300 секунд успеет наплодиться 65000 сокетов, или сколько их там может быть по максимуму)

L>>Можно как-то убрать эти 300 секунд?
А>Убрать конечно можно, но делать этого не в коем слечае нельзя!
А>а чтоб это немешало тебе открывать новые соединения есть такая опция SO_REUSEADDR
А>правда еще есть ситуёвина, что закончатся все доступные хенжлы, вроде в линуксах их не шибко много на процесс, но тут уж ничаго не поделаеш, можеш считать кол-во соединений и посылать клиентам что-нить типа попробуй позже

Ну почему-же . Для снятия ограничения на сокеты для select()
1. Надо до включения socket.h (или аналогичный) проставить переменную FD_SETSIZE
2. Использовать poll() или другие механизмы как kevents в FreeBSD или epoll в linux

Для увеличения кол-ва дескрипторов на процесс:
http://www.opennet.ru/opennews/art.shtml?num=658
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.