ntp: add support for recvmmsg()
This is used to read multiple packets with one system call. It should work on Linux and NetBSD.
This commit is contained in:
parent
895c15d677
commit
e306199588
3 changed files with 29 additions and 3 deletions
14
configure
vendored
14
configure
vendored
|
@ -589,6 +589,20 @@ if test_code 'arc4random_buf()' 'stdlib.h' '' '' 'arc4random_buf(NULL, 0);'; the
|
||||||
add_def HAVE_ARC4RANDOM
|
add_def HAVE_ARC4RANDOM
|
||||||
fi
|
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=""
|
timepps_h=""
|
||||||
if [ $feat_refclock = "1" ] && [ $feat_pps = "1" ]; then
|
if [ $feat_refclock = "1" ] && [ $feat_pps = "1" ]; then
|
||||||
if test_code '<sys/timepps.h>' 'sys/timepps.h' '' '' ''; then
|
if test_code '<sys/timepps.h>' 'sys/timepps.h' '' '' ''; then
|
||||||
|
|
14
ntp_io.c
14
ntp_io.c
|
@ -60,12 +60,18 @@ struct Message {
|
||||||
struct cmsghdr cmsgbuf[CMSGBUF_SIZE / sizeof (struct cmsghdr)];
|
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 MessageHeader {
|
||||||
struct msghdr msg_hdr;
|
struct msghdr msg_hdr;
|
||||||
unsigned int msg_len;
|
unsigned int msg_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_RECV_MESSAGES 1
|
#define MAX_RECV_MESSAGES 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Arrays of Message and MessageHeader */
|
/* Arrays of Message and MessageHeader */
|
||||||
static ARR_Instance recv_messages;
|
static ARR_Instance recv_messages;
|
||||||
|
@ -609,7 +615,7 @@ static void
|
||||||
read_from_socket(int sock_fd, int event, void *anything)
|
read_from_socket(int sock_fd, int event, void *anything)
|
||||||
{
|
{
|
||||||
/* This should only be called when there is something
|
/* This should only be called when there is something
|
||||||
to read, otherwise it will block */
|
to read, otherwise it may block */
|
||||||
|
|
||||||
struct MessageHeader *hdr;
|
struct MessageHeader *hdr;
|
||||||
unsigned int i, n;
|
unsigned int i, n;
|
||||||
|
@ -619,10 +625,16 @@ read_from_socket(int sock_fd, int event, void *anything)
|
||||||
n = ARR_GetSize(recv_headers);
|
n = ARR_GetSize(recv_headers);
|
||||||
assert(n >= 1);
|
assert(n >= 1);
|
||||||
|
|
||||||
|
#ifdef HAVE_RECVMMSG
|
||||||
|
status = recvmmsg(sock_fd, hdr, n, MSG_DONTWAIT, NULL);
|
||||||
|
if (status >= 0)
|
||||||
|
n = status;
|
||||||
|
#else
|
||||||
n = 1;
|
n = 1;
|
||||||
status = recvmsg(sock_fd, &hdr[0].msg_hdr, 0);
|
status = recvmsg(sock_fd, &hdr[0].msg_hdr, 0);
|
||||||
if (status >= 0)
|
if (status >= 0)
|
||||||
hdr[0].msg_len = status;
|
hdr[0].msg_len = status;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
DEBUG_LOG(LOGF_NtpIO, "Could not receive from fd %d : %s", sock_fd,
|
DEBUG_LOG(LOGF_NtpIO, "Could not receive from fd %d : %s", sock_fd,
|
||||||
|
|
|
@ -468,8 +468,8 @@ SYS_Linux_EnableSystemCallFilter(int level)
|
||||||
SCMP_SYS(unlink),
|
SCMP_SYS(unlink),
|
||||||
/* Socket */
|
/* Socket */
|
||||||
SCMP_SYS(bind), SCMP_SYS(connect), SCMP_SYS(getsockname),
|
SCMP_SYS(bind), SCMP_SYS(connect), SCMP_SYS(getsockname),
|
||||||
SCMP_SYS(recvfrom), SCMP_SYS(recvmsg), SCMP_SYS(sendmmsg),
|
SCMP_SYS(recvfrom), SCMP_SYS(recvmmsg), SCMP_SYS(recvmsg),
|
||||||
SCMP_SYS(sendmsg), SCMP_SYS(sendto),
|
SCMP_SYS(sendmmsg), SCMP_SYS(sendmsg), SCMP_SYS(sendto),
|
||||||
/* TODO: check socketcall arguments */
|
/* TODO: check socketcall arguments */
|
||||||
SCMP_SYS(socketcall),
|
SCMP_SYS(socketcall),
|
||||||
/* General I/O */
|
/* General I/O */
|
||||||
|
|
Loading…
Reference in a new issue