diff options
Diffstat (limited to 'src/transport/tcp/tcp_test.c')
| -rw-r--r-- | src/transport/tcp/tcp_test.c | 304 |
1 files changed, 304 insertions, 0 deletions
diff --git a/src/transport/tcp/tcp_test.c b/src/transport/tcp/tcp_test.c new file mode 100644 index 00000000..88b77ab4 --- /dev/null +++ b/src/transport/tcp/tcp_test.c @@ -0,0 +1,304 @@ +// +// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech> +// Copyright 2018 Capitar IT Group BV <info@capitar.com> +// Copyright 2018 Devolutions <info@devolutions.net> +// Copyright 2018 Cody Piersall <cody.piersall@gmail.com> +// +// This software is supplied under the terms of the MIT License, a +// copy of which should be located in the distribution where this +// file was obtained (LICENSE.txt). A copy of the license may also be +// found online at https://opensource.org/licenses/MIT. +// + +#include <nng/nng.h> +#include <nng/protocol/pair0/pair.h> +#include <nng/supplemental/util/platform.h> + +#include <acutest.h> +#include <testutil.h> + +// TCP tests. + +static void +test_tcp_wild_card_connect_fail(void) +{ + nng_socket s; + char addr[NNG_MAXADDRLEN]; + + TEST_NNG_PASS(nng_pair0_open(&s)); + (void) snprintf( + addr, sizeof(addr), "tcp://*:%u", testutil_next_port()); + TEST_NNG_FAIL(nng_dial(s, addr, NULL, 0), NNG_EADDRINVAL); + TEST_NNG_PASS(nng_close(s)); +} + +void +test_tcp_wild_card_bind(void) +{ + nng_socket s1; + nng_socket s2; + char addr[NNG_MAXADDRLEN]; + uint16_t port; + + port = testutil_next_port(); + + TEST_NNG_PASS(nng_pair0_open(&s1)); + TEST_NNG_PASS(nng_pair0_open(&s2)); + (void) snprintf(addr, sizeof(addr), "tcp4://*:%u", port); + TEST_NNG_PASS(nng_listen(s1, addr, NULL, 0)); + // reset port back one + (void) snprintf(addr, sizeof(addr), "tcp://127.0.0.1:%u", port); + TEST_NNG_PASS(nng_dial(s2, addr, NULL, 0)); + TEST_NNG_PASS(nng_close(s2)); + TEST_NNG_PASS(nng_close(s1)); +} + +void +test_tcp_local_address_connect(void) +{ + + nng_socket s1; + nng_socket s2; + char addr[NNG_MAXADDRLEN]; + uint16_t port; + + TEST_NNG_PASS(nng_pair0_open(&s1)); + TEST_NNG_PASS(nng_pair0_open(&s2)); + port = testutil_next_port(); + (void) snprintf(addr, sizeof(addr), "tcp://127.0.0.1:%u", port); + TEST_NNG_PASS(nng_listen(s1, addr, NULL, 0)); + // reset port back one + (void) snprintf( + addr, sizeof(addr), "tcp://127.0.0.1;127.0.0.1:%u", port); + TEST_NNG_PASS(nng_dial(s2, addr, NULL, 0)); + TEST_NNG_PASS(nng_close(s2)); + TEST_NNG_PASS(nng_close(s1)); +} + +void +test_tcp_port_zero_bind(void) +{ + nng_socket s1; + nng_socket s2; + nng_sockaddr sa; + nng_listener l; + char * addr; + + TEST_NNG_PASS(nng_pair0_open(&s1)); + TEST_NNG_PASS(nng_pair_open(&s2)); + TEST_NNG_PASS(nng_listen(s1, "tcp://127.0.0.1:0", &l, 0)); + TEST_NNG_PASS(nng_listener_get_string(l, NNG_OPT_URL, &addr)); + TEST_CHECK(memcmp(addr, "tcp://", 6) == 0); + TEST_NNG_PASS(nng_listener_get_addr(l, NNG_OPT_LOCADDR, &sa)); + TEST_CHECK(sa.s_in.sa_family == NNG_AF_INET); + TEST_CHECK(sa.s_in.sa_port != 0); + TEST_CHECK(sa.s_in.sa_addr = testutil_htonl(0x7f000001)); + TEST_NNG_PASS(nng_dial(s2, addr, NULL, 0)); + nng_strfree(addr); + TEST_NNG_PASS(nng_close(s2)); + TEST_NNG_PASS(nng_close(s1)); +} + +void +test_tcp_bad_local_interface(void) +{ + nng_socket s1; + + TEST_NNG_PASS(nng_pair0_open(&s1)); + TEST_NNG_FAIL(nng_dial(s1, "tcp://bogus1;127.0.0.1:80", NULL, 0), + NNG_EADDRINVAL); + TEST_NNG_PASS(nng_close(s1)); +} + +void +test_tcp_non_local_address(void) +{ + nng_socket s1; + + TEST_NNG_PASS(nng_pair0_open(&s1)); + TEST_NNG_FAIL(nng_dial(s1, "tcp://8.8.8.8;127.0.0.1:80", NULL, 0), + NNG_EADDRINVAL); + TEST_NNG_PASS(nng_close(s1)); +} + +void +test_tcp_malformed_address(void) +{ + nng_socket s1; + + TEST_NNG_PASS(nng_pair0_open(&s1)); + TEST_NNG_FAIL( + nng_dial(s1, "tcp://127.0.0.1", NULL, 0), NNG_EADDRINVAL); + TEST_NNG_FAIL( + nng_dial(s1, "tcp://127.0.0.1.32", NULL, 0), NNG_EADDRINVAL); + TEST_NNG_FAIL( + nng_dial(s1, "tcp://127.0.x.1.32", NULL, 0), NNG_EADDRINVAL); + TEST_NNG_FAIL( + nng_listen(s1, "tcp://127.0.0.1.32", NULL, 0), NNG_EADDRINVAL); + TEST_NNG_FAIL( + nng_listen(s1, "tcp://127.0.x.1.32", NULL, 0), NNG_EADDRINVAL); + TEST_NNG_PASS(nng_close(s1)); +} + +void +test_tcp_no_delay_option(void) +{ + nng_socket s; + nng_dialer d; + nng_listener l; + bool v; + int x; + char addr[64]; + + testutil_scratch_addr("tcp", sizeof(addr), addr); + + TEST_NNG_PASS(nng_pair0_open(&s)); +#ifndef NNG_ELIDE_DEPRECATED + TEST_NNG_PASS(nng_socket_get_bool(s, NNG_OPT_TCP_NODELAY, &v)); + TEST_CHECK(v == true); +#endif + TEST_NNG_PASS(nng_dialer_create(&d, s, addr)); + TEST_NNG_PASS(nng_dialer_get_bool(d, NNG_OPT_TCP_NODELAY, &v)); + TEST_CHECK(v == true); + TEST_NNG_PASS(nng_dialer_set_bool(d, NNG_OPT_TCP_NODELAY, false)); + TEST_NNG_PASS(nng_dialer_get_bool(d, NNG_OPT_TCP_NODELAY, &v)); + TEST_CHECK(v == false); + TEST_NNG_FAIL( + nng_dialer_get_int(d, NNG_OPT_TCP_NODELAY, &x), NNG_EBADTYPE); + x = 0; + TEST_NNG_FAIL( + nng_dialer_set_int(d, NNG_OPT_TCP_NODELAY, x), NNG_EBADTYPE); + // This assumes sizeof (bool) != sizeof (int) + if (sizeof(bool) != sizeof(int)) { + TEST_NNG_FAIL( + nng_dialer_set(d, NNG_OPT_TCP_NODELAY, &x, sizeof(x)), + NNG_EINVAL); + } + + TEST_NNG_PASS(nng_listener_create(&l, s, addr)); + TEST_NNG_PASS(nng_listener_get_bool(l, NNG_OPT_TCP_NODELAY, &v)); + TEST_CHECK(v == true); + x = 0; + TEST_NNG_FAIL( + nng_listener_set_int(l, NNG_OPT_TCP_NODELAY, x), NNG_EBADTYPE); + // This assumes sizeof (bool) != sizeof (int) + TEST_NNG_FAIL(nng_listener_set(l, NNG_OPT_TCP_NODELAY, &x, sizeof(x)), + NNG_EINVAL); + + TEST_NNG_PASS(nng_dialer_close(d)); + TEST_NNG_PASS(nng_listener_close(l)); + + // Make sure socket wide defaults apply. +#ifndef NNG_ELIDE_DEPRECATED + TEST_NNG_PASS(nng_socket_set_bool(s, NNG_OPT_TCP_NODELAY, true)); + v = false; + TEST_NNG_PASS(nng_socket_get_bool(s, NNG_OPT_TCP_NODELAY, &v)); + TEST_CHECK(v == true); + TEST_NNG_PASS(nng_socket_set_bool(s, NNG_OPT_TCP_NODELAY, false)); + TEST_NNG_PASS(nng_dialer_create(&d, s, addr)); + TEST_NNG_PASS(nng_dialer_get_bool(d, NNG_OPT_TCP_NODELAY, &v)); + TEST_CHECK(v == false); +#endif + TEST_NNG_PASS(nng_close(s)); +} + +void +test_tcp_keep_alive_option(void) +{ + nng_socket s; + nng_dialer d; + nng_listener l; + bool v; + int x; + char addr[64]; + + testutil_scratch_addr("tcp", sizeof(addr), addr); + TEST_NNG_PASS(nng_pair0_open(&s)); +#ifndef NNG_ELIDE_DEPRECATED + TEST_NNG_PASS(nng_socket_get_bool(s, NNG_OPT_TCP_KEEPALIVE, &v)); + TEST_CHECK(v == false); +#endif + TEST_NNG_PASS(nng_dialer_create(&d, s, addr)); + TEST_NNG_PASS(nng_dialer_get_bool(d, NNG_OPT_TCP_KEEPALIVE, &v)); + TEST_CHECK(v == false); + TEST_NNG_PASS(nng_dialer_set_bool(d, NNG_OPT_TCP_KEEPALIVE, true)); + TEST_NNG_PASS(nng_dialer_get_bool(d, NNG_OPT_TCP_KEEPALIVE, &v)); + TEST_CHECK(v == true); + TEST_NNG_FAIL( + nng_dialer_get_int(d, NNG_OPT_TCP_KEEPALIVE, &x), NNG_EBADTYPE); + x = 1; + TEST_NNG_FAIL( + nng_dialer_set_int(d, NNG_OPT_TCP_KEEPALIVE, x), NNG_EBADTYPE); + + TEST_NNG_PASS(nng_listener_create(&l, s, addr)); + TEST_NNG_PASS(nng_listener_get_bool(l, NNG_OPT_TCP_KEEPALIVE, &v)); + TEST_CHECK(v == false); + x = 1; + TEST_NNG_FAIL( + nng_listener_set_int(l, NNG_OPT_TCP_KEEPALIVE, x), NNG_EBADTYPE); + + TEST_NNG_PASS(nng_dialer_close(d)); + TEST_NNG_PASS(nng_listener_close(l)); + + // Make sure socket wide defaults apply. +#ifndef NNG_ELIDE_DEPRECATED + TEST_NNG_PASS(nng_socket_set_bool(s, NNG_OPT_TCP_KEEPALIVE, false)); + v = true; + TEST_NNG_PASS(nng_socket_get_bool(s, NNG_OPT_TCP_KEEPALIVE, &v)); + TEST_CHECK(v == false); + TEST_NNG_PASS(nng_socket_set_bool(s, NNG_OPT_TCP_KEEPALIVE, true)); + TEST_NNG_PASS(nng_dialer_create(&d, s, addr)); + TEST_NNG_PASS(nng_dialer_get_bool(d, NNG_OPT_TCP_KEEPALIVE, &v)); + TEST_CHECK(v == true); +#endif + TEST_NNG_PASS(nng_close(s)); +} + +void +test_tcp_recv_max(void) +{ + char msg[256]; + char buf[256]; + nng_socket s0; + nng_socket s1; + nng_listener l; + size_t sz; + char addr[64]; + + testutil_scratch_addr("tcp", sizeof(addr), addr); + + TEST_NNG_PASS(nng_pair0_open(&s0)); + TEST_NNG_PASS(nng_socket_set_ms(s0, NNG_OPT_RECVTIMEO, 100)); + TEST_NNG_PASS(nng_socket_set_size(s0, NNG_OPT_RECVMAXSZ, 200)); + TEST_NNG_PASS(nng_listener_create(&l, s0, addr)); + TEST_NNG_PASS(nng_socket_get_size(s0, NNG_OPT_RECVMAXSZ, &sz)); + TEST_CHECK(sz == 200); + TEST_NNG_PASS(nng_listener_set_size(l, NNG_OPT_RECVMAXSZ, 100)); + TEST_NNG_PASS(nng_listener_start(l, 0)); + + TEST_NNG_PASS(nng_pair0_open(&s1)); + TEST_NNG_PASS(nng_dial(s1, addr, NULL, 0)); + TEST_NNG_PASS(nng_send(s1, msg, 95, 0)); + TEST_NNG_PASS(nng_socket_set_ms(s1, NNG_OPT_SENDTIMEO, 100)); + TEST_NNG_PASS(nng_recv(s0, buf, &sz, 0)); + TEST_CHECK(sz == 95); + TEST_NNG_PASS(nng_send(s1, msg, 150, 0)); + TEST_NNG_FAIL(nng_recv(s0, buf, &sz, 0), NNG_ETIMEDOUT); + TEST_NNG_PASS(nng_close(s0)); + TEST_NNG_PASS(nng_close(s1)); +} + +TEST_LIST = { + + { "tcp wild card connect fail", test_tcp_wild_card_connect_fail }, + { "tcp wild card bind", test_tcp_wild_card_bind }, + { "tcp port zero bind", test_tcp_port_zero_bind }, + { "tcp local address connect", test_tcp_local_address_connect }, + { "tcp bad local interface", test_tcp_bad_local_interface }, + { "tcp non-local address", test_tcp_non_local_address }, + { "tcp malformed address", test_tcp_malformed_address }, + { "tcp no delay option", test_tcp_no_delay_option }, + { "tcp keep alive option", test_tcp_keep_alive_option }, + { "tcp recv max", test_tcp_recv_max }, + { NULL, NULL }, +};
\ No newline at end of file |
