The branch, master has been updated via c7c45b0 tests: Add test for ephemeral port binding in listen() via 1e2f53a swrap: Automatically bind an ephemeral port if needed from f24f91e tests: Add valgrind suppression file for dlopen() issues
https://git.samba.org/?p=socket_wrapper.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit c7c45b0f2abf2fb278c7a63a24090fad3df28fee Author: Andreas Schneider <a...@samba.org> Date: Wed Nov 4 11:22:25 2015 +0100 tests: Add test for ephemeral port binding in listen() Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 1e2f53a6db5b9163ece72b0d75396b5816464460 Author: Andreas Schneider <a...@samba.org> Date: Wed Nov 4 11:21:23 2015 +0100 swrap: Automatically bind an ephemeral port if needed Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> ----------------------------------------------------------------------- Summary of changes: src/socket_wrapper.c | 8 ++++ tests/CMakeLists.txt | 1 + tests/test_tcp_listen.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+) create mode 100644 tests/test_tcp_listen.c Changeset truncated at 500 lines: diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c index b43c877..9ba212b 100644 --- a/src/socket_wrapper.c +++ b/src/socket_wrapper.c @@ -3154,6 +3154,14 @@ static int swrap_listen(int s, int backlog) return libc_listen(s, backlog); } + if (si->bound == 0) { + ret = swrap_auto_bind(s, si, si->family); + if (ret == -1) { + errno = EADDRINUSE; + return ret; + } + } + ret = libc_listen(s, backlog); return ret; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9679177..aecf6b8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -20,6 +20,7 @@ target_link_libraries(${TORTURE_LIBRARY} set(SWRAP_TESTS test_ioctl + test_tcp_listen test_echo_tcp_socket test_echo_tcp_connect test_echo_tcp_bind diff --git a/tests/test_tcp_listen.c b/tests/test_tcp_listen.c new file mode 100644 index 0000000..5641c47 --- /dev/null +++ b/tests/test_tcp_listen.c @@ -0,0 +1,115 @@ +#include <stdarg.h> +#include <stddef.h> +#include <setjmp.h> +#include <cmocka.h> + +#include "config.h" +#include "torture.h" + +#include <errno.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#ifdef HAVE_RPC_RPC_H +#include <rpc/rpc.h> +#endif + +static int setup(void **state) +{ + torture_setup_socket_dir(state); + + return 0; +} + +static int teardown(void **state) +{ + torture_teardown_socket_dir(state); + + return 0; +} + +static void test_listen_unbound_ipv4(void **state) +{ + struct torture_address addr = { + .sa_socklen = sizeof(struct sockaddr_storage), + }; + int rc; + int s1; + int s2; + + (void) state; /* unused */ + + s1 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + assert_return_code(s1, errno); + + rc = listen(s1, SOMAXCONN); + assert_return_code(rc, errno); + + rc = getsockname(s1, &addr.sa.s, &addr.sa_socklen); + assert_return_code(rc, errno); + assert_int_equal(addr.sa_socklen, sizeof(struct sockaddr_in)); + assert_in_range(ntohs(addr.sa.in.sin_port), 1024, 65535); + + s2 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + assert_return_code(s2, errno); + + rc = connect(s2, &addr.sa.s, addr.sa_socklen); + assert_return_code(rc, errno); + + close(s1); + close(s2); +} + +#ifdef HAVE_IPV6 +static void test_listen_unbound_ipv6(void **state) +{ + struct torture_address addr = { + .sa_socklen = sizeof(struct sockaddr_storage), + }; + int rc; + int s1; + int s2; + + (void) state; /* unused */ + + s1 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); + assert_return_code(s1, errno); + + rc = listen(s1, SOMAXCONN); + assert_return_code(rc, errno); + + rc = getsockname(s1, &addr.sa.s, &addr.sa_socklen); + assert_return_code(rc, errno); + assert_int_equal(addr.sa_socklen, sizeof(struct sockaddr_in6)); + assert_in_range(ntohs(addr.sa.in6.sin6_port), 1024, 65535); + + s2 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); + assert_return_code(s2, errno); + + rc = connect(s2, &addr.sa.s, addr.sa_socklen); + assert_return_code(rc, errno); + + close(s1); + close(s2); +} +#endif /* HAVE_IPV6 */ + +int main(void) { + int rc; + + const struct CMUnitTest tcp_listen_tests[] = { + cmocka_unit_test(test_listen_unbound_ipv4), +#ifdef HAVE_IPV6 + cmocka_unit_test(test_listen_unbound_ipv6), +#endif /* HAVE_IPV6 */ + }; + + rc = cmocka_run_group_tests(tcp_listen_tests, setup, teardown); + + return rc; +} -- Socket Wrapper Repository