/* SPDX-License-Identifier: MPL-2.0 */ #ifndef __TESTUTIL_HPP_INCLUDED__ #define __TESTUTIL_HPP_INCLUDED__ #if defined ZMQ_CUSTOM_PLATFORM_HPP #include "platform.hpp" #else #include "../src/platform.hpp" #endif #include "../include/zmq.h" #include "../src/stdint.hpp" // For AF_INET and IPPROTO_TCP #if defined _WIN32 #include "../src/windows.hpp" #if defined(__MINGW32__) #include #endif #else #include #include #include #include #include #endif // This defines the settle time used in tests; raise this if we // get test failures on slower systems due to binds/connects not // settled. Tested to work reliably at 1 msec on a fast PC. #define SETTLE_TIME 300 // In msec // Commonly used buffer size for ZMQ_LAST_ENDPOINT // this used to be sizeof ("tcp://[::ffff:127.127.127.127]:65536"), but this // may be too short for ipc wildcard binds, e.g. #define MAX_SOCKET_STRING 256 // We need to test codepaths with non-random bind ports. List them here to // keep them unique, to allow parallel test runs. #define ENDPOINT_0 "tcp://127.0.0.1:5555" #define ENDPOINT_1 "tcp://127.0.0.1:5556" #define ENDPOINT_2 "tcp://127.0.0.1:5557" #define ENDPOINT_3 "tcp://127.0.0.1:5558" #define ENDPOINT_4 "udp://127.0.0.1:5559" #define ENDPOINT_5 "udp://127.0.0.1:5560" #define PORT_6 5561 // For tests that mock ZMTP const uint8_t zmtp_greeting_null[64] = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0x7f, 3, 0, 'N', 'U', 'L', 'L', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; const uint8_t zmtp_greeting_curve[64] = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0x7f, 3, 0, 'C', 'U', 'R', 'V', 'E', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; const uint8_t zmtp_ready_dealer[43] = { 4, 41, 5, 'R', 'E', 'A', 'D', 'Y', 11, 'S', 'o', 'c', 'k', 'e', 't', '-', 'T', 'y', 'p', 'e', 0, 0, 0, 6, 'D', 'E', 'A', 'L', 'E', 'R', 8, 'I', 'd', 'e', 'n', 't', 'i', 't', 'y', 0, 0, 0, 0}; const uint8_t zmtp_ready_xpub[28] = { 4, 26, 5, 'R', 'E', 'A', 'D', 'Y', 11, 'S', 'o', 'c', 'k', 'e', 't', '-', 'T', 'y', 'p', 'e', 0, 0, 0, 4, 'X', 'P', 'U', 'B'}; const uint8_t zmtp_ready_sub[27] = { 4, 25, 5, 'R', 'E', 'A', 'D', 'Y', 11, 'S', 'o', 'c', 'k', 'e', 't', '-', 'T', 'y', 'p', 'e', 0, 0, 0, 3, 'S', 'U', 'B'}; #undef NDEBUG #ifndef MSG_NOSIGNAL #define MSG_NOSIGNAL 0 #endif // duplicated from fd.hpp #ifdef ZMQ_HAVE_WINDOWS #ifndef NOMINMAX #define NOMINMAX // Macros min(a,b) and max(a,b) #endif #include #include #include #define close closesocket typedef int socket_size_t; inline const char *as_setsockopt_opt_t (const void *opt) { return static_cast (opt); } #else typedef size_t socket_size_t; inline const void *as_setsockopt_opt_t (const void *opt_) { return opt_; } #endif // duplicated from fd.hpp typedef zmq_fd_t fd_t; #ifdef ZMQ_HAVE_WINDOWS #if defined _MSC_VER && _MSC_VER <= 1400 enum { retired_fd = (zmq_fd_t) (~0) }; #else enum #if _MSC_VER >= 1800 : zmq_fd_t #endif { retired_fd = INVALID_SOCKET }; #endif #else enum { retired_fd = -1 }; #endif // In MSVC prior to v14, snprintf is not available // The closest implementation is the _snprintf_s function #if defined _MSC_VER && _MSC_VER < 1900 #define snprintf(buffer_, count_, format_, ...) \ _snprintf_s (buffer_, count_, _TRUNCATE, format_, __VA_ARGS__) #endif #define LIBZMQ_UNUSED(object) (void) object // Bounce a message from client to server and back // For REQ/REP or DEALER/DEALER pairs only void bounce (void *server_, void *client_); // Same as bounce, but expect messages to never arrive // for security or subscriber reasons. void expect_bounce_fail (void *server_, void *client_); // Receive 0MQ string from socket and convert into C string // Caller must free returned string. Returns NULL if the context // is being terminated. char *s_recv (void *socket_); bool streq (const char *lhs, const char *rhs); bool strneq (const char *lhs, const char *rhs); extern const char *SEQ_END; // Sends a message composed of frames that are C strings or null frames. // The list must be terminated by SEQ_END. // Example: s_send_seq (req, "ABC", 0, "DEF", SEQ_END); void s_send_seq (void *socket_, ...); // Receives message a number of frames long and checks that the frames have // the given data which can be either C strings or 0 for a null frame. // The list must be terminated by SEQ_END. // Example: s_recv_seq (rep, "ABC", 0, "DEF", SEQ_END); void s_recv_seq (void *socket_, ...); // Sets a zero linger period on a socket and closes it. void close_zero_linger (void *socket_); // Setups the test environment. Must be called at the beginning of each test // executable. On POSIX systems, it sets an alarm to the specified number of // seconds, after which the test will be killed. Set to 0 to disable this // timeout. void setup_test_environment (int timeout_seconds_ = 60); // Provide portable millisecond sleep // http://www.cplusplus.com/forum/unices/60161/ // http://en.cppreference.com/w/cpp/thread/sleep_for void msleep (int milliseconds_); // check if IPv6 is available (0/false if not, 1/true if it is) // only way to reliably check is to actually open a socket and try to bind it int is_ipv6_available (void); // check if tipc is available (0/false if not, 1/true if it is) // only way to reliably check is to actually open a socket and try to bind it // as it depends on a non-default kernel module to be already loaded int is_tipc_available (void); // Wrapper around 'inet_pton' for systems that don't support it (e.g. Windows // XP) int test_inet_pton (int af_, const char *src_, void *dst_); // Binds an ipv4 BSD socket to an ephemeral port, returns the compiled sockaddr struct sockaddr_in bind_bsd_socket (int socket); // Some custom definitions in addition to IPPROTO_TCP and IPPROTO_UDP #define IPPROTO_WS 10000 #define IPPROTO_WSS 10001 // Connects a BSD socket to the ZMQ endpoint. Works with ipv4/ipv6/unix. fd_t connect_socket (const char *endpoint_, const int af_ = AF_INET, const int protocol_ = IPPROTO_TCP); // Binds a BSD socket to an ephemeral port, returns the file descriptor. // The resulting ZMQ endpoint will be stored in my_endpoint, including the protocol // prefix, so ensure it is writable and of appropriate size. // Works with ipv4/ipv6/unix. With unix sockets address_/port_ can be empty and // my_endpoint_ will contain a random path. fd_t bind_socket_resolve_port (const char *address_, const char *port_, char *my_endpoint_, const int af_ = AF_INET, const int protocol_ = IPPROTO_TCP); int fuzzer_corpus_encode (const char *filename, uint8_t ***data, size_t **len, size_t *num_cases); #endif