void test_req_message_format (void *ctx) { void *req = zmq_socket (ctx, ZMQ_REQ); assert (req); void *router = zmq_socket (ctx, ZMQ_ROUTER); assert (router); int rc = zmq_bind (req, bind_address); assert (rc == 0); size_t len = MAX_SOCKET_STRING; rc = zmq_getsockopt (req, ZMQ_LAST_ENDPOINT, connect_address, &len); assert (rc == 0); rc = zmq_connect (router, connect_address); assert (rc == 0); // Send a multi-part request. s_send_seq (req, "ABC", "DEF", SEQ_END); zmq_msg_t msg; zmq_msg_init (&msg); // Receive peer identity rc = zmq_msg_recv (&msg, router, 0); assert (rc != -1); assert (zmq_msg_size (&msg) > 0); zmq_msg_t peer_id_msg; zmq_msg_init (&peer_id_msg); zmq_msg_copy (&peer_id_msg, &msg); int more = 0; size_t more_size = sizeof (more); rc = zmq_getsockopt (router, ZMQ_RCVMORE, &more, &more_size); assert (rc == 0); assert (more); // Receive the rest. s_recv_seq (router, 0, "ABC", "DEF", SEQ_END); // Send back a single-part reply. rc = zmq_msg_send (&peer_id_msg, router, ZMQ_SNDMORE); assert (rc != -1); s_send_seq (router, 0, "GHI", SEQ_END); // Receive reply. s_recv_seq (req, "GHI", SEQ_END); rc = zmq_msg_close (&msg); assert (rc == 0); rc = zmq_msg_close (&peer_id_msg); assert (rc == 0); close_zero_linger (req); close_zero_linger (router); // Wait for disconnects. msleep (SETTLE_TIME); }
void test_envelope (void *ctx) { void *rep = zmq_socket (ctx, ZMQ_REP); assert (rep); int rc = zmq_bind (rep, bind_address); assert (rc == 0); void *dealer = zmq_socket (ctx, ZMQ_DEALER); assert (dealer); rc = zmq_connect (dealer, connect_address); assert (rc == 0); // minimal envelope s_send_seq (dealer, 0, "A", SEQ_END); s_recv_seq (rep, "A", SEQ_END); s_send_seq (rep, "A", SEQ_END); s_recv_seq (dealer, 0, "A", SEQ_END); // big envelope s_send_seq (dealer, "X", "Y", 0, "A", SEQ_END); s_recv_seq (rep, "A", SEQ_END); s_send_seq (rep, "A", SEQ_END); s_recv_seq (dealer, "X", "Y", 0, "A", SEQ_END); close_zero_linger (rep); close_zero_linger (dealer); // Wait for disconnects. rc = zmq_poll (0, 0, 100); assert (rc == 0); }
void test_fair_queue_in (void *ctx) { void *receiver = zmq_socket (ctx, ZMQ_DEALER); assert (receiver); int timeout = 250; int rc = zmq_setsockopt (receiver, ZMQ_RCVTIMEO, &timeout, sizeof (int)); assert (rc == 0); rc = zmq_bind (receiver, bind_address); assert (rc == 0); const size_t services = 5; void *senders [services]; for (size_t peer = 0; peer < services; ++peer) { senders [peer] = zmq_socket (ctx, ZMQ_DEALER); assert (senders [peer]); rc = zmq_setsockopt (senders [peer], ZMQ_RCVTIMEO, &timeout, sizeof (int)); assert (rc == 0); rc = zmq_connect (senders [peer], connect_address); assert (rc == 0); } zmq_msg_t msg; rc = zmq_msg_init (&msg); assert (rc == 0); s_send_seq (senders [0], "A", SEQ_END); s_recv_seq (receiver, "A", SEQ_END); s_send_seq (senders [0], "A", SEQ_END); s_recv_seq (receiver, "A", SEQ_END); // send our requests for (size_t peer = 0; peer < services; ++peer) s_send_seq (senders [peer], "B", SEQ_END); // Wait for data. rc = zmq_poll (0, 0, 50); assert (rc == 0); // handle the requests for (size_t peer = 0; peer < services; ++peer) s_recv_seq (receiver, "B", SEQ_END); rc = zmq_msg_close (&msg); assert (rc == 0); close_zero_linger (receiver); for (size_t peer = 0; peer < services; ++peer) close_zero_linger (senders [peer]); // Wait for disconnects. rc = zmq_poll (0, 0, 100); assert (rc == 0); }
static void run_test (int opt, T optval, int expected_error, int bounce_test) { int rc; void *ctx = zmq_ctx_new (); assert (ctx); void *sb = zmq_socket (ctx, ZMQ_DEALER); assert (sb); if (opt) { rc = zmq_setsockopt(sb, opt, &optval, sizeof (optval)); if (expected_error) { assert (rc == -1); assert (zmq_errno () == expected_error); } else { assert (rc == 0); } } void *sc = zmq_socket (ctx, ZMQ_DEALER); assert (sc); // If a test fails, don't hang for too long int timeout = 2500; rc = zmq_setsockopt (sb, ZMQ_RCVTIMEO, &timeout, sizeof (int)); assert (rc == 0); rc = zmq_setsockopt (sb, ZMQ_SNDTIMEO, &timeout, sizeof (int)); assert (rc == 0); rc = zmq_setsockopt (sc, ZMQ_RCVTIMEO, &timeout, sizeof (int)); assert (rc == 0); rc = zmq_setsockopt (sc, ZMQ_SNDTIMEO, &timeout, sizeof (int)); assert (rc == 0); int interval = -1; rc = zmq_setsockopt (sc, ZMQ_RECONNECT_IVL, &interval, sizeof (int)); assert (rc == 0); if (bounce_test) { const char* endpoint = "ipc://test_filter_ipc.sock"; int rc = zmq_bind (sb, endpoint); assert (rc == 0); rc = zmq_connect (sc, endpoint); assert (rc == 0); if (bounce_test > 0) bounce (sb, sc); else bounce_fail (sb, sc); } close_zero_linger (sc); close_zero_linger (sb); rc = zmq_ctx_term (ctx); assert (rc == 0); }
int main (void) { setup_test_environment(); size_t len = MAX_SOCKET_STRING; char my_endpoint[MAX_SOCKET_STRING]; void *ctx = zmq_ctx_new (); assert (ctx); // Spawn ZAP handler // We create and bind ZAP socket in main thread to avoid case // where child thread does not start up fast enough. void *handler = zmq_socket (ctx, ZMQ_REP); assert (handler); int rc = zmq_bind (handler, "inproc://zeromq.zap.01"); assert (rc == 0); void *zap_thread = zmq_threadstart (&zap_handler, handler); void *server = zmq_socket (ctx, ZMQ_DEALER); assert (server); void *client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "DOMAIN", 6); assert (rc == 0); rc = zmq_bind (server, "tcp://127.0.0.1:*"); assert (rc == 0); rc = zmq_getsockopt (server, ZMQ_LAST_ENDPOINT, my_endpoint, &len); assert (rc == 0); rc = zmq_connect (client, my_endpoint); assert (rc == 0); s_send (client, "This is a message"); zmq_msg_t msg; zmq_msg_init (&msg); rc = zmq_msg_recv (&msg, server, 0); assert (rc != -1); assert (streq (zmq_msg_gets (&msg, "Hello"), "World")); assert (streq (zmq_msg_gets (&msg, "Socket-Type"), "DEALER")); assert (streq (zmq_msg_gets (&msg, "User-Id"), "anonymous")); assert (streq (zmq_msg_gets (&msg, "Peer-Address"), "127.0.0.1")); assert (zmq_msg_gets (&msg, "No Such") == NULL); assert (zmq_errno () == EINVAL); zmq_msg_close (&msg); close_zero_linger (client); close_zero_linger (server); // Shutdown rc = zmq_ctx_term (ctx); assert (rc == 0); // Wait until ZAP handler terminates zmq_threadclose (zap_thread); return 0; }
void test_round_robin_out (void *ctx) { void *dealer = zmq_socket (ctx, ZMQ_DEALER); assert (dealer); int rc = zmq_bind (dealer, bind_address); assert (rc == 0); const size_t services = 5; void *rep [services]; for (size_t peer = 0; peer < services; ++peer) { rep [peer] = zmq_socket (ctx, ZMQ_REP); assert (rep [peer]); int timeout = 250; rc = zmq_setsockopt (rep [peer], ZMQ_RCVTIMEO, &timeout, sizeof (int)); assert (rc == 0); rc = zmq_connect (rep [peer], connect_address); assert (rc == 0); } // Wait for connections. rc = zmq_poll (0, 0, 100); assert (rc == 0); // Send all requests for (size_t i = 0; i < services; ++i) s_send_seq (dealer, 0, "ABC", SEQ_END); // Expect every REP got one message zmq_msg_t msg; zmq_msg_init (&msg); for (size_t peer = 0; peer < services; ++peer) s_recv_seq (rep [peer], "ABC", SEQ_END); rc = zmq_msg_close (&msg); assert (rc == 0); close_zero_linger (dealer); for (size_t peer = 0; peer < services; ++peer) close_zero_linger (rep [peer]); // Wait for disconnects. rc = zmq_poll (0, 0, 100); assert (rc == 0); }
void test_push_round_robin_out (void *ctx) { void *push = zmq_socket (ctx, ZMQ_PUSH); assert (push); int rc = zmq_bind (push, bind_address); assert (rc == 0); const size_t services = 5; void *pulls [services]; for (size_t peer = 0; peer < services; ++peer) { pulls [peer] = zmq_socket (ctx, ZMQ_PULL); assert (pulls [peer]); int timeout = 100; rc = zmq_setsockopt (pulls [peer], ZMQ_RCVTIMEO, &timeout, sizeof (int)); assert (rc == 0); rc = zmq_connect (pulls [peer], connect_address); assert (rc == 0); } // Wait for connections. rc = zmq_poll (0, 0, 100); assert (rc == 0); // Send 2N messages for (size_t peer = 0; peer < services; ++peer) s_send_seq (push, "ABC", SEQ_END); for (size_t peer = 0; peer < services; ++peer) s_send_seq (push, "DEF", SEQ_END); // Expect every PULL got one of each for (size_t peer = 0; peer < services; ++peer) { s_recv_seq (pulls [peer], "ABC", SEQ_END); s_recv_seq (pulls [peer], "DEF", SEQ_END); } close_zero_linger (push); for (size_t peer = 0; peer < services; ++peer) close_zero_linger (pulls [peer]); // Wait for disconnects. rc = zmq_poll (0, 0, 100); assert (rc == 0); }
int main (void) { setup_test_environment(); void *ctx1 = zmq_ctx_new (); assert (ctx1); void *ctx2 = zmq_ctx_new (); assert (ctx2); void *router = zmq_socket (ctx1, ZMQ_ROUTER); int on = 1; int rc = zmq_setsockopt (router, ZMQ_ROUTER_MANDATORY, &on, sizeof (on)); assert (rc == 0); rc = zmq_bind (router, "tcp://127.0.0.1:5555"); assert (rc != -1); // Repeat often enough to be sure this works as it should for (int cycle = 0; cycle < 100; cycle++) { // Create dealer with unique explicit identity // We assume the router learns this out-of-band void *dealer = zmq_socket (ctx2, ZMQ_DEALER); char identity [10]; sprintf (identity, "%09d", cycle); rc = zmq_setsockopt (dealer, ZMQ_IDENTITY, identity, 10); assert (rc == 0); int rcvtimeo = 1000; rc = zmq_setsockopt (dealer, ZMQ_RCVTIMEO, &rcvtimeo, sizeof (int)); assert (rc == 0); rc = zmq_connect (dealer, "tcp://127.0.0.1:5555"); assert (rc == 0); // Router will try to send to dealer, at short intervals. // It typically takes 2-5 msec for the connection to establish // on a loopback interface, but we'll allow up to one second // before failing the test (e.g. for running on a debugger or // a very slow system). for (int attempt = 0; attempt < 500; attempt++) { zmq_poll (0, 0, 2); rc = zmq_send (router, identity, 10, ZMQ_SNDMORE); if (rc == -1 && errno == EHOSTUNREACH) continue; assert (rc == 10); rc = zmq_send (router, "HELLO", 5, 0); assert (rc == 5); break; } uint8_t buffer [5]; rc = zmq_recv (dealer, buffer, 5, 0); assert (rc == 5); assert (memcmp (buffer, "HELLO", 5) == 0); close_zero_linger (dealer); } zmq_close (router); zmq_ctx_destroy (ctx1); zmq_ctx_destroy (ctx2); return 0; }
void test_round_robin_out (void *ctx) { void *req = zmq_socket (ctx, ZMQ_REQ); assert (req); int rc = zmq_bind (req, bind_address); assert (rc == 0); size_t len = MAX_SOCKET_STRING; rc = zmq_getsockopt (req, ZMQ_LAST_ENDPOINT, connect_address, &len); assert (rc == 0); const size_t services = 5; void *rep [services]; for (size_t peer = 0; peer < services; peer++) { rep [peer] = zmq_socket (ctx, ZMQ_REP); assert (rep [peer]); int timeout = 250; rc = zmq_setsockopt (rep [peer], ZMQ_RCVTIMEO, &timeout, sizeof (int)); assert (rc == 0); rc = zmq_connect (rep [peer], connect_address); assert (rc == 0); } // We have to give the connects time to finish otherwise the requests // will not properly round-robin. We could alternatively connect the // REQ sockets to the REP sockets. msleep (SETTLE_TIME); // Send our peer-replies, and expect every REP it used once in order for (size_t peer = 0; peer < services; peer++) { s_send_seq (req, "ABC", SEQ_END); s_recv_seq (rep [peer], "ABC", SEQ_END); s_send_seq (rep [peer], "DEF", SEQ_END); s_recv_seq (req, "DEF", SEQ_END); } close_zero_linger (req); for (size_t peer = 0; peer < services; peer++) close_zero_linger (rep [peer]); // Wait for disconnects. msleep (SETTLE_TIME); }
void test_round_robin_out (void *ctx) { void *req = zmq_socket (ctx, ZMQ_REQ); assert (req); int rc = zmq_bind (req, bind_address); assert (rc == 0); const size_t services = 5; void *rep [services]; for (size_t peer = 0; peer < services; peer++) { rep [peer] = zmq_socket (ctx, ZMQ_REP); assert (rep [peer]); int timeout = 100; rc = zmq_setsockopt (rep [peer], ZMQ_RCVTIMEO, &timeout, sizeof (int)); assert (rc == 0); rc = zmq_connect (rep [peer], connect_address); assert (rc == 0); } // We have to give the connects time to finish otherwise the requests // will not properly round-robin. We could alternatively connect the // REQ sockets to the REP sockets. struct timespec t = { 0, 250 * 1000000 }; nanosleep (&t, NULL); // Send our peer-replies, and expect every REP it used once in order for (size_t peer = 0; peer < services; peer++) { s_send_seq (req, "ABC", SEQ_END); s_recv_seq (rep [peer], "ABC", SEQ_END); s_send_seq (rep [peer], "DEF", SEQ_END); s_recv_seq (req, "DEF", SEQ_END); } close_zero_linger (req); for (size_t peer = 0; peer < services; peer++) close_zero_linger (rep [peer]); // Wait for disconnects. rc = zmq_poll (0, 0, 100); assert (rc == 0); }
int main (void) { setup_test_environment (); void *ctx = zmq_ctx_new (); assert (ctx); void *stream = zmq_socket (ctx, ZMQ_STREAM); assert (stream); void *dealer = zmq_socket (ctx, ZMQ_DEALER); assert (dealer); int rc = zmq_bind (stream, "tcp://127.0.0.1:5555"); assert (rc >= 0); rc = zmq_connect (dealer, "tcp://127.0.0.1:5555"); assert (rc >= 0); zmq_send (dealer, "", 0, 0); zmq_msg_t ident, empty; zmq_msg_init (&ident); rc = zmq_msg_recv (&ident, stream, 0); assert (rc >= 0); rc = zmq_msg_init_data (&empty, (void *) "", 0, NULL, NULL); assert (rc >= 0); rc = zmq_msg_send (&ident, stream, ZMQ_SNDMORE); assert (rc >= 0); rc = zmq_msg_close (&ident); assert (rc >= 0); rc = zmq_msg_send (&empty, stream, 0); assert (rc >= 0); // This close used to fail with Bad Address rc = zmq_msg_close (&empty); assert (rc >= 0); close_zero_linger (dealer); close_zero_linger (stream); zmq_ctx_term (ctx); }
static void zap_handler (void *handler) { uint8_t metadata [] = { 5, 'H', 'e', 'l', 'l', 'o', 0, 0, 0, 5, 'W', 'o', 'r', 'l', 'd' }; // Process ZAP requests forever while (true) { char *version = s_recv (handler); if (!version) break; // Terminating char *sequence = s_recv (handler); char *domain = s_recv (handler); char *address = s_recv (handler); char *routing_id = s_recv (handler); char *mechanism = s_recv (handler); assert (streq (version, "1.0")); assert (streq (mechanism, "NULL")); s_sendmore (handler, version); s_sendmore (handler, sequence); if (streq (domain, "DOMAIN")) { s_sendmore (handler, "200"); s_sendmore (handler, "OK"); s_sendmore (handler, "anonymous"); zmq_send (handler, metadata, sizeof (metadata), 0); } else { s_sendmore (handler, "400"); s_sendmore (handler, "BAD DOMAIN"); s_sendmore (handler, ""); s_send (handler, ""); } free (version); free (sequence); free (domain); free (address); free (routing_id); free (mechanism); } close_zero_linger (handler); }
static void zap_handler (void *handler) { // Process ZAP requests forever while (true) { char *version = s_recv (handler); if (!version) break; // Terminating char *sequence = s_recv (handler); char *domain = s_recv (handler); char *address = s_recv (handler); char *identity = s_recv (handler); char *mechanism = s_recv (handler); assert (streq (version, "1.0")); assert (streq (mechanism, "NULL")); s_sendmore (handler, version); s_sendmore (handler, sequence); if (streq (domain, "TEST")) { s_sendmore (handler, "200"); s_sendmore (handler, "OK"); s_sendmore (handler, "anonymous"); s_send (handler, ""); } else { s_sendmore (handler, "400"); s_sendmore (handler, "BAD DOMAIN"); s_sendmore (handler, ""); s_send (handler, ""); } free (version); free (sequence); free (domain); free (address); free (identity); free (mechanism); } close_zero_linger (handler); }
int main (void) { setup_test_environment (); size_t len = MAX_SOCKET_STRING; char my_endpoint[MAX_SOCKET_STRING]; void *ctx = zmq_ctx_new (); assert (ctx); // We'll monitor these two sockets void *client = zmq_socket (ctx, ZMQ_DEALER); assert (client); void *server = zmq_socket (ctx, ZMQ_DEALER); assert (server); // Socket monitoring only works over inproc:// int rc = zmq_socket_monitor (client, "tcp://127.0.0.1:*", 0); assert (rc == -1); assert (zmq_errno () == EPROTONOSUPPORT); // Monitor all events on client and server sockets rc = zmq_socket_monitor (client, "inproc://monitor-client", ZMQ_EVENT_ALL); assert (rc == 0); rc = zmq_socket_monitor (server, "inproc://monitor-server", ZMQ_EVENT_ALL); assert (rc == 0); // Create two sockets for collecting monitor events void *client_mon = zmq_socket (ctx, ZMQ_PAIR); assert (client_mon); void *server_mon = zmq_socket (ctx, ZMQ_PAIR); assert (server_mon); // Connect these to the inproc endpoints so they'll get events rc = zmq_connect (client_mon, "inproc://monitor-client"); assert (rc == 0); rc = zmq_connect (server_mon, "inproc://monitor-server"); assert (rc == 0); // Now do a basic ping test rc = zmq_bind (server, "tcp://127.0.0.1:*"); assert (rc == 0); rc = zmq_getsockopt (server, ZMQ_LAST_ENDPOINT, my_endpoint, &len); assert (rc == 0); rc = zmq_connect (client, my_endpoint); assert (rc == 0); bounce (server, client); // Close client and server close_zero_linger (client); close_zero_linger (server); // Now collect and check events from both sockets int event = get_monitor_event (client_mon, NULL, NULL); if (event == ZMQ_EVENT_CONNECT_DELAYED) event = get_monitor_event (client_mon, NULL, NULL); assert (event == ZMQ_EVENT_CONNECTED); #ifdef ZMQ_BUILD_DRAFT_API expect_monitor_event (client_mon, ZMQ_EVENT_HANDSHAKE_SUCCEEDED); #endif expect_monitor_event (client_mon, ZMQ_EVENT_MONITOR_STOPPED); // This is the flow of server events expect_monitor_event (server_mon, ZMQ_EVENT_LISTENING); expect_monitor_event (server_mon, ZMQ_EVENT_ACCEPTED); #ifdef ZMQ_BUILD_DRAFT_API expect_monitor_event (server_mon, ZMQ_EVENT_HANDSHAKE_SUCCEEDED); #endif event = get_monitor_event (server_mon, NULL, NULL); // Sometimes the server sees the client closing before it gets closed. if (event != ZMQ_EVENT_DISCONNECTED) { assert (event == ZMQ_EVENT_CLOSED); event = get_monitor_event (server_mon, NULL, NULL); } if (event != ZMQ_EVENT_DISCONNECTED) { assert (event == ZMQ_EVENT_MONITOR_STOPPED); } // Close down the sockets close_zero_linger (client_mon); close_zero_linger (server_mon); zmq_ctx_term (ctx); return 0; }
void test_req_only_listens_to_current_peer (void *ctx) { void *req = zmq_socket (ctx, ZMQ_REQ); assert (req); int rc = zmq_setsockopt(req, ZMQ_IDENTITY, "A", 2); assert (rc == 0); rc = zmq_bind (req, bind_address); assert (rc == 0); const size_t services = 3; void *router [services]; for (size_t i = 0; i < services; ++i) { router [i] = zmq_socket (ctx, ZMQ_ROUTER); assert (router [i]); int timeout = 100; rc = zmq_setsockopt (router [i], ZMQ_RCVTIMEO, &timeout, sizeof (timeout)); assert (rc == 0); int enabled = 1; rc = zmq_setsockopt (router [i], ZMQ_ROUTER_MANDATORY, &enabled, sizeof (enabled)); assert (rc == 0); rc = zmq_connect (router [i], connect_address); assert (rc == 0); } // Wait for connects to finish. rc = zmq_poll (0, 0, 100); assert (rc == 0); for (size_t i = 0; i < services; ++i) { // There still is a race condition when a stale peer's message // arrives at the REQ just after a request was sent to that peer. // To avoid that happening in the test, sleep for a bit. rc = zmq_poll (0, 0, 10); assert (rc == 0); s_send_seq (req, "ABC", SEQ_END); // Receive on router i s_recv_seq (router [i], "A", 0, "ABC", SEQ_END); // Send back replies on all routers for (size_t j = 0; j < services; ++j) { const char *replies [] = { "WRONG", "GOOD" }; const char *reply = replies [i == j ? 1 : 0]; s_send_seq (router [j], "A", 0, reply, SEQ_END); } // Receive only the good reply s_recv_seq (req, "GOOD", SEQ_END); } close_zero_linger (req); for (size_t i = 0; i < services; ++i) close_zero_linger (router [i]); // Wait for disconnects. rc = zmq_poll (0, 0, 100); assert (rc == 0); }
int main (void) { setup_test_environment(); void *ctx = zmq_ctx_new (); assert (ctx); // Spawn ZAP handler // We create and bind ZAP socket in main thread to avoid case // where child thread does not start up fast enough. void *handler = zmq_socket (ctx, ZMQ_REP); assert (handler); int rc = zmq_bind (handler, "inproc://zeromq.zap.01"); assert (rc == 0); void *zap_thread = zmq_threadstart (&zap_handler, handler); // We bounce between a binding server and a connecting client // We first test client/server with no ZAP domain // Libzmq does not call our ZAP handler, the connect must succeed void *server = zmq_socket (ctx, ZMQ_DEALER); assert (server); void *client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_bind (server, "tcp://127.0.0.1:9000"); assert (rc == 0); rc = zmq_connect (client, "tcp://127.0.0.1:9000"); assert (rc == 0); bounce (server, client); close_zero_linger (client); close_zero_linger (server); // Now define a ZAP domain for the server; this enables // authentication. We're using the wrong domain so this test // must fail. server = zmq_socket (ctx, ZMQ_DEALER); assert (server); client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "WRONG", 5); assert (rc == 0); rc = zmq_bind (server, "tcp://127.0.0.1:9001"); assert (rc == 0); rc = zmq_connect (client, "tcp://127.0.0.1:9001"); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); close_zero_linger (server); // Now use the right domain, the test must pass server = zmq_socket (ctx, ZMQ_DEALER); assert (server); client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "TEST", 4); assert (rc == 0); rc = zmq_bind (server, "tcp://127.0.0.1:9002"); assert (rc == 0); rc = zmq_connect (client, "tcp://127.0.0.1:9002"); assert (rc == 0); bounce (server, client); close_zero_linger (client); close_zero_linger (server); // Unauthenticated messages from a vanilla socket shouldn't be received server = zmq_socket (ctx, ZMQ_DEALER); assert (server); rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "WRONG", 5); assert (rc == 0); rc = zmq_bind (server, "tcp://127.0.0.1:9003"); assert (rc == 0); struct sockaddr_in ip4addr; int s; ip4addr.sin_family = AF_INET; ip4addr.sin_port = htons(9003); #if (_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, (struct sockaddr*) &ip4addr, sizeof ip4addr); assert (rc > -1); // send anonymous ZMTP/1.0 greeting send (s, "\x01\x00", 2, 0); // send sneaky message that shouldn't be received send (s, "\x08\x00sneaky\0", 9, 0); int timeout = 250; zmq_setsockopt (server, ZMQ_RCVTIMEO, &timeout, sizeof (timeout)); char *buf = s_recv (server); if (buf != NULL) { printf ("Received unauthenticated message: %s\n", buf); assert (buf == NULL); } close (s); close_zero_linger (server); // Shutdown rc = zmq_ctx_term (ctx); assert (rc == 0); // Wait until ZAP handler terminates zmq_threadclose (zap_thread); return 0; }
void test_pull_fair_queue_in (void *ctx) { void *pull = zmq_socket (ctx, ZMQ_PULL); assert (pull); int rc = zmq_bind (pull, bind_address); assert (rc == 0); const size_t services = 5; void *pushs [services]; for (size_t peer = 0; peer < services; ++peer) { pushs [peer] = zmq_socket (ctx, ZMQ_PUSH); assert (pushs [peer]); rc = zmq_connect (pushs [peer], connect_address); assert (rc == 0); } // Wait for connections. msleep (SETTLE_TIME); int first_half = 0; int second_half = 0; // Send 2N messages for (size_t peer = 0; peer < services; ++peer) { char *str = strdup("A"); str [0] += peer; s_send_seq (pushs [peer], str, SEQ_END); first_half += str [0]; str [0] += services; s_send_seq (pushs [peer], str, SEQ_END); second_half += str [0]; free (str); } // Wait for data. msleep (SETTLE_TIME); zmq_msg_t msg; rc = zmq_msg_init (&msg); assert (rc == 0); // Expect to pull one from each first for (size_t peer = 0; peer < services; ++peer) { rc = zmq_msg_recv (&msg, pull, 0); assert (rc == 2); const char *str = (const char *)zmq_msg_data (&msg); first_half -= str [0]; } assert (first_half == 0); // And then get the second batch for (size_t peer = 0; peer < services; ++peer) { rc = zmq_msg_recv (&msg, pull, 0); assert (rc == 2); const char *str = (const char *)zmq_msg_data (&msg); second_half -= str [0]; } assert (second_half == 0); rc = zmq_msg_close (&msg); assert (rc == 0); close_zero_linger (pull); for (size_t peer = 0; peer < services; ++peer) close_zero_linger (pushs [peer]); // Wait for disconnects. msleep (SETTLE_TIME); }
int main (void) { setup_test_environment (); size_t len = MAX_SOCKET_STRING; char my_endpoint[MAX_SOCKET_STRING]; void *ctx = zmq_ctx_new (); assert (ctx); void *req = zmq_socket (ctx, ZMQ_REQ); assert (req); void *router = zmq_socket (ctx, ZMQ_ROUTER); assert (router); int enabled = 1; int rc = zmq_setsockopt (req, ZMQ_REQ_CORRELATE, &enabled, sizeof (int)); assert (rc == 0); int rcvtimeo = 100; rc = zmq_setsockopt (req, ZMQ_RCVTIMEO, &rcvtimeo, sizeof (int)); assert (rc == 0); rc = zmq_bind (router, "tcp://127.0.0.1:*"); assert (rc == 0); rc = zmq_getsockopt (router, ZMQ_LAST_ENDPOINT, my_endpoint, &len); assert (rc == 0); rc = zmq_connect (req, my_endpoint); assert (rc == 0); // Send a multi-part request. s_send_seq (req, "ABC", "DEF", SEQ_END); zmq_msg_t msg; zmq_msg_init (&msg); // Receive peer routing id rc = zmq_msg_recv (&msg, router, 0); assert (rc != -1); assert (zmq_msg_size (&msg) > 0); zmq_msg_t peer_id_msg; zmq_msg_init (&peer_id_msg); zmq_msg_copy (&peer_id_msg, &msg); int more = 0; size_t more_size = sizeof (more); rc = zmq_getsockopt (router, ZMQ_RCVMORE, &more, &more_size); assert (rc == 0); assert (more); // Receive request id 1 rc = zmq_msg_recv (&msg, router, 0); assert (rc != -1); assert (zmq_msg_size (&msg) == sizeof (uint32_t)); uint32_t req_id = *static_cast<uint32_t *> (zmq_msg_data (&msg)); zmq_msg_t req_id_msg; zmq_msg_init (&req_id_msg); zmq_msg_copy (&req_id_msg, &msg); more = 0; more_size = sizeof (more); rc = zmq_getsockopt (router, ZMQ_RCVMORE, &more, &more_size); assert (rc == 0); assert (more); // Receive the rest. s_recv_seq (router, 0, "ABC", "DEF", SEQ_END); uint32_t bad_req_id = req_id + 1; // Send back a bad reply: wrong req id, 0, data zmq_msg_copy (&msg, &peer_id_msg); rc = zmq_msg_send (&msg, router, ZMQ_SNDMORE); assert (rc != -1); zmq_msg_init_data (&msg, &bad_req_id, sizeof (uint32_t), NULL, NULL); rc = zmq_msg_send (&msg, router, ZMQ_SNDMORE); assert (rc != -1); s_send_seq (router, 0, "DATA", SEQ_END); // Send back a good reply: good req id, 0, data zmq_msg_copy (&msg, &peer_id_msg); rc = zmq_msg_send (&msg, router, ZMQ_SNDMORE); assert (rc != -1); zmq_msg_copy (&msg, &req_id_msg); rc = zmq_msg_send (&msg, router, ZMQ_SNDMORE); assert (rc != -1); s_send_seq (router, 0, "GHI", SEQ_END); // Receive reply. If bad reply got through, we wouldn't see // this particular data. s_recv_seq (req, "GHI", SEQ_END); rc = zmq_msg_close (&msg); assert (rc == 0); rc = zmq_msg_close (&peer_id_msg); assert (rc == 0); rc = zmq_msg_close (&req_id_msg); assert (rc == 0); close_zero_linger (req); close_zero_linger (router); rc = zmq_ctx_term (ctx); assert (rc == 0); return 0; }
int main (void) { setup_test_environment(); void *ctx = zmq_ctx_new (); assert (ctx); // Spawn ZAP handler void *zap_thread = zmq_threadstart (&zap_handler, ctx); // Server socket will accept connections void *server = zmq_socket (ctx, ZMQ_DEALER); assert (server); int rc = zmq_setsockopt (server, ZMQ_IDENTITY, "IDENT", 6); assert (rc == 0); int as_server = 1; rc = zmq_setsockopt (server, ZMQ_PLAIN_SERVER, &as_server, sizeof (int)); assert (rc == 0); rc = zmq_bind (server, "tcp://127.0.0.1:9998"); assert (rc == 0); char username [256]; char password [256]; // Check PLAIN security with correct username/password void *client = zmq_socket (ctx, ZMQ_DEALER); assert (client); strcpy (username, "admin"); rc = zmq_setsockopt (client, ZMQ_PLAIN_USERNAME, username, strlen (username)); assert (rc == 0); strcpy (password, "password"); rc = zmq_setsockopt (client, ZMQ_PLAIN_PASSWORD, password, strlen (password)); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); bounce (server, client); rc = zmq_close (client); assert (rc == 0); // Check PLAIN security with badly configured client (as_server) // This will be caught by the plain_server class, not passed to ZAP client = zmq_socket (ctx, ZMQ_DEALER); assert (client); as_server = 1; rc = zmq_setsockopt (client, ZMQ_PLAIN_SERVER, &as_server, sizeof (int)); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Check PLAIN security -- failed authentication client = zmq_socket (ctx, ZMQ_DEALER); assert (client); strcpy (username, "wronguser"); strcpy (password, "wrongpass"); rc = zmq_setsockopt (client, ZMQ_PLAIN_USERNAME, username, strlen (username)); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_PLAIN_PASSWORD, password, strlen (password)); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Shutdown rc = zmq_close (server); assert (rc == 0); rc = zmq_ctx_term (ctx); assert (rc == 0); // Wait until ZAP handler terminates zmq_threadclose (zap_thread); return 0; }
void test_fair_queue_in (void *ctx) { void *receiver = zmq_socket (ctx, ZMQ_ROUTER); assert (receiver); int timeout = 100; int rc = zmq_setsockopt (receiver, ZMQ_RCVTIMEO, &timeout, sizeof (int)); assert (rc == 0); rc = zmq_bind (receiver, bind_address); assert (rc == 0); const size_t services = 5; void *senders [services]; for (size_t peer = 0; peer < services; ++peer) { senders [peer] = zmq_socket (ctx, ZMQ_DEALER); assert (senders [peer]); rc = zmq_setsockopt (senders [peer], ZMQ_RCVTIMEO, &timeout, sizeof (int)); assert (rc == 0); char *str = strdup("A"); str [0] += peer; rc = zmq_setsockopt (senders [peer], ZMQ_IDENTITY, str, 2); assert (rc == 0); free (str); rc = zmq_connect (senders [peer], connect_address); assert (rc == 0); } zmq_msg_t msg; rc = zmq_msg_init (&msg); assert (rc == 0); s_send_seq (senders [0], "M", SEQ_END); s_recv_seq (receiver, "A", "M", SEQ_END); s_send_seq (senders [0], "M", SEQ_END); s_recv_seq (receiver, "A", "M", SEQ_END); int sum = 0; // send N requests for (size_t peer = 0; peer < services; ++peer) { s_send_seq (senders [peer], "M", SEQ_END); sum += 'A' + peer; } assert (sum == services * 'A' + services * (services - 1) / 2); // handle N requests for (size_t peer = 0; peer < services; ++peer) { rc = zmq_msg_recv (&msg, receiver, 0); assert (rc == 2); const char *id = (const char *)zmq_msg_data (&msg); sum -= id [0]; s_recv_seq (receiver, "M", SEQ_END); } assert (sum == 0); rc = zmq_msg_close (&msg); assert (rc == 0); close_zero_linger (receiver); for (size_t peer = 0; peer < services; ++peer) close_zero_linger (senders [peer]); // Wait for disconnects. rc = zmq_poll (0, 0, 100); assert (rc == 0); }
int main (void) { #ifndef HAVE_LIBSODIUM printf ("libsodium not installed, skipping CURVE test\n"); return 0; #endif // Generate new keypairs for this test int rc = zmq_curve_keypair (client_public, client_secret); assert (rc == 0); rc = zmq_curve_keypair (server_public, server_secret); assert (rc == 0); setup_test_environment (); void *ctx = zmq_ctx_new (); assert (ctx); // Spawn ZAP handler // We create and bind ZAP socket in main thread to avoid case // where child thread does not start up fast enough. void *handler = zmq_socket (ctx, ZMQ_REP); assert (handler); rc = zmq_bind (handler, "inproc://zeromq.zap.01"); assert (rc == 0); void *zap_thread = zmq_threadstart (&zap_handler, handler); // Server socket will accept connections void *server = zmq_socket (ctx, ZMQ_DEALER); assert (server); int as_server = 1; rc = zmq_setsockopt (server, ZMQ_CURVE_SERVER, &as_server, sizeof (int)); assert (rc == 0); rc = zmq_setsockopt (server, ZMQ_CURVE_SECRETKEY, server_secret, 41); assert (rc == 0); rc = zmq_setsockopt (server, ZMQ_IDENTITY, "IDENT", 6); assert (rc == 0); rc = zmq_bind (server, "tcp://127.0.0.1:9998"); assert (rc == 0); // Check CURVE security with valid credentials void *client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 41); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 41); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 41); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); bounce (server, client); rc = zmq_close (client); assert (rc == 0); // Check CURVE security with a garbage server key // This will be caught by the curve_server class, not passed to ZAP char garbage_key [] = "0000111122223333444455556666777788889999"; client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, garbage_key, 41); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 41); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 41); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Check CURVE security with a garbage client public key // This will be caught by the curve_server class, not passed to ZAP client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 41); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, garbage_key, 41); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 41); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Check CURVE security with a garbage client secret key // This will be caught by the curve_server class, not passed to ZAP client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 41); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 41); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, garbage_key, 41); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Check CURVE security with bogus client credentials // This must be caught by the ZAP handler char bogus_public [41]; char bogus_secret [41]; zmq_curve_keypair (bogus_public, bogus_secret); client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 41); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, bogus_public, 41); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, bogus_secret, 41); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Check CURVE security with NULL client credentials // This must be caught by the curve_server class, not passed to ZAP client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Check CURVE security with PLAIN client credentials // This must be caught by the curve_server class, not passed to ZAP client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_setsockopt (client, ZMQ_PLAIN_USERNAME, "admin", 5); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_PLAIN_PASSWORD, "password", 8); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Unauthenticated messages from a vanilla socket shouldn't be received struct sockaddr_in ip4addr; int s; ip4addr.sin_family = AF_INET; ip4addr.sin_port = htons (9998); #if (_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, (struct sockaddr*) &ip4addr, sizeof (ip4addr)); assert (rc > -1); // send anonymous ZMTP/1.0 greeting send (s, "\x01\x00", 2, 0); // send sneaky message that shouldn't be received send (s, "\x08\x00sneaky\0", 9, 0); int timeout = 250; zmq_setsockopt (server, ZMQ_RCVTIMEO, &timeout, sizeof (timeout)); char *buf = s_recv (server); if (buf != NULL) { printf ("Received unauthenticated message: %s\n", buf); assert (buf == NULL); } close (s); // Check return codes for invalid buffer sizes client = zmq_socket (ctx, ZMQ_DEALER); assert (client); errno = 0; rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 123); assert (rc == -1 && errno == EINVAL); errno = 0; rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 123); assert (rc == -1 && errno == EINVAL); errno = 0; rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 123); assert (rc == -1 && errno == EINVAL); rc = zmq_close (client); assert (rc == 0); // Shutdown rc = zmq_close (server); assert (rc == 0); rc = zmq_ctx_term (ctx); assert (rc == 0); // Wait until ZAP handler terminates zmq_threadclose (zap_thread); return 0; }
void test_destroy_queue_on_disconnect (void *ctx) { void *A = zmq_socket (ctx, ZMQ_DEALER); assert (A); int rc = zmq_bind (A, bind_address); assert (rc == 0); void *B = zmq_socket (ctx, ZMQ_DEALER); assert (B); rc = zmq_connect (B, connect_address); assert (rc == 0); // Send a message in both directions s_send_seq (A, "ABC", SEQ_END); s_send_seq (B, "DEF", SEQ_END); rc = zmq_disconnect (B, connect_address); assert (rc == 0); // Disconnect may take time and need command processing. zmq_pollitem_t poller [2] = { { A, 0, 0, 0 }, { B, 0, 0, 0 } }; rc = zmq_poll (poller, 2, 100); assert (rc == 0); rc = zmq_poll (poller, 2, 100); assert (rc == 0); // No messages should be available, sending should fail. zmq_msg_t msg; zmq_msg_init (&msg); rc = zmq_send (A, 0, 0, ZMQ_DONTWAIT); assert (rc == -1); assert (errno == EAGAIN); rc = zmq_msg_recv (&msg, A, ZMQ_DONTWAIT); assert (rc == -1); assert (errno == EAGAIN); // After a reconnect of B, the messages should still be gone rc = zmq_connect (B, connect_address); assert (rc == 0); rc = zmq_msg_recv (&msg, A, ZMQ_DONTWAIT); assert (rc == -1); assert (errno == EAGAIN); rc = zmq_msg_recv (&msg, B, ZMQ_DONTWAIT); assert (rc == -1); assert (errno == EAGAIN); rc = zmq_msg_close (&msg); assert (rc == 0); close_zero_linger (A); close_zero_linger (B); // Wait for disconnects. rc = zmq_poll (0, 0, 100); assert (rc == 0); }
int main (void) { setup_test_environment(); void *ctx = zmq_ctx_new (); assert (ctx); // Spawn ZAP handler void *zap_thread = zmq_threadstart (&zap_handler, ctx); // Server socket will accept connections void *server = zmq_socket (ctx, ZMQ_DEALER); assert (server); int rc = zmq_setsockopt (server, ZMQ_IDENTITY, "IDENT", 6); assert (rc == 0); int as_server = 1; rc = zmq_setsockopt (server, ZMQ_PLAIN_SERVER, &as_server, sizeof (int)); assert (rc == 0); rc = zmq_bind (server, "tcp://127.0.0.1:9998"); assert (rc == 0); char username [256]; char password [256]; // Check PLAIN security with correct username/password void *client = zmq_socket (ctx, ZMQ_DEALER); assert (client); strcpy (username, "admin"); rc = zmq_setsockopt (client, ZMQ_PLAIN_USERNAME, username, strlen (username)); assert (rc == 0); strcpy (password, "password"); rc = zmq_setsockopt (client, ZMQ_PLAIN_PASSWORD, password, strlen (password)); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); bounce (server, client); rc = zmq_close (client); assert (rc == 0); // Check PLAIN security with badly configured client (as_server) // This will be caught by the plain_server class, not passed to ZAP client = zmq_socket (ctx, ZMQ_DEALER); assert (client); as_server = 1; rc = zmq_setsockopt (client, ZMQ_PLAIN_SERVER, &as_server, sizeof (int)); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Check PLAIN security -- failed authentication client = zmq_socket (ctx, ZMQ_DEALER); assert (client); strcpy (username, "wronguser"); strcpy (password, "wrongpass"); rc = zmq_setsockopt (client, ZMQ_PLAIN_USERNAME, username, strlen (username)); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_PLAIN_PASSWORD, password, strlen (password)); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Unauthenticated messages from a vanilla socket shouldn't be received struct sockaddr_in ip4addr; int s; ip4addr.sin_family = AF_INET; ip4addr.sin_port = htons (9998); inet_pton (AF_INET, "127.0.0.1", &ip4addr.sin_addr); s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); rc = connect (s, (struct sockaddr*) &ip4addr, sizeof (ip4addr)); assert (rc > -1); // send anonymous ZMTP/1.0 greeting send (s, "\x01\x00", 2, 0); // send sneaky message that shouldn't be received send (s, "\x08\x00sneaky\0", 9, 0); int timeout = 250; zmq_setsockopt (server, ZMQ_RCVTIMEO, &timeout, sizeof (timeout)); char *buf = s_recv (server); if (buf != NULL) { printf ("Received unauthenticated message: %s\n", buf); assert (buf == NULL); } close (s); // Shutdown rc = zmq_close (server); assert (rc == 0); rc = zmq_ctx_term (ctx); assert (rc == 0); // Wait until ZAP handler terminates zmq_threadclose (zap_thread); return 0; }
void test_destroy_queue_on_disconnect (void *ctx) { void *A = zmq_socket (ctx, ZMQ_PUSH); assert (A); int hwm = 1; int rc = zmq_setsockopt (A, ZMQ_SNDHWM, &hwm, sizeof (hwm)); assert (rc == 0); rc = zmq_bind (A, bind_address); assert (rc == 0); void *B = zmq_socket (ctx, ZMQ_PULL); assert (B); rc = zmq_setsockopt (B, ZMQ_RCVHWM, &hwm, sizeof (hwm)); assert (rc == 0); rc = zmq_connect (B, connect_address); assert (rc == 0); // Send two messages, one should be stuck in A's outgoing queue, the other // arrives at B. s_send_seq (A, "ABC", SEQ_END); s_send_seq (A, "DEF", SEQ_END); // Both queues should now be full, indicated by A blocking on send. rc = zmq_send (A, 0, 0, ZMQ_DONTWAIT); assert (rc == -1); assert (errno == EAGAIN); rc = zmq_disconnect (B, connect_address); assert (rc == 0); // Disconnect may take time and need command processing. zmq_pollitem_t poller [2] = { { A, 0, 0, 0 }, { B, 0, 0, 0 } }; rc = zmq_poll (poller, 2, 100); assert (rc == 0); rc = zmq_poll (poller, 2, 100); assert (rc == 0); zmq_msg_t msg; rc = zmq_msg_init (&msg); assert (rc == 0); // Can't receive old data on B. rc = zmq_msg_recv (&msg, B, ZMQ_DONTWAIT); assert (rc == -1); assert (errno == EAGAIN); // Sending fails. rc = zmq_send (A, 0, 0, ZMQ_DONTWAIT); assert (rc == -1); assert (errno == EAGAIN); // Reconnect B rc = zmq_connect (B, connect_address); assert (rc == 0); // Still can't receive old data on B. rc = zmq_msg_recv (&msg, B, ZMQ_DONTWAIT); assert (rc == -1); assert (errno == EAGAIN); // two messages should be sendable before the queues are filled up. s_send_seq (A, "ABC", SEQ_END); s_send_seq (A, "DEF", SEQ_END); rc = zmq_send (A, 0, 0, ZMQ_DONTWAIT); assert (rc == -1); assert (errno == EAGAIN); rc = zmq_msg_close (&msg); assert (rc == 0); close_zero_linger (A); close_zero_linger (B); // Wait for disconnects. msleep (SETTLE_TIME); }
int main (void) { #ifndef HAVE_LIBSODIUM printf ("libsodium not installed, skipping CURVE test\n"); return 0; #endif // Generate new keypairs for this test int rc = zmq_curve_keypair (client_public, client_secret); assert (rc == 0); rc = zmq_curve_keypair (server_public, server_secret); assert (rc == 0); setup_test_environment (); void *ctx = zmq_ctx_new (); assert (ctx); // Spawn ZAP handler // We create and bind ZAP socket in main thread to avoid case // where child thread does not start up fast enough. void *handler = zmq_socket (ctx, ZMQ_REP); assert (handler); rc = zmq_bind (handler, "inproc://zeromq.zap.01"); assert (rc == 0); void *zap_thread = zmq_threadstart (&zap_handler, handler); // Server socket will accept connections void *server = zmq_socket (ctx, ZMQ_DEALER); assert (server); int as_server = 1; rc = zmq_setsockopt (server, ZMQ_CURVE_SERVER, &as_server, sizeof (int)); assert (rc == 0); rc = zmq_setsockopt (server, ZMQ_CURVE_SECRETKEY, server_secret, 40); assert (rc == 0); rc = zmq_setsockopt (server, ZMQ_IDENTITY, "IDENT", 6); assert (rc == 0); rc = zmq_bind (server, "tcp://127.0.0.1:9998"); assert (rc == 0); // Check CURVE security with valid credentials void *client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 40); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 40); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 40); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); bounce (server, client); rc = zmq_close (client); assert (rc == 0); // Check CURVE security with a garbage server key // This will be caught by the curve_server class, not passed to ZAP char garbage_key [] = "0000111122223333444455556666777788889999"; client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, garbage_key, 40); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 40); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 40); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Check CURVE security with a garbage client public key // This will be caught by the curve_server class, not passed to ZAP client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 40); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, garbage_key, 40); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 40); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Check CURVE security with a garbage client secret key // This will be caught by the curve_server class, not passed to ZAP client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 40); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 40); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, garbage_key, 40); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Check CURVE security with bogus client credentials // This must be caught by the ZAP handler char bogus_public [40]; char bogus_secret [40]; zmq_curve_keypair (bogus_public, bogus_secret); client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 40); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, bogus_public, 40); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, bogus_secret, 40); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Check CURVE security with NULL client credentials // This must be caught by the curve_server class, not passed to ZAP client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Check CURVE security with PLAIN client credentials // This must be caught by the curve_server class, not passed to ZAP client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_setsockopt (client, ZMQ_PLAIN_USERNAME, "admin", 5); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_PLAIN_PASSWORD, "password", 8); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Shutdown rc = zmq_close (server); assert (rc == 0); rc = zmq_ctx_term (ctx); assert (rc == 0); // Wait until ZAP handler terminates zmq_threadclose (zap_thread); return 0; }
void test_fair_queue_in (void *ctx) { void *rep = zmq_socket (ctx, ZMQ_REP); assert (rep); int timeout = 100; int rc = zmq_setsockopt (rep, ZMQ_RCVTIMEO, &timeout, sizeof (int)); assert (rc == 0); rc = zmq_bind (rep, bind_address); assert (rc == 0); const size_t services = 5; void *reqs [services]; for (size_t peer = 0; peer < services; ++peer) { reqs [peer] = zmq_socket (ctx, ZMQ_REQ); assert (reqs [peer]); rc = zmq_setsockopt (reqs [peer], ZMQ_RCVTIMEO, &timeout, sizeof (int)); assert (rc == 0); rc = zmq_connect (reqs [peer], connect_address); assert (rc == 0); } s_send_seq (reqs [0], "A", SEQ_END); s_recv_seq (rep, "A", SEQ_END); s_send_seq (rep, "A", SEQ_END); s_recv_seq (reqs [0], "A", SEQ_END); s_send_seq (reqs [0], "A", SEQ_END); s_recv_seq (rep, "A", SEQ_END); s_send_seq (rep, "A", SEQ_END); s_recv_seq (reqs [0], "A", SEQ_END); // send N requests for (size_t peer = 0; peer < services; ++peer) { char * str = strdup("A"); str [0] += peer; s_send_seq (reqs [peer], str, SEQ_END); free (str); } // handle N requests for (size_t peer = 0; peer < services; ++peer) { char * str = strdup("A"); str [0] += peer; s_recv_seq (rep, str, SEQ_END); s_send_seq (rep, str, SEQ_END); s_recv_seq (reqs [peer], str, SEQ_END); free (str); } close_zero_linger (rep); for (size_t peer = 0; peer < services; ++peer) close_zero_linger (reqs [peer]); // Wait for disconnects. rc = zmq_poll (0, 0, 100); assert (rc == 0); }
int main (void) { setup_test_environment(); void *ctx = zmq_ctx_new (); assert (ctx); // Spawn ZAP handler // We create and bind ZAP socket in main thread to avoid case // where child thread does not start up fast enough. void *handler = zmq_socket (ctx, ZMQ_REP); assert (handler); int rc = zmq_bind (handler, "inproc://zeromq.zap.01"); assert (rc == 0); void *zap_thread = zmq_threadstart (&zap_handler, handler); // We bounce between a binding server and a connecting client // We first test client/server with no ZAP domain // Libzmq does not call our ZAP handler, the connect must succeed void *server = zmq_socket (ctx, ZMQ_DEALER); assert (server); void *client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_bind (server, "tcp://127.0.0.1:9000"); assert (rc == 0); rc = zmq_connect (client, "tcp://127.0.0.1:9000"); assert (rc == 0); bounce (server, client); close_zero_linger (client); close_zero_linger (server); // Now define a ZAP domain for the server; this enables // authentication. We're using the wrong domain so this test // must fail. server = zmq_socket (ctx, ZMQ_DEALER); assert (server); client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "WRONG", 5); assert (rc == 0); rc = zmq_bind (server, "tcp://127.0.0.1:9001"); assert (rc == 0); rc = zmq_connect (client, "tcp://127.0.0.1:9001"); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); close_zero_linger (server); // Now use the right domain, the test must pass server = zmq_socket (ctx, ZMQ_DEALER); assert (server); client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "TEST", 4); assert (rc == 0); rc = zmq_bind (server, "tcp://127.0.0.1:9002"); assert (rc == 0); rc = zmq_connect (client, "tcp://127.0.0.1:9002"); assert (rc == 0); bounce (server, client); close_zero_linger (client); close_zero_linger (server); // Shutdown rc = zmq_ctx_term (ctx); assert (rc == 0); // Wait until ZAP handler terminates zmq_threadclose (zap_thread); return 0; }
int main (void) { setup_test_environment(); void *ctx = zmq_ctx_new (); assert (ctx); // We'll monitor these two sockets void *client = zmq_socket (ctx, ZMQ_DEALER); assert (client); void *server = zmq_socket (ctx, ZMQ_DEALER); assert (server); // Socket monitoring only works over inproc:// int rc = zmq_socket_monitor (client, "tcp://127.0.0.1:9999", 0); assert (rc == -1); assert (zmq_errno () == EPROTONOSUPPORT); // Monitor all events on client and server sockets rc = zmq_socket_monitor (client, "inproc://monitor-client", ZMQ_EVENT_ALL); assert (rc == 0); rc = zmq_socket_monitor (server, "inproc://monitor-server", ZMQ_EVENT_ALL); assert (rc == 0); // Create two sockets for collecting monitor events void *client_mon = zmq_socket (ctx, ZMQ_PAIR); assert (client_mon); void *server_mon = zmq_socket (ctx, ZMQ_PAIR); assert (server_mon); // Connect these to the inproc endpoints so they'll get events rc = zmq_connect (client_mon, "inproc://monitor-client"); assert (rc == 0); rc = zmq_connect (server_mon, "inproc://monitor-server"); assert (rc == 0); // Now do a basic ping test rc = zmq_bind (server, "tcp://127.0.0.1:9998"); assert (rc == 0); rc = zmq_connect (client, "tcp://127.0.0.1:9998"); assert (rc == 0); bounce (client, server); // Close client and server close_zero_linger (client); close_zero_linger (server); // Now collect and check events from both sockets int event = get_monitor_event (client_mon, NULL, NULL); if (event == ZMQ_EVENT_CONNECT_DELAYED) event = get_monitor_event (client_mon, NULL, NULL); assert (event == ZMQ_EVENT_CONNECTED); event = get_monitor_event (client_mon, NULL, NULL); assert (event == ZMQ_EVENT_MONITOR_STOPPED); // This is the flow of server events event = get_monitor_event (server_mon, NULL, NULL); assert (event == ZMQ_EVENT_LISTENING); event = get_monitor_event (server_mon, NULL, NULL); assert (event == ZMQ_EVENT_ACCEPTED); event = get_monitor_event (server_mon, NULL, NULL); assert (event == ZMQ_EVENT_CLOSED); event = get_monitor_event (server_mon, NULL, NULL); assert (event == ZMQ_EVENT_MONITOR_STOPPED); // Close down the sockets close_zero_linger (client_mon); close_zero_linger (server_mon); zmq_ctx_term (ctx); return 0 ; }