From 8caaa0b056a308cb5fe481b26b3b37e6a18b9443 Mon Sep 17 00:00:00 2001 From: Josef 'Jeff' Sipek Date: Wed, 9 Aug 2023 07:58:38 -0400 Subject: [PATCH] socket: enable nanosecond resolution RX timestamp on FreeBSD FreeBSD allows switching the receive timestamp format to struct timespec by setting the SO_TS_CLOCK socket option to SO_TS_REALTIME after enabling SO_TIMESTAMP. If successful, the kernel then starts adding SCM_REALTIME control messages instead of SCM_TIMESTAMP. --- socket.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/socket.c b/socket.c index 8a5d046..aa060a8 100644 --- a/socket.c +++ b/socket.c @@ -869,6 +869,11 @@ process_header(struct msghdr *msg, int msg_length, int sock_fd, int flags, memcpy(&message->timestamp.kernel, CMSG_DATA(cmsg), sizeof (message->timestamp.kernel)); } #endif +#ifdef SCM_REALTIME + else if (match_cmsg(cmsg, SOL_SOCKET, SCM_REALTIME, sizeof (message->timestamp.kernel))) { + memcpy(&message->timestamp.kernel, CMSG_DATA(cmsg), sizeof (message->timestamp.kernel)); + } +#endif #ifdef HAVE_LINUX_TIMESTAMPING #ifdef HAVE_LINUX_TIMESTAMPING_OPT_PKTINFO else if (match_cmsg(cmsg, SOL_SOCKET, SCM_TIMESTAMPING_PKTINFO, @@ -1386,8 +1391,15 @@ SCK_EnableKernelRxTimestamping(int sock_fd) return 1; #endif #ifdef SO_TIMESTAMP - if (SCK_SetIntOption(sock_fd, SOL_SOCKET, SO_TIMESTAMP, 1)) + if (SCK_SetIntOption(sock_fd, SOL_SOCKET, SO_TIMESTAMP, 1)) { +#if defined(SO_TS_CLOCK) && defined(SO_TS_REALTIME) + /* We don't care about the return value - we'll get either a + SCM_REALTIME (if we succeded) or a SCM_TIMESTAMP (if we failed) */ + if (!SCK_SetIntOption(sock_fd, SOL_SOCKET, SO_TS_CLOCK, SO_TS_REALTIME)) + ; +#endif return 1; + } #endif return 0;