Hello community, here is the log from the commit of package socket_wrapper for openSUSE:Factory checked in at 2015-11-02 12:55:09 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/socket_wrapper (Old) and /work/SRC/openSUSE:Factory/.socket_wrapper.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "socket_wrapper" Changes: -------- --- /work/SRC/openSUSE:Factory/socket_wrapper/socket_wrapper.changes 2015-09-09 20:21:32.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.socket_wrapper.new/socket_wrapper.changes 2015-11-02 12:55:11.000000000 +0100 @@ -1,0 +2,7 @@ +Thu Oct 15 09:15:14 UTC 2015 - asn@cryptomilk.org + +- Update to version 1.1.5 + * Added support for TCP_NODELAY in setsockopt/getsockopt + * Fixed cmsg space calculation + +------------------------------------------------------------------- Old: ---- socket_wrapper-1.1.4.tar.gz New: ---- socket_wrapper-1.1.5.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ socket_wrapper.spec ++++++ --- /var/tmp/diff_new_pack.AkFJdV/_old 2015-11-02 12:55:11.000000000 +0100 +++ /var/tmp/diff_new_pack.AkFJdV/_new 2015-11-02 12:55:11.000000000 +0100 @@ -24,7 +24,7 @@ ############################# NOTE ################################## Name: socket_wrapper -Version: 1.1.4 +Version: 1.1.5 Release: 0 Summary: A library passing all socket communications trough Unix sockets License: BSD-3-Clause ++++++ socket_wrapper-1.1.4.tar.gz -> socket_wrapper-1.1.5.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/socket_wrapper-1.1.4/CMakeLists.txt new/socket_wrapper-1.1.5/CMakeLists.txt --- old/socket_wrapper-1.1.4/CMakeLists.txt 2015-08-24 17:53:17.000000000 +0200 +++ new/socket_wrapper-1.1.5/CMakeLists.txt 2015-10-15 09:36:23.000000000 +0200 @@ -8,7 +8,7 @@ set(APPLICATION_VERSION_MAJOR "1") set(APPLICATION_VERSION_MINOR "1") -set(APPLICATION_VERSION_PATCH "4") +set(APPLICATION_VERSION_PATCH "5") set(APPLICATION_VERSION "${APPLICATION_VERSION_MAJOR}.${APPLICATION_VERSION_MINOR}.${APPLICATION_VERSION_PATCH}") @@ -19,7 +19,7 @@ # Increment AGE. Set REVISION to 0 # If the source code was changed, but there were no interface changes: # Increment REVISION. -set(LIBRARY_VERSION "0.1.4") +set(LIBRARY_VERSION "0.1.5") set(LIBRARY_SOVERSION "0") # where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/socket_wrapper-1.1.4/ChangeLog new/socket_wrapper-1.1.5/ChangeLog --- old/socket_wrapper-1.1.4/ChangeLog 2015-08-24 17:54:04.000000000 +0200 +++ new/socket_wrapper-1.1.5/ChangeLog 2015-10-15 10:25:33.000000000 +0200 @@ -1,6 +1,10 @@ ChangeLog ========== +version 1.1.5 (released 2015-10-15) + * Added support for TCP_NODELAY in setsockopt/getsockopt + * Fixed cmsg space calculation + version 1.1.4 (released 2015-08-25) * Fixed handling of msg_name in recvmsg() * Fixed sendmsg()/recvmsg() TCP support diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/socket_wrapper-1.1.4/src/socket_wrapper.c new/socket_wrapper-1.1.5/src/socket_wrapper.c --- old/socket_wrapper-1.1.4/src/socket_wrapper.c 2015-08-17 12:21:00.000000000 +0200 +++ new/socket_wrapper-1.1.5/src/socket_wrapper.c 2015-10-15 09:36:23.000000000 +0200 @@ -248,6 +248,7 @@ int connected; int defer_connect; int pktinfo; + int tcp_nodelay; /* The unix path so we can unlink it on close() */ struct sockaddr_un un_addr; @@ -3350,6 +3351,29 @@ optval, optlen); } + } else if (level == IPPROTO_TCP) { + switch (optname) { +#ifdef TCP_NODELAY + case TCP_NODELAY: + /* + * This enables sending packets directly out over TCP. + * As a unix socket is doing that any way, report it as + * enabled. + */ + if (optval == NULL || optlen == NULL || + *optlen < (socklen_t)sizeof(int)) { + errno = EINVAL; + return -1; + } + + *optlen = sizeof(int); + *(int *)optval = si->tcp_nodelay; + + return 0; +#endif /* TCP_NODELAY */ + default: + break; + } } errno = ENOPROTOOPT; @@ -3388,6 +3412,35 @@ optname, optval, optlen); + } else if (level == IPPROTO_TCP) { + switch (optname) { +#ifdef TCP_NODELAY + case TCP_NODELAY: { + int i; + + /* + * This enables sending packets directly out over TCP. + * A unix socket is doing that any way. + */ + if (optval == NULL || optlen == 0 || + optlen < (socklen_t)sizeof(int)) { + errno = EINVAL; + return -1; + } + + i = *discard_const_p(int, optval); + if (i != 0 && i != 1) { + errno = EINVAL; + return -1; + } + si->tcp_nodelay = i; + + return 0; + } +#endif /* TCP_NODELAY */ + default: + break; + } } switch (si->family) { @@ -3686,9 +3739,7 @@ size_t cmspace; uint8_t *p; - cmspace = - (*cm_data_space) + - CMSG_SPACE(cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr))); + cmspace = *cm_data_space + CMSG_ALIGN(cmsg->cmsg_len); p = realloc((*cm_data), cmspace); if (p == NULL) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/socket_wrapper-1.1.4/tests/CMakeLists.txt new/socket_wrapper-1.1.5/tests/CMakeLists.txt --- old/socket_wrapper-1.1.4/tests/CMakeLists.txt 2015-08-11 17:30:20.000000000 +0200 +++ new/socket_wrapper-1.1.5/tests/CMakeLists.txt 2015-10-14 11:38:17.000000000 +0200 @@ -30,7 +30,8 @@ test_echo_tcp_get_peer_sock_name test_echo_udp_sendto_recvfrom test_echo_udp_send_recv - test_echo_udp_sendmsg_recvmsg) + test_echo_udp_sendmsg_recvmsg + test_swrap_unit) if (HAVE_STRUCT_MSGHDR_MSG_CONTROL) set(SWRAP_TESTS ${SWRAP_TESTS} test_sendmsg_recvmsg_fd) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/socket_wrapper-1.1.4/tests/test_echo_tcp_socket_options.c new/socket_wrapper-1.1.5/tests/test_echo_tcp_socket_options.c --- old/socket_wrapper-1.1.4/tests/test_echo_tcp_socket_options.c 2015-08-11 17:30:20.000000000 +0200 +++ new/socket_wrapper-1.1.5/tests/test_echo_tcp_socket_options.c 2015-10-14 11:38:17.000000000 +0200 @@ -10,6 +10,7 @@ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> +#include <netinet/tcp.h> #include <arpa/inet.h> #include <netdb.h> #include <stdlib.h> @@ -293,6 +294,51 @@ } #endif +static void test_sockopt_tcp(void **state) +{ + struct torture_address addr = { + .sa_socklen = sizeof(struct sockaddr_in), + }; + int opt = -1; + socklen_t optlen = sizeof(int); + int rc; + + int s; + + (void) state; /* unused */ + + s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + assert_int_not_equal(s, -1); + + addr.sa.in.sin_family = AF_INET; + addr.sa.in.sin_port = htons(torture_server_port()); + + rc = inet_pton(addr.sa.in.sin_family, + torture_server_address(AF_INET), + &addr.sa.in.sin_addr); + assert_int_equal(rc, 1); + + rc = connect(s, &addr.sa.s, addr.sa_socklen); + assert_int_equal(rc, 0); + + rc = getsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, &optlen); + assert_return_code(rc, errno); + assert_int_equal(opt, 0); + + opt = 1; /* Turn on TCP_NODELAY */ + optlen = sizeof(int); + rc = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, optlen); + assert_return_code(rc, errno); + + opt = -1; + optlen = sizeof(int); + rc = getsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, &optlen); + assert_return_code(rc, errno); + assert_int_equal(opt, 1); + + close(s); +} + int main(void) { int rc; @@ -311,6 +357,9 @@ setup_ipv6, teardown), #endif + cmocka_unit_test_setup_teardown(test_sockopt_tcp, + setup_echo_srv_tcp_ipv4, + teardown), }; rc = cmocka_run_group_tests(sockopt_tests, NULL, NULL); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/socket_wrapper-1.1.4/tests/test_swrap_unit.c new/socket_wrapper-1.1.5/tests/test_swrap_unit.c --- old/socket_wrapper-1.1.4/tests/test_swrap_unit.c 1970-01-01 01:00:00.000000000 +0100 +++ new/socket_wrapper-1.1.5/tests/test_swrap_unit.c 2015-10-14 11:38:17.000000000 +0200 @@ -0,0 +1,120 @@ +#include <stdarg.h> +#include <stddef.h> +#include <setjmp.h> +#include <cmocka.h> +#include <stdio.h> +#include <string.h> + +#include "config.h" + +#include "socket_wrapper.c" + +#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL + +/** + * test wrap_sendmsg_filter_cmsghdr() + * + * Prepare a message with two cmsg: + * - the first cmsg is a char buf with the string "Hello World" + * - the second cmsg is a char buf with the string "!\n" + * + * Both cmsgs will be copied without modification by + * wrap_sendmsg_filter_cmsghdr(), so we can check that the msg + * controllen, the cmsg sizes and the payload are the same. + * + * We use an not existing cmsg_type which triggers cmsg copying. + */ +static void test_sendmsg_cmsg(void **state) +{ + int rc = 0; + char byte = '!'; + struct iovec iov; + struct msghdr msg = { 0 }; + struct cmsghdr *cmsg; + char *cmsgbuf; + int cmsgbuf_size; + const char *s1 = "Hello World"; + const int s1_len = strlen(s1); + const char *s2 = "!\n"; + const int s2_len = strlen(s2); + uint8_t *cmbuf = NULL; + size_t cmlen = 0; + + (void)state; /* unused */ + + iov.iov_base = &byte; + iov.iov_len = 1; + + /* + * Prepare cmsgbuf and msg + */ + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + cmsgbuf_size = CMSG_SPACE(s1_len) + CMSG_SPACE(s2_len); + cmsgbuf = calloc(cmsgbuf_size, sizeof(char)); + assert_non_null(cmsgbuf); + msg.msg_control = cmsgbuf; + msg.msg_controllen = cmsgbuf_size; + + /* + * Prepare first cmsg with string "Hello World" + */ + cmsg = CMSG_FIRSTHDR(&msg); + assert_non_null(cmsg); + + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = ~0 - 1; + cmsg->cmsg_len = CMSG_LEN(s1_len); + memcpy(CMSG_DATA(cmsg), s1, s1_len); + + /* + * Prepare second cmsg with string "!\n" + */ + cmsg = CMSG_NXTHDR(&msg, cmsg); + assert_non_null(cmsg); + + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = ~0 - 2; + cmsg->cmsg_len = CMSG_LEN(s2_len); + memcpy(CMSG_DATA(cmsg), s2, s2_len); + + /* + * Now call swrap_sendmsg_filter_cmsghdr() on the msg + */ + rc = swrap_sendmsg_filter_cmsghdr(&msg, &cmbuf, &cmlen); + assert_return_code(rc, errno); + assert_int_equal(cmlen, msg.msg_controllen); + + /* + * Insert filtered cmsgbug into msg and validate cmsgs. + */ + msg.msg_control = cmbuf; + + cmsg = CMSG_FIRSTHDR(&msg); + assert_non_null(cmsg); + assert_int_equal(cmsg->cmsg_len, CMSG_LEN(s1_len)); + assert_memory_equal(CMSG_DATA(cmsg), s1, s1_len); + + cmsg = CMSG_NXTHDR(&msg, cmsg); + assert_non_null(cmsg); + assert_int_equal(cmsg->cmsg_len, CMSG_LEN(s2_len)); + assert_memory_equal(CMSG_DATA(cmsg), s2, s2_len); + + free(cmbuf); + free(cmsgbuf); +} +#endif + +int main(void) { + int rc; + + const struct CMUnitTest unit_tests[] = { +#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL + cmocka_unit_test(test_sendmsg_cmsg), +#endif + }; + + rc = cmocka_run_group_tests(unit_tests, NULL, NULL); + + return rc; +}