Timestamp ausgehende Pakete

Ich versuche, präzise Zeitstempel für die ausgehenden Pakete (gesendet mit raw-sockets). Nach Linux/Documentation/networking/timestamping.txt, "Für sende-Zeitstempel des ausgehenden Pakete werden geloopt zurück an den socket error-queue mit dem sende-Zeitstempel(s) befestigt ist. Es kann empfangen werden, mit recvmsg(flags=MSG_ERRQUEUE).".

Leider recvmsg ist immer wiederkehrenden -1 wenn man auf einem raw-socket (erstellt mit socket(PF_INET, SOCK_RAW, IPPROTO_RAW) und mit SO_TIMESTAMP eingestellt 1 mit setsockopt). Was mache ich falsch? Gibt es einen besseren Weg, um eine genaue Zeitstempel für eine ausgehende Paket?

Nachtrag (Informationen):

Ich auch versucht, immer den timestamp aus aus einem gesendeten Paket durch einen UDP-socket (Quellcode unten) und recvmsg zurück -1: der Fehler "Resource temporarily unavailable" (EAGAIN).

Nachtrag (source-code):

#include <arpa/inet.h>
#include <linux/net_tstamp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>

void die(char* s)
{
    perror(s);
    exit(1);
}

int main(int argc, char* argv[])
{
    char* destination_ip = "10.0.0.1";
    int destination_port = 1234;

    int sock;
    if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
        die("socket()");
    }

    int timestamp_flags = SOF_TIMESTAMPING_TX_SOFTWARE;
    if (setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, &timestamp_flags, sizeof(timestamp_flags)) < 0) {
        die("setsockopt()");
    }

    struct sockaddr_in si_server;
    memset(&si_server, 0, sizeof(si_server));
    si_server.sin_family = AF_INET;
    si_server.sin_port = htons(destination_port);
    if (inet_aton(destination_ip, &si_server.sin_addr) == 0) {
        die("inet_aton()");
    }

    const int buffer_len = 256;
    char buffer[buffer_len];

    const int n_packets = 10;
    for (int i = 0; i < n_packets; ++i) {
        sprintf(buffer, "Packet %d", i);
        if (sendto(sock, buffer, buffer_len, 0, (const sockaddr*) &si_server, sizeof(si_server)) < 0) {
            die("sendto()");
        }

        //Obtain the sent packet timestamp.
        char data[256];
        struct msghdr msg;
        struct iovec entry;
        struct sockaddr_in from_addr;
        struct {
            struct cmsghdr cm;
            char control[512];
        } control;
        int res;

        memset(&msg, 0, sizeof(msg));
        msg.msg_iov = &entry;
        msg.msg_iovlen = 1;
        entry.iov_base = data;
        entry.iov_len = sizeof(data);
        msg.msg_name = (caddr_t)&from_addr;
        msg.msg_namelen = sizeof(from_addr);
        msg.msg_control = &control;
        msg.msg_controllen = sizeof(control);        
        if (recvmsg(sock, &msg, MSG_ERRQUEUE) < 0) {
            die("recvmsg()");
        }
    }
    return 0;
}
  • erhalten Sie verschiedene timing-wenn Sie SOCK_STREAM?
  • btw ich benutze setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int)); zu deaktivieren Nagel-Algorithmus. Ich denke, Sie sollten das auch tun. Aber ich Frage mich, wenn Sie können, verwenden Sie zwei setsockopt in einer Reihe?
  • anscheinend kann man auch hinzufügen, die sockopt auf jeder Ebene, die Sie wollen, um echtes timing-ich denke, Sie würde SO_TIMESTAMP am IPPROTO_RAW Ebene
  • Nicht das Lesen aus der error queue nicht blockierend? Ich nehme an, du bist immer EAGAIN, weil der Zeitstempel ist noch nicht bereit, wenn Sie anrufen recvmsg(). Vielleicht versuchen Sie es mit poll() und warten Sie, bis POLLERR.
InformationsquelleAutor bruno nery | 2012-07-31
Schreibe einen Kommentar