diff --git a/configure b/configure index 892fede..249b134 100755 --- 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' '' '' ''; then diff --git a/ntp_io.c b/ntp_io.c index d263e29..75be9e4 100644 --- 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, diff --git a/sys_linux.c b/sys_linux.c index c802da9..b6df86c 100644 --- a/sys_linux.c +++ b/sys_linux.c @@ -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 */