Socket: Wie erkenne ich einen Link down?



  • Hallo,

    ich habe einen kleinen Server geschrieben, der per select und fd auf zwei Events wartet: neue Daten von TCPIP und Zeit.
    Nun musste ich feststellen, das ein Accept den Select auslösst und ich den Accept durchführen kann, danach geht die Routine wieder in den select und wartet.
    Wenn ich den TCP connect abbreche geht es über den select und ich erkenne einen Disonnect.
    Allerdings reagieren sockets hier nicht auf einen Link down, als wenn das Kabel gezogen wird. Die Verbindung geht verloren, aber es kommt zu keinem Disconnect, da mein select immer noch nach einem Accept auf weitere Events wartet.

    Wie macht man solche Erkennungen?

    Grüße
    TheNoName



  • AFAIK geht das nur mit einem Mechanismus auf Appliaktions-Ebene.
    Bsp. Eine Seite sendet eine AliveRequest, welcher von der anderen Seite innerhalb einer bestimmten Zeit mit einer AliveResponse beantwortet werden muss. Steht die Antwort nach dem Timeout aus (edit oder schlägt das senden des AliveRequests fehl), dann wird die Verbindung als Down angesehen (und das Socket geschlossen).

    Natürlich können das beide Seiten tun und es müssen auch nur Alive-Messages ausgetauscht werden wenn keine anderen Messages ausgetauscht werden.



  • Naja, ich kann einen Ping senden aber ich kann mir nicht vorstellen das bei sockets ein Link down nicht behandelt wird, das würde jede Serververbindung stehenlassen.



  • thenoname schrieb:

    Allerdings reagieren sockets hier nicht auf einen Link down, als wenn das Kabel gezogen wird.

    Naja, das sollten sie ja auch nicht.
    Wenn der Fehler schnell genug wieder verschwindet, und kein Gerät in der Kette beschliesst irgendwie besonders auf den "link down" Status zu reagieren, dann fängt sich die Verbindung wieder, und alles geht weiter als wäre nix gewesen.
    Dadurch kann man auch mal eben nen Server von einem Switch auf nen anderen umstöpseln, und die Connections bleiben erhalten.
    Oder nen virtuellen Server von einem Host auf einen anderen rüberschieben ohne dass TCP Connections getrennt würden.
    Oder sogar nen Switch/Router dazwischen rebooten, bzw. 100 andere Sachen.

    Die Verbindung geht verloren,

    Bist du sicher? Probier's mal aus. Abstöpseln, 2-3 Sekunden warten, wieder anstöpseln. TCP Verbindungen sollten das eigentlich überleben.

    aber es kommt zu keinem Disconnect, da mein select immer noch nach einem Accept auf weitere Events wartet.

    Es kommt garantiert zu einem Disconnect wenn ...

    1. Der Server gerade einen send() Call laufen hat. Dann gibt's irgendwann ein Timeout, weil der TCP/IP Stack des Senders auf Bestätigung vom Empfänger wartet, und keine kommt. Timeout liegt da IIRC irgendwo im Minuten-Bereich, also nix wildes.
    2. TCP Keep-Alive aktiv ist.

    Keep-Alive ist unter Windows per Default deaktiviert, kann aber entweder auf Interface-Ebene in der Registry aktiviert werden, oder für einzelne Connections per setsockopt().
    Bis dadurch ein Disconnect erkannt wird, dauert es allerdings reichlich lange, da per Default erst nach 2 Stunden das erste Keep-Alive Paket verschickt wird.

    Wie macht man solche Erkennungen?

    Indem du deinem Server-Programm beibringst, Verbindungen einfach zu trennen, auf denen schon lange keine Daten mehr dahergekommen sind. (Bzw. ab die auch schon lange nix mehr gesendet wurde.)
    Alternativ, wenn du das Protokoll selbst bestimmen kannst, muss der Server auch nur alle paar Minuten ein paar Byte an den Client schicken (irgend ein "Dummy-Paket", etwas worauf der Client nicht reagiert). Dann greift nämlich wieder der Fall (1) oben, und du bekommst relativ schnell nen Fehler gemeldet.



  • Also das mit den Dummys fällt aus.
    Nimm mal einen selbstgebauten FTP Server.
    Connect kommt, ich gehe auf accept und warte.
    FTP Client Software von Hersteller X stürzt ab oder link geht down.
    Meine Server App bleibt der Meinung das irgendwann mal was kommen müsste, mindestens ein close des Sockets.
    Leider ist da keine Anwendung mehr, bzw. kann der Client X keinen Ping durchführen, ist ja eine Fremdsoftware. (wie bei mir, kein Pingen!)
    Ich erwarte das wenn der Client abstürzt oder ein "Link down" durch abstöpseln kommt mein Socket ein Socket Close bekommt, sonst kann ich ja damit Schindluder treiben und damit Zombie Ports öffnen.



  • thenoname schrieb:

    Ich erwarte das wenn der Client abstürzt oder ein "Link down" durch abstöpseln kommt mein Socket ein Socket Close bekommt, sonst kann ich ja damit Schindluder treiben und damit Zombie Ports öffnen.

    Och, erwarte ruhig was du willst. Die Wirklichkeit wird sich dadurch aber nicht ändern.
    Und die ist, dass du keine Benachrichtigung bekommst, so lange du nicht versuchst was an die Gegenstelle zu senden. Oder das Keep-Alive Feature aktiv ist. Wobei das eben "relativ" lahm ist, die bereits erwähnten 2 Stunden sind ja nicht gerade kurz.
    Ist halt einfach so.

    Wenn du nen FTP Server programmierst, dann schmeiss den Client einfach nach 5 Minuten Inaktivität raus. Jeder gute FTP Client kann
    a) Selbständig Dummy-Befehle zwecks "bitte nicht rauswerfen" an den Server schicken und
    b) Die Connection im Falle des Falles selbständig neu aufbauen
    Oder die ganz feine Variante: mach das Timeout per Config-File einstellbar.

    ps: jede gute Firewall (und damit meine ich jetzt nicht Home-Router um 0€50 aus dem Kaugummiautomaten) hat ne DoS-Detection drinnen. Die blockt IPs die dich mit Connections zumüllen dann selbständig für ne gewisse Zeit. Und gegen DDoS lässt sich sowieso kaum sinnvoll irgendwas machen. Und überschätz' mal nicht deine Wichtigkeit, du musst schon erstmal ein interessantes Ziel abgeben bevor dich jemand DoSt.

    ps2: Wenn der FTP Client abstürzt, dann lebt ja noch das OS und der TCP/IP Stack weiter. Das OS bekommt dann spitz dass der "Besitzer" der Socket-Connection hopps gegangen ist, und schickt netterweise das entsprechende "RST" Paket, damit die Gegenstelle auch gleich weiss was Sache ist.



  • Wenn der FTP Client abstürzt, dann lebt ja noch das OS und der TCP/IP Stack weiter. Das OS bekommt dann spitz dass der "Besitzer" der Socket-Connection hopps gegangen ist, und schickt netterweise das entsprechende "RST" Paket, damit die Gegenstelle auch gleich weiss was Sache ist.

    Na sag ich doch. Was allerdings wenn der PC brutal ausgeschalten wird?

    Was ich nun gelernt habe: TCP/IP hat keinen eigenen Keep Alive?
    Was ist der Internet TimeToLive?



  • thenoname schrieb:

    Was ist der Internet TimeToLive?

    timetolive ist etwas völlig anderes. Das verhindert nur, dass ein und dasselbe Paket unbegrenzt lange im Kreis fährt.



  • Was ich nun gelernt habe: TCP/IP hat keinen eigenen Keep Alive?

    Doch! Aber das ist AFAIK ist nicht wirklich brauchbar.



  • thenoname schrieb:

    Wenn der FTP Client abstürzt, dann lebt ja noch das OS und der TCP/IP Stack weiter. Das OS bekommt dann spitz dass der "Besitzer" der Socket-Connection hopps gegangen ist, und schickt netterweise das entsprechende "RST" Paket, damit die Gegenstelle auch gleich weiss was Sache ist.

    Na sag ich doch.

    Boah mir geht gleich der Hut hoch!

    Was allerdings wenn der PC brutal ausgeschalten wird?

    N
    I
    X

    War es bei den ersten beiden Erklärungen wirklich SO schwer zu verstehen?


Log in to reply