diff options
| -rw-r--r-- | CMakeLists.txt | 4 | ||||
| -rw-r--r-- | cmake/NNGOptions.cmake | 5 | ||||
| -rw-r--r-- | src/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | src/compat/nanomsg/CMakeLists.txt | 15 | ||||
| -rw-r--r-- | src/compat/nanomsg/compat_msg_test.c | 92 | ||||
| -rw-r--r-- | src/compat/nanomsg/compat_tcp_test.c | 233 | ||||
| -rw-r--r-- | src/compat/nanomsg/nn.c | 1336 | ||||
| -rw-r--r-- | src/compat/nanomsg/nuts_compat.h | 73 | ||||
| -rw-r--r-- | tests/CMakeLists.txt | 27 | ||||
| -rw-r--r-- | tests/compat_block.c | 69 | ||||
| -rw-r--r-- | tests/compat_bug777.c | 48 | ||||
| -rw-r--r-- | tests/compat_bus.c | 88 | ||||
| -rw-r--r-- | tests/compat_cmsg.c | 117 | ||||
| -rw-r--r-- | tests/compat_device.c | 189 | ||||
| -rw-r--r-- | tests/compat_iovec.c | 74 | ||||
| -rw-r--r-- | tests/compat_msg.c | 131 | ||||
| -rw-r--r-- | tests/compat_options.c | 57 | ||||
| -rw-r--r-- | tests/compat_pair.c | 50 | ||||
| -rw-r--r-- | tests/compat_pipeline.c | 85 | ||||
| -rw-r--r-- | tests/compat_poll.c | 203 | ||||
| -rw-r--r-- | tests/compat_reqrep.c | 203 | ||||
| -rw-r--r-- | tests/compat_reqttl.c | 153 | ||||
| -rw-r--r-- | tests/compat_shutdown.c | 48 | ||||
| -rw-r--r-- | tests/compat_survey.c | 106 | ||||
| -rw-r--r-- | tests/compat_surveyttl.c | 146 | ||||
| -rw-r--r-- | tests/compat_testutil.c | 240 | ||||
| -rw-r--r-- | tests/compat_testutil.h | 86 |
27 files changed, 0 insertions, 3882 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b753d38..ffe4f9e5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,10 +98,6 @@ target_compile_definitions(nng_private INTERFACE NNG_PRIVATE) if (NNG_ELIDE_DEPRECATED) target_compile_definitions(nng PRIVATE NNG_ELIDE_DEPRECATED) endif() -if (NNG_ENABLE_COMPAT) - target_compile_definitions(nng PRIVATE NNG_ENABLE_COMPAT) -endif() - # We can use rlimit to configure the stack size for systems # that have too small defaults. This is not used for Windows, diff --git a/cmake/NNGOptions.cmake b/cmake/NNGOptions.cmake index bbbd3dd9..d117ee36 100644 --- a/cmake/NNGOptions.cmake +++ b/cmake/NNGOptions.cmake @@ -39,11 +39,6 @@ option(NNG_ENABLE_COVERAGE "Enable coverage reporting." OFF) # for the public library. option(NNG_ELIDE_DEPRECATED "Elide deprecated functionality." OFF) -# Turning off the compatibility layer can save some space, and -# compilation time, but may break legacy applications It should -# be left enabled when building a shared library. -option(NNG_ENABLE_COMPAT "Enable legacy nanomsg API." ON) - option(NNG_ENABLE_STATS "Enable statistics." ON) mark_as_advanced(NNG_ENABLE_STATS) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ab33292d..f1dff72b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -21,10 +21,6 @@ add_subdirectory(supplemental) add_subdirectory(tools) add_subdirectory(testing) -if (NNG_ENABLE_COMPAT) - add_subdirectory(compat) -endif() - # When building shared libraries we prefer to suppress default symbol # visibility, so that only the symbols that should be exposed in the # resulting library are. This is the default with Windows. diff --git a/src/compat/nanomsg/CMakeLists.txt b/src/compat/nanomsg/CMakeLists.txt deleted file mode 100644 index 51679b34..00000000 --- a/src/compat/nanomsg/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -# -# Copyright 2023 Staysail Systems, Inc. <info@staysail.tech> -# -# 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. -# - -nng_sources(nn.c) - -set(NNG_TEST_PREFIX ${NNG_TEST_PREFIX}.compat.nanomsg) - -nng_test(compat_msg_test) -nng_test(compat_tcp_test) diff --git a/src/compat/nanomsg/compat_msg_test.c b/src/compat/nanomsg/compat_msg_test.c deleted file mode 100644 index d037a0b4..00000000 --- a/src/compat/nanomsg/compat_msg_test.c +++ /dev/null @@ -1,92 +0,0 @@ -// -// Copyright 2023 Staysail Systems, Inc. <info@staysail.tech> -// -// 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/compat/nanomsg/nn.h> -#include <nng/compat/nanomsg/pair.h> -#include <nng/compat/nanomsg/tcp.h> - -#include "nuts_compat.h" - -#include <nuts.h> - -void -test_msg_alloc(void) -{ - char *msg; - msg = nn_allocmsg(1, 0); - NUTS_TRUE(msg != NULL); - NUTS_NN_PASS(nn_freemsg(msg)); -} - -void -test_msg_zero_length(void) -{ - char *msg; - msg = nn_allocmsg(0, 0); // empty message is invalid - NUTS_TRUE(msg == NULL); - NUTS_TRUE(nn_errno() == EINVAL); -} - -void -test_msg_overflow(void) -{ - char *msg; - msg = nn_allocmsg((size_t)-1, 0); // this will overflow - NUTS_TRUE(msg == NULL); - NUTS_TRUE(nn_errno() == EINVAL); -} - -void -test_msg_bad_type(void) -{ - char *msg; - msg = nn_allocmsg(0, 1); // we only support message type 0 - NUTS_TRUE(msg == NULL); - NUTS_TRUE(nn_errno() == EINVAL); -} - -void -test_msg_realloc(void) -{ - char *msg0; - char *msg1; - char *msg2; - char *msg3; - - msg0 = nn_allocmsg(5, 0); - NUTS_TRUE(msg0 != NULL); - - memcpy(msg0, "this", 5); - - msg1 = nn_reallocmsg(msg0, 65536); - NUTS_TRUE(msg1 != NULL); - NUTS_TRUE(msg1 != msg0); - NUTS_MATCH(msg1, "this"); - - msg1[65000] = 'A'; - - msg2 = nn_reallocmsg(msg1, 5); - NUTS_TRUE(msg2 == msg1); - - // test for overflow - msg3 = nn_reallocmsg(msg2, (size_t)-1); - NUTS_TRUE(msg3 == NULL); - NUTS_TRUE(nn_errno() == EINVAL); - - nn_freemsg(msg2); -} - -TEST_LIST = { - { "alloc msg", test_msg_alloc }, - { "zero length", test_msg_zero_length }, - { "invalid type", test_msg_bad_type }, - { "overflow", test_msg_overflow }, - { "reallocate msg", test_msg_realloc }, - { NULL, NULL }, -}; diff --git a/src/compat/nanomsg/compat_tcp_test.c b/src/compat/nanomsg/compat_tcp_test.c deleted file mode 100644 index a23c878d..00000000 --- a/src/compat/nanomsg/compat_tcp_test.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - Copyright 2020 Staysail Systems, Inc. <info@staysail.tech> - Copyright (c) 2012 Martin Sustrik All rights reserved. - Copyright 2016 Franklin "Snaipe" Mathieu <franklinmathieu@gmail.com> - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom - the Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -// This test is a pretty much completely rewritten version of the -// legacy nanomsg tcp test. The NNG test infrastructure is a bit more -// robust, and we take advantage of that. - -#include <nng/compat/nanomsg/nn.h> -#include <nng/compat/nanomsg/pair.h> -#include <nng/compat/nanomsg/tcp.h> - -#include "nuts_compat.h" - -#include <nuts.h> - -void -test_bind_and_close(void) -{ - int sb; - char *addr; - - NUTS_ADDR(addr, "tcp"); - - NUTS_TRUE((sb = nn_socket(AF_SP, NN_PAIR)) >= 0); - NUTS_TRUE(nn_bind(sb, addr) >= 0); - NUTS_TRUE(nn_close(sb) == 0); -} - -void -test_connect_and_close(void) -{ - int sc; - char *addr; - - NUTS_ADDR(addr, "tcp"); - NUTS_NN_PASS((sc = nn_socket(AF_SP, NN_PAIR)) >= 0); - NUTS_NN_PASS(nn_connect(sc, addr)); - NUTS_NN_PASS(nn_close(sc)); -} - -void -test_bind_and_connect(void) -{ - int sb, sc, p1, p2; - char *addr; - - NUTS_ADDR(addr, "tcp"); - NUTS_TRUE((sb = nn_socket(AF_SP, NN_PAIR)) >= 0); - NUTS_TRUE((sc = nn_socket(AF_SP, NN_PAIR)) >= 0); - NUTS_TRUE(sb != sc); - - NUTS_NN_MARRY_EX(sb, sc, addr, p1, p2); - - NUTS_NN_PASS(nn_close(sb)); - NUTS_NN_PASS(nn_close(sc)); -} - -void -test_bad_addresses(void) -{ - int s; - NUTS_TRUE((s = nn_socket(AF_SP, NN_PAIR)) >= 0); - - NUTS_NN_FAIL(nn_connect(s, "tcp://*:"), EINVAL); - NUTS_NN_FAIL(nn_connect(s, "tcp://*:1000000"), EINVAL); - NUTS_NN_FAIL(nn_connect(s, "tcp://*:some_port"), EINVAL); - NUTS_NN_FAIL(nn_connect(s, "tcp://127.0.0.1"), EINVAL); - NUTS_NN_FAIL(nn_connect(s, "tcp://:5555"), EINVAL); - NUTS_NN_FAIL(nn_connect(s, "tcp://abc.123.---.#:5555"), EINVAL); - - NUTS_NN_FAIL(nn_bind(s, "tcp://127.0.0.1:1000000"), EINVAL); - NUTS_NN_PASS(nn_close(s)); -} - -void -test_ping_pong(void) -{ - int sb, sc, p1, p2; - char *addr; - - NUTS_ADDR(addr, "tcp"); - NUTS_NN_PASS((sb = nn_socket(AF_SP, NN_PAIR))); - NUTS_NN_PASS((sc = nn_socket(AF_SP, NN_PAIR))); - NUTS_TRUE(sb != sc); - NUTS_NN_MARRY_EX(sc, sb, addr, p1, p2); - NUTS_TRUE(p1 >= 0); - NUTS_TRUE(p2 >= 0); - - /* Ping-pong test. */ - for (int i = 0; i != 100; ++i) { - - char buf[4]; - int n; - NUTS_NN_PASS(nn_send(sc, "ABC", 3, 0)); - NUTS_NN_PASS(n = nn_recv(sb, buf, 4, 0)); - NUTS_TRUE(n == 3); - NUTS_TRUE(memcmp(buf, "ABC", 3) == 0); - - NUTS_NN_PASS(nn_send(sb, "DEF", 3, 0)); - NUTS_NN_PASS(n = nn_recv(sc, buf, 4, 0)); - NUTS_TRUE(n == 3); - NUTS_TRUE(memcmp(buf, "DEF", 3) == 0); - } - - NUTS_NN_PASS(nn_close(sb)); - NUTS_NN_PASS(nn_close(sc)); -} - -void -test_pair_reject(void) -{ - int sb, sc, sd, p1, p2; - char *addr; - - NUTS_ADDR(addr, "tcp"); - - NUTS_TRUE((sb = nn_socket(AF_SP, NN_PAIR)) >= 0); - NUTS_TRUE((sc = nn_socket(AF_SP, NN_PAIR)) >= 0); - NUTS_TRUE((sd = nn_socket(AF_SP, NN_PAIR)) >= 0); - NUTS_TRUE(sb != sc); - - NUTS_NN_MARRY_EX(sc, sb, addr, p1, p2); - - NUTS_TRUE(nn_connect(sd, addr) >= 0); - NUTS_SLEEP(200); - - NUTS_NN_PASS(nn_close(sb)); - NUTS_NN_PASS(nn_close(sc)); - NUTS_NN_PASS(nn_close(sd)); -} - -void -test_addr_in_use(void) -{ - int sb, sc; - char *addr; - - NUTS_ADDR(addr, "tcp"); - NUTS_TRUE((sb = nn_socket(AF_SP, NN_PAIR)) >= 0); - NUTS_TRUE((sc = nn_socket(AF_SP, NN_PAIR)) >= 0); - NUTS_TRUE(sb != sc); - NUTS_NN_PASS(nn_bind(sb, addr)); - NUTS_NN_FAIL(nn_bind(sc, addr), EADDRINUSE); - - NUTS_NN_PASS(nn_close(sb)); - NUTS_NN_PASS(nn_close(sc)); -} - -void -test_max_recv_size(void) -{ - int sb, sc, p1, p2; - int opt; - int n; - size_t sz; - char buf[64]; - char *addr; - - NUTS_ADDR(addr, "tcp"); - - NUTS_TRUE((sb = nn_socket(AF_SP, NN_PAIR)) >= 0); - NUTS_TRUE((sc = nn_socket(AF_SP, NN_PAIR)) >= 0); - NUTS_TRUE(sb != sc); - opt = 100; - sz = sizeof(opt); - NUTS_NN_PASS(nn_setsockopt(sb, NN_SOL_SOCKET, NN_RCVTIMEO, &opt, sz)); - - /* Test that NN_RCVMAXSIZE can be -1, but not lower */ - sz = sizeof(opt); - opt = -1; - NUTS_NN_PASS( - nn_setsockopt(sb, NN_SOL_SOCKET, NN_RCVMAXSIZE, &opt, sz)); - - opt = -2; - NUTS_NN_FAIL( - nn_setsockopt(sb, NN_SOL_SOCKET, NN_RCVMAXSIZE, &opt, sz), EINVAL); - - opt = 4; - NUTS_NN_PASS( - nn_setsockopt(sb, NN_SOL_SOCKET, NN_RCVMAXSIZE, &opt, sz)); - opt = -5; - NUTS_NN_PASS( - nn_getsockopt(sb, NN_SOL_SOCKET, NN_RCVMAXSIZE, &opt, &sz)); - NUTS_TRUE(opt == 4); - NUTS_TRUE(sz == sizeof(opt)); - - NUTS_NN_MARRY_EX(sc, sb, addr, p1, p2); - - NUTS_NN_PASS(nn_send(sc, "ABC", 4, 0)); - NUTS_NN_PASS(nn_send(sc, "012345", 6, 0)); - - NUTS_NN_PASS(n = nn_recv(sb, buf, sizeof(buf), 0)); - NUTS_TRUE(n == 4); - NUTS_TRUE(strcmp(buf, "ABC") == 0); - - NUTS_NN_FAIL(nn_recv(sb, buf, sizeof(buf), 0), ETIMEDOUT); - - NUTS_NN_PASS(nn_close(sb)); - NUTS_NN_PASS(nn_close(sc)); -} - -TEST_LIST = { - { "compat tcp bind and close ", test_bind_and_close }, - { "compat tcp connect and close ", test_connect_and_close }, - { "compat tcp bind and connect ", test_bind_and_connect }, - { "compat tcp invalid addresses", test_bad_addresses }, - { "compat tcp ping pong", test_ping_pong }, - { "compat tcp pair reject", test_pair_reject }, - { "compat tcp addr in use", test_addr_in_use }, - { "compat tcp max recv size", test_max_recv_size }, - { NULL, NULL }, -}; diff --git a/src/compat/nanomsg/nn.c b/src/compat/nanomsg/nn.c deleted file mode 100644 index af4db5d3..00000000 --- a/src/compat/nanomsg/nn.c +++ /dev/null @@ -1,1336 +0,0 @@ -// -// Copyright 2023 Staysail Systems, Inc. <info@staysail.tech> -// Copyright 2018 Capitar IT Group BV <info@capitar.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/compat/nanomsg/nn.h" - -// transports -#include "nng/compat/nanomsg/inproc.h" -#include "nng/compat/nanomsg/ipc.h" -#include "nng/compat/nanomsg/tcp.h" -#include "nng/compat/nanomsg/ws.h" - -// protocols -#include "nng/compat/nanomsg/bus.h" -#include "nng/compat/nanomsg/pair.h" -#include "nng/compat/nanomsg/pipeline.h" -#include "nng/compat/nanomsg/pubsub.h" -#include "nng/compat/nanomsg/reqrep.h" -#include "nng/compat/nanomsg/survey.h" - -// underlying NNG headers -#include "nng/nng.h" -#include "nng/protocol/bus0/bus.h" -#include "nng/protocol/pair0/pair.h" -#include "nng/protocol/pipeline0/pull.h" -#include "nng/protocol/pipeline0/push.h" -#include "nng/protocol/pubsub0/pub.h" -#include "nng/protocol/pubsub0/sub.h" -#include "nng/protocol/reqrep0/rep.h" -#include "nng/protocol/reqrep0/req.h" -#include "nng/protocol/survey0/respond.h" -#include "nng/protocol/survey0/survey.h" - -#include "core/nng_impl.h" - -#include <stdio.h> -#include <string.h> - -// This file supplies the legacy compatibility API. Applications should -// avoid using these if at all possible, and instead use the new style APIs. - -static const struct { - int nerr; - int perr; -} nn_errnos[] = { - // clang-format off - { NNG_EINTR, EINTR }, - { NNG_ENOMEM, ENOMEM }, - { NNG_EINVAL, EINVAL }, - { NNG_EBUSY, EBUSY }, - { NNG_ETIMEDOUT, ETIMEDOUT }, - { NNG_ECONNREFUSED, ECONNREFUSED }, - { NNG_ECLOSED, EBADF }, - { NNG_EAGAIN, EAGAIN }, - { NNG_ENOTSUP, ENOTSUP }, - { NNG_EADDRINUSE, EADDRINUSE }, - { NNG_ESTATE, EFSM }, - { NNG_ENOENT, ENOENT }, - { NNG_EPROTO, EPROTO }, - { NNG_EUNREACHABLE, EHOSTUNREACH }, - { NNG_EADDRINVAL, EINVAL }, - { NNG_EPERM, EACCES }, - { NNG_EMSGSIZE, EMSGSIZE }, - { NNG_ECONNABORTED, ECONNABORTED }, - { NNG_ECONNRESET, ECONNRESET }, - { NNG_ECANCELED, EBADF }, - { NNG_EEXIST, EEXIST }, - { NNG_EWRITEONLY, EACCES }, - { NNG_EREADONLY, EACCES }, - { NNG_ECRYPTO, EACCES }, - { NNG_EPEERAUTH, EACCES }, - { NNG_EBADTYPE, EINVAL }, - { NNG_EAMBIGUOUS, EINVAL }, - { NNG_ENOFILES, EMFILE }, - { NNG_ENOSPC, ENOSPC }, - { 0, 0 }, - // clang-format on -}; - -const char * -nn_strerror(int err) -{ - int i; - static char msgbuf[32]; - - for (i = 0; nn_errnos[i].perr != 0; i++) { - if (nn_errnos[i].perr == err) { - return (nng_strerror(nn_errnos[i].nerr)); - } - } - if (err == EIO) { - return ("Unknown I/O error"); - } - - // Arguably we could use strerror() here, but we should only - // be getting errnos we understand at this point. - (void) snprintf(msgbuf, sizeof(msgbuf), "Unknown error %d", err); - return (msgbuf); -} - -static void -nn_seterror(int err) -{ - int i; - - for (i = 0; nn_errnos[i].nerr != 0; i++) { - if (nn_errnos[i].nerr == err) { - errno = nn_errnos[i].perr; - return; - } - } - // No idea... - errno = EIO; -} - -int -nn_errno(void) -{ - return (errno); -} - -static const struct { - uint16_t p_id; - int (*p_open)(nng_socket *); - int (*p_open_raw)(nng_socket *); -} nn_protocols[] = { -#ifdef NNG_HAVE_BUS0 - { - .p_id = NN_BUS, - .p_open = nng_bus0_open, - .p_open_raw = nng_bus0_open_raw, - }, -#endif -#ifdef NNG_HAVE_PAIR0 - { - .p_id = NN_PAIR, - .p_open = nng_pair0_open, - .p_open_raw = nng_pair0_open_raw, - }, -#endif -#ifdef NNG_HAVE_PULL0 - { - .p_id = NN_PULL, - .p_open = nng_pull0_open, - .p_open_raw = nng_pull0_open_raw, - }, -#endif -#ifdef NNG_HAVE_PUSH0 - { - .p_id = NN_PUSH, - .p_open = nng_push0_open, - .p_open_raw = nng_push0_open_raw, - }, -#endif -#ifdef NNG_HAVE_PUB0 - { - .p_id = NN_PUB, - .p_open = nng_pub0_open, - .p_open_raw = nng_pub0_open_raw, - }, -#endif -#ifdef NNG_HAVE_SUB0 - { - .p_id = NN_SUB, - .p_open = nng_sub0_open, - .p_open_raw = nng_sub0_open_raw, - }, -#endif -#ifdef NNG_HAVE_REQ0 - { - .p_id = NN_REQ, - .p_open = nng_req0_open, - .p_open_raw = nng_req0_open_raw, - }, -#endif -#ifdef NNG_HAVE_REP0 - { - .p_id = NN_REP, - .p_open = nng_rep0_open, - .p_open_raw = nng_rep0_open_raw, - }, -#endif -#ifdef NNG_HAVE_SURVEYOR0 - { - .p_id = NN_SURVEYOR, - .p_open = nng_surveyor0_open, - .p_open_raw = nng_surveyor0_open_raw, - }, -#endif -#ifdef NNG_HAVE_RESPONDENT0 - { - .p_id = NN_RESPONDENT, - .p_open = nng_respondent0_open, - .p_open_raw = nng_respondent0_open_raw, - }, -#endif - { - .p_id = 0, - }, -}; - -int -nn_socket(int domain, int protocol) -{ - nng_socket sock; - int rv; - int i; - - if ((domain != AF_SP) && (domain != AF_SP_RAW)) { - errno = EAFNOSUPPORT; - return (-1); - } - - for (i = 0; nn_protocols[i].p_id != 0; i++) { - if (nn_protocols[i].p_id == protocol) { - break; - } - } - if (nn_protocols[i].p_open == NULL) { - errno = ENOTSUP; - return (-1); - } - - if (domain == AF_SP_RAW) { - rv = nn_protocols[i].p_open_raw(&sock); - } else { - rv = nn_protocols[i].p_open(&sock); - } - if (rv != 0) { - nn_seterror(rv); - return (-1); - } - - // Legacy sockets have Nagle disabled. - (void) nng_socket_set_bool(sock, NNG_OPT_TCP_NODELAY, false); - return ((int) sock.id); -} - -int -nn_close(int s) -{ - int rv; - nng_socket sid; - - sid.id = (uint32_t) s; - - if ((rv = nng_close(sid)) != 0) { - nn_seterror(rv); - return (-1); - } - return (0); -} - -int -nn_bind(int s, const char *addr) -{ - int rv; - nng_listener l; - nng_socket sid; - - sid.id = (uint32_t) s; - if ((rv = nng_listen(sid, addr, &l, 0)) != 0) { - nn_seterror(rv); - return (-1); - } - return ((int) l.id); -} - -int -nn_connect(int s, const char *addr) -{ - int rv; - nng_dialer d; - nng_socket sid; - - sid.id = (uint32_t) s; - if ((rv = nng_dial(sid, addr, &d, NNG_FLAG_NONBLOCK)) != 0) { - nn_seterror(rv); - return (-1); - } - return ((int) d.id); -} - -int -nn_shutdown(int s, int ep) -{ - int rv; - (void) s; // Unused - nng_dialer d; - nng_listener l; - - // Socket is wired into the endpoint... so passing a bad endpoint - // ID can result in affecting the wrong socket. But this requires - // a buggy application, and because we don't recycle endpoints - // until wrap, it's unlikely to actually come up in practice. - // Note that listeners and dialers share the same namespace - // in the core, so we can close either one this way. - - d.id = l.id = (uint32_t) ep; - if (((rv = nng_dialer_close(d)) != 0) && - ((rv = nng_listener_close(l)) != 0)) { - nn_seterror(rv); - return (-1); - } - return (0); -} - -void * -nn_allocmsg(size_t size, int type) -{ - nng_msg *msg; - int rv; - - // Validate type and non-zero size. This also checks for overflow. - if ((type != 0) || (size < 1) || ((size + sizeof(msg) < size))) { - nn_seterror(NNG_EINVAL); - return (NULL); - } - - // So our "messages" from nn are really going to be nng messages - // but to make this work, we use a bit of headroom in the message - // to stash the message header. - if ((rv = nng_msg_alloc(&msg, size)) != 0) { - nn_seterror(rv); - return (NULL); - } - - nng_msg_insert(msg, &msg, sizeof(msg)); - - // We are counting on the implementation of nn_msg_trim to not - // reallocate the message but just to leave the prefix inplace. - (void) nng_msg_trim(msg, sizeof(msg)); - - return (nng_msg_body(msg)); -} - -int -nn_freemsg(void *ptr) -{ - nng_msg *msg; - - msg = *(nng_msg **) (((char *) ptr) - sizeof(msg)); - nng_msg_free(msg); - return (0); -} - -void * -nn_reallocmsg(void *ptr, size_t len) -{ - nng_msg *msg; - int rv; - - if ((len + sizeof(msg)) < len) { - // overflowed! - nn_seterror(NNG_EINVAL); - return (NULL); - } - - // This counts on message bodies being aligned sensibly. - msg = *(nng_msg **) (((char *) ptr) - sizeof(msg)); - - // We need to realloc the requested len, plus size for our header. - if ((rv = nng_msg_realloc(msg, len)) != 0) { - // We don't free the old message. Code is free to cope - // as it sees fit. - nn_seterror(rv); - return (NULL); - } - // Stash the msg header pointer - nng_msg_insert(msg, &msg, sizeof(msg)); - nng_msg_trim(msg, sizeof(msg)); - return (nng_msg_body(msg)); -} - -static int -nn_flags(int flags) -{ - switch (flags) { - case 0: - return (0); - - case NN_DONTWAIT: - return (NNG_FLAG_NONBLOCK); - - default: - nn_seterror(NNG_EINVAL); - return (-1); - } -} - -int -nn_send(int s, const void *buf, size_t len, int flags) -{ - struct nn_iovec iov; - struct nn_msghdr hdr; - - iov.iov_base = (void *) buf; - iov.iov_len = len; - - hdr.msg_iov = &iov; - hdr.msg_iovlen = 1; - hdr.msg_control = NULL; - hdr.msg_controllen = 0; - - return (nn_sendmsg(s, &hdr, flags)); -} - -int -nn_recv(int s, void *buf, size_t len, int flags) -{ - struct nn_iovec iov; - struct nn_msghdr hdr; - - iov.iov_base = buf; - iov.iov_len = len; - - hdr.msg_iov = &iov; - hdr.msg_iovlen = 1; - hdr.msg_control = NULL; - hdr.msg_controllen = 0; - - return (nn_recvmsg(s, &hdr, flags)); -} - -int -nn_recvmsg(int s, struct nn_msghdr *mh, int flags) -{ - int rv; - nng_msg *msg; - size_t len; - int keep = 0; - nng_socket sid; - - if ((flags = nn_flags(flags)) == -1) { - return (-1); - } - if (mh == NULL) { - nn_seterror(NNG_EINVAL); - return (-1); - } - if (mh->msg_iovlen < 0) { - nn_seterror(NNG_EMSGSIZE); - return (-1); - } - - sid.id = (uint32_t) s; - if ((rv = nng_recvmsg(sid, &msg, flags)) != 0) { - nn_seterror(rv); - return (-1); - } - if ((mh->msg_iovlen == 1) && (mh->msg_iov[0].iov_len == NN_MSG)) { - // Receiver wants to have a dynamically allocated message. - // There can only be one of these. - if ((rv = nng_msg_insert(msg, &msg, sizeof(msg))) != 0) { - nng_msg_free(msg); - nn_seterror(rv); - return (-1); - } - nng_msg_trim(msg, sizeof(msg)); - *(void **) (mh->msg_iov[0].iov_base) = nng_msg_body(msg); - len = nng_msg_len(msg); - keep = 1; // Do not discard message! - } else { - // copyout to multiple iovecs. - char *ptr = nng_msg_body(msg); - len = nng_msg_len(msg); - - for (int i = 0; i < mh->msg_iovlen; i++) { - size_t n; - if ((n = mh->msg_iov[i].iov_len) == NN_MSG) { - // This is forbidden! - nn_seterror(NNG_EINVAL); - nng_msg_free(msg); - return (-1); - } - if (n > len) { - n = len; - } - memcpy(mh->msg_iov[i].iov_base, ptr, n); - len -= n; - ptr += n; - } - - // If we copied everything, len will be zero, otherwise, - // it represents the amount of data that we were unable to - // copyout. The caller is responsible for noticing this, - // as there is no API to pass this information out. - len = nng_msg_len(msg); - } - - // If the caller has requested control information (header details), - // we grab it. - if (mh->msg_control != NULL) { - char *cdata; - size_t clen; - size_t tlen; - size_t spsz; - struct nn_cmsghdr *hdr; - - spsz = nng_msg_header_len(msg); - clen = NN_CMSG_SPACE(sizeof(spsz) + spsz); - - if ((tlen = mh->msg_controllen) == NN_MSG) { - // Ideally we'd use the same msg, but we would need - // to set up reference counts on the message, so - // instead we just make a new message. - nng_msg *nmsg; - - rv = nng_msg_alloc(&nmsg, clen + sizeof(nmsg)); - if (rv != 0) { - nng_msg_free(msg); - nn_seterror(rv); - return (-1); - } - memcpy(nng_msg_body(nmsg), &nmsg, sizeof(nmsg)); - nng_msg_trim(nmsg, sizeof(nmsg)); - cdata = nng_msg_body(nmsg); - *(void **) mh->msg_control = cdata; - tlen = clen; - } else { - cdata = mh->msg_control; - memset(cdata, 0, - tlen > sizeof(*hdr) ? sizeof(*hdr) : tlen); - } - - if (clen <= tlen) { - uint8_t *ptr = NN_CMSG_DATA(cdata); - hdr = (void *) cdata; - hdr->cmsg_len = clen; - hdr->cmsg_level = PROTO_SP; - hdr->cmsg_type = SP_HDR; - - memcpy(ptr, &spsz, sizeof(spsz)); - ptr += sizeof(spsz); - memcpy(ptr, nng_msg_header(msg), spsz); - } - } - - if (!keep) { - nng_msg_free(msg); - } - return ((int) len); -} - -int -nn_sendmsg(int s, const struct nn_msghdr *mh, int flags) -{ - nng_msg *msg = NULL; - nng_msg *cmsg = NULL; - nng_socket sid; - char *cdata; - int keep = 0; - size_t sz; - int rv; - - sid.id = (uint32_t) s; - - if ((flags = nn_flags(flags)) == -1) { - return (-1); - } - - if (mh == NULL) { - nn_seterror(NNG_EINVAL); - return (-1); - } - - if (mh->msg_iovlen < 0) { - nn_seterror(NNG_EMSGSIZE); - return (-1); - } - - if ((mh->msg_iovlen == 1) && (mh->msg_iov[0].iov_len == NN_MSG)) { - char *bufp = *(char **) (mh->msg_iov[0].iov_base); - - msg = *(nng_msg **) (bufp - sizeof(msg)); - keep = 1; // keep the message on error - } else { - char *ptr; - int i; - - sz = 0; - // Get the total message size. - for (i = 0; i < mh->msg_iovlen; i++) { - sz += mh->msg_iov[i].iov_len; - } - if ((rv = nng_msg_alloc(&msg, sz)) != 0) { - nn_seterror(rv); - return (-1); - } - // Now copy it out. - ptr = nng_msg_body(msg); - for (i = 0; i < mh->msg_iovlen; i++) { - memcpy(ptr, mh->msg_iov[i].iov_base, - mh->msg_iov[i].iov_len); - ptr += mh->msg_iov[i].iov_len; - } - } - - // Now suck up the control data... - // This POSIX-inspired API is one of the most painful for - // usability we've ever seen. - cmsg = NULL; - if ((cdata = mh->msg_control) != NULL) { - size_t clen; - size_t offs; - size_t spsz; - unsigned char *data; - - if ((clen = mh->msg_controllen) == NN_MSG) { - // Underlying data is a message. This is awkward, - // because we have to copy the data, but we should - // only free this message on success. So we save the - // message now. - cdata = *(void **) cdata; - cmsg = *(nng_msg **) (cdata - sizeof(cmsg)); - clen = nng_msg_len(cmsg); - } else { - clen = mh->msg_controllen; - } - - offs = 0; - while ((offs + sizeof(NN_CMSG_LEN(0))) < clen) { - struct nn_cmsghdr *chdr = (void *) (cdata + offs); - if ((chdr->cmsg_level != PROTO_SP) || - (chdr->cmsg_type != SP_HDR)) { - offs += chdr->cmsg_len; - } - - // SP header in theory. Starts with size, then - // any backtrace details. - if (chdr->cmsg_len < sizeof(size_t)) { - offs += chdr->cmsg_len; - continue; - } - data = NN_CMSG_DATA(chdr); - memcpy(&spsz, data, sizeof(spsz)); - if ((spsz + sizeof(spsz)) > chdr->cmsg_len) { - // Truncated header? Ignore it. - offs += chdr->cmsg_len; - continue; - } - data += sizeof(spsz); - rv = nng_msg_header_append(msg, data, spsz); - if (rv != 0) { - if (!keep) { - nng_msg_free(msg); - } - nn_seterror(rv); - return (-1); - } - - break; - } - } - - sz = nng_msg_len(msg); - if ((rv = nng_sendmsg(sid, msg, flags)) != 0) { - if (!keep) { - nng_msg_free(msg); - } - nn_seterror(rv); - return (-1); - } - - if (cmsg != NULL) { - // We sent successfully, so free up the control message. - nng_msg_free(cmsg); - } - return ((int) sz); -} - -static int -nn_getdomain(nng_socket s, void *valp, size_t *szp) -{ - int i; - bool b; - int rv; - - if ((rv = nng_socket_get_bool(s, NNG_OPT_RAW, &b)) != 0) { - nn_seterror(rv); - return (-1); - } - i = b ? AF_SP_RAW : AF_SP; - memcpy(valp, &i, *szp < sizeof(int) ? *szp : sizeof(int)); - *szp = sizeof(int); - return (0); -} - -#ifndef NNG_PLATFORM_WINDOWS -#define SOCKET int -#endif - -static int -nn_getfd(nng_socket s, void *valp, size_t *szp, const char *opt) -{ - int ifd; - int rv; - SOCKET sfd; - - if ((rv = nng_socket_get_int(s, opt, &ifd)) != 0) { - nn_seterror(rv); - return (-1); - } - sfd = (SOCKET) ifd; - memcpy(valp, &sfd, *szp < sizeof(sfd) ? *szp : sizeof(sfd)); - *szp = sizeof(sfd); - return (0); -} - -static int -nn_getrecvfd(nng_socket s, void *valp, size_t *szp) -{ - return (nn_getfd(s, valp, szp, NNG_OPT_RECVFD)); -} - -static int -nn_getsendfd(nng_socket s, void *valp, size_t *szp) -{ - return (nn_getfd(s, valp, szp, NNG_OPT_SENDFD)); -} - -static int -nn_getzero(nng_socket s, void *valp, size_t *szp) -{ - int zero = 0; - NNI_ARG_UNUSED(s); - memcpy(valp, &zero, *szp < sizeof(zero) ? *szp : sizeof(zero)); - *szp = sizeof(zero); - return (0); -} - -static int -nn_setignore(nng_socket s, const void *valp, size_t sz) -{ - NNI_ARG_UNUSED(valp); - NNI_ARG_UNUSED(s); - if (sz != sizeof(int)) { - nn_seterror(NNG_EINVAL); - return (-1); - } - return (0); -} - -static int -nn_getwsmsgtype(nng_socket s, void *valp, size_t *szp) -{ - int val = NN_WS_MSG_TYPE_BINARY; - NNI_ARG_UNUSED(s); - memcpy(valp, &val, *szp < sizeof(val) ? *szp : sizeof(val)); - *szp = sizeof(val); - return (0); -} - -static int -nn_setwsmsgtype(nng_socket s, const void *valp, size_t sz) -{ - int val; - NNI_ARG_UNUSED(s); - if (sz != sizeof(val)) { - nn_seterror(NNG_EINVAL); - return (-1); - } - memcpy(&val, valp, sizeof(val)); - if (val != NN_WS_MSG_TYPE_BINARY) { - nn_seterror(NNG_EINVAL); - return (-1); - } - return (0); -} - -static int -nn_settcpnodelay(nng_socket s, const void *valp, size_t sz) -{ - bool val; - int ival; - int rv; - - if (sz != sizeof(ival)) { - errno = EINVAL; - return (-1); - } - memcpy(&ival, valp, sizeof(ival)); - switch (ival) { - case 0: - val = false; - break; - case 1: - val = true; - break; - default: - nn_seterror(NNG_EINVAL); - return (-1); - } - - if ((rv = nng_socket_set_bool(s, NNG_OPT_TCP_NODELAY, val)) != 0) { - nn_seterror(rv); - return (-1); - } - return (0); -} - -static int -nn_gettcpnodelay(nng_socket s, void *valp, size_t *szp) -{ - bool val; - int ival; - int rv; - - if ((rv = nng_socket_get_bool(s, NNG_OPT_TCP_NODELAY, &val)) != 0) { - nn_seterror(rv); - return (-1); - } - ival = val ? 1 : 0; - memcpy(valp, &ival, *szp < sizeof(ival) ? *szp : sizeof(ival)); - *szp = sizeof(ival); - return (0); -} - -static int -nn_getrcvbuf(nng_socket s, void *valp, size_t *szp) -{ - int cnt; - int rv; - - if ((rv = nng_socket_get_int(s, NNG_OPT_RECVBUF, &cnt)) != 0) { - nn_seterror(rv); - return (-1); - } - cnt *= 1024; - memcpy(valp, &cnt, *szp < sizeof(cnt) ? *szp : sizeof(cnt)); - *szp = sizeof(cnt); - return (0); -} - -static int -nn_setrcvbuf(nng_socket s, const void *valp, size_t sz) -{ - int cnt; - int rv; - - if (sz != sizeof(cnt)) { - errno = EINVAL; - return (-1); - } - memcpy(&cnt, valp, sizeof(cnt)); - // Round up to a whole number of kilobytes, then divide by kB to - // go from buffer size in bytes to messages. This is a coarse - // estimate, and assumes messages are 1kB on average. - cnt += 1023; - cnt /= 1024; - if ((rv = nng_socket_set_int(s, NNG_OPT_RECVBUF, cnt)) != 0) { - nn_seterror(rv); - return (-1); - } - return (0); -} - -static int -nn_getsndbuf(nng_socket s, void *valp, size_t *szp) -{ - int cnt; - int rv; - - if ((rv = nng_socket_get_int(s, NNG_OPT_SENDBUF, &cnt)) != 0) { - nn_seterror(rv); - return (-1); - } - cnt *= 1024; - memcpy(valp, &cnt, *szp < sizeof(cnt) ? *szp : sizeof(cnt)); - *szp = sizeof(cnt); - return (0); -} - -static int -nn_setsndbuf(nng_socket s, const void *valp, size_t sz) -{ - int cnt; - int rv; - - if (sz != sizeof(cnt)) { - errno = EINVAL; - return (-1); - } - memcpy(&cnt, valp, sizeof(cnt)); - // Round up to a whole number of kilobytes, then divide by kB to - // go from buffer size in bytes to messages. This is a coarse - // estimate, and assumes messages are 1kB on average. - cnt += 1023; - cnt /= 1024; - if ((rv = nng_socket_set_int(s, NNG_OPT_SENDBUF, cnt)) != 0) { - nn_seterror(rv); - return (-1); - } - return (0); -} - -static int -nn_setrcvmaxsz(nng_socket s, const void *valp, size_t sz) -{ - int ival; - size_t val; - int rv; - - if (sz != sizeof(ival)) { - errno = EINVAL; - return (-1); - } - memcpy(&ival, valp, sizeof(ival)); - if (ival == -1) { - val = 0; - } else if (ival >= 0) { - // Note that if the user sets 0, it disables the limit. - // This is a different semantic. - val = (size_t) ival; - } else { - errno = EINVAL; - return (-1); - } - if ((rv = nng_socket_set_size(s, NNG_OPT_RECVMAXSZ, val)) != 0) { - nn_seterror(rv); - return (-1); - } - return (0); -} - -static int -nn_getrcvmaxsz(nng_socket s, void *valp, size_t *szp) -{ - int ival; - int rv; - size_t val; - - if ((rv = nng_socket_get_size(s, NNG_OPT_RECVMAXSZ, &val)) != 0) { - nn_seterror(rv); - return (-1); - } - // Legacy uses -1 to mean unlimited. New code uses 0. Note that - // as a consequence, we can't set a message limit of zero. - // We report any size beyond 2GB as effectively unlimited. - // There is an implicit assumption here that ints are 32-bits, - // but that's generally true of any platform we support. - if ((val == 0) || (val > 0x7FFFFFFF)) { - ival = -1; - } else { - ival = (int) val; - } - memcpy(valp, &ival, *szp < sizeof(ival) ? *szp : sizeof(ival)); - *szp = sizeof(ival); - return (0); -} - -// options which we convert -- most of the array is initialized at run time. -static const struct { - int nnlevel; - int nnopt; - const char *opt; - int (*get)(nng_socket, void *, size_t *); - int (*set)(nng_socket, const void *, size_t); -} options[] = { - { - .nnlevel = NN_SOL_SOCKET, - .nnopt = NN_LINGER, - .get = nn_getzero, - .set = nn_setignore, - }, // review - { - .nnlevel = NN_SOL_SOCKET, - .nnopt = NN_DOMAIN, - .get = nn_getdomain, - .set = NULL, - }, - { - .nnlevel = NN_SOL_SOCKET, - .nnopt = NN_RCVBUF, - .get = nn_getrcvbuf, - .set = nn_setrcvbuf, - }, - { - .nnlevel = NN_SOL_SOCKET, - .nnopt = NN_SNDBUF, - .get = nn_getsndbuf, - .set = nn_setsndbuf, - }, - { - .nnlevel = NN_SOL_SOCKET, - .nnopt = NN_RECONNECT_IVL, - .opt = NNG_OPT_RECONNMINT, - }, - { - .nnlevel = NN_SOL_SOCKET, - .nnopt = NN_RECONNECT_IVL_MAX, - .opt = NNG_OPT_RECONNMAXT, - }, - { - .nnlevel = NN_SOL_SOCKET, - .nnopt = NN_SNDFD, - .opt = NNG_OPT_SENDFD, - .get = nn_getsendfd, - }, - { - .nnlevel = NN_SOL_SOCKET, - .nnopt = NN_RCVFD, - .opt = NNG_OPT_RECVFD, - .get = nn_getrecvfd, - }, - { - .nnlevel = NN_SOL_SOCKET, - .nnopt = NN_RCVMAXSIZE, - .get = nn_getrcvmaxsz, - .set = nn_setrcvmaxsz, - }, - { - .nnlevel = NN_SOL_SOCKET, - .nnopt = NN_MAXTTL, - .opt = NNG_OPT_MAXTTL, - }, - { - .nnlevel = NN_SOL_SOCKET, - .nnopt = NN_RCVTIMEO, - .opt = NNG_OPT_RECVTIMEO, - }, - { - .nnlevel = NN_SOL_SOCKET, - .nnopt = NN_SNDTIMEO, - .opt = NNG_OPT_SENDTIMEO, - }, - { - .nnlevel = NN_SOL_SOCKET, - .nnopt = NN_PROTOCOL, - .opt = NNG_OPT_PROTO, - }, - { - .nnlevel = NN_SOL_SOCKET, - .nnopt = NN_SOCKET_NAME, - .opt = NNG_OPT_SOCKNAME, - }, - { - .nnlevel = NN_REQ, - .nnopt = NN_REQ_RESEND_IVL, - .opt = NNG_OPT_REQ_RESENDTIME, - }, - { - .nnlevel = NN_SUB, - .nnopt = NN_SUB_SUBSCRIBE, - .opt = NNG_OPT_SUB_SUBSCRIBE, - }, - { - .nnlevel = NN_SUB, - .nnopt = NN_SUB_UNSUBSCRIBE, - .opt = NNG_OPT_SUB_UNSUBSCRIBE, - }, - { - .nnlevel = NN_SURVEYOR, - .nnopt = NN_SURVEYOR_DEADLINE, - .opt = NNG_OPT_SURVEYOR_SURVEYTIME, - }, - { - .nnlevel = NN_TCP, - .nnopt = NN_TCP_NODELAY, - .get = nn_gettcpnodelay, - .set = nn_settcpnodelay, - }, - { - .nnlevel = NN_WS, - .nnopt = NN_WS_MSG_TYPE, - .get = nn_getwsmsgtype, - .set = nn_setwsmsgtype, - } - // XXX: IPV4ONLY, SNDPRIO, RCVPRIO -}; - -int -nn_getsockopt(int s, int nnlevel, int nnopt, void *valp, size_t *szp) -{ - const char *name = NULL; - int (*get)(nng_socket, void *, size_t *) = NULL; - int rv; - nng_socket sid; - - sid.id = (uint32_t) s; - - for (unsigned i = 0; i < sizeof(options) / sizeof(options[0]); i++) { - if ((options[i].nnlevel == nnlevel) && - (options[i].nnopt == nnopt)) { - get = options[i].get; - name = options[i].opt; - break; - } - } - - if (get != NULL) { - return (get(sid, valp, szp)); - } - - if (name == NULL) { - errno = ENOPROTOOPT; - return (-1); - } - - if ((rv = nng_socket_get(sid, name, valp, szp)) != 0) { - nn_seterror(rv); - return (-1); - } - - return (0); -} - -int -nn_setsockopt(int s, int nnlevel, int nnopt, const void *valp, size_t sz) -{ - nng_socket sid; - const char *name = NULL; - int (*set)(nng_socket, const void *, size_t) = NULL; - int rv; - - sid.id = (uint32_t) s; - - for (unsigned i = 0; i < sizeof(options) / sizeof(options[0]); i++) { - if ((options[i].nnlevel == nnlevel) && - (options[i].nnopt == nnopt)) { - - set = options[i].set; - name = options[i].opt; - break; - } - } - - if (set != NULL) { - return (set(sid, valp, sz)); - } - - if (name == NULL) { - errno = ENOPROTOOPT; - return (-1); - } - - if ((rv = nng_socket_set(sid, name, valp, sz)) != 0) { - nn_seterror(rv); - return (-1); - } - if ((nnlevel == NN_REQ) && (nnopt == NN_REQ_RESEND_IVL)) { - // Only one context here, so it won't be too bad to tick - // as quickly as this, and it avoids some possible friction - // (e.g. with legacy tests). - (void) nng_socket_set_ms(sid, NNG_OPT_REQ_RESENDTICK, 10); - } - - return (0); -} - -struct nn_cmsghdr * -nn_cmsg_next(struct nn_msghdr *mh, struct nn_cmsghdr *first) -{ - size_t clen; - char *data; - - // We only support SP headers, so there can be at most one header. - if (first != NULL) { - return (NULL); - } - if ((clen = mh->msg_controllen) == NN_MSG) { - nng_msg *msg; - data = *((void **) (mh->msg_control)); - msg = *(nng_msg **) (data - sizeof(msg)); - clen = nng_msg_len(msg); - } else { - data = mh->msg_control; - } - - if (first == NULL) { - first = (void *) data; - } else { - first = first + first->cmsg_len; - } - - if (((char *) first + sizeof(*first)) > (data + clen)) { - return (NULL); - } - return (first); -} - -int -nn_device(int s1, int s2) -{ - int rv; - nng_socket sid1; - nng_socket sid2; - - sid1.id = (uint32_t) s1; - sid2.id = (uint32_t) s2; - - rv = nng_device(sid1, sid2); - // rv must always be nonzero - nn_seterror(rv); - return (-1); -} - -// Windows stuff. -#ifdef NNG_PLATFORM_WINDOWS -#define poll WSAPoll -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include <mswsock.h> -#include <windows.h> -#elif defined NNG_PLATFORM_POSIX -#include <poll.h> -#endif - -int -nn_poll(struct nn_pollfd *fds, int nfds, int timeout) -{ -// This function is rather unfortunate. poll() is available -// on POSIX, and on Windows as WSAPoll. On other systems it might -// not exist at all. We could also benefit from using a notification -// that didn't have to access file descriptors... sort of access to -// the pollable element on the socket. We don't have that, so we -// just use poll. This function is definitely suboptimal compared to -// using callbacks. -#if defined(NNG_PLATFORM_WINDOWS) || defined(NNG_PLATFORM_POSIX) - struct pollfd *pfd; - int npfd; - int rv; - - if ((pfd = NNI_ALLOC_STRUCTS(pfd, nfds * 2)) == NULL) { - errno = ENOMEM; - return (-1); - } - - // First prepare the master polling structure. - npfd = 0; - for (int i = 0; i < nfds; i++) { - int fd; - if (fds[i].events & NN_POLLIN) { - nng_socket s; - s.id = fds[i].fd; - if ((rv = nng_socket_get_int( - s, NNG_OPT_RECVFD, &fd)) != 0) { - nn_seterror(rv); - NNI_FREE_STRUCTS(pfd, nfds * 2); - return (-1); - } -#ifdef NNG_PLATFORM_WINDOWS - pfd[npfd].fd = (SOCKET) fd; -#else - pfd[npfd].fd = fd; -#endif - pfd[npfd].events = POLLIN; - npfd++; - } - if (fds[i].events & NN_POLLOUT) { - nng_socket s; - s.id = fds[i].fd; - if ((rv = nng_socket_get_int( - s, NNG_OPT_SENDFD, &fd)) != 0) { - nn_seterror(rv); - NNI_FREE_STRUCTS(pfd, nfds * 2); - return (-1); - } -#ifdef NNG_PLATFORM_WINDOWS - pfd[npfd].fd = (SOCKET) fd; -#else - pfd[npfd].fd = fd; -#endif - pfd[npfd].events = POLLIN; - npfd++; - } - } - - rv = poll(pfd, npfd, timeout); - if (rv < 0) { - int e = errno; - NNI_FREE_STRUCTS(pfd, nfds * 2); - errno = e; - return (-1); - } - - // Now update the nn_poll from the system poll. - npfd = 0; - rv = 0; - for (int i = 0; i < nfds; i++) { - fds[i].revents = 0; - if (fds[i].events & NN_POLLIN) { - if (pfd[npfd].revents & POLLIN) { - fds[i].revents |= NN_POLLIN; - } - npfd++; - } - if (fds[i].events & NN_POLLOUT) { - if (pfd[npfd].revents & POLLIN) { - fds[i].revents |= NN_POLLOUT; - } - npfd++; - } - if (fds[i].revents) { - rv++; - } - } - NNI_FREE_STRUCTS(pfd, nfds * 2); - return (rv); - -#else // NNG_PLATFORM_WINDOWS or NNG_PLATFORM_POSIX - NNI_ARG_UNUSED(fds); - NNI_ARG_UNUSED(nfds); - NNI_ARG_UNUSED(timeout); - errno = ENOTSUP; - return (-1); -#endif -} - -// nn_term is suitable only for shutting down the entire library, -// and is not thread-safe with other functions. -void -nn_term(void) -{ - // This function is relatively toxic, since it can affect - // all sockets in the process, including those - // in use by libraries, etc. Accordingly, do not use this - // in a library -- only e.g. atexit() and similar. - nni_sock_closeall(); -} - -uint64_t -nn_get_statistic(int x, int y) -{ - (void) x; - (void) y; - - return (0); -} diff --git a/src/compat/nanomsg/nuts_compat.h b/src/compat/nanomsg/nuts_compat.h deleted file mode 100644 index d7bd56e7..00000000 --- a/src/compat/nanomsg/nuts_compat.h +++ /dev/null @@ -1,73 +0,0 @@ -// -// Copyright 2021 Staysail Systems, Inc. <info@staysail.tech> -// -// 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. -// - -#ifndef NUTS_COMPAT_H -#define NUTS_COMPAT_H - -#include <stdbool.h> -#include <stdint.h> - -// The following headers are provided for test code convenience. -#include <nng/nng.h> - -#ifdef __cplusplus -extern "C" { -#endif - -// NUTS_NN_PASS tests for NN success. It reports the failure if it did not. -#define NUTS_NN_PASS(cond) \ - do { \ - int result_ = (cond); \ - TEST_CHECK_(result_ >= 0, "%s succeeds", #cond); \ - TEST_MSG("%s: expected success, got %s (%d)", #cond, \ - nn_strerror(errno), errno); \ - } while (0) - -#define NUTS_NN_FAIL(cond, expect) \ - do { \ - int result_ = (cond); \ - int err_ = errno; \ - TEST_CHECK_(result_ < 0, "%s did not succeed", #cond); \ - TEST_CHECK_( \ - err_ == (expect), "%s fails with %s", #cond, #expect); \ - TEST_MSG("%s: expected %s, got %d / %d (%s)", #cond, #expect, \ - result_, (expect), nng_strerror(err_)); \ - } while (0) - -// These macros use some details of the socket and pipe which are not public. -// We do that to facilitate testing. Don't rely on this equivalence in your -// own application code. - -#define NUTS_NN_MARRY(s1, s2) \ - do { \ - nng_socket s1_, s2_; \ - s1_.id = s1; \ - s2_.id = s2; \ - \ - NUTS_MARRY(s1_, s2_); \ - } while (0) - -#define NUTS_NN_MARRY_EX(s1, s2, url, p1, p2) \ - do { \ - nng_socket s1_, s2_; \ - nng_pipe p1_, p2_; \ - s1_.id = s1; \ - s2_.id = s2; \ - NUTS_MARRY_EX(s1_, s2_, url, &p1_, &p2_); \ - (p1) = p1_.id; \ - (p2) = p2_.id; \ - NUTS_TRUE((p1) >= 0); \ - NUTS_TRUE((p2) >= 0); \ - } while (0) - -#ifdef __cplusplus -}; -#endif - -#endif // NUTS_COMPAT diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 35a3b44f..2fcc331e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -148,32 +148,5 @@ add_nng_test1(zt 60 NNG_TRANSPORT_ZEROTIER) add_nng_test(reqctx 5) add_nng_test(reqstress 60) -# compatibility tests -# We only support these if ALL the legacy protocols are supported. This -# is because we don't want to make modifications to partially enable some -# of these tests. Folks minimizing the library probably don't care too -# much about these anyway. -if (NNG_ENABLE_COMPAT) - add_nng_compat_test(compat_block 10) - add_nng_compat_test(compat_bug777 10) - add_nng_compat_test(compat_bus 10) - add_nng_compat_test(compat_cmsg 10) - add_nng_compat_test(compat_msg 10) - add_nng_compat_test(compat_iovec 10) - add_nng_compat_test(compat_device 10) - add_nng_compat_test(compat_pair 10) - add_nng_compat_test(compat_pipeline 10) - add_nng_compat_test(compat_poll 10) - add_nng_compat_test(compat_reqrep 10) - add_nng_compat_test(compat_survey 10) - add_nng_compat_test(compat_reqttl 10) - add_nng_compat_test(compat_shutdown 10) - add_nng_compat_test(compat_surveyttl 10) - - # These are special tests for compat mode, not inherited from the - # legacy libnanomsg suite. - add_nng_test(compat_options 5) -endif() - # c++ tests add_nng_cpp_test(cplusplus_pair 5) diff --git a/tests/compat_block.c b/tests/compat_block.c deleted file mode 100644 index a0a1fd1a..00000000 --- a/tests/compat_block.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - Copyright (c) 2012 Martin Sustrik All rights reserved. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom - the Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. -*/ - -#include <nng/compat/nanomsg/nn.h> -#include <nng/compat/nanomsg/pair.h> -#include "compat_testutil.h" - -/* This test checks whether blocking on send/recv works as expected. */ - -#define SOCKET_ADDRESS "inproc://a" - -int sc; -int sb; - -void worker (NN_UNUSED void *arg) -{ - /* Wait 0.1 sec for the main thread to block. */ - nn_sleep (100); - - test_send (sc, "ABC"); - - /* Wait 0.1 sec for the main thread to process the previous message - and block once again. */ - nn_sleep (100); - - test_send (sc, "ABC"); -} - -int main () -{ - struct nn_thread thread; - - sb = test_socket (AF_SP, NN_PAIR); - test_bind (sb, SOCKET_ADDRESS); - sc = test_socket (AF_SP, NN_PAIR); - test_connect (sc, SOCKET_ADDRESS); - - nn_thread_init (&thread, worker, NULL); - - test_recv (sb, "ABC"); - test_recv (sb, "ABC"); - - nn_thread_term (&thread); - - test_close (sc); - test_close (sb); - - return 0; -} - diff --git a/tests/compat_bug777.c b/tests/compat_bug777.c deleted file mode 100644 index 638c41b2..00000000 --- a/tests/compat_bug777.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> - Copyright 2018 Capitar IT Group BV <info@capitar.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom - the Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. -*/ - -#include <nng/compat/nanomsg/nn.h> -#include <nng/compat/nanomsg/pair.h> -#include "compat_testutil.h" - -int main (NN_UNUSED int argc, NN_UNUSED const char *argv[]) -{ - int sb; - int sc1; - int sc2; - - sb = test_socket (AF_SP, NN_PAIR); - test_bind (sb, "inproc://pair"); - sc1 = test_socket (AF_SP, NN_PAIR); - test_connect (sc1, "inproc://pair"); - nn_sleep (100); - sc2 = test_socket (AF_SP, NN_PAIR); - test_connect (sc2, "inproc://pair"); - - test_send (sb, "HELLO"); - test_recv (sc1, "HELLO"); - - test_send (sc1, "THERE"); - test_recv (sb, "THERE"); - return 0; -} diff --git a/tests/compat_bus.c b/tests/compat_bus.c deleted file mode 100644 index 70506047..00000000 --- a/tests/compat_bus.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - Copyright (c) 2012 Martin Sustrik All rights reserved. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom - the Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. -*/ - -#include <nng/compat/nanomsg/nn.h> -#include <nng/compat/nanomsg/bus.h> -#include "compat_testutil.h" - -#define SOCKET_ADDRESS_A "inproc://a" -#define SOCKET_ADDRESS_B "inproc://b" - -int main () -{ - int rc; - int bus1; - int bus2; - int bus3; - char buf [3]; - - /* Create a simple bus topology consisting of 3 nodes. */ - bus1 = test_socket (AF_SP, NN_BUS); - test_bind (bus1, SOCKET_ADDRESS_A); - bus2 = test_socket (AF_SP, NN_BUS); - test_bind (bus2, SOCKET_ADDRESS_B); - - nn_sleep(100); - - test_connect (bus2, SOCKET_ADDRESS_A); - bus3 = test_socket (AF_SP, NN_BUS); - test_connect (bus3, SOCKET_ADDRESS_A); - test_connect (bus3, SOCKET_ADDRESS_B); - - /* Wait for connections to establish asynchronously. */ - nn_sleep(100); - - /* Send a message from each node. */ - test_send (bus1, "A"); - test_send (bus2, "AB"); - test_send (bus3, "ABC"); - - /* Check that two messages arrived at each node. */ - rc = nn_recv (bus1, buf, 3, 0); - errno_assert (rc >= 0); - nn_assert (rc == 2 || rc == 3); - rc = nn_recv (bus1, buf, 3, 0); - errno_assert (rc >= 0); - nn_assert (rc == 2 || rc == 3); - rc = nn_recv (bus2, buf, 3, 0); - errno_assert (rc >= 0); - nn_assert (rc == 1 || rc == 3); - rc = nn_recv (bus2, buf, 3, 0); - errno_assert (rc >= 0); - nn_assert (rc == 1 || rc == 3); - rc = nn_recv (bus3, buf, 3, 0); - errno_assert (rc >= 0); - nn_assert (rc == 1 || rc == 2); - rc = nn_recv (bus3, buf, 3, 0); - errno_assert (rc >= 0); - nn_assert (rc == 1 || rc == 2); - - /* Wait till both connections are established. */ - nn_sleep (10); - - test_close (bus3); - test_close (bus2); - test_close (bus1); - - return 0; -} - diff --git a/tests/compat_cmsg.c b/tests/compat_cmsg.c deleted file mode 100644 index 06d67467..00000000 --- a/tests/compat_cmsg.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - Copyright (c) 2014 Martin Sustrik All rights reserved. - Copyright 2018 Garrett D'Amore <garrett@damore.org> - Copyright 2016 Franklin "Snaipe" Mathieu <franklinmathieu@gmail.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom - the Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. -*/ - -#include <nng/compat/nanomsg/nn.h> -#include <nng/compat/nanomsg/tcp.h> -#include <nng/compat/nanomsg/reqrep.h> - -#include "compat_testutil.h" - -int main (int argc, const char *argv[]) -{ - int rc; - int rep; - int req; - struct nn_msghdr hdr; - struct nn_iovec iovec; - unsigned char body [3]; - unsigned char ctrl [256]; - struct nn_cmsghdr *cmsg; - unsigned char *data; - void *buf; - char socket_address[128]; - - test_addr_from(socket_address, "tcp", "127.0.0.1", - get_test_port(argc, argv)); - strcpy(socket_address, "inproc://testaddr"); - - rep = test_socket (AF_SP_RAW, NN_REP); - test_bind (rep, socket_address); - req = test_socket (AF_SP, NN_REQ); - test_connect (req, socket_address); - - /* Test ancillary data in static buffer. */ - - test_send (req, "ABC"); - - iovec.iov_base = body; - iovec.iov_len = sizeof (body); - hdr.msg_iov = &iovec; - hdr.msg_iovlen = 1; - hdr.msg_control = ctrl; - hdr.msg_controllen = sizeof (ctrl); - rc = nn_recvmsg (rep, &hdr, 0); - errno_assert (rc == 3); - - cmsg = NN_CMSG_FIRSTHDR (&hdr); - while (1) { - nn_assert (cmsg); - if (cmsg->cmsg_level == PROTO_SP && cmsg->cmsg_type == SP_HDR) - break; - cmsg = NN_CMSG_NXTHDR (&hdr, cmsg); - } - nn_assert (cmsg->cmsg_len == NN_CMSG_SPACE (8+sizeof (size_t))); - data = NN_CMSG_DATA (cmsg); - nn_assert (!(data[0+sizeof (size_t)] & 0x80)); - nn_assert (data[4+sizeof (size_t)] & 0x80); - - rc = nn_sendmsg (rep, &hdr, 0); - nn_assert (rc == 3); - test_recv (req, "ABC"); - - /* Test ancillary data in dynamically allocated buffer (NN_MSG). */ - - test_send (req, "ABC"); - - iovec.iov_base = body; - iovec.iov_len = sizeof (body); - hdr.msg_iov = &iovec; - hdr.msg_iovlen = 1; - hdr.msg_control = &buf; - hdr.msg_controllen = NN_MSG; - rc = nn_recvmsg (rep, &hdr, 0); - errno_assert (rc == 3); - - cmsg = NN_CMSG_FIRSTHDR (&hdr); - while (1) { - nn_assert (cmsg); - if (cmsg->cmsg_level == PROTO_SP && cmsg->cmsg_type == SP_HDR) - break; - cmsg = NN_CMSG_NXTHDR (&hdr, cmsg); - } - nn_assert (cmsg->cmsg_len == NN_CMSG_SPACE (8+sizeof (size_t))); - data = NN_CMSG_DATA (cmsg); - nn_assert (!(data[0+sizeof (size_t)] & 0x80)); - nn_assert (data[4+sizeof (size_t)] & 0x80); - - rc = nn_sendmsg (rep, &hdr, 0); - nn_assert (rc == 3); - test_recv (req, "ABC"); - - test_close (req); - test_close (rep); - - return 0; -} - diff --git a/tests/compat_device.c b/tests/compat_device.c deleted file mode 100644 index 3c96e5b9..00000000 --- a/tests/compat_device.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (c) 2012 Martin Sustrik All rights reserved. - * Copyright (c) 2013 GoPivotal, Inc. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include <nng/compat/nanomsg/nn.h> -#include <nng/compat/nanomsg/bus.h> -#include <nng/compat/nanomsg/pair.h> -#include <nng/compat/nanomsg/pipeline.h> -#include <nng/compat/nanomsg/inproc.h> -#include "compat_testutil.h" - -#define SOCKET_ADDRESS_A "inproc://a" -#define SOCKET_ADDRESS_B "inproc://b" -#define SOCKET_ADDRESS_C "inproc://c" -#define SOCKET_ADDRESS_D "inproc://d" -#define SOCKET_ADDRESS_E "inproc://e" - -int deva = -1; -int devb = -1; -int devc = -1; -int devd = -1; -int deve = -1; - -void device1(NN_UNUSED void *arg) -{ - int rc; - - /* Intialise the device sockets. */ - deva = test_socket(AF_SP_RAW, NN_PAIR); - test_bind(deva, SOCKET_ADDRESS_A); - devb = test_socket(AF_SP_RAW, NN_PAIR); - test_bind(devb, SOCKET_ADDRESS_B); - - /* Run the device. */ - rc = nn_device(deva, devb); - nn_assert(rc < 0 && (nn_errno() == EBADF)); -} - - -void device2(NN_UNUSED void *arg) -{ - int rc; - - /* Intialise the device sockets. */ - devc = test_socket(AF_SP_RAW, NN_PULL); - test_bind(devc, SOCKET_ADDRESS_C); - devd = test_socket(AF_SP_RAW, NN_PUSH); - test_bind(devd, SOCKET_ADDRESS_D); - - /* Run the device. */ - rc = nn_device(devc, devd); - nn_assert(rc < 0 && nn_errno() == EBADF); -} - - -void device3(NN_UNUSED void *arg) -{ - int rc; - - /* Intialise the device socket. */ - deve = test_socket(AF_SP_RAW, NN_BUS); - test_bind(deve, SOCKET_ADDRESS_E); - - /* Run the device. */ - rc = nn_device(deve, -1); - nn_assert(rc < 0 && nn_errno() == EBADF); -} - - -int main() -{ - int enda; - int endb; - int endc; - int endd; - int ende1; - int ende2; - struct nn_thread thread1; - struct nn_thread thread2; - struct nn_thread thread3; - int timeo; - - /* Test the bi-directional device. */ - - /* Start the device. */ - nn_thread_init(&thread1, device1, NULL); - - /* Create two sockets to connect to the device. */ - enda = test_socket(AF_SP, NN_PAIR); - test_connect(enda, SOCKET_ADDRESS_A); - endb = test_socket(AF_SP, NN_PAIR); - test_connect(endb, SOCKET_ADDRESS_B); - - nn_sleep(100); - - /* Pass a pair of messages between endpoints. */ - test_send(enda, "ABC"); - test_recv(endb, "ABC"); - test_send(endb, "ABC"); - test_recv(enda, "ABC"); - - /* Clean up. */ - test_close(endb); - test_close(enda); - test_close(deva); - test_close(devb); - - /* Test the uni-directional device. */ - - /* Start the device. */ - nn_thread_init(&thread2, device2, NULL); - - nn_sleep(100); - - /* Create two sockets to connect to the device. */ - endc = test_socket(AF_SP, NN_PUSH); - test_connect(endc, SOCKET_ADDRESS_C); - endd = test_socket(AF_SP, NN_PULL); - test_connect(endd, SOCKET_ADDRESS_D); - - - /* Pass a message between endpoints. */ - test_send(endc, "XYZ"); - test_recv(endd, "XYZ"); - - /* Clean up. */ - test_close(endd); - test_close(endc); - test_close(devc); - test_close(devd); - - /* Test the loopback device. */ - - /* Start the device. */ - nn_thread_init(&thread3, device3, NULL); - nn_sleep(100); - - /* Create two sockets to connect to the device. */ - ende1 = test_socket(AF_SP, NN_BUS); - test_connect(ende1, SOCKET_ADDRESS_E); - ende2 = test_socket(AF_SP, NN_BUS); - test_connect(ende2, SOCKET_ADDRESS_E); - - /* BUS is unreliable so wait a bit for connections to be established. */ - nn_sleep(200); - - /* Pass a message to the bus. */ - test_send(ende1, "KLM"); - test_recv(ende2, "KLM"); - - /* Make sure that the message doesn't arrive at the socket it was - * originally sent to. */ - timeo = 100; - test_setsockopt(ende1, NN_SOL_SOCKET, NN_RCVTIMEO, - &timeo, sizeof (timeo)); - test_drop(ende1, ETIMEDOUT); - - /* Clean up. */ - test_close(ende2); - test_close(ende1); - test_close(deve); - - /* Shut down the devices. */ - nn_term(); - nn_thread_term(&thread1); - nn_thread_term(&thread2); - nn_thread_term(&thread3); - - return (0); -} diff --git a/tests/compat_iovec.c b/tests/compat_iovec.c deleted file mode 100644 index 54f078aa..00000000 --- a/tests/compat_iovec.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - Copyright (c) 2013 Martin Sustrik All rights reserved. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom - the Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. -*/ - -#include <nng/compat/nanomsg/nn.h> -#include <nng/compat/nanomsg/pair.h> - -#include "compat_testutil.h" - -#include <string.h> - -#define SOCKET_ADDRESS "inproc://a" - -int main () -{ - int rc; - int sb; - int sc; - struct nn_iovec iov [2]; - struct nn_msghdr hdr; - char buf [6]; - - sb = test_socket (AF_SP, NN_PAIR); - test_bind (sb, SOCKET_ADDRESS); - sc = test_socket (AF_SP, NN_PAIR); - test_connect (sc, SOCKET_ADDRESS); - - iov [0].iov_base = "AB"; - iov [0].iov_len = 2; - iov [1].iov_base = "CDEF"; - iov [1].iov_len = 4; - memset (&hdr, 0, sizeof (hdr)); - hdr.msg_iov = iov; - hdr.msg_iovlen = 2; - rc = nn_sendmsg (sc, &hdr, 0); - errno_assert (rc >= 0); - nn_assert (rc == 6); - - iov [0].iov_base = buf; - iov [0].iov_len = 4; - iov [1].iov_base = buf + 4; - iov [1].iov_len = 2; - memset (&hdr, 0, sizeof (hdr)); - hdr.msg_iov = iov; - hdr.msg_iovlen = 2; - rc = nn_recvmsg (sb, &hdr, 0); - errno_assert (rc >= 0); - nn_assert (rc == 6); - nn_assert (memcmp (buf, "ABCDEF", 6) == 0); - - test_close (sc); - test_close (sb); - - return 0; -} - diff --git a/tests/compat_msg.c b/tests/compat_msg.c deleted file mode 100644 index c2efb2cc..00000000 --- a/tests/compat_msg.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - Copyright (c) 2013 Martin Sustrik All rights reserved. - Copyright 2016 Franklin "Snaipe" Mathieu <franklinmathieu@gmail.com> - Copyright 2017 Garrett D'Amore <garrett@damore.org> - Copyright 2017 Capitar IT Group BV <info@capitar.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom - the Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. -*/ - -#include <nng/compat/nanomsg/nn.h> -#include <nng/compat/nanomsg/pair.h> - -#include "compat_testutil.h" - -#include <string.h> - -#define SOCKET_ADDRESS "inproc://a" - -char longdata[1 << 20]; - -int main (int argc, const char *argv[]) -{ - int rc; - int sb; - int sc; - unsigned char *buf1, *buf2; - int i; - struct nn_iovec iov; - struct nn_msghdr hdr; - char socket_address_tcp[128]; - - test_addr_from(socket_address_tcp, "tcp", "127.0.0.1", - get_test_port(argc, argv)); - - sb = test_socket (AF_SP, NN_PAIR); - test_bind (sb, SOCKET_ADDRESS); - sc = test_socket (AF_SP, NN_PAIR); - test_connect (sc, SOCKET_ADDRESS); - - buf1 = nn_allocmsg (256, 0); - alloc_assert (buf1); - for (i = 0; i != 256; ++i) - buf1 [i] = (unsigned char) i; - rc = nn_send (sc, &buf1, NN_MSG, 0); - errno_assert (rc >= 0); - nn_assert (rc == 256); - - buf2 = NULL; - rc = nn_recv (sb, &buf2, NN_MSG, 0); - errno_assert (rc >= 0); - nn_assert (rc == 256); - nn_assert (buf2); - for (i = 0; i != 256; ++i) - nn_assert (buf2 [i] == (unsigned char) i); - rc = nn_freemsg (buf2); - errno_assert (rc == 0); - - buf1 = nn_allocmsg (256, 0); - alloc_assert (buf1); - for (i = 0; i != 256; ++i) - buf1 [i] = (unsigned char) i; - iov.iov_base = &buf1; - iov.iov_len = NN_MSG; - memset (&hdr, 0, sizeof (hdr)); - hdr.msg_iov = &iov; - hdr.msg_iovlen = 1; - rc = nn_sendmsg (sc, &hdr, 0); - errno_assert (rc >= 0); - nn_assert (rc == 256); - - buf2 = NULL; - iov.iov_base = &buf2; - iov.iov_len = NN_MSG; - memset (&hdr, 0, sizeof (hdr)); - hdr.msg_iov = &iov; - hdr.msg_iovlen = 1; - rc = nn_recvmsg (sb, &hdr, 0); - errno_assert (rc >= 0); - nn_assert (rc == 256); - nn_assert (buf2); - for (i = 0; i != 256; ++i) - nn_assert (buf2 [i] == (unsigned char) i); - rc = nn_freemsg (buf2); - errno_assert (rc == 0); - - test_close (sc); - test_close (sb); - - /* Test receiving of large message */ - - sb = test_socket (AF_SP, NN_PAIR); - test_bind (sb, socket_address_tcp); - sc = test_socket (AF_SP, NN_PAIR); - test_connect (sc, socket_address_tcp); - - for (i = 0; i < (int) sizeof (longdata); ++i) - longdata[i] = '0' + (i % 10); - longdata [sizeof (longdata) - 1] = 0; - test_send (sb, longdata); - - rc = nn_recv (sc, &buf2, NN_MSG, 0); - errno_assert (rc >= 0); - nn_assert (rc == sizeof (longdata) - 1); - nn_assert (buf2); - for (i = 0; i < (int) sizeof (longdata) - 1; ++i) - nn_assert (buf2 [i] == longdata [i]); - rc = nn_freemsg (buf2); - errno_assert (rc == 0); - - test_close (sc); - test_close (sb); - - return 0; -} - diff --git a/tests/compat_options.c b/tests/compat_options.c deleted file mode 100644 index 305ae128..00000000 --- a/tests/compat_options.c +++ /dev/null @@ -1,57 +0,0 @@ -// -// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> -// Copyright 2018 Capitar IT Group BV <info@capitar.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/compat/nanomsg/nn.h> -#include <nng/compat/nanomsg/reqrep.h> - -#include "convey.h" -#include "compat_testutil.h" - -#include <string.h> - -#define SECONDS(x) ((x) *1000) - -TestMain("Compatible Options", { - - atexit(nn_term); - - Convey("Given a compat NN_REP socket", { - int repsock; - - So((repsock = nn_socket(AF_SP, NN_REP)) != -1); - Reset({ nn_close(repsock); }); - - Convey("NN_DOMAIN works", { - int dom = 4321; - size_t sz; - sz = sizeof(dom); - So(nn_getsockopt(repsock, NN_SOL_SOCKET, NN_DOMAIN, - &dom, &sz) == 0); - So(sz == sizeof(dom)); - So(dom == AF_SP); - - So(nn_setsockopt(repsock, NN_SOL_SOCKET, NN_DOMAIN, - &dom, sz) == -1); - So(nn_errno() == ENOPROTOOPT); - }); - Convey("NN_LINGER has no effect", { - int l = 4321; - size_t sz; - sz = sizeof(l); - So(nn_setsockopt(repsock, NN_SOL_SOCKET, NN_LINGER, &l, - sz) == 0); - - So(nn_getsockopt(repsock, NN_SOL_SOCKET, NN_LINGER, &l, - &sz) == 0); - So(sz == sizeof(l)); - So(l == 0); - }); - }); -}) diff --git a/tests/compat_pair.c b/tests/compat_pair.c deleted file mode 100644 index 000944c1..00000000 --- a/tests/compat_pair.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - Copyright (c) 2012 Martin Sustrik All rights reserved. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom - the Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. -*/ - -#include <nng/compat/nanomsg/nn.h> -#include <nng/compat/nanomsg/pair.h> - -#include "compat_testutil.h" - -#define SOCKET_ADDRESS "inproc://a" - -int main () -{ - int sb; - int sc; - - sb = test_socket (AF_SP, NN_PAIR); - test_bind (sb, SOCKET_ADDRESS); - sc = test_socket (AF_SP, NN_PAIR); - test_connect (sc, SOCKET_ADDRESS); - - test_send (sc, "ABC"); - test_recv (sb, "ABC"); - test_send (sb, "DEF"); - test_recv (sc, "DEF"); - - test_close (sc); - test_close (sb); - - return 0; -} - diff --git a/tests/compat_pipeline.c b/tests/compat_pipeline.c deleted file mode 100644 index 679f08f7..00000000 --- a/tests/compat_pipeline.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - Copyright (c) 2012 Martin Sustrik All rights reserved. - Copyright (c) 2013 GoPivotal, Inc. All rights reserved. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom - the Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. -*/ - -#include <nng/compat/nanomsg/nn.h> -#include <nng/compat/nanomsg/pipeline.h> -#include "compat_testutil.h" - -#define SOCKET_ADDRESS "inproc://a" - -int main () -{ - int push1; - int push2; - int pull1; - int pull2; - - /* Test fan-out. */ - - push1 = test_socket (AF_SP, NN_PUSH); - test_bind (push1, SOCKET_ADDRESS); - pull1 = test_socket (AF_SP, NN_PULL); - test_connect (pull1, SOCKET_ADDRESS); - nn_sleep (20); - pull2 = test_socket (AF_SP, NN_PULL); - test_connect (pull2, SOCKET_ADDRESS); - - /* Wait till both connections are established to get messages spread - evenly between the two pull sockets. */ - nn_sleep (20); - - test_send (push1, "ABC"); - test_send (push1, "DEF"); - - test_recv (pull1, "ABC"); - test_recv (pull2, "DEF"); - - test_close (push1); - test_close (pull1); - test_close (pull2); - - /* Test fan-in. */ - - pull1 = test_socket (AF_SP, NN_PULL); - test_bind (pull1, SOCKET_ADDRESS); - push1 = test_socket (AF_SP, NN_PUSH); - test_connect (push1, SOCKET_ADDRESS); - push2 = test_socket (AF_SP, NN_PUSH); - test_connect (push2, SOCKET_ADDRESS); - - nn_sleep (10); - test_send (push1, "ABC"); - - nn_sleep (10); - test_send (push2, "DEF"); - - test_recv (pull1, "ABC"); - test_recv (pull1, "DEF"); - - test_close (pull1); - test_close (push1); - test_close (push2); - - return 0; -} - diff --git a/tests/compat_poll.c b/tests/compat_poll.c deleted file mode 100644 index 3431f5f2..00000000 --- a/tests/compat_poll.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - Copyright (c) 2013 Martin Sustrik All rights reserved. - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom - the Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - - -#if defined _WIN32 -#define poll WSAPoll -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include <windows.h> -#include <winsock2.h> -#include <mswsock.h> -#else -#include <sys/select.h> -#endif -#include "compat_testutil.h" -#include <nng/compat/nanomsg/nn.h> -#include <nng/compat/nanomsg/pair.h> -#include <nng/compat/nanomsg/inproc.h> - -/* Test of polling via NN_SNDFD/NN_RCVFD mechanism. */ - -#define SOCKET_ADDRESS "inproc://a" - -int sc; - -void -routine1(NN_UNUSED void *arg) -{ - nn_sleep(10); - test_send(sc, "ABC"); -} - -void -routine2(NN_UNUSED void *arg) -{ - nn_sleep(10); - nn_term(); -} - -#define NN_IN 1 -#define NN_OUT 2 - -int -getevents(int s, int events, int timeout) -{ - int rc; - fd_set pollset; -#if defined _WIN32 - SOCKET rcvfd; - SOCKET sndfd; -#else - int rcvfd; - int sndfd; - int maxfd; -#endif - size_t fdsz; - struct timeval tv; - int revents; - -#if !defined _WIN32 - maxfd = 0; -#endif - FD_ZERO(&pollset); - - if (events & NN_IN) { - fdsz = sizeof(rcvfd); - rc = nn_getsockopt( - s, NN_SOL_SOCKET, NN_RCVFD, (char *) &rcvfd, &fdsz); - errno_assert(rc == 0); - nn_assert(fdsz == sizeof(rcvfd)); - FD_SET(rcvfd, &pollset); -#if !defined _WIN32 - if (rcvfd + 1 > maxfd) - maxfd = rcvfd + 1; -#endif - } - - if (events & NN_OUT) { - fdsz = sizeof(sndfd); - rc = nn_getsockopt( - s, NN_SOL_SOCKET, NN_SNDFD, (char *) &sndfd, &fdsz); - errno_assert(rc == 0); - nn_assert(fdsz == sizeof(sndfd)); - FD_SET(sndfd, &pollset); -#if !defined _WIN32 - if (sndfd + 1 > maxfd) - maxfd = sndfd + 1; -#endif - } - - if (timeout >= 0) { - tv.tv_sec = timeout / 1000; - tv.tv_usec = (timeout % 1000) * 1000; - } -#if defined _WIN32 - rc = select(0, &pollset, NULL, NULL, timeout < 0 ? NULL : &tv); - wsa_assert(rc != SOCKET_ERROR); -#else - rc = select(maxfd, &pollset, NULL, NULL, timeout < 0 ? NULL : &tv); - errno_assert(rc >= 0); -#endif - revents = 0; - if ((events & NN_IN) && FD_ISSET(rcvfd, &pollset)) - revents |= NN_IN; - if ((events & NN_OUT) && FD_ISSET(sndfd, &pollset)) - revents |= NN_OUT; - return revents; -} - -int -main() -{ - int rc; - int sb; - char buf[3]; - struct nn_thread thread; - struct nn_pollfd pfd[2]; - - /* Test nn_poll() function. */ - sb = test_socket(AF_SP, NN_PAIR); - test_bind(sb, SOCKET_ADDRESS); - sc = test_socket(AF_SP, NN_PAIR); - test_connect(sc, SOCKET_ADDRESS); - nn_sleep(200); - test_send(sc, "ABC"); - nn_sleep(100); - pfd[0].fd = sb; - pfd[0].events = NN_POLLIN | NN_POLLOUT; - pfd[1].fd = sc; - pfd[1].events = NN_POLLIN | NN_POLLOUT; - rc = nn_poll(pfd, 2, -1); - errno_assert(rc >= 0); - nn_assert(rc == 2); - nn_assert(pfd[0].revents == (NN_POLLIN | NN_POLLOUT)); - nn_assert(pfd[1].revents == NN_POLLOUT); - test_close(sc); - test_close(sb); - - /* Create a simple topology. */ - sb = test_socket(AF_SP, NN_PAIR); - test_bind(sb, SOCKET_ADDRESS); - sc = test_socket(AF_SP, NN_PAIR); - test_connect(sc, SOCKET_ADDRESS); - - /* Check the initial state of the socket. */ - rc = getevents(sb, NN_IN | NN_OUT, 1000); - nn_assert(rc == NN_OUT); - - /* Poll for IN when there's no message available. The call should - time out. */ - rc = getevents(sb, NN_IN, 10); - nn_assert(rc == 0); - - /* Send a message and start polling. This time IN event should be - signaled. */ - test_send(sc, "ABC"); - rc = getevents(sb, NN_IN, 1000); - nn_assert(rc == NN_IN); - - /* Receive the message and make sure that IN is no longer signaled. */ - test_recv(sb, "ABC"); - rc = getevents(sb, NN_IN, 10); - nn_assert(rc == 0); - - /* Check signalling from a different thread. */ - nn_thread_init(&thread, routine1, NULL); - rc = getevents(sb, NN_IN, 1000); - nn_assert(rc == NN_IN); - test_recv(sb, "ABC"); - nn_thread_term(&thread); - - /* Check terminating the library from a different thread. */ - nn_thread_init(&thread, routine2, NULL); - rc = nn_recv(sb, buf, sizeof(buf), 0); - nn_assert(rc < 0 && nn_errno() == EBADF); - nn_thread_term(&thread); - - /* Clean up. */ - test_close(sc); - test_close(sb); - - return 0; -} diff --git a/tests/compat_reqrep.c b/tests/compat_reqrep.c deleted file mode 100644 index 7bd7bf7b..00000000 --- a/tests/compat_reqrep.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - Copyright (c) 2012 Martin Sustrik All rights reserved. - Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> - Copyright 2018 Capitar IT Group BV <info@capitar.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom - the Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. -*/ - -#include <nng/compat/nanomsg/nn.h> -#include <nng/compat/nanomsg/reqrep.h> - -#include "compat_testutil.h" - -#define SOCKET_ADDRESS "inproc://test" - -int main () -{ - int rc; - int rep1; - int rep2; - int req1; - int req2; - int resend_ivl; - char buf [7]; - int timeo; - - /* Test req/rep with full socket types. */ - rep1 = test_socket (AF_SP, NN_REP); - test_bind (rep1, SOCKET_ADDRESS); - req1 = test_socket (AF_SP, NN_REQ); - test_connect (req1, SOCKET_ADDRESS); - req2 = test_socket (AF_SP, NN_REQ); - test_connect (req2, SOCKET_ADDRESS); - - /* Check invalid sequence of sends and recvs. */ - rc = nn_send (rep1, "ABC", 3, 0); - nn_assert (rc == -1 && nn_errno () == EFSM); - rc = nn_recv (req1, buf, sizeof (buf), 0); - nn_assert (rc == -1 && nn_errno () == EFSM); - - /* Check fair queueing the requests. */ - test_send (req2, "ABC"); - test_recv (rep1, "ABC"); - test_send (rep1, "ABC"); - test_recv (req2, "ABC"); - - test_send (req1, "ABC"); - test_recv (rep1, "ABC"); - test_send (rep1, "ABC"); - test_recv (req1, "ABC"); - - test_close (rep1); - test_close (req1); - test_close (req2); - - /* Check load-balancing of requests. */ - req1 = test_socket (AF_SP, NN_REQ); - test_bind (req1, SOCKET_ADDRESS); - - rep1 = test_socket (AF_SP, NN_REP); - test_connect (rep1, SOCKET_ADDRESS); - - nn_sleep(10); // ensure rep1 binds before rep2 - - rep2 = test_socket (AF_SP, NN_REP); - test_connect (rep2, SOCKET_ADDRESS); - - timeo = 500; - test_setsockopt (req1, NN_SOL_SOCKET, NN_RCVTIMEO, &timeo, sizeof (timeo)); - test_setsockopt (rep1, NN_SOL_SOCKET, NN_RCVTIMEO, &timeo, sizeof (timeo)); - test_setsockopt (rep2, NN_SOL_SOCKET, NN_RCVTIMEO, &timeo, sizeof (timeo)); - - // Give time for connections to settle -- required for LB stuff. - nn_sleep(100); - - test_send (req1, "ABC"); - test_recv (rep1, "ABC"); - test_send (rep1, "ABC"); - test_recv (req1, "ABC"); - - test_send (req1, "ABC"); - test_recv (rep2, "ABC"); - test_send (rep2, "ABC"); - test_recv (req1, "ABC"); - - test_close (rep2); - test_close (rep1); - test_close (req1); - - /* Test re-sending of the request. */ - rep1 = test_socket (AF_SP, NN_REP); - test_bind (rep1, SOCKET_ADDRESS); - req1 = test_socket (AF_SP, NN_REQ); - test_connect (req1, SOCKET_ADDRESS); - resend_ivl = 100; - rc = nn_setsockopt (req1, NN_REQ, NN_REQ_RESEND_IVL, - &resend_ivl, sizeof (resend_ivl)); - errno_assert (rc == 0); - - test_send (req1, "ABC"); - test_recv (rep1, "ABC"); - /* The following waits for request to be resent */ - test_recv (rep1, "ABC"); - - test_close (req1); - test_close (rep1); - - - /* Check sending a request when the peer is not available. (It should - be sent immediately when the peer comes online rather than relying - on the resend algorithm.) */ - req1 = test_socket (AF_SP, NN_REQ); - timeo = 10; - test_setsockopt (req1, NN_SOL_SOCKET, NN_RECONNECT_IVL, &timeo, sizeof (timeo)); - test_connect (req1, SOCKET_ADDRESS); - - rep1 = test_socket (AF_SP, NN_REP); - test_bind (rep1, SOCKET_ADDRESS); - - timeo = 500; - test_setsockopt (rep1, NN_SOL_SOCKET, NN_RCVTIMEO, &timeo, sizeof (timeo)); - errno_assert (rc == 0); - test_send (req1, "ABC"); - - /* Now close the peer, and reopen it. This should still work. */ - test_close(rep1); - rep1 = test_socket (AF_SP, NN_REP); - test_bind (rep1, SOCKET_ADDRESS); - - test_recv (rep1, "ABC"); - - test_close (req1); - test_close (rep1); - - /* Check removing socket request sent to (It should - be sent immediatelly to other peer rather than relying - on the resend algorithm). */ - req1 = test_socket (AF_SP, NN_REQ); - test_bind (req1, SOCKET_ADDRESS); - rep1 = test_socket (AF_SP, NN_REP); - test_connect (rep1, SOCKET_ADDRESS); - rep2 = test_socket (AF_SP, NN_REP); - nn_sleep (10); // give time for rep1 to connect - test_connect (rep2, SOCKET_ADDRESS); - - timeo = 500; // Was 200, but Windows occasionally fails at that rate. - test_setsockopt (rep1, NN_SOL_SOCKET, NN_RCVTIMEO, &timeo, sizeof (timeo)); - test_setsockopt (rep2, NN_SOL_SOCKET, NN_RCVTIMEO, &timeo, sizeof (timeo)); - - test_send (req1, "ABC"); - /* We got request through rep1 */ - test_recv (rep1, "ABC"); - /* But instead replying we simulate crash */ - test_close (rep1); - /* The rep2 should get request immediately */ - test_recv (rep2, "ABC"); - /* Let's check it's delivered well */ - test_send (rep2, "REPLY"); - test_recv (req1, "REPLY"); - - test_close (req1); - test_close (rep2); - - /* Test cancelling delayed request */ - - req1 = test_socket (AF_SP, NN_REQ); - test_connect (req1, SOCKET_ADDRESS); - - rep1 = test_socket (AF_SP, NN_REP); - test_bind (rep1, SOCKET_ADDRESS); - - test_send (req1, "ABC"); - test_send (req1, "DEF"); - test_close (rep1); - - rep1 = test_socket (AF_SP, NN_REP); - test_bind (rep1, SOCKET_ADDRESS); - - timeo = 100; - test_recv (rep1, "DEF"); - - test_close (req1); - test_close (rep1); - - return 0; -} - diff --git a/tests/compat_reqttl.c b/tests/compat_reqttl.c deleted file mode 100644 index 939ca567..00000000 --- a/tests/compat_reqttl.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - Copyright (c) 2012 Martin Sustrik All rights reserved. - Copyright (c) 2013 GoPivotal, Inc. All rights reserved. - Copyright 2016 Franklin "Snaipe" Mathieu <franklinmathieu@gmail.com> - Copyright 2018 Garrett D'Amore <garrett@damore.org> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom - the Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. -*/ - -#include <nng/compat/nanomsg/nn.h> -#include <nng/compat/nanomsg/reqrep.h> -#include <nng/compat/nanomsg/tcp.h> - -#include "compat_testutil.h" - -static char socket_address_a[128]; -static char socket_address_b[128]; -int dev0; -int dev1; - -void device (NN_UNUSED void *arg) -{ - int rc; - - /* Run the device. */ - rc = nn_device (dev0, dev1); - nn_assert (rc < 0 && nn_errno () == EBADF); - - /* Clean up. */ - nn_close (dev0); - nn_close (dev1); -} - -int main (int argc, const char *argv[]) -{ - int end0; - int end1; - struct nn_thread thread1; - int timeo; - int maxttl; - size_t sz; - int rc; - - int port = get_test_port(argc, argv); - - test_addr_from(socket_address_a, "tcp", "127.0.0.1", port); - test_addr_from(socket_address_b, "tcp", "127.0.0.1", port + 1); - - /* Intialise the device sockets. */ - dev0 = test_socket (AF_SP_RAW, NN_REP); - dev1 = test_socket (AF_SP_RAW, NN_REQ); - - test_bind (dev0, socket_address_a); - test_bind (dev1, socket_address_b); - - /* Start the device. */ - nn_thread_init (&thread1, device, NULL); - - end0 = test_socket (AF_SP, NN_REQ); - end1 = test_socket (AF_SP, NN_REP); - - /* Test the bi-directional device TTL */ - test_connect (end0, socket_address_a); - test_connect (end1, socket_address_b); - - /* Wait for TCP to establish. */ - nn_sleep (100); - - /* Pass a message between endpoints. */ - /* Set up max receive timeout. */ - timeo = 100; - test_setsockopt (end0, NN_SOL_SOCKET, NN_RCVTIMEO, &timeo, sizeof (timeo)); - timeo = 100; - test_setsockopt (end1, NN_SOL_SOCKET, NN_RCVTIMEO, &timeo, sizeof (timeo)); - - /* Test default TTL is 8. */ - sz = sizeof (maxttl); - maxttl = -1; - rc = nn_getsockopt(end1, NN_SOL_SOCKET, NN_MAXTTL, &maxttl, &sz); - nn_assert (rc == 0); - nn_assert (sz == sizeof (maxttl)); - nn_assert (maxttl == 8); - - /* Test to make sure option TTL cannot be set below 1. */ - maxttl = -1; - rc = nn_setsockopt(end1, NN_SOL_SOCKET, NN_MAXTTL, &maxttl, sizeof (maxttl)); - nn_assert (rc < 0 && nn_errno () == EINVAL); - nn_assert (maxttl == -1); - maxttl = 0; - rc = nn_setsockopt(end1, NN_SOL_SOCKET, NN_MAXTTL, &maxttl, sizeof (maxttl)); - nn_assert (rc < 0 && nn_errno () == EINVAL); - nn_assert (maxttl == 0); - - /* Test to set non-integer size */ - maxttl = 8; - rc = nn_setsockopt(end1, NN_SOL_SOCKET, NN_MAXTTL, &maxttl, 1); - nn_assert (rc < 0 && nn_errno () == EINVAL); - nn_assert (maxttl == 8); - - test_send (end0, "XYZ"); - - test_recv (end1, "XYZ"); - - /* Now send a reply. */ - test_send (end1, "REPLYXYZ\n"); - test_recv (end0, "REPLYXYZ\n"); - - /* Now set the max TTL. */ - maxttl = 1; - test_setsockopt (end0, NN_SOL_SOCKET, NN_MAXTTL, &maxttl, sizeof (maxttl)); - test_setsockopt (end1, NN_SOL_SOCKET, NN_MAXTTL, &maxttl, sizeof (maxttl)); - - test_send (end0, "DROPTHIS"); - test_drop (end1, ETIMEDOUT); - - /* Now set the max TTL up. */ - maxttl = 2; - test_setsockopt (end0, NN_SOL_SOCKET, NN_MAXTTL, &maxttl, sizeof (maxttl)); - test_setsockopt (end1, NN_SOL_SOCKET, NN_MAXTTL, &maxttl, sizeof (maxttl)); - - test_send (end0, "DONTDROP"); - test_recv (end1, "DONTDROP"); - - test_send (end1, "GOTIT"); - test_recv (end0, "GOTIT"); - - /* Clean up. */ - test_close (end0); - test_close (end1); - - /* Shut down the devices. */ - nn_term (); - - nn_thread_term (&thread1); - - return 0; -} diff --git a/tests/compat_shutdown.c b/tests/compat_shutdown.c deleted file mode 100644 index 84d4d244..00000000 --- a/tests/compat_shutdown.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright (c) 2013 GoPivotal, Inc. All rights reserved. - Copyright 2016 Franklin "Snaipe" Mathieu <franklinmathieu@gmail.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom - the Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. -*/ - -#include <nng/compat/nanomsg/nn.h> -#include <nng/compat/nanomsg/tcp.h> -#include <nng/compat/nanomsg/reqrep.h> -#include "compat_testutil.h" - -int main (int argc, const char *argv[]) -{ - int s; - int rc; - int eid; - char socket_address[128]; - - test_addr_from(socket_address, "tcp", "127.0.0.1", - get_test_port(argc, argv)); - - /* Run endpoint shutdown and socket shutdown in parallel. */ - s = test_socket (AF_SP, NN_REQ); - eid = test_connect (s, socket_address); - rc = nn_shutdown (s, eid); - errno_assert (rc == 0); - test_close (s); - - return 0; -} - diff --git a/tests/compat_survey.c b/tests/compat_survey.c deleted file mode 100644 index 645021eb..00000000 --- a/tests/compat_survey.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - Copyright (c) 2012 Martin Sustrik All rights reserved. - Copyright 2017 Garrett D'Amore - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom - the Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#include <nng/compat/nanomsg/nn.h> -#include <nng/compat/nanomsg/survey.h> - -#include "compat_testutil.h" - -#define SOCKET_ADDRESS "inproc://test" - -int -main() -{ - int rc; - int surveyor; - int respondent1; - int respondent2; - int respondent3; - int deadline; - char buf[7]; - - /* Test a simple survey with three respondents. */ - surveyor = test_socket(AF_SP, NN_SURVEYOR); - deadline = 500; - rc = nn_setsockopt(surveyor, NN_SURVEYOR, NN_SURVEYOR_DEADLINE, - &deadline, sizeof(deadline)); - errno_assert(rc == 0); - test_bind(surveyor, SOCKET_ADDRESS); - respondent1 = test_socket(AF_SP, NN_RESPONDENT); - test_connect(respondent1, SOCKET_ADDRESS); - respondent2 = test_socket(AF_SP, NN_RESPONDENT); - test_connect(respondent2, SOCKET_ADDRESS); - respondent3 = test_socket(AF_SP, NN_RESPONDENT); - test_connect(respondent3, SOCKET_ADDRESS); - - /* Sleep a tiny bit. */ - nn_sleep(1000); - - /* Check that attempt to recv with no survey pending is EFSM. */ - rc = nn_recv(surveyor, buf, sizeof(buf), 0); - errno_assert(rc == -1 && nn_errno() == EFSM); - - /* Send the survey. */ - test_send(surveyor, "ABC"); - - /* First respondent answers. */ - test_recv(respondent1, "ABC"); - test_send(respondent1, "DEF"); - - /* Second respondent answers. */ - test_recv(respondent2, "ABC"); - test_send(respondent2, "DEF"); - - /* Surveyor gets the responses. */ - test_recv(surveyor, "DEF"); - test_recv(surveyor, "DEF"); - - /* There are no more responses. Surveyor hits the deadline. */ - rc = nn_recv(surveyor, buf, sizeof(buf), 0); - errno_assert(rc == -1 && nn_errno() == ETIMEDOUT); - - /* Third respondent answers (it have already missed the deadline). */ - test_recv(respondent3, "ABC"); - test_send(respondent3, "GHI"); - - /* Surveyor initiates new survey. */ - test_send(surveyor, "ABC"); - - /* Check that stale response from third respondent is not delivered. - */ - rc = nn_recv(surveyor, buf, sizeof(buf), 0); - errno_assert(rc == -1 && nn_errno() == ETIMEDOUT); - - /* Check that subsequent attempt to recv with no survey pending is - * EFSM. */ - nn_sleep(1000); // nng - sleep a bit as there may be a thread race - rc = nn_recv(surveyor, buf, sizeof(buf), 0); - errno_assert(rc == -1 && nn_errno() == EFSM); - - test_close(surveyor); - test_close(respondent1); - test_close(respondent2); - test_close(respondent3); - - return 0; -} diff --git a/tests/compat_surveyttl.c b/tests/compat_surveyttl.c deleted file mode 100644 index 00915da4..00000000 --- a/tests/compat_surveyttl.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - Copyright (c) 2012 Martin Sustrik All rights reserved. - Copyright (c) 2013 GoPivotal, Inc. All rights reserved. - Copyright 2016 Garrett D'Amore <garrett@damore.org> - Copyright 2016 Franklin "Snaipe" Mathieu <franklinmathieu@gmail.com> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom - the Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. -*/ - -#include <nng/compat/nanomsg/nn.h> -#include <nng/compat/nanomsg/survey.h> -#include <nng/compat/nanomsg/tcp.h> - -#include "compat_testutil.h" - -static char socket_address_a[128]; -static char socket_address_b[128]; -int dev0; -int dev1; - -void device (NN_UNUSED void *arg) -{ - int rc; - - /* Run the device. */ - rc = nn_device (dev0, dev1); - nn_assert (rc < 0 && nn_errno () == EBADF); - - /* Clean up. */ - test_close (dev0); - test_close (dev1); -} - -int main (int argc, const char *argv[]) -{ - int end0; - int end1; - struct nn_thread thread1; - int timeo; - int maxttl; - size_t sz; - int rc; - - int port = get_test_port(argc, argv); - - test_addr_from(socket_address_a, "tcp", "127.0.0.1", port); - test_addr_from(socket_address_b, "tcp", "127.0.0.1", port + 1); - - /* Intialise the device sockets. */ - dev0 = test_socket (AF_SP_RAW, NN_RESPONDENT); - dev1 = test_socket (AF_SP_RAW, NN_SURVEYOR); - - test_bind (dev0, socket_address_a); - test_bind (dev1, socket_address_b); - - /* Start the device. */ - nn_thread_init (&thread1, device, NULL); - - end0 = test_socket (AF_SP, NN_SURVEYOR); - end1 = test_socket (AF_SP, NN_RESPONDENT); - - /* Test the bi-directional device TTL */ - test_connect (end0, socket_address_a); - test_connect (end1, socket_address_b); - - /* Wait for TCP to establish. */ - nn_sleep (100); - - /* Set up max receive timeout. */ - timeo = 100; - test_setsockopt (end0, NN_SOL_SOCKET, NN_RCVTIMEO, &timeo, sizeof (timeo)); - timeo = 100; - test_setsockopt (end1, NN_SOL_SOCKET, NN_RCVTIMEO, &timeo, sizeof (timeo)); - - /* Test default TTL is 8. */ - sz = sizeof (maxttl); - maxttl = -1; - rc = nn_getsockopt(end1, NN_SOL_SOCKET, NN_MAXTTL, &maxttl, &sz); - nn_assert (rc == 0); - nn_assert (sz == sizeof (maxttl)); - nn_assert (maxttl == 8); - - /* Test to make sure option TTL cannot be set below 1. */ - maxttl = -1; - rc = nn_setsockopt(end1, NN_SOL_SOCKET, NN_MAXTTL, &maxttl, sizeof (maxttl)); - nn_assert (rc < 0 && nn_errno () == EINVAL); - nn_assert (maxttl == -1); - maxttl = 0; - rc = nn_setsockopt(end1, NN_SOL_SOCKET, NN_MAXTTL, &maxttl, sizeof (maxttl)); - nn_assert (rc < 0 && nn_errno () == EINVAL); - nn_assert (maxttl == 0); - - /* Test to set non-integer size */ - maxttl = 8; - rc = nn_setsockopt(end1, NN_SOL_SOCKET, NN_MAXTTL, &maxttl, 1); - nn_assert (rc < 0 && nn_errno () == EINVAL); - nn_assert (maxttl == 8); - - /* Pass a message between endpoints. */ - test_send (end0, "SURVEY"); - test_recv (end1, "SURVEY"); - - /* Now send a reply. */ - test_send (end1, "REPLYXYZ"); - test_recv (end0, "REPLYXYZ"); - - /* Now set the max TTL. */ - maxttl = 1; - test_setsockopt (end0, NN_SOL_SOCKET, NN_MAXTTL, &maxttl, sizeof (maxttl)); - test_setsockopt (end1, NN_SOL_SOCKET, NN_MAXTTL, &maxttl, sizeof (maxttl)); - - test_send (end0, "DROPTHIS"); - test_drop (end1, ETIMEDOUT); - - maxttl = 2; - test_setsockopt (end0, NN_SOL_SOCKET, NN_MAXTTL, &maxttl, sizeof (maxttl)); - test_setsockopt (end1, NN_SOL_SOCKET, NN_MAXTTL, &maxttl, sizeof (maxttl)); - test_send (end0, "DONTDROP"); - test_recv (end1, "DONTDROP"); - - /* Clean up. */ - test_close (end0); - test_close (end1); - - /* Shut down the devices. */ - nn_term (); - nn_thread_term (&thread1); - - return 0; -} diff --git a/tests/compat_testutil.c b/tests/compat_testutil.c deleted file mode 100644 index aff8f02d..00000000 --- a/tests/compat_testutil.c +++ /dev/null @@ -1,240 +0,0 @@ -/* - Copyright (c) 2013 Insollo Entertainment, LLC. All rights reserved. - Copyright 2016 Franklin "Snaipe" Mathieu <franklinmathieu@gmail.com> - Copyright 2018 Capitar IT Group BV <info@capitar.com> - Copyright 2024 Staysail Systems, Inc. <info@staysail.tech> - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom - the Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -// Note: This file started life in nanomsg. We have copied it, and adjusted -// it for validating the compatibility features of nanomsg. As much as -// possible we want to run tests from the nanomsg test suite unmodified. - -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "compat_testutil.h" -#include <nng/compat/nanomsg/nn.h> - -int test_socket_impl(char *file, int line, int family, int protocol); -int test_connect_impl(char *file, int line, int sock, char *address); -int test_bind_impl(char *file, int line, int sock, char *address); -void test_close_impl(char *file, int line, int sock); -void test_send_impl(char *file, int line, int sock, char *data); -void test_recv_impl(char *file, int line, int sock, char *data); -void test_drop_impl(char *file, int line, int sock, int err); -int test_setsockopt_impl(char *file, int line, int sock, int level, int option, - const void *optval, size_t optlen); - -int -test_socket_impl(char *file, int line, int family, int protocol) -{ - int sock; - - sock = nn_socket(family, protocol); - if (sock == -1) { - fprintf(stderr, "Failed create socket: %s [%d] (%s:%d)\n", - nn_err_strerror(errno), (int) errno, file, line); - nn_err_abort(); - } - - return (sock); -} - -int -test_connect_impl(char *file, int line, int sock, char *address) -{ - int rc; - - rc = nn_connect(sock, address); - if (rc < 0) { - fprintf(stderr, "Failed connect to \"%s\": %s [%d] (%s:%d)\n", - address, nn_err_strerror(errno), (int) errno, file, line); - nn_err_abort(); - } - return (rc); -} - -int -test_bind_impl(char *file, int line, int sock, char *address) -{ - int rc; - - rc = nn_bind(sock, address); - if (rc < 0) { - fprintf(stderr, "Failed bind to \"%s\": %s [%d] (%s:%d)\n", - address, nn_err_strerror(errno), (int) errno, file, line); - nn_err_abort(); - } - return (rc); -} - -int -test_setsockopt_impl(char *file, int line, int sock, int level, int option, - const void *optval, size_t optlen) -{ - int rc; - - rc = nn_setsockopt(sock, level, option, optval, optlen); - if (rc < 0) { - fprintf(stderr, "Failed set option \"%d\": %s [%d] (%s:%d)\n", - option, nn_err_strerror(errno), (int) errno, file, line); - nn_err_abort(); - } - return rc; -} - -void -test_close_impl(char *file, int line, int sock) -{ - int rc; - - rc = nn_close(sock); - if ((rc != 0) && (errno != EBADF && errno != ETERM)) { - fprintf(stderr, "Failed to close socket: %s [%d] (%s:%d)\n", - nn_err_strerror(errno), (int) errno, file, line); - nn_err_abort(); - } -} - -void -test_send_impl(char *file, int line, int sock, char *data) -{ - size_t data_len; - int rc; - - data_len = strlen(data); - - rc = nn_send(sock, data, data_len, 0); - if (rc < 0) { - fprintf(stderr, "Failed to send: %s [%d] (%s:%d)\n", - nn_err_strerror(errno), (int) errno, file, line); - nn_err_abort(); - } - if (rc != (int) data_len) { - fprintf(stderr, - "Data to send is truncated: %d != %d (%s:%d)\n", rc, - (int) data_len, file, line); - nn_err_abort(); - } -} - -void -test_recv_impl(char *file, int line, int sock, char *data) -{ - size_t data_len; - int rc; - char *buf; - - data_len = strlen(data); - /* We allocate plus one byte so that we are sure that message received - has correct length and not truncated */ - buf = malloc(data_len + 1); - alloc_assert(buf); - - rc = nn_recv(sock, buf, data_len + 1, 0); - if (rc < 0) { - fprintf(stderr, "Failed to recv: %s [%d] (%s:%d)\n", - nn_err_strerror(errno), (int) errno, file, line); - nn_err_abort(); - } - if (rc != (int) data_len) { - fprintf(stderr, - "Received data has wrong length: %d != %d (%s:%d)\n", rc, - (int) data_len, file, line); - nn_err_abort(); - } - if (memcmp(data, buf, data_len) != 0) { - /* We don't print the data as it may have binary garbage */ - fprintf( - stderr, "Received data is wrong (%s:%d)\n", file, line); - nn_err_abort(); - } - - free(buf); -} - -void -test_drop_impl(char *file, int line, int sock, int err) -{ - int rc; - char buf[1024]; - - rc = nn_recv(sock, buf, sizeof(buf), 0); - if (rc < 0 && err != errno) { - fprintf(stderr, - "Got wrong err to recv: %s [%d != %d] (%s:%d)\n", - nn_err_strerror(errno), (int) errno, err, file, line); - nn_err_abort(); - } else if (rc >= 0) { - fprintf(stderr, "Did not drop message: [%d bytes] (%s:%d)\n", - rc, file, line); - nn_err_abort(); - } -} - -int -get_test_port(int argc, const char *argv[]) -{ - return (atoi(argc < 2 ? "5555" : argv[1])); -} - -void -test_addr_from(char *out, const char *proto, const char *ip, int port) -{ - (void) snprintf(out, 128, "%s://%s:%d", proto, ip, port); -} - -extern int nng_thread_create(void **, void (*)(void *), void *); - -int -nn_thread_init(struct nn_thread *thr, void (*func)(void *), void *arg) -{ - return (nng_thread_create(&thr->thr, func, arg)); -} - -extern void nng_thread_destroy(void *); - -void -nn_thread_term(struct nn_thread *thr) -{ - nng_thread_destroy(thr->thr); -} - -extern void nng_msleep(int32_t); - -void -nn_sleep(int ms) -{ - nng_msleep(ms); -} - -void -nn_assert_impl(bool b, const char *expression, const char *file, int line) -{ - if (b) { - return; - } - fprintf( - stderr, "%s:%d: Assertion failed: %s\n", file, line, expression); - abort(); -} diff --git a/tests/compat_testutil.h b/tests/compat_testutil.h deleted file mode 100644 index da9baaa9..00000000 --- a/tests/compat_testutil.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - Copyright (c) 2013 Insollo Entertainment, LLC. All rights reserved. - Copyright 2017 Garrett D'Amore <garrett@damore.org> - Copyright 2016 Franklin "Snaipe" Mathieu <franklinmathieu@gmail.com> - Copyright 2018 Capitar IT Group BV <info@capitar.com> - Copyright 2024 Staysail Systems, Inc. <info@staysail.tech> - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom - the Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -// Note: This file started life in nanomsg. We have copied it, and adjusted -// it for validating the compatibility features of nanomsg. As much as -// possible we want to run tests from the nanomsg test suite unmodified. - -#ifndef COMPAT_TESTUTIL_H_INCLUDED -#define COMPAT_TESTUTIL_H_INCLUDED - -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#define nn_err_strerror nn_strerror -#define nn_err_abort abort -#define errno_assert nn_assert -#define wsa_assert nn_assert -#define alloc_assert(x) nn_assert((x) != NULL) - -#if defined __GNUC__ || defined __llvm__ || defined __clang__ -#define NN_UNUSED __attribute__((unused)) -#else -#define NN_UNUSED -#endif - -#define nn_assert(x) nn_assert_impl(x, #x, __FILE__, __LINE__) - -extern int test_socket_impl(char *file, int line, int family, int protocol); -extern int test_connect_impl(char *file, int line, int sock, char *address); -extern int test_bind_impl(char *file, int line, int sock, char *address); -extern void test_close_impl(char *file, int line, int sock); -extern void test_send_impl(char *file, int line, int sock, char *data); -extern void test_recv_impl(char *file, int line, int sock, char *data); -extern void test_drop_impl(char *file, int line, int sock, int err); -extern int test_setsockopt_impl(char *file, int line, int sock, int level, - int option, const void *optval, size_t optlen); -extern int get_test_port(int argc, const char *argv[]); -extern void test_addr_from( - char *out, const char *proto, const char *ip, int port); -extern void nn_sleep(int); -extern void nn_assert_impl( - bool b, const char *expression, const char *file, int line); - -#define test_socket(f, p) test_socket_impl(__FILE__, __LINE__, (f), (p)) -#define test_connect(s, a) test_connect_impl(__FILE__, __LINE__, (s), (a)) -#define test_bind(s, a) test_bind_impl(__FILE__, __LINE__, (s), (a)) -#define test_send(s, d) test_send_impl(__FILE__, __LINE__, (s), (d)) -#define test_recv(s, d) test_recv_impl(__FILE__, __LINE__, (s), (d)) -#define test_drop(s, e) test_drop_impl(__FILE__, __LINE__, (s), (e)) -#define test_close(s) test_close_impl(__FILE__, __LINE__, (s)) -#define test_setsockopt(s, l, o, v, z) \ - test_setsockopt_impl(__FILE__, __LINE__, (s), (l), (o), (v), (z)) - -struct nn_thread { - void *thr; -}; - -extern int nn_thread_init(struct nn_thread *, void (*)(void *), void *); -extern void nn_thread_term(struct nn_thread *); - -#endif // COMPAT_TESTUTIL_H_INCLUDED |
