2010-05-06 15 views
15

Einer unserer Kunden hat Schwierigkeiten, Daten von unserer Anwendung (auf seinem PC) an einen Server (an einem anderen geografischen Ort) zu senden. Beim Senden von Paketen unter 1100 Bytes funktioniert alles einwandfrei, aber darüber sehen wir, dass TCP das Paket alle paar Sekunden erneut sendet und keine Antwort erhält. Die Pakete, die wir zum Testen verwenden, sind ungefähr 1400 Bytes (aber weniger als 1472). Ich kann einen ICMP-Ping an www.google.com senden, der 1472 Byte groß ist und eine Antwort erhält (also nicht der Router/die ersten Hops).Vorteile von "nicht fragmentieren" auf TCP-Paketen?

Ich habe festgestellt, dass unsere Anwendung das DF-Flag für diese Pakete setzt, und ich glaube, dass ein Router auf dem Weg zum Server eine MTU kleiner/gleich 1100 hat und das Paket fallen lässt.

Dies betrifft 1 Client in 5000, aber da jeder Routen anders sein wird dies erwartet.

Die Daten sind eine SOAP-Hülle und wir erwarten eine SOAP-Antwort zurück. Ich kann nicht rechtfertigen, warum wir es tun, der Code dafür wurde von einem früheren Entwickler geschrieben.

So ... Gibt es irgendwelche Vorteile oder Berechtigung, das DF-Flag auf TCP-Pakete für Anwendungsdaten zu setzen?

Ich kann mir Gründe vorstellen, die für Netzwerkdiagnoseanwendungen benötigt werden, aber nicht in unserer Situation (wir wollen, dass die Daten zum Endpunkt gelangen, fragmentiert oder nicht). Einer unserer Systemadministratoren sagte, dass es etwas mit SSL zu tun haben könnte, aber soweit ich weiß, ist SSL wie ein Stream und unabhängig von der Fragmentierung, solange der Stream am Ende neu aufgebaut wird, gibt es kein Problem.

Wenn es keine gute Begründung gibt, werde ich das Verhalten unserer Anwendung ändern.

Vielen Dank im Voraus.

+0

Was ist der tatsächliche Socket-API-Aufruf, den Sie vornehmen, der bewirkt, dass das DF-Bit gesetzt wird? –

+1

Es gibt einige nette Diskussionen darüber, wo der DF hier nützlich sein könnte: http://StackOverflow.com/questions/351806/where-is-the-dont-fragment-bit-of-the-ip-flags-used-in Kurz, es scheint wie eine Situation, in der, wenn Sie nicht wissen, dass Sie es brauchen, dann nicht. –

Antwort

35

Das DF-Flag wird normalerweise auf IP-Pakete gesetzt, die TCP-Segmente tragen.

Dies liegt daran, dass eine TCP-Verbindung ihre Segmentgröße dynamisch an die Pfad-MTU anpassen kann und eine bessere Gesamtleistung erreicht wird, wenn die TCP-Segmente jeweils in einem IP-Paket enthalten sind.

So TCP-Pakete haben die DF-Flag gesetzt, die sollte eine ICMP Fragmentierung benötigt Paket zurückgegeben werden, wenn ein Zwischen-Router ein Paket verwerfen muss, weil es zu groß ist. Das sendende TCP wird dann seine Schätzung der Pfad-MTU (Maximum Transmission Unit) der Verbindung reduzieren und kleinere Segmente erneut senden. Wenn DF nicht festgelegt wurde, würde das sendende TCP niemals wissen, dass es zu große Segmente gesendet hat. Dieser Prozess wird PMTU-D ("Path MTU Discovery") genannt.

Wenn die ICMP Fragmentierung Needed-Pakete nicht durchkommen, dann handelt es sich um ein defektes Netzwerk. Idealerweise wäre der erste Schritt, das falsch konfigurierte Gerät zu identifizieren und es korrigieren zu lassen; Wenn dies jedoch nicht funktioniert, fügen Sie Ihrer Anwendung einen Konfigurationsregler hinzu, der sie anweist, die Socket-Option TCP_MAXSEG mit setsockopt() zu setzen. (Ein typisches Beispiel für ein falsch konfiguriertes Gerät ist ein Router oder eine Firewall, der von einem unerfahrenen Netzwerkadministrator so konfiguriert wurde, dass er ICMP löscht, ohne zu erkennen, dass TCPMTU-D Pakete mit erforderlicher Fragmentierung benötigt).

+0

Sie haben diesen hier getroffen! – jathanism

-2

Offensichtlich profitieren einige Protokolle wie NFS von der Vermeidung von Fragmentierung (link text). Sie haben jedoch recht, dass Sie DF in der Regel nicht anfordern sollten, wenn Sie es nicht wirklich benötigen.

2

Die Funktionsweise der Pfad-MTU-Erkennung ist in RFC 1191, https://tools.ietf.org/html/rfc1191 beschrieben. Es ist besser für TCP, die Path-MTU zu entdecken, als jedes Paket über eine bestimmte Größe in zwei Teile (typischerweise eine große und eine kleine) zu zerlegen.