From 5917939256af392914d8a648de0c3287042ddbf6 Mon Sep 17 00:00:00 2001 From: Dave Wallace Date: Tue, 7 Nov 2017 02:20:07 -0500 Subject: [PATCH] VCL-LDPRELOAD: enable accept4() wrapper Change-Id: I56567953fb8329315393047913e30fc7f2242bdb Signed-off-by: Dave Wallace --- src/vcl/sock_test_server.c | 2 + src/vcl/vcom.c | 19 ++++++--- src/vcl/vcom_glibc_socket.h | 2 - src/vcl/vcom_socket.c | 93 ++++++++++++++++++++++++++++--------------- src/vcl/vcom_socket.h | 2 - src/vcl/vcom_socket_wrapper.c | 10 ----- src/vcl/vcom_socket_wrapper.h | 10 ++--- test/scripts/socket_test.sh | 2 +- 8 files changed, 80 insertions(+), 60 deletions(-) diff --git a/src/vcl/sock_test_server.c b/src/vcl/sock_test_server.c index 753a7da790c..728a6a7a14e 100644 --- a/src/vcl/sock_test_server.c +++ b/src/vcl/sock_test_server.c @@ -304,6 +304,8 @@ new_client (void) -1.0 /* wait forever */ ); if (client_fd < 0) errno = -client_fd; +#elif HAVE_ACCEPT4 + client_fd = accept4 (ssm->listen_fd, (struct sockaddr *) NULL, NULL, NULL); #else client_fd = accept (ssm->listen_fd, (struct sockaddr *) NULL, NULL); #endif diff --git a/src/vcl/vcom.c b/src/vcl/vcom.c index b215771e70c..ed52bfac8e4 100644 --- a/src/vcl/vcom.c +++ b/src/vcl/vcom.c @@ -2568,7 +2568,6 @@ accept (int __fd, __SOCKADDR_ARG __addr, socklen_t * __restrict __addr_len) return libc_accept (__fd, __addr, __addr_len); } -#ifdef __USE_GNU /* * Similar to 'accept' but takes an additional parameter to specify * flags. @@ -2592,9 +2591,14 @@ int accept4 (int __fd, __SOCKADDR_ARG __addr, socklen_t * __restrict __addr_len, int __flags) { - int rv; + int rv = 0; pid_t pid = getpid (); + fprintf (stderr, + "[%d] accept4: in the beginning... " + "'%04d'='%04d', '%p', '%p', '%04x'\n", + pid, rv, __fd, __addr, __addr_len, __flags); + if (is_vcom_socket_fd (__fd)) { if (VCOM_DEBUG > 0) @@ -2602,7 +2606,7 @@ accept4 (int __fd, __SOCKADDR_ARG __addr, rv = vcom_accept4 (__fd, __addr, __addr_len, __flags); if (VCOM_DEBUG > 0) fprintf (stderr, - "[%d] accept4: " + "[%d] accept4: VCL " "'%04d'='%04d', '%p', '%p', '%04x'\n", pid, rv, __fd, __addr, __addr_len, __flags); if (VCOM_DEBUG > 0) @@ -2614,11 +2618,14 @@ accept4 (int __fd, __SOCKADDR_ARG __addr, } return rv; } + fprintf (stderr, + "[%d] accept4: libc " + "'%04d'='%04d', '%p', '%p', '%04x'\n", + pid, rv, __fd, __addr, __addr_len, __flags); + return libc_accept4 (__fd, __addr, __addr_len, __flags); } -#endif - /* * Shut down all or part of the connection open on socket FD. * HOW determines what to shut down: @@ -2822,7 +2829,7 @@ epoll_wait (int __epfd, struct epoll_event *__events, rv = vcom_socket_epoll_pwait (__epfd, __events, __maxevents, __timeout, NULL); - if (VCOM_DEBUG > 0) + if (VCOM_DEBUG > 1) fprintf (stderr, "[%d] epoll_wait: " "'%04d'='%04d', '%p', " diff --git a/src/vcl/vcom_glibc_socket.h b/src/vcl/vcom_glibc_socket.h index 4eb60fb65c7..969029f3e63 100644 --- a/src/vcl/vcom_glibc_socket.h +++ b/src/vcl/vcom_glibc_socket.h @@ -249,7 +249,6 @@ extern int __THROW listen (int __fd, int __n); extern int accept (int __fd, __SOCKADDR_ARG __addr, socklen_t * __restrict __addr_len); -#ifdef __USE_GNU /* Similar to 'accept' but takes an additional parameter to specify flags. This function is a cancellation point and therefore not marked with @@ -258,7 +257,6 @@ accept (int __fd, __SOCKADDR_ARG __addr, socklen_t * __restrict __addr_len); extern int accept4 (int __fd, __SOCKADDR_ARG __addr, socklen_t * __restrict __addr_len, int __flags); -#endif /* Shut down all or part of the connection open on socket FD. HOW determines what to shut down: diff --git a/src/vcl/vcom_socket.c b/src/vcl/vcom_socket.c index ece9b69a44b..6fcc4e5820e 100644 --- a/src/vcl/vcom_socket.c +++ b/src/vcl/vcom_socket.c @@ -781,10 +781,24 @@ vcom_session_ioctl_va (int __sid, int __cmd, va_list __ap) { int rv; - if (__cmd == FIONREAD) - rv = vppcom_session_attr (__sid, VPPCOM_ATTR_GET_NREAD, 0, 0); - else - rv = -EOPNOTSUPP; + switch (__cmd) + { + case FIONREAD: + rv = vppcom_session_attr (__sid, VPPCOM_ATTR_GET_NREAD, 0, 0); + break; + + case FIONBIO: + { + u32 flags = va_arg (__ap, int) ? O_NONBLOCK : 0; + u32 len = sizeof (flags); + rv = vppcom_session_attr (__sid, VPPCOM_ATTR_SET_FLAGS, &flags, &len); + } + break; + + default: + rv = -EOPNOTSUPP; + break; + } return rv; } @@ -1015,7 +1029,6 @@ vcom_socket_select (int vcom_nfds, fd_set * __restrict vcom_readfds, struct timeval *__restrict timeout) { static unsigned long vcom_nsid_fds = 0; - vcom_socket_main_t *vsm = &vcom_socket_main; int vcom_nsid = 0; int rv = -EBADF; @@ -1086,14 +1099,14 @@ vcom_socket_select (int vcom_nfds, fd_set * __restrict vcom_readfds, if (VCOM_DEBUG > 0) fprintf (stderr, "[%d] vcom_socket_select called to " - "emulate delay_ns()!\n", vsm->my_pid); + "emulate delay_ns()!\n", getpid ()); rv = vppcom_select (0, NULL, NULL, NULL, time_to_wait); } else { fprintf (stderr, "[%d] vcom_socket_select called vcom_nfds = 0 " "and invalid time_to_wait (%f)!\n", - vsm->my_pid, time_to_wait); + getpid (), time_to_wait); } return 0; } @@ -1128,7 +1141,7 @@ vcom_socket_select (int vcom_nfds, fd_set * __restrict vcom_readfds, NULL, time_to_wait); if (VCOM_DEBUG > 2) fprintf (stderr, "[%d] called vppcom_select(): " - "'%04d'='%04d'\n", vsm->my_pid, rv, (int) vcom_nsid_fds); + "'%04d'='%04d'\n", getpid (), rv, (int) vcom_nsid_fds); /* check if any file descriptors changed status */ if (rv > 0) @@ -2278,9 +2291,17 @@ vcom_socket_accept_flags (int __fd, __SOCKADDR_ARG __addr, /* flags can be 0 or can be bitwise OR * of any of SOCK_NONBLOCK and SOCK_CLOEXEC */ + if (VCOM_DEBUG > 2) + fprintf (stderr, "[%d] vcom_socket_accept_flags: " + "fd = %d, __addr = %p, __addr_len = %p flags = %d (0x%x)\n", + getpid (), __fd, __addr, __addr_len, flags, flags); + if (!(!flags || (flags & (SOCK_NONBLOCK | SOCK_CLOEXEC)))) { /* TBD: return proper error code */ + fprintf (stderr, "[%d] ERROR: vcom_socket_accept_flags: " + "invalid flags = %d (0x%x)\n", getpid (), flags, flags); + return -1; } @@ -2288,6 +2309,8 @@ vcom_socket_accept_flags (int __fd, __SOCKADDR_ARG __addr, if (!vcom_socket_is_connection_mode_socket (__fd)) { + fprintf (stderr, "[%d] ERROR: vcom_socket_accept_flags: " + "connection mode socket support TBD!\n", getpid ()); return -EOPNOTSUPP; } @@ -2300,6 +2323,8 @@ vcom_socket_accept_flags (int __fd, __SOCKADDR_ARG __addr, rv = vcom_fcntl (vsock->fd, F_GETFL, 0); if (rv < 0) { + fprintf (stderr, "[%d] ERROR: vcom_socket_accept_flags: " + "vcom_fcnt() returned %d!\n", getpid (), rv); return rv; } @@ -2334,6 +2359,9 @@ vcom_socket_accept_flags (int __fd, __SOCKADDR_ARG __addr, } if (rv < 0) { + if (rv != VPPCOM_EAGAIN) + fprintf (stderr, "[%d] ERROR: vcom_socket_accept_flags: " + "vppcom_session_accept() returned %d!", getpid (), rv); return rv; } @@ -2347,6 +2375,9 @@ vcom_socket_accept_flags (int __fd, __SOCKADDR_ARG __addr, &domain, &type, &protocol, flags); if (fd < 0) { + fprintf (stderr, "[%d] ERROR: vcom_socket_accept_flags: " + "vcom_socket_connected_socket() returned %d!", + getpid (), rv); return fd; } @@ -2426,18 +2457,6 @@ vcom_socket_accept_flags (int __fd, __SOCKADDR_ARG __addr, } } } - else - { - /* when __addr is NULL, nothing is filled in, - * in this case, __addr_len is not used, - * and should also be null - * */ - if (__addr_len) - { - /* TBD: return proper error code */ - return -1; - } - } } return rv; @@ -2451,7 +2470,6 @@ vcom_socket_accept (int __fd, __SOCKADDR_ARG __addr, return vcom_socket_accept_flags (__fd, __addr, __addr_len, 0); } -#ifdef __USE_GNU int vcom_socket_accept4 (int __fd, __SOCKADDR_ARG __addr, socklen_t * __restrict __addr_len, int __flags) @@ -2459,7 +2477,6 @@ vcom_socket_accept4 (int __fd, __SOCKADDR_ARG __addr, /* SOCK_NONBLOCK and SOCK_CLOEXEC can be bitwise ORed in flags */ return vcom_socket_accept_flags (__fd, __addr, __addr_len, __flags); } -#endif /* TBD: move it to vppcom */ static inline int @@ -2757,7 +2774,6 @@ vcom_socket_epoll_ctl_internal (int __epfd, int __op, int __fd, struct epoll_event *__event, int free_vepitem_on_del) { - vcom_socket_main_t *vsm = &vcom_socket_main; int rv = -1; i32 cnt; vcom_epoll_t *vepoll; @@ -2790,7 +2806,7 @@ vcom_socket_epoll_ctl_internal (int __epfd, int __op, int __fd, "[%d] vcom_socket_epoll_ctl_i: vppcom_epoll_ctl() " "returned %d\n\tepfd %d, vep_idx %d, fd %d sid %d op %d" "\n\tcount %d, vcl_cnt %d, libc_cnt %d\n", - vsm->my_pid, rv, __epfd, vep_idx, __fd, sid, __op, + getpid (), rv, __epfd, vep_idx, __fd, sid, __op, vepoll->count, vepoll->vcl_cnt, vepoll->libc_cnt); } else @@ -2808,7 +2824,7 @@ vcom_socket_epoll_ctl_internal (int __epfd, int __op, int __fd, "[%d] vcom_socket_epoll_ctl_i: libc_epoll_ctl() " "returned %d\n\tepfd %d, vep_idx %d, fd %d sid %d op %d" "\n\tcount %d, vcl_cnt %d, libc_cnt %d\n", - vsm->my_pid, rv, __epfd, vep_idx, __fd, sid, __op, + getpid (), rv, __epfd, vep_idx, __fd, sid, __op, vepoll->count, vepoll->vcl_cnt, vepoll->libc_cnt); } @@ -2853,7 +2869,7 @@ vcom_socket_epoll_pwait (int __epfd, struct epoll_event *__events, if (!__events || (__timeout < -1)) { fprintf (stderr, "[%d] ERROR: vcom_socket_epoll_pwait: " - "Bad args __events %p, __timeout %d\n", vsm->my_pid, + "Bad args __events %p, __timeout %d\n", getpid (), __events, __timeout); rv = -EFAULT; goto out; @@ -2866,7 +2882,7 @@ vcom_socket_epoll_pwait (int __epfd, struct epoll_event *__events, if (vep_idx == INVALID_VEP_IDX) { fprintf (stderr, "[%d] ERROR: vcom_socket_epoll_pwait: " - "Bad epoll fd %d\n", vsm->my_pid, __epfd); + "Bad epoll fd %d\n", getpid (), __epfd); return -EBADF; } @@ -2874,21 +2890,31 @@ vcom_socket_epoll_pwait (int __epfd, struct epoll_event *__events, { fprintf (stderr, "[%d] ERROR: vcom_socket_epoll_pwait: No events" " in epfd!\n\tcount %d, vcl_cnt %d, libc_cnt %d\n", - vsm->my_pid, vepoll->count, vepoll->vcl_cnt, vepoll->libc_cnt); + getpid (), vepoll->count, vepoll->vcl_cnt, vepoll->libc_cnt); rv = -EINVAL; goto out; } if (vepoll->libc_cnt == 0) { + if (VCOM_DEBUG > 2) + fprintf (stderr, "[%d] vcom_socket_epoll_pwait: libc_cnt = 0, " + "calling vppcom_epoll_wait()\n", getpid ()); rv = vppcom_epoll_wait (vep_idx, __events, __maxevents, time_to_wait); } else if (vepoll->vcl_cnt == 0) { + if (VCOM_DEBUG > 2) + fprintf (stderr, "[%d] vcom_socket_epoll_pwait: vcl_cnt = 0, " + "calling libc_epoll_pwait()\n", getpid ()); rv = libc_epoll_pwait (__epfd, __events, __maxevents, __timeout, __ss); } else { + if (VCOM_DEBUG > 2) + fprintf (stderr, "[%d] vcom_socket_epoll_pwait: vcl_cnt = %d, " + "libc_cnt = %d -> mixed polling\n", getpid (), + vepoll->vcl_cnt, vepoll->libc_cnt); vec_validate (libc_ev, __maxevents); timeout = clib_time_now (&vsm->clib_time) + time_to_wait; do @@ -2897,6 +2923,9 @@ vcom_socket_epoll_pwait (int __epfd, struct epoll_event *__events, rv2 = libc_epoll_pwait (__epfd, libc_ev, __maxevents, 1, __ss); if ((rv > 0) || (rv2 > 0)) { + if (VCOM_DEBUG > 2) + fprintf (stderr, "[%d] vcom_socket_epoll_pwait: " + "rv = %d, rv2 = %d\n", getpid (), rv, rv2); int n = __maxevents - rv; n = rv2 <= n ? rv2 : n; rv = (rv > 0) ? rv : 0; @@ -2910,12 +2939,12 @@ vcom_socket_epoll_pwait (int __epfd, struct epoll_event *__events, if (rv < 0) fprintf (stderr, "[%d] ERROR: vppcom_epoll_wait() returned %d\n", - vsm->my_pid, rv); + getpid (), rv); if (rv2 < 0) { fprintf (stderr, "[%d] ERROR: libc_epoll_wait() failed, errno %d\n", - vsm->my_pid, errno); + getpid (), errno); rv = (rv < 0) ? rv : -errno; } goto out; @@ -3116,7 +3145,6 @@ vcom_socket_poll_select_impl (struct pollfd *__fds, nfds_t __nfds, int __timeout) { int rv; - vcom_socket_main_t *vsm = &vcom_socket_main; nfds_t fds_idx = 0; int nfd = 0; @@ -3205,7 +3233,7 @@ vcom_socket_poll_select_impl (struct pollfd *__fds, nfds_t __nfds, if (VCOM_DEBUG > 2) fprintf (stderr, "[%d] vcom_socket_select: " - "'%04d'='%04d'\n", vsm->my_pid, vcom_nfd, vcom_nfds); + "'%04d'='%04d'\n", getpid (), vcom_nfd, vcom_nfds); if (vcom_nfd < 0) { @@ -3339,7 +3367,6 @@ vcom_socket_main_init (void) vsm->epitemidxs_by_fd = hash_create (0, sizeof (i32 *)); clib_time_init (&vsm->clib_time); - vsm->my_pid = getpid (); vsm->init = 1; } diff --git a/src/vcl/vcom_socket.h b/src/vcl/vcom_socket.h index e86bab35672..0a5335fab9c 100644 --- a/src/vcl/vcom_socket.h +++ b/src/vcl/vcom_socket.h @@ -432,11 +432,9 @@ int vcom_socket_accept (int __fd, __SOCKADDR_ARG __addr, socklen_t * __restrict __addr_len); -#ifdef __USE_GNU int vcom_socket_accept4 (int __fd, __SOCKADDR_ARG __addr, socklen_t * __restrict __addr_len, int __flags); -#endif int vcom_socket_shutdown (int __fd, int __how); diff --git a/src/vcl/vcom_socket_wrapper.c b/src/vcl/vcom_socket_wrapper.c index 8d546929218..d73f4b20562 100644 --- a/src/vcl/vcom_socket_wrapper.c +++ b/src/vcl/vcom_socket_wrapper.c @@ -154,14 +154,11 @@ PRINTF_ATTRIBUTE (3, 4); * SWRAP LOADING LIBC FUNCTIONS *********************************************************/ -#ifdef HAVE_ACCEPT4 typedef int (*__libc_accept4) (int sockfd, struct sockaddr * addr, socklen_t * addrlen, int flags); -#else typedef int (*__libc_accept) (int sockfd, struct sockaddr * addr, socklen_t * addrlen); -#endif typedef int (*__libc_bind) (int sockfd, const struct sockaddr * addr, socklen_t addrlen); typedef int (*__libc_close) (int fd); @@ -282,11 +279,8 @@ typedef int (*__libc_ppoll) (struct pollfd * __fds, nfds_t __nfds, struct swrap_libc_symbols { -#ifdef HAVE_ACCEPT4 SWRAP_SYMBOL_ENTRY (accept4); -#else SWRAP_SYMBOL_ENTRY (accept); -#endif SWRAP_SYMBOL_ENTRY (bind); SWRAP_SYMBOL_ENTRY (close); SWRAP_SYMBOL_ENTRY (connect); @@ -474,7 +468,6 @@ _swrap_bind_symbol (enum swrap_lib lib, const char *fn_name) * has probably something todo with with the linker. * So we need load each function at the point it is called the first time. */ -#ifdef HAVE_ACCEPT4 int libc_accept4 (int sockfd, struct sockaddr *addr, socklen_t * addrlen, int flags) @@ -484,8 +477,6 @@ libc_accept4 (int sockfd, return swrap.libc.symbols._libc_accept4.f (sockfd, addr, addrlen, flags); } -#else /* HAVE_ACCEPT4 */ - int libc_accept (int sockfd, struct sockaddr *addr, socklen_t * addrlen) { @@ -493,7 +484,6 @@ libc_accept (int sockfd, struct sockaddr *addr, socklen_t * addrlen) return swrap.libc.symbols._libc_accept.f (sockfd, addr, addrlen); } -#endif /* HAVE_ACCEPT4 */ int libc_bind (int sockfd, const struct sockaddr *addr, socklen_t addrlen) diff --git a/src/vcl/vcom_socket_wrapper.h b/src/vcl/vcom_socket_wrapper.h index 9e85ecf2b6c..f44b5a8ef3b 100644 --- a/src/vcl/vcom_socket_wrapper.h +++ b/src/vcl/vcom_socket_wrapper.h @@ -66,6 +66,7 @@ #include #include #include +#include /* GCC have printf type attribute check. */ @@ -104,13 +105,10 @@ * has probably something todo with with the linker. * So we need load each function at the point it is called the first time. */ -#ifdef HAVE_ACCEPT4 -int -libc_accept4 (int sockfd, - struct sockaddr *addr, socklen_t * addrlen, int flags); -#else /* HAVE_ACCEPT4 */ +int libc_accept4 (int sockfd, struct sockaddr *addr, socklen_t * addrlen, + int flags); + int libc_accept (int sockfd, struct sockaddr *addr, socklen_t * addrlen); -#endif /* HAVE_ACCEPT4 */ int libc_bind (int sockfd, const struct sockaddr *addr, socklen_t addrlen); diff --git a/test/scripts/socket_test.sh b/test/scripts/socket_test.sh index 03164a96250..f269efcad81 100755 --- a/test/scripts/socket_test.sh +++ b/test/scripts/socket_test.sh @@ -569,7 +569,7 @@ write_gdb_cmdfile() { echo "set confirm off" >> $1 if [ -n "$4" ] ; then echo "set exec-wrapper env LD_PRELOAD=$4" >> $1 - echo "start" >> $1 + # echo "start" >> $1 fi if [ ! -f $2 ] ; then -- 2.16.6