]> git.gsnw.org Git - fping.git/commitdiff
complete SO_TIMESTAMPNS to SO_TIMESTAMP fallback
authorErik Auerswald <auerswal@unix-ag.uni-kl.de>
Thu, 16 Jan 2025 11:12:51 +0000 (12:12 +0100)
committerErik Auerswald <auerswal@unix-ag.uni-kl.de>
Sun, 26 Jan 2025 20:13:28 +0000 (21:13 +0100)
Commit e8660637ccc3bf2aae163fa7c26216843ae98180 added a
fallback from setting the socket option SO_TIMESTAMPNS to
setting the socket option SO_TIMESTAMP if the nanosecond
timestamp option could not be set.  But it did not add
code to also look for the control message related to
SO_TIMESTAMP.  Thus microsecond timestamps were requested,
but not read.

This commit adds the missing code to read microsecond
timestamp control messages.

The problem was reported in GitHub issue #374 by @payload.

CHANGELOG.md
src/fping.c

index 880e7e59f2b29c0280c9ab7bfddf20b213d0f2f9..6f92dbac1f33ee78b410cd68e4798226c04e3248 100644 (file)
@@ -1,3 +1,11 @@
+Next
+====
+
+## Bugfixes and other changes
+
+- Fix fallback to SO\_TIMESTAMP if SO\_TIMESTAMPNS is not available (#375, thanks
+  @auerswal)
+
 fping 5.3 (2025-01-02)
 ======================
 
index 5e059d0a834c709591fbd894a1738a3a40e8a0b7..01cfc17cf96ace12e6f614538f0c247875e720cd 100644 (file)
@@ -1284,6 +1284,14 @@ static inline int64_t timespec_ns(struct timespec *a)
     return ((int64_t)a->tv_sec * 1000000000) + a->tv_nsec;
 }
 
+#if HAVE_SO_TIMESTAMPNS
+/* convert a struct timeval to nanoseconds */
+static inline int64_t timeval_ns(struct timeval *a)
+{
+    return ((int64_t)a->tv_sec * 1000000000) + ((int64_t)a->tv_usec * 1000);
+}
+#endif /* HAVE_SO_TIMESTAMPNS */
+
 void add_cidr(char *addr)
 {
     char *addr_end;
@@ -2105,6 +2113,7 @@ int receive_packet(int64_t wait_time,
     /* ancilliary data */
     {
         struct timespec reply_timestamp_ts;
+        struct timeval reply_timestamp_tv;
         for (cmsg = CMSG_FIRSTHDR(&recv_msghdr);
              cmsg != NULL;
              cmsg = CMSG_NXTHDR(&recv_msghdr, cmsg)) {
@@ -2112,6 +2121,10 @@ int receive_packet(int64_t wait_time,
                 memcpy(&reply_timestamp_ts, CMSG_DATA(cmsg), sizeof(reply_timestamp_ts));
                 *reply_timestamp = timespec_ns(&reply_timestamp_ts);
             }
+            if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_TIMESTAMP) {
+                memcpy(&reply_timestamp_tv, CMSG_DATA(cmsg), sizeof(reply_timestamp_tv));
+                *reply_timestamp = timeval_ns(&reply_timestamp_tv);
+            }
         }
     }
 #endif