vcl: better handlig of ldp apis that rely on gnu source 25/38125/6
authorFlorin Coras <fcoras@cisco.com>
Thu, 2 Feb 2023 20:56:16 +0000 (12:56 -0800)
committerDave Barach <vpp@barachs.net>
Tue, 7 Feb 2023 18:06:44 +0000 (18:06 +0000)
Control use of apis that rely on _GNU_SOURCE being defined with compile
time macro.

Also fixes sendmmsg and recvmmsg which were not probably wrapped.

Type: improvement

Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: I207de23210d4b9dc960bb4289159502760c5614d

src/vcl/CMakeLists.txt
src/vcl/ldp.c
src/vcl/ldp.h
src/vcl/ldp_glibc_socket.h
src/vcl/ldp_socket_wrapper.c
src/vcl/ldp_socket_wrapper.h

index e6d8f98..610b422 100644 (file)
@@ -30,6 +30,11 @@ add_vpp_library(vppcom
   api_headers
 )
 
+option(LDP_HAS_GNU_SOURCE "LDP configured to use _GNU_SOURCE" ON)
+if (LDP_HAS_GNU_SOURCE)
+  add_compile_definitions(HAVE_GNU_SOURCE)
+endif(LDP_HAS_GNU_SOURCE)
+
 add_vpp_library(vcl_ldpreload
   SOURCES
   ldp_socket_wrapper.c
index 522e85d..482af3f 100644 (file)
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
+#ifdef HAVE_GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
 #include <unistd.h>
 #include <stdio.h>
 #include <signal.h>
 
 #define LDP_MAX_NWORKERS 32
 
+#ifdef HAVE_GNU_SOURCE
+#define SOCKADDR_GET_SA(__addr) __addr.__sockaddr__;
+#else
+#define SOCKADDR_GET_SA(__addr) _addr;
+#endif
+
 typedef struct ldp_worker_ctx_
 {
   u8 *io_buffer;
@@ -1052,8 +1063,9 @@ socketpair (int domain, int type, int protocol, int fds[2])
 }
 
 int
-bind (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
+bind (int fd, __CONST_SOCKADDR_ARG _addr, socklen_t len)
 {
+  const struct sockaddr *addr = SOCKADDR_GET_SA (_addr);
   vls_handle_t vlsh;
   int rv;
 
@@ -1124,11 +1136,10 @@ done:
 }
 
 static inline int
-ldp_copy_ep_to_sockaddr (__SOCKADDR_ARG addr, socklen_t * __restrict len,
-                        vppcom_endpt_t * ep)
+ldp_copy_ep_to_sockaddr (struct sockaddr *addr, socklen_t *__restrict len,
+                        vppcom_endpt_t *ep)
 {
-  int rv = 0;
-  int sa_len, copy_len;
+  int rv = 0, sa_len, copy_len;
 
   ldp_init_check ();
 
@@ -1169,8 +1180,9 @@ ldp_copy_ep_to_sockaddr (__SOCKADDR_ARG addr, socklen_t * __restrict len,
 }
 
 int
-getsockname (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
+getsockname (int fd, __SOCKADDR_ARG _addr, socklen_t *__restrict len)
 {
+  struct sockaddr *addr = SOCKADDR_GET_SA (_addr);
   vls_handle_t vlsh;
   int rv;
 
@@ -1203,15 +1215,16 @@ getsockname (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
     }
   else
     {
-      rv = libc_getsockname (fd, addr, len);
+      rv = libc_getsockname (fd, _addr, len);
     }
 
   return rv;
 }
 
 int
-connect (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
+connect (int fd, __CONST_SOCKADDR_ARG _addr, socklen_t len)
 {
+  const struct sockaddr *addr = SOCKADDR_GET_SA (_addr);
   vls_handle_t vlsh;
   int rv;
 
@@ -1291,8 +1304,9 @@ done:
 }
 
 int
-getpeername (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
+getpeername (int fd, __SOCKADDR_ARG _addr, socklen_t *__restrict len)
 {
+  struct sockaddr *addr = SOCKADDR_GET_SA (_addr);
   vls_handle_t vlsh;
   int rv;
 
@@ -1543,8 +1557,9 @@ __recv_chk (int fd, void *buf, size_t n, size_t buflen, int flags)
 static inline int
 ldp_vls_sendo (vls_handle_t vlsh, const void *buf, size_t n,
               vppcom_endpt_tlv_t *ep_tlv, int flags,
-              __CONST_SOCKADDR_ARG addr, socklen_t addr_len)
+              __CONST_SOCKADDR_ARG _addr, socklen_t addr_len)
 {
+  const struct sockaddr *addr = SOCKADDR_GET_SA (_addr);
   vppcom_endpt_t *ep = 0;
   vppcom_endpt_t _ep;
 
@@ -1582,11 +1597,11 @@ ldp_vls_sendo (vls_handle_t vlsh, const void *buf, size_t n,
 }
 
 static int
-ldp_vls_recvfrom (vls_handle_t vlsh, void *__restrict buf, size_t n,
-                 int flags, __SOCKADDR_ARG addr,
-                 socklen_t * __restrict addr_len)
+ldp_vls_recvfrom (vls_handle_t vlsh, void *__restrict buf, size_t n, int flags,
+                 __SOCKADDR_ARG _addr, socklen_t *__restrict addr_len)
 {
   u8 src_addr[sizeof (struct sockaddr_in6)];
+  struct sockaddr *addr = SOCKADDR_GET_SA (_addr);
   vppcom_endpt_t ep;
   ssize_t size;
   int rv;
@@ -1611,8 +1626,9 @@ ldp_vls_recvfrom (vls_handle_t vlsh, void *__restrict buf, size_t n,
 
 ssize_t
 sendto (int fd, const void *buf, size_t n, int flags,
-       __CONST_SOCKADDR_ARG addr, socklen_t addr_len)
+       __CONST_SOCKADDR_ARG _addr, socklen_t addr_len)
 {
+  const struct sockaddr *addr = SOCKADDR_GET_SA (_addr);
   vls_handle_t vlsh;
   ssize_t size;
 
@@ -1723,7 +1739,7 @@ sendmsg (int fd, const struct msghdr * msg, int flags)
   return size;
 }
 
-#ifdef USE_GNU
+#ifdef _GNU_SOURCE
 int
 sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
 {
@@ -1822,7 +1838,7 @@ recvmsg (int fd, struct msghdr * msg, int flags)
   return size;
 }
 
-#ifdef USE_GNU
+#ifdef _GNU_SOURCE
 int
 recvmmsg (int fd, struct mmsghdr *vmessages,
          unsigned int vlen, int flags, struct timespec *tmo)
@@ -2139,9 +2155,10 @@ listen (int fd, int n)
 }
 
 static inline int
-ldp_accept4 (int listen_fd, __SOCKADDR_ARG addr,
-            socklen_t * __restrict addr_len, int flags)
+ldp_accept4 (int listen_fd, __SOCKADDR_ARG _addr,
+            socklen_t *__restrict addr_len, int flags)
 {
+  struct sockaddr *addr = SOCKADDR_GET_SA (_addr);
   vls_handle_t listen_vlsh, accept_vlsh;
   int rv;
 
@@ -2671,7 +2688,7 @@ done:
   return rv;
 }
 
-#ifdef USE_GNU
+#ifdef _GNU_SOURCE
 int
 ppoll (struct pollfd *fds, nfds_t nfds,
        const struct timespec *timeout, const sigset_t * sigmask)
index 8d78ead..327e73c 100644 (file)
@@ -23,9 +23,9 @@
 #define LDP_DEBUG_INIT 0
 #endif
 
+#include <vcl/ldp_glibc_socket.h>
 #include <vppinfra/error.h>
 #include <vppinfra/types.h>
-#include <vcl/ldp_glibc_socket.h>
 
 #define LDP_ENV_DEBUG     "LDP_DEBUG"
 #define LDP_ENV_APP_NAME  "LDP_APP_NAME"
index 95fb7c8..dcd3720 100644 (file)
@@ -200,15 +200,14 @@ recvfrom (int __fd, void *__restrict __buf,
 extern ssize_t
 sendmsg (int __fd, const struct msghdr *__message, int __flags);
 
-#ifdef __USE_GNU
+#ifdef _GNU_SOURCE
 /* Send a VLEN messages as described by VMESSAGES to socket FD.
    Returns the number of datagrams successfully written or -1 for errors.
 
    This function is a cancellation point and therefore not marked with
    __THROW.  */
-extern int
-sendmmsg (int __fd, struct mmsghdr *__vmessages,
-         unsigned int __vlen, int __flags);
+extern int sendmmsg (int __fd, struct mmsghdr *__vmessages,
+                    unsigned int __vlen, int __flags);
 #endif
 
 /* Receive a message as described by MESSAGE from socket FD.
@@ -218,7 +217,7 @@ sendmmsg (int __fd, struct mmsghdr *__vmessages,
    __THROW.  */
 extern ssize_t recvmsg (int __fd, struct msghdr *__message, int __flags);
 
-#ifdef __USE_GNU
+#ifdef _GNU_SOURCE
 /* Receive up to VLEN messages as described by VMESSAGES from socket FD.
    Returns the number of messages received or -1 for errors.
 
@@ -337,7 +336,7 @@ epoll_pwait (int __epfd, struct epoll_event *__events,
    __THROW.  */
 extern int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout);
 
-#ifdef __USE_GNU
+#ifdef _GNU_SOURCE
 /* Like poll, but before waiting the threads signal mask is replaced
    with that specified in the fourth parameter.  For better usability,
    the timeout value is specified using a TIMESPEC object.
index e4e0f44..7ae2a22 100644 (file)
    is set.
 */
 
+#ifdef HAVE_GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
 #include <signal.h>
 #include <dlfcn.h>
 
@@ -67,7 +71,6 @@
 
 #include <vcl/ldp_socket_wrapper.h>
 
-
 enum swrap_dbglvl_e
 {
   SWRAP_LOG_ERROR = 0,
@@ -156,16 +159,14 @@ PRINTF_ATTRIBUTE (3, 4);
  * SWRAP LOADING LIBC FUNCTIONS
  *********************************************************/
 
-typedef int (*__libc_accept4) (int sockfd,
-                              struct sockaddr * addr,
-                              socklen_t * addrlen, int flags);
-typedef int (*__libc_accept) (int sockfd,
-                             struct sockaddr * addr, socklen_t * addrlen);
-typedef int (*__libc_bind) (int sockfd,
-                           const struct sockaddr * addr, socklen_t addrlen);
+typedef int (*__libc_accept4) (int sockfd, __SOCKADDR_ARG addr,
+                              socklen_t *addrlen, int flags);
+typedef int (*__libc_accept) (int sockfd, __SOCKADDR_ARG addr,
+                             socklen_t *addrlen);
+typedef int (*__libc_bind) (int sockfd, __CONST_SOCKADDR_ARG addr,
+                           socklen_t addrlen);
 typedef int (*__libc_close) (int fd);
-typedef int (*__libc_connect) (int sockfd,
-                              const struct sockaddr * addr,
+typedef int (*__libc_connect) (int sockfd, __CONST_SOCKADDR_ARG addr,
                               socklen_t addrlen);
 
 #if 0
@@ -185,16 +186,12 @@ typedef FILE *(*__libc_fopen64) (const char *name, const char *mode);
 #ifdef HAVE_EVENTFD
 typedef int (*__libc_eventfd) (int count, int flags);
 #endif
-typedef int (*__libc_getpeername) (int sockfd,
-                                  struct sockaddr * addr,
-                                  socklen_t * addrlen);
-typedef int (*__libc_getsockname) (int sockfd,
-                                  struct sockaddr * addr,
-                                  socklen_t * addrlen);
-typedef int (*__libc_getsockopt) (int sockfd,
-                                 int level,
-                                 int optname,
-                                 void *optval, socklen_t * optlen);
+typedef int (*__libc_getpeername) (int sockfd, __SOCKADDR_ARG addr,
+                                  socklen_t *addrlen);
+typedef int (*__libc_getsockname) (int sockfd, __SOCKADDR_ARG addr,
+                                  socklen_t *addrlen);
+typedef int (*__libc_getsockopt) (int sockfd, int level, int optname,
+                                 void *optval, socklen_t *optlen);
 typedef int (*__libc_ioctl) (int d, unsigned long int request, ...);
 typedef int (*__libc_listen) (int sockfd, int backlog);
 typedef int (*__libc_open) (const char *pathname, int flags, mode_t mode);
@@ -204,25 +201,29 @@ typedef int (*__libc_open64) (const char *pathname, int flags, mode_t mode);
 typedef int (*__libc_openat) (int dirfd, const char *path, int flags, ...);
 typedef int (*__libc_pipe) (int pipefd[2]);
 typedef int (*__libc_read) (int fd, void *buf, size_t count);
-typedef ssize_t (*__libc_readv) (int fd, const struct iovec * iov,
-                                int iovcnt);
+typedef ssize_t (*__libc_readv) (int fd, const struct iovec *iov, int iovcnt);
 typedef int (*__libc_recv) (int sockfd, void *buf, size_t len, int flags);
-typedef int (*__libc_recvfrom) (int sockfd,
-                               void *buf,
-                               size_t len,
-                               int flags,
-                               struct sockaddr * src_addr,
-                               socklen_t * addrlen);
-typedef int (*__libc_recvmsg) (int sockfd, const struct msghdr * msg,
+typedef int (*__libc_recvfrom) (int sockfd, void *buf, size_t len, int flags,
+                               __SOCKADDR_ARG src_addr, socklen_t *addrlen);
+typedef int (*__libc_recvmsg) (int sockfd, const struct msghdr *msg,
                               int flags);
+#ifdef _GNU_SOURCE
+typedef int (*__libc_recvmmsg) (int fd, struct mmsghdr *vmessages,
+                               unsigned int vlen, int flags,
+                               struct timespec *tmo);
+#endif
 typedef int (*__libc_send) (int sockfd, const void *buf, size_t len,
                            int flags);
 typedef ssize_t (*__libc_sendfile) (int out_fd, int in_fd, off_t * offset,
                                    size_t len);
 typedef int (*__libc_sendmsg) (int sockfd, const struct msghdr * msg,
                               int flags);
+#ifdef _GNU_SOURCE
+typedef int (*__libc_sendmmsg) (int __fd, struct mmsghdr *__vmessages,
+                               unsigned int __vlen, int __flags);
+#endif
 typedef int (*__libc_sendto) (int sockfd, const void *buf, size_t len,
-                             int flags, const struct sockaddr * dst_addr,
+                             int flags, __CONST_SOCKADDR_ARG dst_addr,
                              socklen_t addrlen);
 typedef int (*__libc_setsockopt) (int sockfd, int level, int optname,
                                  const void *optval, socklen_t optlen);
@@ -271,7 +272,7 @@ typedef int (*__libc_epoll_pwait) (int __epfd, struct epoll_event * __events,
 typedef int (*__libc_poll) (struct pollfd * __fds, nfds_t __nfds,
                            int __timeout);
 
-#ifdef __USE_GNU
+#ifdef _GNU_SOURCE
 typedef int (*__libc_ppoll) (struct pollfd * __fds, nfds_t __nfds,
                             const struct timespec * __timeout,
                             const __sigset_t * __ss);
@@ -323,9 +324,15 @@ struct swrap_libc_symbols
   SWRAP_SYMBOL_ENTRY (recv);
   SWRAP_SYMBOL_ENTRY (recvfrom);
   SWRAP_SYMBOL_ENTRY (recvmsg);
+#ifdef _GNU_SOURCE
+  SWRAP_SYMBOL_ENTRY (recvmmsg);
+#endif
   SWRAP_SYMBOL_ENTRY (send);
   SWRAP_SYMBOL_ENTRY (sendfile);
   SWRAP_SYMBOL_ENTRY (sendmsg);
+#ifdef _GNU_SOURCE
+  SWRAP_SYMBOL_ENTRY (sendmmsg);
+#endif
   SWRAP_SYMBOL_ENTRY (sendto);
   SWRAP_SYMBOL_ENTRY (setsockopt);
 #ifdef HAVE_SIGNALFD
@@ -350,7 +357,7 @@ struct swrap_libc_symbols
   SWRAP_SYMBOL_ENTRY (epoll_wait);
   SWRAP_SYMBOL_ENTRY (epoll_pwait);
   SWRAP_SYMBOL_ENTRY (poll);
-#ifdef __USE_GNU
+#ifdef _GNU_SOURCE
   SWRAP_SYMBOL_ENTRY (ppoll);
 #endif
 };
@@ -480,8 +487,7 @@ _swrap_bind_symbol (enum swrap_lib lib, const char *fn_name)
  * So we need load each function at the point it is called the first time.
  */
 int
-libc_accept4 (int sockfd,
-             struct sockaddr *addr, socklen_t * addrlen, int flags)
+libc_accept4 (int sockfd, __SOCKADDR_ARG addr, socklen_t *addrlen, int flags)
 {
   swrap_bind_symbol_libc (accept4);
 
@@ -489,7 +495,7 @@ libc_accept4 (int sockfd,
 }
 
 int
-libc_accept (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
+libc_accept (int sockfd, __SOCKADDR_ARG addr, socklen_t *addrlen)
 {
   swrap_bind_symbol_libc (accept);
 
@@ -497,7 +503,7 @@ libc_accept (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
 }
 
 int
-libc_bind (int sockfd, const struct sockaddr *addr, socklen_t addrlen)
+libc_bind (int sockfd, __CONST_SOCKADDR_ARG addr, socklen_t addrlen)
 {
   swrap_bind_symbol_libc (bind);
 
@@ -513,7 +519,7 @@ libc_close (int fd)
 }
 
 int
-libc_connect (int sockfd, const struct sockaddr *addr, socklen_t addrlen)
+libc_connect (int sockfd, __CONST_SOCKADDR_ARG addr, socklen_t addrlen)
 {
   swrap_bind_symbol_libc (connect);
 
@@ -587,7 +593,7 @@ libc_vioctl (int fd, int cmd, va_list ap)
 }
 
 int
-libc_getpeername (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
+libc_getpeername (int sockfd, __SOCKADDR_ARG addr, socklen_t *addrlen)
 {
   swrap_bind_symbol_libc (getpeername);
 
@@ -595,7 +601,7 @@ libc_getpeername (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
 }
 
 int
-libc_getsockname (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
+libc_getsockname (int sockfd, __SOCKADDR_ARG addr, socklen_t *addrlen)
 {
   swrap_bind_symbol_libc (getsockname);
 
@@ -647,10 +653,8 @@ libc_recv (int sockfd, void *buf, size_t len, int flags)
 }
 
 int
-libc_recvfrom (int sockfd,
-              void *buf,
-              size_t len,
-              int flags, struct sockaddr *src_addr, socklen_t * addrlen)
+libc_recvfrom (int sockfd, void *buf, size_t len, int flags,
+              __SOCKADDR_ARG src_addr, socklen_t *addrlen)
 {
   swrap_bind_symbol_libc (recvfrom);
 
@@ -667,6 +671,17 @@ libc_recvmsg (int sockfd, struct msghdr *msg, int flags)
   return swrap.libc.symbols._libc_recvmsg.f (sockfd, msg, flags);
 }
 
+#ifdef _GNU_SOURCE
+int
+libc_recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
+              struct timespec *tmo)
+{
+  swrap_bind_symbol_libc (recvmmsg);
+
+  return swrap.libc.symbols._libc_recvmmsg.f (fd, vmessages, vlen, flags, tmo);
+}
+#endif
+
 int
 libc_send (int sockfd, const void *buf, size_t len, int flags)
 {
@@ -691,11 +706,19 @@ libc_sendmsg (int sockfd, const struct msghdr *msg, int flags)
   return swrap.libc.symbols._libc_sendmsg.f (sockfd, msg, flags);
 }
 
+#ifdef _GNU_SOURCE
+int
+libc_sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
+{
+  swrap_bind_symbol_libc (sendmmsg);
+
+  return swrap.libc.symbols._libc_sendmmsg.f (fd, vmessages, vlen, flags);
+}
+#endif
+
 int
-libc_sendto (int sockfd,
-            const void *buf,
-            size_t len,
-            int flags, const struct sockaddr *dst_addr, socklen_t addrlen)
+libc_sendto (int sockfd, const void *buf, size_t len, int flags,
+            __CONST_SOCKADDR_ARG dst_addr, socklen_t addrlen)
 {
   swrap_bind_symbol_libc (sendto);
 
@@ -838,7 +861,7 @@ libc_poll (struct pollfd *__fds, nfds_t __nfds, int __timeout)
   return swrap.libc.symbols._libc_poll.f (__fds, __nfds, __timeout);
 }
 
-#ifdef __USE_GNU
+#ifdef _GNU_SOURCE
 int
 libc_ppoll (struct pollfd *__fds, nfds_t __nfds,
            const struct timespec *__timeout, const __sigset_t * __ss)
index 0d167cf..bf1b0e3 100644 (file)
  * has probably something todo with with the linker.
  * So we need load each function at the point it is called the first time.
  */
-int libc_accept4 (int sockfd, struct sockaddr *addr, socklen_t * addrlen,
+int libc_accept4 (int sockfd, __SOCKADDR_ARG addr, socklen_t *addrlen,
                  int flags);
 
-int libc_accept (int sockfd, struct sockaddr *addr, socklen_t * addrlen);
+int libc_accept (int sockfd, __SOCKADDR_ARG addr, socklen_t *addrlen);
 
-int libc_bind (int sockfd, const struct sockaddr *addr, socklen_t addrlen);
+int libc_bind (int sockfd, __CONST_SOCKADDR_ARG addr, socklen_t addrlen);
 
 int libc_close (int fd);
 
-int libc_connect (int sockfd, const struct sockaddr *addr, socklen_t addrlen);
+int libc_connect (int sockfd, __CONST_SOCKADDR_ARG addr, socklen_t addrlen);
 
 #if 0
 /* TBD: dup and dup2 to be implemented later */
@@ -128,9 +128,9 @@ int libc_vfcntl64 (int fd, int cmd, va_list ap);
 
 int libc_vioctl (int fd, int cmd, va_list ap);
 
-int libc_getpeername (int sockfd, struct sockaddr *addr, socklen_t * addrlen);
+int libc_getpeername (int sockfd, __SOCKADDR_ARG addr, socklen_t *addrlen);
 
-int libc_getsockname (int sockfd, struct sockaddr *addr, socklen_t * addrlen);
+int libc_getsockname (int sockfd, __SOCKADDR_ARG addr, socklen_t *addrlen);
 
 int
 libc_getsockopt (int sockfd,
@@ -144,25 +144,29 @@ ssize_t libc_readv (int fd, const struct iovec *iov, int iovcnt);
 
 int libc_recv (int sockfd, void *buf, size_t len, int flags);
 
-int
-libc_recvfrom (int sockfd,
-              void *buf,
-              size_t len,
-              int flags, struct sockaddr *src_addr, socklen_t * addrlen);
+int libc_recvfrom (int sockfd, void *buf, size_t len, int flags,
+                  __SOCKADDR_ARG src_addr, socklen_t *addrlen);
 
 int libc_recvmsg (int sockfd, struct msghdr *msg, int flags);
 
+#ifdef _GNU_SOURCE
+int libc_recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen,
+                  int flags, struct timespec *tmo);
+#endif
+
 int libc_send (int sockfd, const void *buf, size_t len, int flags);
 
 ssize_t libc_sendfile (int out_fd, int in_fd, off_t * offset, size_t len);
 
 int libc_sendmsg (int sockfd, const struct msghdr *msg, int flags);
 
-int
-libc_sendto (int sockfd,
-            const void *buf,
-            size_t len,
-            int flags, const struct sockaddr *dst_addr, socklen_t addrlen);
+#ifdef _GNU_SOURCE
+int libc_sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen,
+                  int flags);
+#endif
+
+int libc_sendto (int sockfd, const void *buf, size_t len, int flags,
+                __CONST_SOCKADDR_ARG dst_addr, socklen_t addrlen);
 
 int
 libc_setsockopt (int sockfd,
@@ -210,7 +214,7 @@ int libc_epoll_pwait (int __epfd, struct epoll_event *__events,
 
 int libc_poll (struct pollfd *__fds, nfds_t __nfds, int __timeout);
 
-#ifdef __USE_GNU
+#ifdef _GNU_SOURCE
 int libc_ppoll (struct pollfd *__fds, nfds_t __nfds,
                const struct timespec *__timeout, const __sigset_t * __ss);
 #endif