简体   繁体   中英

Enabling UDP packet timestamps on macOS with SCM_TIMESTAMP

I tried to enable hardware UDP packet timestamps on macOS (and iOS) and have trouble getting it to work (working on macOS 10.13.4, Xcode 9.3).

My goal is to get as precise as possible timestamps for outgoing and incoming UDP packets, ideally something equivalent to the nanosecond timestamps that can be requested with SO_TIMESTAMPNS on Linux .

The example below works on Linux, but not macOS where trying to request the SCM_TIMESTAMP option fails with a -1 return code to the setsockopt() call.

I am aware that the socket implementation in macOS follows POSIX (and as such do not expect SO_TIMESTAMPNS to work), but I am surprised that I could not even get SCM_TIMESTAMP to work (also because I found the definition of SCM_TIMESTAMP in my sys/socket.h ):

// testing SCM_TIMESTAMP
#include <stdio.h>
#include <sys/socket.h>

int main() {
    // open socket
    int sd, ret, optval;
    socklen_t len;

    sd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sd < 0) {
        fprintf(stderr, "failed to open socket: %d\n", sd);
        return 1;
    }

    // set SCM_TIMESTAMP
    optval = 1;
    ret = setsockopt(sd, SOL_SOCKET, SCM_TIMESTAMP, &optval, sizeof(optval));
    if (ret < 0) {
        fprintf(stderr, "request for setting SCM_TIMESTAMP failed: %d\n", ret);
        return 1;
    }

    // get SCM_TIMESTAMP
    optval = 0;
    len = 0;
    ret = getsockopt(sd, SOL_SOCKET, SCM_TIMESTAMP, &optval, &len);
    if (ret < 0) {
        fprintf(stderr, "request for getting SCM_TIMESTAMP failed: %d\n", ret);
        return 1;
    }

    fprintf(stderr, "SCM_TIMESTAMP: %d %d\n", optval, len);
    return 0;
}

Is there something obvious that I am missing? What is the most precise timestamps I can obtain on macOS and also iOS?

Any help is appreciated!

EDIT:

I found that UDP timestamping functionality was supposedly added to NetBSD a while ago , but could not find any information on macOS.

The constant you are looking for is SO_TIMESTAMP . SCM_TIMESTAMP is for specifying a S ocket-level C ontrol M essage type. SO_TIMESTAMP is used to specify a S ocket O ption.

As a side note, at the end of your code snippet you print optval and len, but even if setsockopt and getsockopt worked, you will always print 0 0 there. By passing a pointer to 0 as the last parameter to getsockopt you tell it that the buffer int the second-to-last argument (optval) has size 0, effectively forbidding it from using it at all. If you set len to sizeof(int) instead, it will copy the value of the option you specified into optval, as you seem to expect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM