diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake index 2c78b83f168dabde65f1c1b20dc7c03bc0ff0b31..7de9325d06dff894fc9f09a0bb0f592466cd5d35 100644 --- a/ConfigureChecks.cmake +++ b/ConfigureChecks.cmake @@ -147,6 +147,14 @@ if (HAVE_EVENTFD) HAVE_EVENTFD_UNSIGNED_INT) endif (HAVE_EVENTFD) +set(CMAKE_REQUIRED_FLAGS -D_GNU_SOURCE) +check_prototype_definition(recvmmsg + "int recvmmsg (int __fd, struct mmsghdr *__vmessages, unsigned int __vlen, int __flags, const struct timespec *__tmo)" + "-1" + "sys/socket.h" + HAVE_RECVMMSG_CONST_TIMEOUT) +unset(CMAKE_REQUIRED_FLAGS) + # IPV6 check_c_source_compiles(" #include diff --git a/config.h.cmake b/config.h.cmake index 0f2fb09e58b224c13f9e6b47661dc9faf59b0525..5c15a1f544738265284fab42a21aaf983ffd31dd 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -52,6 +52,7 @@ #cmakedefine HAVE_ACCEPT_PSOCKLEN_T 1 #cmakedefine HAVE_IOCTL_INT 1 #cmakedefine HAVE_EVENTFD_UNSIGNED_INT 1 +#cmakedefine HAVE_RECVMMSG_CONST_TIMEOUT 1 /*************************** LIBRARIES ***************************/ diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c index ec8321fe0afcf35660e39a2954e7f342f530d9cc..8865c91865fb3b10d964d8cf60c066c4829836fe 100644 --- a/src/socket_wrapper.c +++ b/src/socket_wrapper.c @@ -539,6 +539,12 @@ typedef int (*__libc_recvfrom)(int sockfd, typedef int (*__libc_recvmsg)(int sockfd, const struct msghdr *msg, int flags); typedef int (*__libc_send)(int sockfd, const void *buf, size_t len, int flags); typedef int (*__libc_sendmsg)(int sockfd, const struct msghdr *msg, int flags); +typedef int (*__libc_sendmmsg)(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags); +#if defined(HAVE_RECVMMSG_CONST_TIMEOUT) +typedef int (*__libc_recvmmsg)(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, const struct timespec *timeout); +#else +typedef int (*__libc_recvmmsg)(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, struct timespec *timeout); +#endif typedef int (*__libc_sendto)(int sockfd, const void *buf, size_t len, @@ -607,6 +613,8 @@ struct swrap_libc_symbols { SWRAP_SYMBOL_ENTRY(recvmsg); SWRAP_SYMBOL_ENTRY(send); SWRAP_SYMBOL_ENTRY(sendmsg); + SWRAP_SYMBOL_ENTRY(sendmmsg); + SWRAP_SYMBOL_ENTRY(recvmmsg); SWRAP_SYMBOL_ENTRY(sendto); SWRAP_SYMBOL_ENTRY(setsockopt); #ifdef HAVE_SIGNALFD @@ -1246,6 +1254,8 @@ static void __swrap_bind_symbol_all_once(void) swrap_bind_symbol_libsocket(recvmsg); swrap_bind_symbol_libsocket(send); swrap_bind_symbol_libsocket(sendmsg); + swrap_bind_symbol_libsocket(sendmmsg); + swrap_bind_symbol_libsocket(recvmmsg); swrap_bind_symbol_libsocket(sendto); swrap_bind_symbol_libsocket(setsockopt); #ifdef HAVE_SIGNALFD @@ -7287,6 +7297,89 @@ ssize_t sendmsg(int s, const struct msghdr *omsg, int flags) return swrap_sendmsg(s, omsg, flags); } +/**************************************************************************** + * SENDMMSG + ***************************************************************************/ + +static int swrap_sendmmsg(int s, struct mmsghdr *msgvec, unsigned int vlen, int flags) +{ + unsigned int i; + + SWRAP_LOG(SWRAP_LOG_DEBUG, "%s: vlen=%u\n", __func__, vlen); + + for (i=0; imsg_hdr; + ssize_t ret; + + ret = swrap_sendmsg(s, msg, flags); + SWRAP_LOG(SWRAP_LOG_DEBUG, "%s: msg[%i] sent, ret=%zd\n", + __func__, i, ret); + if (ret == -1) { + return -1; + } + mmsg->msg_len = ret; + } + + return i; +} + +int sendmmsg(int s, struct mmsghdr *msgvec, unsigned int vlen, int flags) +{ + return swrap_sendmmsg(s, msgvec, vlen, flags); +} + +/**************************************************************************** + * RECVMMSG + ***************************************************************************/ + +#if defined(HAVE_RECVMMSG_CONST_TIMEOUT) +static int swrap_recvmmsg(int s, struct mmsghdr *msgvec, unsigned int vlen, int flags, + const struct timespec *timeout) +#else +static int swrap_recvmmsg(int s, struct mmsghdr *msgvec, unsigned int vlen, int flags, + struct timespec *timeout) +#endif +{ + unsigned int i; + + SWRAP_LOG(SWRAP_LOG_DEBUG, "%s: vlen=%u\n", __func__, vlen); + + if (timeout != NULL) { + SWRAP_LOG(SWRAP_LOG_ERROR, "%s: timeout arg not supported\n", __func__); + errno = ENOSYS; + return -1; + } + + for (i=0; imsg_hdr; + ssize_t ret; + + ret = swrap_recvmsg(s, msg, flags); + SWRAP_LOG(SWRAP_LOG_DEBUG, "%s: msg[%i] received, ret=%zd\n", + __func__, i, ret); + if (ret == -1) { + return -1; + } + mmsg->msg_len = ret; + + } + + return i; +} + +#if defined(HAVE_RECVMMSG_CONST_TIMEOUT) +int recvmmsg(int s, struct mmsghdr *msgvec, unsigned int vlen, int flags, + const struct timespec *timeout) +#else +extern int recvmmsg(int s, struct mmsghdr *msgvec, unsigned int vlen, + int flags, struct timespec *timeout) +#endif +{ + return swrap_recvmmsg(s, msgvec, vlen, flags, timeout); +} + /**************************************************************************** * READV ***************************************************************************/ @@ -7881,6 +7974,8 @@ SWRAP_SYMBOL_ALIAS(recvfrom, _recvfrom); SWRAP_SYMBOL_ALIAS(recvmsg, _recvmsg); SWRAP_SYMBOL_ALIAS(send, _send); SWRAP_SYMBOL_ALIAS(sendmsg, _sendmsg); +SWRAP_SYMBOL_ALIAS(sendmmsg, _sendmmsg); +SWRAP_SYMBOL_ALIAS(recvmmsg, _recvmmsg); SWRAP_SYMBOL_ALIAS(sendto, _sendto); SWRAP_SYMBOL_ALIAS(setsockopt, _setsockopt); SWRAP_SYMBOL_ALIAS(socket, _socket);