2016-04-20 20 views
0

Frage Update: Zusätzlich zu dem Problem unten scheint es, unsere Client/Server-Anwendung mit dem Linux-PLPMTUD-Mechanismus wird zu groß Pfad MTU. Hat jemand dies gesehen, d. H. Die tatsächliche Pfad-MTU ist 1500, aber getsockopt w TCP_MAXSEG, die die MTUs der Endpunkte zurückgibt, in unserem Fall 3000? Ich habe versucht, GRO, GSO und TSO mit ethtool zu drehen, aber der Fehler bleibt bestehen. Normaler Ping schafft nur Pakete von 1472 Bytes oder kleiner. Erwähnenswert ist auch, dass PLPMTUD perfekt für kleinere MTUs funktioniert. Wenn zum Beispiel w Endpunkte bei 1500 MTU und eine Schnittstelle des Zwischenrouters auf beispielsweise 1200 MTU gesetzt sind, prüft und meldet der Kernel-TCP TCP_MAXSEG (1200 - Header) korrekt.TCP_MAXSEG ungenau? (Was: Linux-Pfad MTU Sondierung funktioniert nicht auf accept(): ed Socket, wenn angefordert mit setsockopt())

Ich verwende die Linux RFC4821-konforme Paketierung Layer Path MTU Entdeckung in einer Anwendung. Grundsätzlich hat der Kunde ein setsockopt auf einem TCP-Socket:

setsockopt (fd, SOL_IP, IP_MTU_DISCOVER, & sopt, sizeof (sopt)) mit Optionswert auf IP_PMTUDISC_PROBE. Die Setsockopt gibt keinen Fehler zurück.

Der Client sendet große TCP-Pakete an einen Ablehnungsserver und der Pfad MTU wird vom Linux-Kernel kalibriert - tcpdump zeigt tcp-Pakete mit DF-Bitsatz gesendet wird, variiert die Paketgröße, bis der Kernel den Pfad MTU kennt. Um dies jedoch in die andere Richtung funktionieren zu lassen (Empfangsserver akzeptieren: Verbindungen von Clients, Senden von Daten und Kalibrieren von PMTU in Richtung vom Server zum Client) muss ich die globale Option für tcp Pfad mtu discovery,/proc/sys einstellen/net/ipv4/tcp_mtu_probing. Wenn nicht, wird der Server doof weiterhin zu große Pakete senden, die von einem Zwischenrouter verworfen werden, ohne dass ICMP zurückgeschickt wird. Beide Endpunkte haben eine MTU auf 3000 eingestellt, während die Zwischenhops MTU 1500 haben.

Ich hoffe jemand hat eine Idee was schief geht. Wenn mehr Informationen benötigt werden, lass es mich wissen und ich bearbeite die Frage. Probleme gibt es sowohl bei Linux Kernel 4.2.0 als auch bei 3.19.0, beide sind Kubuntu LTS Kernel. (x86/x86-64)

Ich setze die gleiche Socket-Option serverseitig ebenso auf alle accept: ed-Sockets, bevor Daten in umgekehrter Richtung gesendet werden.

+0

Versuchen Sie, die Socket-Option anstelle der akzeptierten Sockets auf den hörenden Socket zu setzen. Es wird von ihnen geerbt werden. Es kann zu spät sein, es auf den akzeptierten Sockets zu setzen, da der Verbindungs-Handshake bereits stattgefunden hat, der Fenster-Maßstab ausgehandelt wurde usw. – EJP

+0

@EJP: Gute Idee, aber ich habe das früher ohne Erfolg versucht. –

+0

Es klingt, als ob Sie einen Intermediate-Router haben, der die MTU-Erkennung des richtigen Pfads unterbricht. Es ist also keine Überraschung, dass die Pfad-MTU-Erkennung nur funktioniert, wenn Sie Workarounds aktivieren. Was ist das Geheimnis genau? Beheben Sie den Zwischenrouter, indem Sie sich bei demjenigen beschweren, der ihn verwaltet. –

Antwort

0

FWIW, Ich habe Workarounds/Lösungen für die Probleme gefunden, werde mehr Tests durchführen, aber meine Ergebnisse hier kurz beschreiben, falls es jemand anderem hilft.

Das Problem mit der Pfadfindung mtu pro Socket nicht festlegen zu können, wurde behoben, Brute Force, indem es während der Ausführung meines Programms systemweit aktiviert wurde und dann wieder deaktiviert wurde.

Das zweite Problem des falschen Pfades mtu, das von Getsockopt TCP_MAXSEG zurückgegeben wird, wurde behoben, indem auf TCP-ACK gesendeter TCP-Daten gewartet wurde, die ebenfalls Getsockopt (tcp_info.tcpi_unacked) verwendeten. Auf diese Weise kann ich sicher sein, dass das Sondieren beendet ist, bevor ich TCP_MAXSEG erhalte.

Schließlich gab es im März 2015 einen Patchsatz zur Verbesserung der Pfad-Mtu-Sondierungsgenauigkeit, die zum Mainline-Linux-Kernel fusioniert wurde. Ohne diese Patches ist das Sondieren sehr ungenau. Patchset ist Teil der 4.1.y-Serie Kernel und weiter.