Bei einer TCP-Kommunikation muss vor der eigentlichen Datenübertragung eine TCP-Session aufgebaut werden. Anders wie bei UDP.

Besteht einmal eine Session bleibt diese so lange aktiv, bis diese aktiv beendet wird. Zum Beenden ist folgender Vorgang nötig:

Der Kommunikationspartner teilt mit, dass er die Verbindung beenden möchte und übermittelt dazu ein TCP-Paket mit gesetztem FIN (F) Flag. Der Empfänger erhält dieses Paket und beendet daraufhin die Session.

Hier ist erkennbar, dass unter verschiedenen Umständen, Verbindungen ewig offen bleiben können. Nämlich wenn:

Eine Gegenseite abstürzt und kein FIN sendet.
Eine Gegenseite ein FIN sendet, welches aber nicht ankommt.
Eine Gegenseite ein FIN sendet, welches ankommt, aber nicht verarbeitet wird.

Für alle oben genannten Umstände gibt es eine Abhilfe. Das TCP-Keepalive Feature. Dies sorgt dafür, dass alle Verbindungen überwacht werden und nach einem vordefinierten Zeitraum und bei ausbleibender Interaktion mit dem Kommunikationspartner, selbstständig beendet werden.

Das Keepalive-Feature muss anwendungsseitig beim Öffnen einer TCP-Verbindung aktiviert werden. Ob für eine TCP-Session Keepalive aktiv ist, zeigt sich unter Linux mit folgendem Befehl:

# netstat -to

Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State Timer
tcp 0 0 t480:42616 52.114.76.235:https ESTABLISHED keepalive (22.12/0/0)
tcp 0 0 t480:44930 145.253.233.68:https ESTABLISHED off (0.00/0/0)

Hier sehen wir an der letzten Spalte Timer, dass für eine Verbindung keepalive aktiv ist. Für die zweite nicht.

Das Keepalive-Feature sendet in regelmäßigen Abständen einen Probe-Request (echo) an den Kommunikationspartner.

Standardmäßig erfolgt der erste Probe nach 2 Stunden und dann wird 9 mal im Abstand von 75 Sekunden versucht, eine Antwort zu erhalten. Scheitert der letzte Versuch, wird die Verbindung lokal abgebaut.

# cat /proc/sys/net/ipv4/tcp_keepalive_*

tcp_keepalive_intvl tcp_keepalive_probes tcp_keepalive_time
# cat /proc/sys/net/ipv4/tcp_keepalive_*
75
9
7200

Erfolgt eine Antwort, wird der Timer von 2 Stunden zurück auf 0 gesetzt. Für weitere knapp 2 Stunden erfolgt kein neuer Probe.

Unabhängig vom TCP-Timer kann auch die Anwendung selbst also z.B. ein Webserver unabhängig von TCP, einen Probe/Check/Keepalive nutzen um z.B. alte Clientverbindungen zu terminieren.

Categories: Blog