Ich versuche genaue Zeitstempel für ausgehende Pakete zu bekommen (gesendet mit rohen Sockets). Laut Linux/Documentation/networking/timestamping.txt
, "Für Sendezeitstempel die Das ausgehende Paket wird mit den angehängten Sendezeitmarken an die Fehlerwarteschlange des Sockets zurückgeschleift. Es kann mit recvmsg (flags = MSG_ERRQUEUE) empfangen werden. ".
Leider liefert recvmsg
immer -1
zurück, wenn ein roher Socket aufgerufen wird (erstellt mit socket(PF_INET, SOCK_RAW, IPPROTO_RAW)
und mit SO_TIMESTAMP
auf 1
mit setsockopt
). Was mache ich falsch? Gibt es eine bessere Möglichkeit, einen genauen Zeitstempel für ein ausgehendes Paket zu erhalten?
Zusatz (Information):
Ich habe auch versucht, den Zeitstempel von einem Paket über einen UDP-Socket (Quellcode unten) zu bekommen und recvmsg
gibt -1
zurück: Der Fehler ist "Ressource vorübergehend nicht verfügbar" ( EAGAIN
).
Addendum (Quellcode):
%Vor% Beim Betrachten des Linux-Kernel-Quellcodes habe ich festgestellt, dass die Funktion, die dafür verantwortlich ist, dass die Nachricht, die den Zeitstempel des Pakets enthält, in der Fehlerwarteschlange steht: skb_tx_timestamp
. Diese Funktion soll vom NIC-Treiber aufgerufen werden und leider ruft der e1000
-Treiber ihn nicht auf (es gibt eine ähnliche Funktion für Hardware-Timestamping, aber das hängt natürlich vom NIC-Treiber ab, der es unterstützt).
Laut dieser NetDev-Diskussion vom letzten September "ruft kein Treiber skb_tx_timestamp ()" und " Sie müssen Ihren NIC-Treiber anpassen, um mit diesen TX-Zeitstempeln zu spielen ". Nach dem Hinzufügen eines Aufrufs zu skb_tx_timestamp
zu e1000_xmit_frame
zu e1000_main.c
konnte ich Zeitstempel für ausgehende Pakete (über einen UDP-Socket) erhalten. Ich konnte jedoch keine Zeitstempel für ausgehende Pakete auf einem RAW-Socket erhalten (ich bekomme immer noch EAGAIN
).
Es ist schwer zu wissen, was Sie falsch machen, da wir Ihren Code nicht sehen können.
Jedoch:
Die Dokumentation besagt, dass SO_TIMESTAMP
für eingehende Pakete ist, während SO_TIMESTAMPING
für ausgehende Pakete ist.
Die Kernel-Dokumentation enthält ein vollständiges Beispiel, das Sie als Basis verwenden könnten - obwohl es UDP verwendet, aber Sie sollten es an die Verwendung eines RAW-Sockets anpassen können. Siehe den Linux-Kernel Dokumentation / Netzwerk / Zeitstempel / Zeitstempelung.c
EDIT: Es scheint, dass der Sendezeitstempel nicht universell unterstützt wird, siehe z.B. hier . Sogar heute implementieren nur eine Handvoll nic-Treiber Software-Unterstützung, und einige haben Hardware-Unterstützung.
sock_tx_timestamp wird nur für SOCK_DGRAM-Sockets im aktuellen Kernel-Code aufgerufen.
Übrigens, das Dokument Dokumentation / Vernetzung / Zeitstempel / Zeitstempel.c ist nicht sehr genau.
SO_TIMESTAMP / SO_TIMESTAMPNS / SO_TIMESTAMPING / SIOCGSTAMP / SIOCGSTAMPNS sind ähnlich. Jeder von ihnen ermöglicht der Anwendung, den Zeitstempel eines empfangenen Pakets zu erhalten.
Mit SOF_TIMESTAMPING_TX_SOFTWARE wird eines der obigen Flags der Anwendung außerdem ein CMSG in MSG_ERRQUEUE bereitstellen, das den Zeitstempel eines gesendeten Pakets angibt.
Aber SOF_TIMESTAMPING_RX_SOFTWARE ist überhaupt nutzlos. Es kann nicht einmal verwendet werden, um die Meldung von Zeitstempeln empfangener Pakete zu deaktivieren.
Ich denke, Sie müssen das Timestamping-Flag als
erwähnen %Vor%Außerdem müssen Sie den Fehler für alle Systemaufrufe überprüfen, bevor Sie die Daten aus dem msg-Warteschlangenfehler abrufen. Dies wird Ihnen helfen, die EAGAIN-Nachricht loszuwerden.
Tags und Links c linux timestamp raw-sockets