The branch, master has been updated via f3489d5 swrap: Simplify cmspace calculation in swrap_sendmsg_copy_cmsg() via c5e809f tests: Add a unit test for wrap_sendmsg_filter_cmsghdr() from 84a4e23 tests: Add test for TCP_NODELAY setsockopt()
https://git.samba.org/?p=socket_wrapper.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit f3489d5cb77a804891bdaff3d90449fa7f293dd6 Author: Ralph Boehme <s...@samba.org> Date: Thu Oct 8 03:25:53 2015 +0200 swrap: Simplify cmspace calculation in swrap_sendmsg_copy_cmsg() With cmsg->cmsg_len = CMSG_LEN(len) => CMSG_ALIGN(cmsg->cmsg_len) = CMSG_ALIGN(CMSG_LEN(len)) = CMSG_ALIGN(CMSG_ALIGN(sizeof(struct cmsghdr)) + len) = CMSG_ALIGN(sizeof(struct cmsghdr)) + CMSG_ALIGN(len) = CMSG_SPACE(len) = CMSG_SPACE(CMSG_ALIGN(sizeof(struct cmsghdr)) + len - CMSG_ALIGN(sizeof(struct cmsghdr))) = CMSG_SPACE(CMSG_LEN(len) - CMSG_ALIGN(sizeof(struct cmsghdr))) = CMSG_SPACE(cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr))) :) Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit c5e809fed9a9e2cfce40312150322f28d3d338a6 Author: Ralph Boehme <s...@samba.org> Date: Tue Oct 13 16:38:26 2015 +0200 tests: Add a unit test for wrap_sendmsg_filter_cmsghdr() Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> ----------------------------------------------------------------------- Summary of changes: src/socket_wrapper.c | 4 +- tests/CMakeLists.txt | 3 +- tests/test_swrap_unit.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 tests/test_swrap_unit.c Changeset truncated at 500 lines: diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c index aad5f3e..353ad1d 100644 --- a/src/socket_wrapper.c +++ b/src/socket_wrapper.c @@ -3739,9 +3739,7 @@ static int swrap_sendmsg_copy_cmsg(struct cmsghdr *cmsg, 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 --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 0cb7f78..9679177 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -30,7 +30,8 @@ set(SWRAP_TESTS 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 --git a/tests/test_swrap_unit.c b/tests/test_swrap_unit.c new file mode 100644 index 0000000..469aa24 --- /dev/null +++ b/tests/test_swrap_unit.c @@ -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; +} -- Socket Wrapper Repository