]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
ntp: add support for recvmmsg()
authorMiroslav Lichvar <mlichvar@redhat.com>
Tue, 2 Aug 2016 10:17:15 +0000 (12:17 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Thu, 11 Aug 2016 08:45:48 +0000 (10:45 +0200)
This is used to read multiple packets with one system call. It should
work on Linux and NetBSD.

configure
ntp_io.c
sys_linux.c

index 892fede5cfcf5461d7c36c5b678400bb0b772271..249b134d2dccf77deb539f91c9b0785bb174ad06 100755 (executable)
--- a/configure
+++ b/configure
@@ -589,6 +589,20 @@ if test_code 'arc4random_buf()' 'stdlib.h' '' '' 'arc4random_buf(NULL, 0);'; the
   add_def HAVE_ARC4RANDOM
 fi
 
+RECVMMSG_CODE='
+  struct mmsghdr hdr;
+  return !recvmmsg(0, &hdr, 1, MSG_DONTWAIT, 0);'
+if test_code 'recvmmsg()' 'sys/socket.h' '' "$EXTRA_LIBS" "$RECVMMSG_CODE"; then
+  add_def HAVE_RECVMMSG
+else
+  if test_code 'recvmmsg() with _GNU_SOURCE' 'sys/socket.h' '-D_GNU_SOURCE' \
+    "$EXTRA_LIBS" "$RECVMMSG_CODE"
+  then
+    add_def _GNU_SOURCE
+    add_def HAVE_RECVMMSG
+  fi
+fi
+
 timepps_h=""
 if [ $feat_refclock = "1" ] && [ $feat_pps = "1" ]; then
   if test_code '<sys/timepps.h>' 'sys/timepps.h' '' '' ''; then
index d263e294c5c17c71bce3466d45881992f85bbe52..75be9e44b1eac2b605cb5adbd70fa57c6fe3b91b 100644 (file)
--- a/ntp_io.c
+++ b/ntp_io.c
@@ -60,12 +60,18 @@ struct Message {
   struct cmsghdr cmsgbuf[CMSGBUF_SIZE / sizeof (struct cmsghdr)];
 };
 
+#ifdef HAVE_RECVMMSG
+#define MAX_RECV_MESSAGES 4
+#define MessageHeader mmsghdr
+#else
+/* Compatible with mmsghdr */
 struct MessageHeader {
   struct msghdr msg_hdr;
   unsigned int msg_len;
 };
 
 #define MAX_RECV_MESSAGES 1
+#endif
 
 /* Arrays of Message and MessageHeader */
 static ARR_Instance recv_messages;
@@ -609,7 +615,7 @@ static void
 read_from_socket(int sock_fd, int event, void *anything)
 {
   /* This should only be called when there is something
-     to read, otherwise it will block */
+     to read, otherwise it may block */
 
   struct MessageHeader *hdr;
   unsigned int i, n;
@@ -619,10 +625,16 @@ read_from_socket(int sock_fd, int event, void *anything)
   n = ARR_GetSize(recv_headers);
   assert(n >= 1);
 
+#ifdef HAVE_RECVMMSG
+  status = recvmmsg(sock_fd, hdr, n, MSG_DONTWAIT, NULL);
+  if (status >= 0)
+    n = status;
+#else
   n = 1;
   status = recvmsg(sock_fd, &hdr[0].msg_hdr, 0);
   if (status >= 0)
     hdr[0].msg_len = status;
+#endif
 
   if (status < 0) {
     DEBUG_LOG(LOGF_NtpIO, "Could not receive from fd %d : %s", sock_fd,
index c802da99e04644ec98b1ffe5a783014055f30637..b6df86c310f6b12573d4ea28731a19517de867ce 100644 (file)
@@ -468,8 +468,8 @@ SYS_Linux_EnableSystemCallFilter(int level)
     SCMP_SYS(unlink),
     /* Socket */
     SCMP_SYS(bind), SCMP_SYS(connect), SCMP_SYS(getsockname),
-    SCMP_SYS(recvfrom), SCMP_SYS(recvmsg), SCMP_SYS(sendmmsg),
-    SCMP_SYS(sendmsg), SCMP_SYS(sendto),
+    SCMP_SYS(recvfrom), SCMP_SYS(recvmmsg), SCMP_SYS(recvmsg),
+    SCMP_SYS(sendmmsg), SCMP_SYS(sendmsg), SCMP_SYS(sendto),
     /* TODO: check socketcall arguments */
     SCMP_SYS(socketcall),
     /* General I/O */