Na vině jsou Solaris a Windows. V podstatě jde o to, že win klienti neumějí správně ukončit TCP spojení a Solaris, i když by měl, se z toho nedostane.
Správné ukončení TCP spojení má vypadat asi takto:
client server
1 --- FIN,ACK -->
2 <---- ACK -----
3 <-- FIN,ACK ---
4 ----- ACK ---->
Ve chvíli, kdy klient požádá u ukončení (1), server mu ukončení potvrdí (2) a po vyřízení všech požadavků pošle i klientovi zprávu, že přechází do stavu CLOSE (3) a klient mu to potvrdí (4). Toto poslední potvrzení (4) ale některé verze windows neposílají a server tak čeká a čeká a .... Správně by měl podle nastavení timeoutu sám po určité době spojení uzavřít. Tento timeout můžeme zkusit nastavit pomocí ndd:
ndd -set /dev/tcp tcp_close_wait_interval 60000
(1 minuta)
Ale u Solarisu se tak neděje. Pomůže jedině ukončení procesu, který spojení udržuje. Jenže u velkých systémů může nastat problém, že podle čísla portu nejsme schopni jednoznačně určit, jaký proces port "drží". V linuxu by se to dalo vyřešit
netstat -p
a dostaneme u každého spojení i číslo/název procesu. V Solarisu si musíme pomoci příkazem
lsof -i
Ta nám v podstatě udělá stejnou službu. Pak už stačí zjištěný proces zabít ručně. V Solarisu 9 je již
lsof součástí systému, do starších verzí lze
lsof nainstalovat například z
Sunfreeware.com.
Stránky projektu Lsof
Poor English excerpt:
Many semi-closed connections in Solaris can be frozen in CLOSE_WAIT state by reason that some clients (e.g. Windows) does not close up TCP/IP session regulary. We have to kill process, which hold this connection. In Linux we can use netstat -p to identify that one, but in Solaris we have to use lsof utility, which can do the same work (list open TCP/IP sessions with process id holder). You can also try to decrease tcp-force-close timeout to 1 minute by
ndd -set /dev/tcp tcp_close_wait_interval 60000
Lsof project