Reduzierte Message Transfer Unit
Dieses Problem hat mich fast verrückt gemacht. Wenn etwas funktioniert und scheinbar alles in Ordnung ist, aber eine bestimmte, wesentliche Kleinigkeit nicht funktioniert. Und auf den ersten Blick war für mich nicht zu erkennen, was da auf einmal nicht funktionierte.
Wir setzen in unserer Firma gelegentlich UMTS-Router zur Verbindung mit mobilen Außenstellen ein. Ein Gerät sollte ich vorbereiten und eine VPN-Schnittstelle zu unserem Netz einrichten. Soweit so gut. Die Installation ging zügig voran, insofern man bei dem Web-Interface von zügig sprechen kann.
Das Problem
Für die VPN-Schnittstelle musste ich ein paar Schlüsseldateien installieren. Und genau da war Schluss mit lustig.
Der Browser brauchte eine gefühlte Ewigkeit zum Hochladen der Datei und nach etwa einer Minute kam die Meldung "400 Invalid Request". Egal, was ich versuchte, immer das gleiche, das Gerät nahm keine Schlüssel an. Also suchte und fand ich beim Hersteller eine neuere Firmware und lud diese auf meinen Rechner. Beim Einspielen kam wieder nur "400 Invalid Request".
Geräte zwischen Rechner und Router gab es nicht, beide waren per Netzwerkkabel direkt miteinander verbunden.
Ein erster Hinweis
Nach einigen weiteren erfolglosen Versuchen griff ich zu einem meiner Lieblingswerkzeuge bei unklaren Verbindungsproblemen, zu tcpdump. Damit protokollierte ich den erfolglosen Upload-Versuch:
00:00:00.000000 IP 192.168.2.38.56381 > 192.168.2.1.80: Flags [S],
seq 1888862808, win 5840,
options [mss 1460,sackOK,TS val 2549239 ecr 0,nop,wscale 6],
length 0
00:00:00.000621 IP 192.168.2.1.80 > 192.168.2.38.56381: Flags [S.],
seq 2580876073, ack 1888862809, win 5792,
options [mss 1460,sackOK,TS val 255259 ecr 2549239,nop,wscale 1],
length 0
00:00:00.000687 IP 192.168.2.38.56381 > 192.168.2.1.80: Flags [.],
ack 1, win 92,
options [nop,nop,TS val 2549239 ecr 255259],
length 0
00:00:00.000933 IP 192.168.2.38.56381 > 192.168.2.1.80: Flags [.],
seq 1:1449, ack 1, win 92,
options [nop,nop,TS val 2549239 ecr 255259],
length 1448
00:00:00.000966 IP 192.168.2.38.56381 > 192.168.2.1.80: Flags [P.],
seq 1449:2805, ack 1, win 92,
options [nop,nop,TS val 2549239 ecr 255259],
length 1356
00:00:00.001852 IP 192.168.2.1.80 > 192.168.2.38.56381: Flags [.],
ack 1, win 2896,
options [nop,nop,TS val 255259 ecr 2549239,nop,nop,sack 1 {1449:2805}],
length 0
00:00:00.218960 IP 192.168.2.38.56381 > 192.168.2.1.80: Flags [.],
seq 1:1449, ack 1, win 92,
options [nop,nop,TS val 2549294 ecr 255259],
length 1448
00:00:00.658950 IP 192.168.2.38.56381 > 192.168.2.1.80: Flags [.],
seq 1:1449, ack 1, win 92,
options [nop,nop,TS val 2549404 ecr 255259],
length 1448
00:00:01.538953 IP 192.168.2.38.56381 > 192.168.2.1.80: Flags [.],
seq 1:1449, ack 1, win 92,
options [nop,nop,TS val 2549624 ecr 255259],
length 1448
00:00:03.298951 IP 192.168.2.38.56381 > 192.168.2.1.80: Flags [.],
seq 1:1449, ack 1, win 92,
options [nop,nop,TS val 2550064 ecr 255259],
length 1448
00:00:06.818959 IP 192.168.2.38.56381 > 192.168.2.1.80: Flags [.],
seq 1:1449, ack 1, win 92,
options [nop,nop,TS val 2550944 ecr 255259],
length 1448
00:00:13.858957 IP 192.168.2.38.56381 > 192.168.2.1.80: Flags [.],
seq 1:1449, ack 1, win 92,
options [nop,nop,TS val 2552704 ecr 255259],
length 1448
00:00:27.938956 IP 192.168.2.38.56381 > 192.168.2.1.80: Flags [.],
seq 1:1449, ack 1, win 92,
options [nop,nop,TS val 2556224 ecr 255259],
length 1448
00:00:56.098966 IP 192.168.2.38.56381 > 192.168.2.1.80: Flags [.],
seq 1:1449, ack 1, win 92,
options [nop,nop,TS val 2563264 ecr 255259],
length 1448
00:01:00.005791 IP 192.168.2.1.80 > 192.168.2.38.56381: Flags [P.],
seq 1:356, ack 1, win 2896,
options [nop,nop,TS val 261259 ecr 2549239,nop,nop,sack 1 {1449:2805}],
length 355
00:01:00.005878 IP 192.168.2.38.56381 > 192.168.2.1.80: Flags [.],
ack 356, win 108,
options [nop,nop,TS val 2564240 ecr 261259],
length 0
00:01:00.006594 IP 192.168.2.1.80 > 192.168.2.38.56381: Flags [F.],
seq 356, ack 1, win 2896,
options [nop,nop,TS val 261259 ecr 2549239,nop,nop,sack 1 {1449:2805}],
length 0
00:01:00.006934 IP 192.168.2.38.56381 > 192.168.2.1.80: Flags [F.],
seq 2805, ack 357, win 108,
options [nop,nop,TS val 2564240 ecr 261259],
length 0
Der Mitschnitt zeigt, dass die TCP-Verbindung normal aufgebaut wird, mein Rechner Daten sendet, aber der Router keines der Pakete mit Nutzdaten bestätigt. Nach einer Minute sendete der Router etwas und beendete dann die Verbindung. Der vom Router gesendete Text war:
HTTP/1.0 400 Invalid Request
Date: Thu, 28 Jun 2012 13:47:52 GMT
Content-Type: text/html; charset=utf-8
Cache-Control: no-cache, no-store, must-revalidate, private
Expires: Thu, 31 Dec 1970 00:00:00 GMT
Pragma: no-cache
Connection: close
<html><head><title>Http Error</title></head><body>
<h2>400 Invalid Request</h2> Invalid Request</body></html>
So etwas hatte ich bis dahin noch nicht gesehen. Eine TCP-Verbindung, die aus einem Monolog (den unbestätigten Datenpaketen meines Rechners an den Router) und einem Dialog (den bestätigten Datenpaketen des Routers) bestand. Ich konnte mir das nicht erklären, hatte aber zumindest etwas in der Hand, mit dem ich die Supportabteilung in Bewegung setzen konnte.
Die Hotline kennt das Problem schon
Die nächste Überraschung war das Gespräch mit dem Supportmitarbeiter. Kaum hatte ich begonnen, das Problem zu schildern, unterbrach er mich und fragte:
Was haben Sie für ein System? LTS, 10.04? [er meinte Ubuntu und ja, das ist auf meinem Rechner drauf] Ich habe genau dasselbe Problem gehabt, die Entwickler wissen davon, haben aber das Problem nicht und darum auch noch keine Lösung. Es funktioniert aber mit Fedora oder irgendeinem anderen Linux, auch mit MS Windows, nur eben nicht mit Ubuntu 10.04.
Ein Workaround
Natürlich war ich erstmal baff. Wie sollte das denn gehen? Zum Glück hatte ich noch einen Windows-Rechner zur Hand, mit installiertem Wireshark. Damit konnte ich die Schlüssel auf den Router kopieren.
Analyse
Natürlich hatte ich die Verbindung mitgeschnitten:
00:00:00.000000 IP 192.168.2.2.60598 > 192.168.2.1.80: Flags [S],
seq 424058276, win 8192,
options [mss 1460,nop,wscale 2,nop,nop,sackOK], length 0
00:00:00.000818 IP 192.168.2.1.80 > 192.168.2.2.60598: Flags [S.],
seq 1165036987, ack 424058277, win 5840,
options [mss 1460,nop,nop,sackOK,nop,wscale 1], length 0
00:00:00.000870 IP 192.168.2.2.60598 > 192.168.2.1.80: Flags [.],
ack 1, win 16425, length 0
00:00:00.013135 IP 192.168.2.1.80 > 192.168.2.2.60598: Flags [.],
ack 1, win 2920,
options [nop,nop,sack 1 {1461:2604}], length 0
00:00:00.319237 IP 192.168.2.2.60598 > 192.168.2.1.80: Flags [.],
seq 1:1461, ack 1, win 16425, length 1460
00:00:00.919266 IP 192.168.2.2.60598 > 192.168.2.1.80: Flags [.],
seq 1:1461, ack 1, win 16425, length 1460
00:00:02.119292 IP 192.168.2.2.60598 > 192.168.2.1.80: Flags [.],
seq 1:537, ack 1, win 16425, length 536
00:00:02.120163 IP 192.168.2.1.80 > 192.168.2.2.60598: Flags [.],
ack 537, win 3456,
options [nop,nop,sack 1 {1461:2604}], length 0
00:00:02.120207 IP 192.168.2.2.60598 > 192.168.2.1.80: Flags [.],
seq 537:1073, ack 1, win 16425, length 536
00:00:02.120238 IP 192.168.2.2.60598 > 192.168.2.1.80: Flags [.],
seq 1073:1609, ack 1, win 16425, length 536
00:00:02.120943 IP 192.168.2.1.80 > 192.168.2.2.60598: Flags [.],
ack 1073, win 3992,
options [nop,nop,sack 1 {1461:2604}], length 0
00:00:02.121234 IP 192.168.2.1.80 > 192.168.2.2.60598: Flags [.],
ack 2604, win 4528,
options [nop,nop,sack 1 {1461:1609}], length 0
00:00:02.257257 IP 192.168.2.1.80 > 192.168.2.2.60598: Flags [P.],
seq 1:1151, ack 2604, win 4528, length 1150
00:00:02.257297 IP 192.168.2.1.80 > 192.168.2.2.60598: Flags [F.],
seq 1151, ack 2604, win 4528, length 0
00:00:02.257319 IP 192.168.2.2.60598 > 192.168.2.1.80: Flags [.],
ack 1152, win 16425, length 0
00:00:02.280084 IP 192.168.2.2.60598 > 192.168.2.1.80: Flags [F.],
seq 2604, ack 1152, win 16425, length 0
00:00:02.280657 IP 192.168.2.1.80 > 192.168.2.2.60598: Flags [.],
ack 2605, win 4528, length 0
Hier konnte ich deutlich sehen, was passiert. Der Windows-Rechner versucht es zunächst, wie der Ubuntu-Rechner, mit der maximalen Paketgröße. Da er keine Antwort bekommt, versucht er es nach 2 Sekunden mit auf 536 Byte reduzierter Paketgröße und diese Pakete beantwortet der Router.
Noch ein Workaround
Das Problem liegt also in der Paketgröße. Die kann ich administrativ beeinflussen. Zum Test habe ich auf dem Ubuntu-Rechner die Paketgröße verringert:
$ sudo ifconfig eth0 mtu 1000
Danach konnte ich auch mit diesem Rechner Dateien auf den Router kopieren.
Fazit
Bleiben also zwei Probleme, deren Zusammenspiel das Installieren von Dateien auf dem Router von einem Ubuntu LTS 10.04 System aus verhindert hat.
Warum akzeptiert der Router keine Datenpakete mit 1460 Byte Nutzdaten? Darum kann sich der Hersteller der Routers kümmern. Dem Supportmitarbeiter habe ich meine Erkenntnisse bereits mitgeteilt.
Warum reduziert der TCP-Stack im Ubuntu LTS 10.04 Kernel nicht automatisch die Paketgröße, wenn keine ACK-Pakete ankommen? Der TCP-Stack von MS Windows hat es gemacht, und andere machen es vermutlich ebenso. Das ist ein Problem für einen anderen Tag.