Wie setze ich das Do not Fragment (DF) Flag auf einem Socket?

8

Ich versuche, das DF (nicht fragmentieren Flag) zum Senden von Paketen mit UDP zu setzen.

Betrachten wir das Buch von Richard Steven Volume 1 Unix Network Programming; Die Sockets-Netzwerk-API kann nicht gefunden werden, wie dies eingerichtet wird.

Ich vermute, dass ich es mit setsockopt () machen würde, aber ich finde es nicht in der Tabelle auf Seite 193.

Bitte schlagen Sie vor, wie das gemacht wird.

    
WilliamKF 10.06.2009, 02:30
quelle

3 Antworten

18

Sie tun es mit dem Aufruf setsockopt() , indem Sie die IP_DONTFRAG Option ::

verwenden %Vor%

Hier ist eine Seite, die das genauer erklärt.

Für Linux scheint es, dass Sie die Option IP_MTU_DISCOVER mit dem Wert IP_PMTUDISC_DO (oder IP_PMTUDISC_DONT , um es auszuschalten) verwenden müssen:

%Vor%

Ich habe das nicht getestet, habe nur in die Header-Dateien und ein bisschen eine Websuche gesucht, also müssen Sie es testen.

Gibt es eine andere Möglichkeit, das DF Flag zu setzen:

  

Ich finde nirgendwo in meinem Programm, wo das "force DF Flag" gesetzt ist, aber tcpdump deutet darauf hin, dass es ist. Gibt es eine andere Möglichkeit, dies zu erreichen?

Von dieser ausgezeichneten Seite hier :

  

IP_MTU_DISCOVER: Setzt oder definiert die Path MTU Discovery-Einstellung für einen Socket. Wenn diese Option aktiviert ist, führt Linux die Pfad-MTU-Erkennung gemäß RFC 1191 für diesen Socket durch. Das Flag nicht fragmentieren wird für alle ausgehenden Datagramme gesetzt. Der systemweite Standardwert wird von den Sockets ip_no_pmtu_disc sysctl für SOCK_STREAM und bei allen anderen Sockets deaktiviert. Für nicht SOCK_STREAM -Sockets ist der Benutzer dafür verantwortlich, die Daten in MTU-großen Blöcken zu paketieren und die Übertragungen gegebenenfalls durchzuführen. Der Kernel wird Pakete zurückweisen, die größer als die MTU des bekannten Pfads sind, wenn dieses Flag gesetzt ist (mit EMSGSIZE ).

Das sieht so aus, als könnten Sie den systemweiten Standard mit sysctl :

festlegen %Vor%

gibt "error: "ip_no_pmtu_disc" is an unknown key" auf meinem System zurück, aber möglicherweise wird es auf deins gesetzt. Abgesehen davon ist mir nichts anderes bekannt (außer setsockopt() wie zuvor erwähnt), das die Einstellung beeinflussen kann.

    
paxdiablo 10.06.2009, 02:34
quelle
3

Wenn Sie in Userland mit der Absicht arbeiten, den Netzwerkstack des Kernels zu umgehen und somit Ihre eigenen Pakete und Header zu erstellen und sie einem benutzerdefinierten Kernelmodul zu übergeben, gibt es eine bessere Option als setsockopt() .

Sie können das DF-Flag genauso einstellen wie jedes andere Feld von struct iphdr , das in linux/ip.h definiert ist. Die 3-Bit-IP-Flags sind tatsächlich Teil von frag_off  (Fragment Offset) Mitglied der Struktur.

Wenn Sie darüber nachdenken, ist es sinnvoll, diese beiden Dinge zu gruppieren, da die Flags fragmentiert sind. Laut dem RFC-791 , der Abschnitt, der die IP-Header-Struktur beschreibt, dass Fragment Offset ist 13-Bit lang und Es gibt drei 1-Bit-Flags. Der Member frag_off hat den Typ __be16 , der 13 + 3 Bits enthalten kann.

Lange Rede, kurzer Sinn, hier ist eine Lösung:

%Vor%

Wir setzen hier das DF-Bit genau ein, indem wir die für IP_DF bestimmte Maske verwenden.

IP_DF ist in net/ip.h (natürlich Kernel-Header) definiert, während struct iphdr in linux/ip.h definiert ist.

    
Asblarf 01.02.2012 05:50
quelle
0

Ich stimme der Antwort von paxdiablo zu.

  • setsockopt (sockfd, IPPROTO_IP, IP_MTU_DISCOVER, & amp; val, sizeof (val))
%Vor%
  • ip_no_pmtu_disc in der Kernelquelle:
  

if (ipv4_config.no_pmttu_disc) inet- & gt; pmtudisc = IP_PMTUDISC_DONT; sonst   inet- & gt; pmtudisc = IP_PMTUDISC_WANT;

    
EdwardLewis 26.12.2013 06:49
quelle

Tags und Links