Esse problema foi interessante, já que muitas vezes me perguntei. Fiz alguns testes e encontrei alguns resultados interessantes. Se eu abrir uma conexão para um servidor e esperar 60 segundos, ele seria invariavelmente limpo (nunca chegaria a 0.00 / 0/0). Se eu abri 100 conexões, elas também foram limpas após 60 segundos. Se eu abrisse 101 conexões, começaria a ver conexões no estado que você considerou (que eu também já vi antes). E eles parecem durar aproximadamente 120s ou 2xMSL (que é 60), independentemente do que fin_timeout está definido. Fiz algumas pesquisas no código-fonte do kernel e descobri o que acredito ser a "razão". Parece haver algum código que tenta limitar a quantidade de coleta de soquete que acontece por 'ciclo'. A frequência do ciclo em si é definida em uma escala baseada em HZ:
linux-source-2.6.38/include/net/inet_timewait_sock.h:
35 #define INET_TWDR_RECYCLE_SLOTS_LOG 5
36 #define INET_TWDR_RECYCLE_SLOTS (1 << INET_TWDR_RECYCLE_SLOTS_LOG)
37
38 /*
39 * If time > 4sec, it is "slow" path, no recycling is required,
40 * so that we select tick to get range about 4 seconds.
41 */
42 #if HZ <= 16 || HZ > 4096
43 # error Unsupported: HZ <= 16 or HZ > 4096
44 #elif HZ <= 32
45 # define INET_TWDR_RECYCLE_TICK (5 + 2 - INET_TWDR_RECYCLE_SLOTS_LOG)
46 #elif HZ <= 64
47 # define INET_TWDR_RECYCLE_TICK (6 + 2 - INET_TWDR_RECYCLE_SLOTS_LOG)
48 #elif HZ <= 128
49 # define INET_TWDR_RECYCLE_TICK (7 + 2 - INET_TWDR_RECYCLE_SLOTS_LOG)
50 #elif HZ <= 256
51 # define INET_TWDR_RECYCLE_TICK (8 + 2 - INET_TWDR_RECYCLE_SLOTS_LOG)
52 #elif HZ <= 512
53 # define INET_TWDR_RECYCLE_TICK (9 + 2 - INET_TWDR_RECYCLE_SLOTS_LOG)
54 #elif HZ <= 1024
55 # define INET_TWDR_RECYCLE_TICK (10 + 2 - INET_TWDR_RECYCLE_SLOTS_LOG)
56 #elif HZ <= 2048
57 # define INET_TWDR_RECYCLE_TICK (11 + 2 - INET_TWDR_RECYCLE_SLOTS_LOG)
58 #else
59 # define INET_TWDR_RECYCLE_TICK (12 + 2 - INET_TWDR_RECYCLE_SLOTS_LOG)
60 #endif
61
62 /* TIME_WAIT reaping mechanism. */
63 #define INET_TWDR_TWKILL_SLOTS 8 /* Please keep this a power of 2. */
The number of slots is also set here:
65 #define INET_TWDR_TWKILL_QUOTA 100
No código do tempo real, você pode ver onde ele usa a citação para parar de matar as conexões TIME_WAIT se já tiver feito muitas:
linux-source-2.6.38/net/ipv4/inet_timewait_sock.c:
213 static int inet_twdr_do_twkill_work(struct inet_timewait_death_row *twdr,
214 const int slot)
215 {
...
240 if (killed > INET_TWDR_TWKILL_QUOTA) {
241 ret = 1;
242 break;
243 }
Há mais informações aqui sobre o motivo pelo qual o HZ é definido como: link Mas não é incomum aumentá-lo. No entanto, acho que é mais comum ativar tw_reuse / recycling para contornar esse mecanismo de bucket / quota (o que me parece confuso agora que li sobre isso, aumentar o HZ seria uma solução muito mais segura e mais limpa). Eu postei isso como uma resposta, mas acho que poderia haver mais discussão aqui sobre qual é o "caminho certo" para consertar isso. Obrigado pela pergunta interessante!