[PATCH] socket: enable nanosecond resolution receive timestamp on FreeBSD

Josef 'Jeff' Sipek <[email protected]>
Newsgroups gmane.comp.time.chrony.user
Message-ID <ZNOEghRB9xvueVKc@satis>
This is just a quick patch to get better resolution receive timestamps from
the kernel.  As far as I can tell, the timestamps are supposed to be using
the unix epoch.  If not, I can switch it up from SO_TS_REALTIME to
SO_TS_MONOTONIC which does marginally less work but its epoch isn't January
1, 1970 - it's essentially the uptime.

Let me know if I missed anything.

Jeff.
0001-socket-enable-nanosecond-resolution-receive-timestam.patch (text/x-diff, 1.8 KB)
From a5a967a270233afcbdb7e5374ad9990362a884f8 Mon Sep 17 00:00:00 2001
From: Josef 'Jeff' Sipek <[email protected]>
Date: Wed, 9 Aug 2023 07:58:38 -0400
Subject: [PATCH] socket: enable nanosecond resolution receive 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 | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/socket.c b/socket.c
index 8a5d046..f4bae6d 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,16 @@ 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).
+     */
+    SCK_SetIntOption(sock_fd, SOL_SOCKET, SO_TS_CLOCK, SO_TS_REALTIME);
+#endif
     return 1;
+  }
 #endif
 
   return 0;
-- 
2.41.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.