mirror of
https://github.com/zeromq/libzmq.git
synced 2025-03-12 09:06:26 +00:00
Problem: using BSD sockets in test is duplicated across many tests
Solution: refactor in testutil.lib, so that they can be used for fuzzers too
This commit is contained in:
parent
c81a973cd8
commit
4f35d1af1a
@ -226,21 +226,7 @@ static void test_heartbeat_timeout (int server_type_, int mock_ping_)
|
||||
prep_server_socket (!mock_ping_, 0, &server, &server_mon, my_endpoint,
|
||||
MAX_SOCKET_STRING, server_type_);
|
||||
|
||||
struct sockaddr_in ip4addr;
|
||||
raw_socket s;
|
||||
|
||||
ip4addr.sin_family = AF_INET;
|
||||
ip4addr.sin_port = htons (atoi (strrchr (my_endpoint, ':') + 1));
|
||||
#if defined(ZMQ_HAVE_WINDOWS) && (_WIN32_WINNT < 0x0600)
|
||||
ip4addr.sin_addr.s_addr = inet_addr ("127.0.0.1");
|
||||
#else
|
||||
inet_pton (AF_INET, "127.0.0.1", &ip4addr.sin_addr);
|
||||
#endif
|
||||
|
||||
s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
rc = TEST_ASSERT_SUCCESS_RAW_ERRNO (
|
||||
connect (s, (struct sockaddr *) &ip4addr, sizeof ip4addr));
|
||||
TEST_ASSERT_GREATER_THAN_INT (-1, rc);
|
||||
fd_t s = connect_socket (my_endpoint);
|
||||
|
||||
// Mock a ZMTP 3 client so we can forcibly time out a connection
|
||||
mock_handshake (s, mock_ping_);
|
||||
|
@ -19,17 +19,6 @@
|
||||
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
#if defined(ZMQ_HAVE_WINDOWS)
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <stdexcept>
|
||||
#define close closesocket
|
||||
typedef SOCKET raw_socket;
|
||||
#else
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
typedef int raw_socket;
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -67,7 +56,7 @@ static int get_monitor_event (void *monitor_)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void recv_with_retry (raw_socket fd_, char *buffer_, int bytes_)
|
||||
static void recv_with_retry (fd_t fd_, char *buffer_, int bytes_)
|
||||
{
|
||||
int received = 0;
|
||||
while (true) {
|
||||
@ -81,7 +70,7 @@ static void recv_with_retry (raw_socket fd_, char *buffer_, int bytes_)
|
||||
}
|
||||
}
|
||||
|
||||
static void mock_handshake (raw_socket fd_, bool sub_command, bool mock_pub)
|
||||
static void mock_handshake (fd_t fd_, bool sub_command, bool mock_pub)
|
||||
{
|
||||
const uint8_t zmtp_greeting[33] = {0xff, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0x7f, 3, 0, 'N', 'U', 'L', 'L', 0};
|
||||
@ -158,21 +147,7 @@ static void test_mock_pub_sub (bool sub_command_, bool mock_pub_)
|
||||
prep_server_socket (&server, &server_mon, my_endpoint, MAX_SOCKET_STRING,
|
||||
mock_pub_ ? ZMQ_SUB : ZMQ_XPUB);
|
||||
|
||||
struct sockaddr_in ip4addr;
|
||||
raw_socket s;
|
||||
|
||||
ip4addr.sin_family = AF_INET;
|
||||
ip4addr.sin_port = htons (atoi (strrchr (my_endpoint, ':') + 1));
|
||||
#if defined(ZMQ_HAVE_WINDOWS) && (_WIN32_WINNT < 0x0600)
|
||||
ip4addr.sin_addr.s_addr = inet_addr ("127.0.0.1");
|
||||
#else
|
||||
inet_pton (AF_INET, "127.0.0.1", &ip4addr.sin_addr);
|
||||
#endif
|
||||
|
||||
s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
rc = TEST_ASSERT_SUCCESS_RAW_ERRNO (
|
||||
connect (s, (struct sockaddr *) &ip4addr, sizeof ip4addr));
|
||||
TEST_ASSERT_GREATER_THAN_INT (-1, rc);
|
||||
fd_t s = connect_socket (my_endpoint);
|
||||
|
||||
// Mock a ZMTP 3 client so we can forcibly try sub commands
|
||||
mock_handshake (s, sub_command_, mock_pub_);
|
||||
|
@ -47,17 +47,6 @@
|
||||
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_security.hpp"
|
||||
#if defined(ZMQ_HAVE_WINDOWS)
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <stdexcept>
|
||||
#define close closesocket
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <unity.h>
|
||||
|
||||
#include "../src/tweetnacl.h"
|
||||
@ -223,34 +212,10 @@ void test_curve_security_with_plain_client_credentials ()
|
||||
expect_zmtp_mechanism_mismatch (client, my_endpoint, server, server_mon);
|
||||
}
|
||||
|
||||
fd_t connect_vanilla_socket (char *my_endpoint_)
|
||||
{
|
||||
fd_t s;
|
||||
struct sockaddr_in ip4addr;
|
||||
|
||||
unsigned short int port;
|
||||
int rc = sscanf (my_endpoint_, "tcp://127.0.0.1:%hu", &port);
|
||||
TEST_ASSERT_EQUAL_INT (1, rc);
|
||||
|
||||
ip4addr.sin_family = AF_INET;
|
||||
ip4addr.sin_port = htons (port);
|
||||
#if defined(ZMQ_HAVE_WINDOWS) && (_WIN32_WINNT < 0x0600)
|
||||
ip4addr.sin_addr.s_addr = inet_addr ("127.0.0.1");
|
||||
#else
|
||||
inet_pton (AF_INET, "127.0.0.1", &ip4addr.sin_addr);
|
||||
#endif
|
||||
|
||||
s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
rc = connect (s, reinterpret_cast<struct sockaddr *> (&ip4addr),
|
||||
sizeof (ip4addr));
|
||||
TEST_ASSERT_GREATER_THAN_INT (-1, rc);
|
||||
return s;
|
||||
}
|
||||
|
||||
void test_curve_security_unauthenticated_message ()
|
||||
{
|
||||
// Unauthenticated messages from a vanilla socket shouldn't be received
|
||||
fd_t s = connect_vanilla_socket (my_endpoint);
|
||||
fd_t s = connect_socket (my_endpoint);
|
||||
// send anonymous ZMTP/1.0 greeting
|
||||
send (s, "\x01\x00", 2, 0);
|
||||
// send sneaky message that shouldn't be received
|
||||
@ -288,7 +253,7 @@ void send_greeting (fd_t s_)
|
||||
|
||||
void test_curve_security_invalid_hello_wrong_length ()
|
||||
{
|
||||
fd_t s = connect_vanilla_socket (my_endpoint);
|
||||
fd_t s = connect_socket (my_endpoint);
|
||||
|
||||
// send GREETING
|
||||
send_greeting (s);
|
||||
@ -355,7 +320,7 @@ template <size_t N> void send_command (fd_t s_, char (&command_)[N])
|
||||
|
||||
void test_curve_security_invalid_hello_command_name ()
|
||||
{
|
||||
fd_t s = connect_vanilla_socket (my_endpoint);
|
||||
fd_t s = connect_socket (my_endpoint);
|
||||
|
||||
send_greeting (s);
|
||||
|
||||
@ -377,7 +342,7 @@ void test_curve_security_invalid_hello_command_name ()
|
||||
|
||||
void test_curve_security_invalid_hello_version ()
|
||||
{
|
||||
fd_t s = connect_vanilla_socket (my_endpoint);
|
||||
fd_t s = connect_socket (my_endpoint);
|
||||
|
||||
send_greeting (s);
|
||||
|
||||
@ -429,7 +394,7 @@ void recv_greeting (fd_t fd_)
|
||||
fd_t connect_exchange_greeting_and_send_hello (
|
||||
char *my_endpoint_, zmq::curve_client_tools_t &tools_)
|
||||
{
|
||||
fd_t s = connect_vanilla_socket (my_endpoint_);
|
||||
fd_t s = connect_socket (my_endpoint_);
|
||||
|
||||
send_greeting (s);
|
||||
recv_greeting (s);
|
||||
|
@ -30,17 +30,6 @@
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_monitoring.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
#if defined(ZMQ_HAVE_WINDOWS)
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <stdexcept>
|
||||
#define close closesocket
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -253,23 +242,7 @@ void test_plain_creds ()
|
||||
// Unauthenticated messages from a vanilla socket shouldn't be received
|
||||
void test_vanilla_socket ()
|
||||
{
|
||||
struct sockaddr_in ip4addr;
|
||||
int s;
|
||||
unsigned short int port;
|
||||
int rc = sscanf (my_endpoint, "tcp://127.0.0.1:%hu", &port);
|
||||
TEST_ASSERT_EQUAL_INT (1, rc);
|
||||
ip4addr.sin_family = AF_INET;
|
||||
ip4addr.sin_port = htons (port);
|
||||
#if defined(ZMQ_HAVE_WINDOWS) && (_WIN32_WINNT < 0x0600)
|
||||
ip4addr.sin_addr.s_addr = inet_addr ("127.0.0.1");
|
||||
#else
|
||||
inet_pton (AF_INET, "127.0.0.1", &ip4addr.sin_addr);
|
||||
#endif
|
||||
|
||||
s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
rc = connect (s, reinterpret_cast<struct sockaddr *> (&ip4addr),
|
||||
sizeof (ip4addr));
|
||||
TEST_ASSERT_GREATER_THAN (-1, rc);
|
||||
fd_t s = connect_socket (my_endpoint);
|
||||
// send anonymous ZMTP/1.0 greeting
|
||||
send (s, "\x01\x00", 2, 0);
|
||||
// send sneaky message that shouldn't be received
|
||||
|
@ -169,25 +169,8 @@ void test_vanilla_socket ()
|
||||
char my_endpoint[MAX_SOCKET_STRING];
|
||||
bind_loopback_ipv4 (server, my_endpoint, sizeof my_endpoint);
|
||||
|
||||
struct sockaddr_in ip4addr;
|
||||
fd_t s;
|
||||
fd_t s = connect_socket (my_endpoint);
|
||||
|
||||
unsigned short int port;
|
||||
int rc = sscanf (my_endpoint, "tcp://127.0.0.1:%hu", &port);
|
||||
TEST_ASSERT_EQUAL_INT (1, rc);
|
||||
|
||||
ip4addr.sin_family = AF_INET;
|
||||
ip4addr.sin_port = htons (port);
|
||||
#if defined(ZMQ_HAVE_WINDOWS) && (_WIN32_WINNT < 0x0600)
|
||||
ip4addr.sin_addr.s_addr = inet_addr ("127.0.0.1");
|
||||
#else
|
||||
inet_pton (AF_INET, "127.0.0.1", &ip4addr.sin_addr);
|
||||
#endif
|
||||
|
||||
s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
rc = connect (s, reinterpret_cast<struct sockaddr *> (&ip4addr),
|
||||
sizeof ip4addr);
|
||||
TEST_ASSERT_GREATER_THAN_INT (-1, rc);
|
||||
// send anonymous ZMTP/1.0 greeting
|
||||
send (s, "\x01\x00", 2, 0);
|
||||
// send sneaky message that shouldn't be received
|
||||
|
@ -30,18 +30,6 @@
|
||||
#include "testutil.hpp"
|
||||
#include "testutil_unity.hpp"
|
||||
|
||||
#if defined(ZMQ_HAVE_WINDOWS)
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <stdexcept>
|
||||
#define close closesocket
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -195,25 +183,7 @@ void test_plain_wrong_credentials_fails ()
|
||||
void test_plain_vanilla_socket ()
|
||||
{
|
||||
// Unauthenticated messages from a vanilla socket shouldn't be received
|
||||
struct sockaddr_in ip4addr;
|
||||
fd_t s;
|
||||
|
||||
unsigned short int port;
|
||||
int rc = sscanf (my_endpoint, "tcp://127.0.0.1:%hu", &port);
|
||||
TEST_ASSERT_EQUAL_INT (1, rc);
|
||||
|
||||
ip4addr.sin_family = AF_INET;
|
||||
ip4addr.sin_port = htons (port);
|
||||
#if defined(ZMQ_HAVE_WINDOWS) && (_WIN32_WINNT < 0x0600)
|
||||
ip4addr.sin_addr.s_addr = inet_addr ("127.0.0.1");
|
||||
#else
|
||||
inet_pton (AF_INET, "127.0.0.1", &ip4addr.sin_addr);
|
||||
#endif
|
||||
|
||||
s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
rc = connect (s, reinterpret_cast<struct sockaddr *> (&ip4addr),
|
||||
sizeof (ip4addr));
|
||||
TEST_ASSERT_GREATER_THAN_INT (-1, rc);
|
||||
fd_t s = connect_socket (my_endpoint);
|
||||
// send anonymous ZMTP/1.0 greeting
|
||||
send (s, "\x01\x00", 2, 0);
|
||||
// send sneaky message that shouldn't be received
|
||||
|
@ -105,21 +105,10 @@ void *setup_socks_server (char *socks_server_address,
|
||||
int socks_server_address_len)
|
||||
{
|
||||
fprintf (stderr, "socks_server: setup socks server\n");
|
||||
int server_fd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
TEST_ASSERT_NOT_EQUAL (-1, server_fd);
|
||||
int flag = 1;
|
||||
int res;
|
||||
#ifdef _WIN32
|
||||
res = setsockopt (server_fd, SOL_SOCKET, SO_REUSEADDR, (const char *) &flag,
|
||||
sizeof (int));
|
||||
#else
|
||||
res = setsockopt (server_fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof (int));
|
||||
#endif
|
||||
TEST_ASSERT_SUCCESS_RAW_ERRNO (res);
|
||||
struct sockaddr_in saddr = bind_bsd_socket (server_fd);
|
||||
int nbytes = snprintf (socks_server_address, socks_server_address_len,
|
||||
"127.0.0.1:%d", ntohs (saddr.sin_port));
|
||||
TEST_ASSERT (nbytes >= 0 && nbytes < socks_server_address_len);
|
||||
int server_fd =
|
||||
bind_socket_resolve_port ("127.0.0.1", "0", socks_server_address);
|
||||
memmove (socks_server_address, strchr (socks_server_address, '/') + 2,
|
||||
strlen (strchr (socks_server_address, '/') + 1));
|
||||
fprintf (stderr, "socks_server: bound to: tcp://%s\n",
|
||||
socks_server_address);
|
||||
return (void *) (intptr_t) server_fd;
|
||||
|
@ -32,12 +32,6 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
SETUP_TEARDOWN_TESTCONTEXT
|
||||
|
||||
void test_stream_exceeds_buffer ()
|
||||
@ -47,16 +41,7 @@ void test_stream_exceeds_buffer ()
|
||||
unsigned char rcvbuf[msgsize];
|
||||
char my_endpoint[MAX_SOCKET_STRING];
|
||||
|
||||
int server_sock =
|
||||
TEST_ASSERT_SUCCESS_RAW_ERRNO (socket (AF_INET, SOCK_STREAM, 0));
|
||||
int enable = 1;
|
||||
TEST_ASSERT_SUCCESS_RAW_ERRNO (setsockopt (server_sock, SOL_SOCKET,
|
||||
SO_REUSEADDR, (char *) &enable,
|
||||
sizeof (enable)));
|
||||
struct sockaddr_in saddr = bind_bsd_socket (server_sock);
|
||||
TEST_ASSERT_SUCCESS_RAW_ERRNO (listen (server_sock, 1));
|
||||
|
||||
sprintf (my_endpoint, "tcp://127.0.0.1:%d", ntohs (saddr.sin_port));
|
||||
int server_sock = bind_socket_resolve_port ("127.0.0.1", "0", my_endpoint);
|
||||
|
||||
void *zsock = test_context_socket (ZMQ_STREAM);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (zsock, my_endpoint));
|
||||
|
@ -37,33 +37,12 @@
|
||||
SETUP_TEARDOWN_TESTCONTEXT
|
||||
|
||||
#if !defined(ZMQ_HAVE_WINDOWS)
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int setup_socket_and_set_fd (void *zmq_socket_,
|
||||
int af_,
|
||||
int protocol_,
|
||||
const sockaddr *addr_,
|
||||
size_t addr_len_)
|
||||
void pre_allocate_sock_tcp (void *socket_, char *my_endpoint_)
|
||||
{
|
||||
const int s_pre =
|
||||
TEST_ASSERT_SUCCESS_ERRNO (socket (af_, SOCK_STREAM, protocol_));
|
||||
|
||||
if (af_ == AF_INET) {
|
||||
int flag = 1;
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
setsockopt (s_pre, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof (int)));
|
||||
}
|
||||
|
||||
TEST_ASSERT_SUCCESS_ERRNO (bind (s_pre, addr_, addr_len_));
|
||||
TEST_ASSERT_SUCCESS_ERRNO (listen (s_pre, SOMAXCONN));
|
||||
|
||||
fd_t s = bind_socket_resolve_port ("127.0.0.1", "0", my_endpoint_);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (zmq_socket_, ZMQ_USE_FD, &s_pre, sizeof (s_pre)));
|
||||
|
||||
return s_pre;
|
||||
zmq_setsockopt (socket_, ZMQ_USE_FD, &s, sizeof (s)));
|
||||
}
|
||||
|
||||
typedef void (*pre_allocate_sock_fun_t) (void *, char *);
|
||||
@ -166,41 +145,6 @@ void test_client_server (pre_allocate_sock_fun_t pre_allocate_sock_fun_)
|
||||
#endif
|
||||
}
|
||||
|
||||
uint16_t pre_allocate_sock_tcp_int (void *zmq_socket_,
|
||||
const char *address_,
|
||||
const char *port_)
|
||||
{
|
||||
struct addrinfo *addr, hint;
|
||||
hint.ai_flags = 0;
|
||||
hint.ai_family = AF_INET;
|
||||
hint.ai_socktype = SOCK_STREAM;
|
||||
hint.ai_protocol = IPPROTO_TCP;
|
||||
hint.ai_addrlen = 0;
|
||||
hint.ai_canonname = NULL;
|
||||
hint.ai_addr = NULL;
|
||||
hint.ai_next = NULL;
|
||||
|
||||
TEST_ASSERT_SUCCESS_ERRNO (getaddrinfo (address_, port_, &hint, &addr));
|
||||
|
||||
const int s_pre = setup_socket_and_set_fd (
|
||||
zmq_socket_, AF_INET, IPPROTO_TCP, addr->ai_addr, addr->ai_addrlen);
|
||||
|
||||
struct sockaddr_in sin;
|
||||
socklen_t len = sizeof (sin);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
getsockname (s_pre, (struct sockaddr *) &sin, &len));
|
||||
|
||||
freeaddrinfo (addr);
|
||||
|
||||
return ntohs (sin.sin_port);
|
||||
}
|
||||
|
||||
void pre_allocate_sock_tcp (void *socket_, char *my_endpoint_)
|
||||
{
|
||||
const uint16_t port = pre_allocate_sock_tcp_int (socket_, "127.0.0.1", "0");
|
||||
sprintf (my_endpoint_, "tcp://127.0.0.1:%u", port);
|
||||
}
|
||||
|
||||
void test_req_rep_tcp ()
|
||||
{
|
||||
test_req_rep (pre_allocate_sock_tcp);
|
||||
@ -218,38 +162,14 @@ void test_client_server_tcp ()
|
||||
#endif
|
||||
}
|
||||
|
||||
void pre_allocate_sock_ipc_int (void *zmq_socket_, const char *path_)
|
||||
{
|
||||
struct sockaddr_un addr;
|
||||
addr.sun_family = AF_UNIX;
|
||||
strcpy (addr.sun_path, path_);
|
||||
|
||||
// TODO check return value of unlink
|
||||
unlink (path_);
|
||||
|
||||
setup_socket_and_set_fd (zmq_socket_, AF_UNIX, 0,
|
||||
reinterpret_cast<struct sockaddr *> (&addr),
|
||||
sizeof (struct sockaddr_un));
|
||||
}
|
||||
|
||||
char ipc_endpoint[16];
|
||||
char ipc_endpoint[MAX_SOCKET_STRING] = "";
|
||||
|
||||
void pre_allocate_sock_ipc (void *sb_, char *my_endpoint_)
|
||||
{
|
||||
strcpy (ipc_endpoint, "tmpXXXXXX");
|
||||
|
||||
#ifdef HAVE_MKDTEMP
|
||||
TEST_ASSERT_TRUE (mkdtemp (ipc_endpoint));
|
||||
strcat (ipc_endpoint, "/ipc");
|
||||
#else
|
||||
int fd = mkstemp (ipc_endpoint);
|
||||
TEST_ASSERT_TRUE (fd != -1);
|
||||
close (fd);
|
||||
#endif
|
||||
|
||||
pre_allocate_sock_ipc_int (sb_, ipc_endpoint);
|
||||
strcpy (my_endpoint_, "ipc://");
|
||||
strcat (my_endpoint_, ipc_endpoint);
|
||||
fd_t s = bind_socket_resolve_port ("", "", my_endpoint_, AF_UNIX, 0);
|
||||
TEST_ASSERT_SUCCESS_ERRNO (
|
||||
zmq_setsockopt (sb_, ZMQ_USE_FD, &s, sizeof (s)));
|
||||
strcpy (ipc_endpoint, strchr (my_endpoint_, '/') + 2);
|
||||
}
|
||||
|
||||
void test_req_rep_ipc ()
|
||||
@ -277,7 +197,7 @@ void test_client_server_ipc ()
|
||||
|
||||
int main ()
|
||||
{
|
||||
setup_test_environment ();
|
||||
setup_test_environment (0);
|
||||
|
||||
UNITY_BEGIN ();
|
||||
RUN_TEST (test_req_rep_tcp);
|
||||
|
@ -35,6 +35,10 @@
|
||||
#if defined _WIN32
|
||||
#include "../src/windows.hpp"
|
||||
#if defined _MSC_VER
|
||||
#if defined ZMQ_HAVE_IPC
|
||||
#include <direct.h>
|
||||
#include <afunix.h>
|
||||
#endif
|
||||
#include <crtdbg.h>
|
||||
#pragma warning(disable : 4996)
|
||||
// iphlpapi is needed for if_nametoindex (not on Windows XP)
|
||||
@ -55,6 +59,7 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/un.h>
|
||||
#if defined(ZMQ_HAVE_AIX)
|
||||
#include <sys/types.h>
|
||||
#include <sys/socketvar.h>
|
||||
@ -365,6 +370,147 @@ sockaddr_in bind_bsd_socket (int socket_)
|
||||
return saddr;
|
||||
}
|
||||
|
||||
fd_t connect_socket (const char *endpoint_, const int af_, const int protocol_)
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
// OSX is very opinionated and wants the size to match the AF family type
|
||||
socklen_t addr_len = sizeof (addr);
|
||||
const fd_t s_pre = socket (af_, SOCK_STREAM, protocol_);
|
||||
TEST_ASSERT_NOT_EQUAL (-1, s_pre);
|
||||
|
||||
if (af_ == AF_INET || af_ == AF_INET6) {
|
||||
const char *port = strrchr (endpoint_, ':') + 1;
|
||||
char address[MAX_SOCKET_STRING];
|
||||
// getaddrinfo does not like [x:y::z]
|
||||
if (*strchr (endpoint_, '/') + 2 == '[') {
|
||||
strcpy (address, strchr (endpoint_, '[') + 1);
|
||||
address[strlen (address) - strlen (port) - 2] = '\0';
|
||||
} else {
|
||||
strcpy (address, strchr (endpoint_, '/') + 2);
|
||||
address[strlen (address) - strlen (port) - 1] = '\0';
|
||||
}
|
||||
|
||||
struct addrinfo *in, hint;
|
||||
hint.ai_flags = AI_NUMERICSERV;
|
||||
hint.ai_family = af_;
|
||||
hint.ai_socktype = SOCK_STREAM;
|
||||
hint.ai_protocol = protocol_;
|
||||
hint.ai_addrlen = 0;
|
||||
hint.ai_canonname = NULL;
|
||||
hint.ai_addr = NULL;
|
||||
hint.ai_next = NULL;
|
||||
|
||||
TEST_ASSERT_SUCCESS_RAW_ZERO_ERRNO (
|
||||
getaddrinfo (address, port, &hint, &in));
|
||||
TEST_ASSERT_NOT_NULL (in);
|
||||
memcpy (&addr, in->ai_addr, in->ai_addrlen);
|
||||
addr_len = (socklen_t) in->ai_addrlen;
|
||||
freeaddrinfo (in);
|
||||
}
|
||||
#if defined(ZMQ_HAVE_IPC)
|
||||
else {
|
||||
struct sockaddr_un *un_addr = (struct sockaddr_un *) &addr;
|
||||
addr_len = sizeof (struct sockaddr_un);
|
||||
un_addr->sun_family = AF_UNIX;
|
||||
strcpy (un_addr->sun_path, endpoint_);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_ASSERT_SUCCESS_RAW_ERRNO (
|
||||
connect (s_pre, (struct sockaddr *) &addr, addr_len));
|
||||
|
||||
return s_pre;
|
||||
}
|
||||
|
||||
fd_t bind_socket_resolve_port (const char *address_,
|
||||
const char *port_,
|
||||
char *my_endpoint_,
|
||||
const int af_,
|
||||
const int protocol_)
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
// OSX is very opinionated and wants the size to match the AF family type
|
||||
socklen_t addr_len = sizeof (addr);
|
||||
const fd_t s_pre = socket (af_, SOCK_STREAM, protocol_);
|
||||
TEST_ASSERT_NOT_EQUAL (-1, s_pre);
|
||||
|
||||
if (af_ == AF_INET || af_ == AF_INET6) {
|
||||
#ifdef ZMQ_HAVE_WINDOWS
|
||||
const char flag = '\1';
|
||||
#elif defined ZMQ_HAVE_VXWORKS
|
||||
char flag = '\1';
|
||||
#else
|
||||
int flag = 1;
|
||||
#endif
|
||||
struct addrinfo *in, hint;
|
||||
hint.ai_flags = AI_NUMERICSERV;
|
||||
hint.ai_family = af_;
|
||||
hint.ai_socktype = protocol_ == IPPROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
|
||||
hint.ai_protocol = protocol_;
|
||||
hint.ai_addrlen = 0;
|
||||
hint.ai_canonname = NULL;
|
||||
hint.ai_addr = NULL;
|
||||
hint.ai_next = NULL;
|
||||
|
||||
TEST_ASSERT_SUCCESS_RAW_ERRNO (
|
||||
setsockopt (s_pre, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof (int)));
|
||||
TEST_ASSERT_SUCCESS_RAW_ZERO_ERRNO (
|
||||
getaddrinfo (address_, port_, &hint, &in));
|
||||
TEST_ASSERT_NOT_NULL (in);
|
||||
memcpy (&addr, in->ai_addr, in->ai_addrlen);
|
||||
addr_len = (socklen_t) in->ai_addrlen;
|
||||
freeaddrinfo (in);
|
||||
}
|
||||
#if defined(ZMQ_HAVE_IPC)
|
||||
else {
|
||||
struct sockaddr_un *un_addr = (struct sockaddr_un *) &addr;
|
||||
addr_len = sizeof (struct sockaddr_un);
|
||||
un_addr->sun_family = AF_UNIX;
|
||||
#if defined ZMQ_HAVE_WINDOWS
|
||||
char buffer[MAX_PATH] = "";
|
||||
|
||||
TEST_ASSERT_SUCCESS_RAW_ERRNO (tmpnam_s (buffer));
|
||||
TEST_ASSERT_SUCCESS_RAW_ERRNO (_mkdir (buffer));
|
||||
strcat (buffer, "/ipc");
|
||||
#else
|
||||
char buffer[PATH_MAX] = "";
|
||||
strcpy (buffer, "tmpXXXXXX");
|
||||
#ifdef HAVE_MKDTEMP
|
||||
TEST_ASSERT_TRUE (mkdtemp (buffer));
|
||||
strcat (buffer, "/socket");
|
||||
#else
|
||||
int fd = mkstemp (buffer);
|
||||
TEST_ASSERT_TRUE (fd != -1);
|
||||
close (fd);
|
||||
#endif
|
||||
#endif
|
||||
strcpy (un_addr->sun_path, buffer);
|
||||
memcpy (my_endpoint_, "ipc://", 7);
|
||||
strcat (my_endpoint_, buffer);
|
||||
|
||||
// TODO check return value of unlink
|
||||
unlink (buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_ASSERT_SUCCESS_RAW_ERRNO (
|
||||
bind (s_pre, (struct sockaddr *) &addr, addr_len));
|
||||
TEST_ASSERT_SUCCESS_RAW_ERRNO (listen (s_pre, SOMAXCONN));
|
||||
|
||||
if (af_ == AF_INET || af_ == AF_INET6) {
|
||||
addr_len = sizeof (struct sockaddr_storage);
|
||||
TEST_ASSERT_SUCCESS_RAW_ERRNO (
|
||||
getsockname (s_pre, (struct sockaddr *) &addr, &addr_len));
|
||||
sprintf (my_endpoint_, "%s://%s:%u",
|
||||
protocol_ == IPPROTO_TCP ? "tcp" : "udp", address_,
|
||||
af_ == AF_INET
|
||||
? ntohs (((struct sockaddr_in *) &addr)->sin_port)
|
||||
: ntohs (((struct sockaddr_in6 *) &addr)->sin6_port));
|
||||
}
|
||||
|
||||
return s_pre;
|
||||
}
|
||||
|
||||
bool streq (const char *lhs_, const char *rhs_)
|
||||
{
|
||||
return strcmp (lhs_, rhs_) == 0;
|
||||
|
@ -38,6 +38,14 @@
|
||||
#include "../include/zmq.h"
|
||||
#include "../src/stdint.hpp"
|
||||
|
||||
// For AF_INET and IPPROTO_TCP
|
||||
#if defined _WIN32
|
||||
#include "../src/windows.hpp"
|
||||
#else
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#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.
|
||||
@ -172,4 +180,20 @@ 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);
|
||||
|
||||
// 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);
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user