static int zyre_node_recv_peer (zyre_node_t *self) { // Router socket tells us the identity of this peer zre_msg_t *msg = zre_msg_recv (self->inbox); if (msg == NULL) return 0; // Interrupted // First frame is sender identity, holding binary UUID zuuid_t *uuid = zuuid_new (); zuuid_set (uuid, zframe_data (zre_msg_address (msg))); // On HELLO we may create the peer if it's unknown // On other commands the peer must already exist zyre_peer_t *peer = (zyre_peer_t *) zhash_lookup (self->peers, zuuid_str (uuid)); if (zre_msg_id (msg) == ZRE_MSG_HELLO) { peer = zyre_node_require_peer (self, uuid, zre_msg_ipaddress (msg), zre_msg_mailbox (msg)); assert (peer); zyre_peer_set_ready (peer, true); } // Ignore command if peer isn't ready if (peer == NULL || !zyre_peer_ready (peer)) { zre_msg_destroy (&msg); zuuid_destroy (&uuid); return 0; } if (!zyre_peer_check_message (peer, msg)) { zclock_log ("W: [%s] lost messages from %s", zuuid_str (self->uuid), zuuid_str (uuid)); assert (false); } // Now process each command if (zre_msg_id (msg) == ZRE_MSG_HELLO) { // Tell the caller about the peer zstr_sendm (self->pipe, "ENTER"); zstr_sendm (self->pipe, zuuid_str (uuid)); zframe_t *headers = zhash_pack (zre_msg_headers (msg)); zframe_send (&headers, self->pipe, 0); // Join peer to listed groups char *name = zre_msg_groups_first (msg); while (name) { zyre_node_join_peer_group (self, peer, name); name = zre_msg_groups_next (msg); } // Hello command holds latest status of peer zyre_peer_set_status (peer, zre_msg_status (msg)); // Store peer headers for future reference zyre_peer_set_headers (peer, zre_msg_headers (msg)); // If peer is a ZRE/LOG collector, connect to it char *collector = zre_msg_headers_string (msg, "X-ZRELOG", NULL); if (collector) zyre_log_connect (self->log, collector); } else if (zre_msg_id (msg) == ZRE_MSG_WHISPER) { // Pass up to caller API as WHISPER event zstr_sendm (self->pipe, "WHISPER"); zstr_sendm (self->pipe, zuuid_str (uuid)); zmsg_t *content = zmsg_dup (zre_msg_content (msg)); zmsg_send (&content, self->pipe); } else if (zre_msg_id (msg) == ZRE_MSG_SHOUT) { // Pass up to caller as SHOUT event zstr_sendm (self->pipe, "SHOUT"); zstr_sendm (self->pipe, zuuid_str (uuid)); zstr_sendm (self->pipe, zre_msg_group (msg)); zmsg_t *content = zmsg_dup (zre_msg_content (msg)); zmsg_send (&content, self->pipe); } else if (zre_msg_id (msg) == ZRE_MSG_PING) { zre_msg_t *msg = zre_msg_new (ZRE_MSG_PING_OK); zyre_peer_send (peer, &msg); } else if (zre_msg_id (msg) == ZRE_MSG_JOIN) { zyre_node_join_peer_group (self, peer, zre_msg_group (msg)); assert (zre_msg_status (msg) == zyre_peer_status (peer)); } else if (zre_msg_id (msg) == ZRE_MSG_LEAVE) { zyre_node_leave_peer_group (self, peer, zre_msg_group (msg)); assert (zre_msg_status (msg) == zyre_peer_status (peer)); } zuuid_destroy (&uuid); zre_msg_destroy (&msg); // Activity from peer resets peer timers zyre_peer_refresh (peer); return 0; }
static int agent_recv_from_peer (agent_t *self) { // Router socket tells us the identity of this peer zre_msg_t *msg = zre_msg_recv (self->inbox); if (msg == NULL) return 0; // Interrupted char *identity = zframe_strdup (zre_msg_address (msg)); // On HELLO we may create the peer if it's unknown // On other commands the peer must already exist zre_peer_t *peer = (zre_peer_t *) zhash_lookup (self->peers, identity); if (zre_msg_id (msg) == ZRE_MSG_HELLO) { peer = s_require_peer ( self, identity, zre_msg_ipaddress (msg), zre_msg_mailbox (msg)); assert (peer); zre_peer_ready_set (peer, true); } // Ignore command if peer isn't ready if (peer == NULL || !zre_peer_ready (peer)) { free(identity); zre_msg_destroy (&msg); return 0; } if (!zre_peer_check_message (peer, msg)) { zclock_log ("W: [%s] lost messages from %s", self->identity, identity); assert (false); } // Now process each command if (zre_msg_id (msg) == ZRE_MSG_HELLO) { // Join peer to listed groups char *name = zre_msg_groups_first (msg); while (name) { s_join_peer_group (self, peer, name); name = zre_msg_groups_next (msg); } // Hello command holds latest status of peer zre_peer_status_set (peer, zre_msg_status (msg)); // Store peer headers for future reference zre_peer_headers_set (peer, zre_msg_headers (msg)); // If peer is a ZRE/LOG collector, connect to it char *collector = zre_msg_headers_string (msg, "X-ZRELOG", NULL); if (collector) zre_log_connect (self->log, collector); // If peer is a FileMQ publisher, connect to it char *publisher = zre_msg_headers_string (msg, "X-FILEMQ", NULL); if (publisher) fmq_client_connect (self->fmq_client, publisher); } else if (zre_msg_id (msg) == ZRE_MSG_WHISPER) { // Pass up to caller API as WHISPER event zframe_t *cookie = zre_msg_content (msg); zstr_sendm (self->pipe, "WHISPER"); zstr_sendm (self->pipe, identity); zframe_send (&cookie, self->pipe, ZFRAME_REUSE); // let msg free the frame } else if (zre_msg_id (msg) == ZRE_MSG_SHOUT) { // Pass up to caller as SHOUT event zframe_t *cookie = zre_msg_content (msg); zstr_sendm (self->pipe, "SHOUT"); zstr_sendm (self->pipe, identity); zstr_sendm (self->pipe, zre_msg_group (msg)); zframe_send (&cookie, self->pipe, ZFRAME_REUSE); // let msg free the frame } else if (zre_msg_id (msg) == ZRE_MSG_PING) { zre_msg_t *msg = zre_msg_new (ZRE_MSG_PING_OK); zre_peer_send (peer, &msg); } else if (zre_msg_id (msg) == ZRE_MSG_JOIN) { s_join_peer_group (self, peer, zre_msg_group (msg)); assert (zre_msg_status (msg) == zre_peer_status (peer)); } else if (zre_msg_id (msg) == ZRE_MSG_LEAVE) { s_leave_peer_group (self, peer, zre_msg_group (msg)); assert (zre_msg_status (msg) == zre_peer_status (peer)); } free (identity); zre_msg_destroy (&msg); // Activity from peer resets peer timers zre_peer_refresh (peer); return 0; }
int zre_msg_test (bool verbose) { printf (" * zre_msg: "); // @selftest // Simple create/destroy test zre_msg_t *self = zre_msg_new (0); assert (self); zre_msg_destroy (&self); // Create pair of sockets we can send through zctx_t *ctx = zctx_new (); assert (ctx); void *output = zsocket_new (ctx, ZMQ_DEALER); assert (output); zsocket_bind (output, "inproc://selftest"); void *input = zsocket_new (ctx, ZMQ_ROUTER); assert (input); zsocket_connect (input, "inproc://selftest"); // Encode/send/decode and verify each message type int instance; zre_msg_t *copy; self = zre_msg_new (ZRE_MSG_HELLO); // Check that _dup works on empty message copy = zre_msg_dup (self); assert (copy); zre_msg_destroy (©); zre_msg_set_sequence (self, 123); zre_msg_set_ipaddress (self, "Life is short but Now lasts for ever"); zre_msg_set_mailbox (self, 123); zre_msg_groups_append (self, "Name: %s", "Brutus"); zre_msg_groups_append (self, "Age: %d", 43); zre_msg_set_status (self, 123); zre_msg_headers_insert (self, "Name", "Brutus"); zre_msg_headers_insert (self, "Age", "%d", 43); // Send twice from same object zre_msg_send_again (self, output); zre_msg_send (&self, output); for (instance = 0; instance < 2; instance++) { self = zre_msg_recv (input); assert (self); assert (zre_msg_routing_id (self)); assert (zre_msg_sequence (self) == 123); assert (streq (zre_msg_ipaddress (self), "Life is short but Now lasts for ever")); assert (zre_msg_mailbox (self) == 123); assert (zre_msg_groups_size (self) == 2); assert (streq (zre_msg_groups_first (self), "Name: Brutus")); assert (streq (zre_msg_groups_next (self), "Age: 43")); assert (zre_msg_status (self) == 123); assert (zre_msg_headers_size (self) == 2); assert (streq (zre_msg_headers_string (self, "Name", "?"), "Brutus")); assert (zre_msg_headers_number (self, "Age", 0) == 43); zre_msg_destroy (&self); } self = zre_msg_new (ZRE_MSG_WHISPER); // Check that _dup works on empty message copy = zre_msg_dup (self); assert (copy); zre_msg_destroy (©); zre_msg_set_sequence (self, 123); zmsg_t *whisper_content = zmsg_new (); zre_msg_set_content (self, &whisper_content); zmsg_addstr (zre_msg_content (self), "Hello, World"); // Send twice from same object zre_msg_send_again (self, output); zre_msg_send (&self, output); for (instance = 0; instance < 2; instance++) { self = zre_msg_recv (input); assert (self); assert (zre_msg_routing_id (self)); assert (zre_msg_sequence (self) == 123); assert (zmsg_size (zre_msg_content (self)) == 1); zre_msg_destroy (&self); } self = zre_msg_new (ZRE_MSG_SHOUT); // Check that _dup works on empty message copy = zre_msg_dup (self); assert (copy); zre_msg_destroy (©); zre_msg_set_sequence (self, 123); zre_msg_set_group (self, "Life is short but Now lasts for ever"); zmsg_t *shout_content = zmsg_new (); zre_msg_set_content (self, &shout_content); zmsg_addstr (zre_msg_content (self), "Hello, World"); // Send twice from same object zre_msg_send_again (self, output); zre_msg_send (&self, output); for (instance = 0; instance < 2; instance++) { self = zre_msg_recv (input); assert (self); assert (zre_msg_routing_id (self)); assert (zre_msg_sequence (self) == 123); assert (streq (zre_msg_group (self), "Life is short but Now lasts for ever")); assert (zmsg_size (zre_msg_content (self)) == 1); zre_msg_destroy (&self); } self = zre_msg_new (ZRE_MSG_JOIN); // Check that _dup works on empty message copy = zre_msg_dup (self); assert (copy); zre_msg_destroy (©); zre_msg_set_sequence (self, 123); zre_msg_set_group (self, "Life is short but Now lasts for ever"); zre_msg_set_status (self, 123); // Send twice from same object zre_msg_send_again (self, output); zre_msg_send (&self, output); for (instance = 0; instance < 2; instance++) { self = zre_msg_recv (input); assert (self); assert (zre_msg_routing_id (self)); assert (zre_msg_sequence (self) == 123); assert (streq (zre_msg_group (self), "Life is short but Now lasts for ever")); assert (zre_msg_status (self) == 123); zre_msg_destroy (&self); } self = zre_msg_new (ZRE_MSG_LEAVE); // Check that _dup works on empty message copy = zre_msg_dup (self); assert (copy); zre_msg_destroy (©); zre_msg_set_sequence (self, 123); zre_msg_set_group (self, "Life is short but Now lasts for ever"); zre_msg_set_status (self, 123); // Send twice from same object zre_msg_send_again (self, output); zre_msg_send (&self, output); for (instance = 0; instance < 2; instance++) { self = zre_msg_recv (input); assert (self); assert (zre_msg_routing_id (self)); assert (zre_msg_sequence (self) == 123); assert (streq (zre_msg_group (self), "Life is short but Now lasts for ever")); assert (zre_msg_status (self) == 123); zre_msg_destroy (&self); } self = zre_msg_new (ZRE_MSG_PING); // Check that _dup works on empty message copy = zre_msg_dup (self); assert (copy); zre_msg_destroy (©); zre_msg_set_sequence (self, 123); // Send twice from same object zre_msg_send_again (self, output); zre_msg_send (&self, output); for (instance = 0; instance < 2; instance++) { self = zre_msg_recv (input); assert (self); assert (zre_msg_routing_id (self)); assert (zre_msg_sequence (self) == 123); zre_msg_destroy (&self); } self = zre_msg_new (ZRE_MSG_PING_OK); // Check that _dup works on empty message copy = zre_msg_dup (self); assert (copy); zre_msg_destroy (©); zre_msg_set_sequence (self, 123); // Send twice from same object zre_msg_send_again (self, output); zre_msg_send (&self, output); for (instance = 0; instance < 2; instance++) { self = zre_msg_recv (input); assert (self); assert (zre_msg_routing_id (self)); assert (zre_msg_sequence (self) == 123); zre_msg_destroy (&self); } zctx_destroy (&ctx); // @end printf ("OK\n"); return 0; }
int zre_msg_test (bool verbose) { printf (" * zre_msg: "); // @selftest // Simple create/destroy test zre_msg_t *self = zre_msg_new (0); assert (self); zre_msg_destroy (&self); // Create pair of sockets we can send through zctx_t *ctx = zctx_new (); assert (ctx); void *output = zsocket_new (ctx, ZMQ_DEALER); assert (output); zsocket_bind (output, "inproc://selftest"); void *input = zsocket_new (ctx, ZMQ_ROUTER); assert (input); zsocket_connect (input, "inproc://selftest"); // Encode/send/decode and verify each message type self = zre_msg_new (ZRE_MSG_HELLO); zre_msg_set_sequence (self, 123); zre_msg_set_ipaddress (self, "Life is short but Now lasts for ever"); zre_msg_set_mailbox (self, 123); zre_msg_groups_append (self, "Name: %s", "Brutus"); zre_msg_groups_append (self, "Age: %d", 43); zre_msg_set_status (self, 123); zre_msg_headers_insert (self, "Name", "Brutus"); zre_msg_headers_insert (self, "Age", "%d", 43); zre_msg_send (&self, output); self = zre_msg_recv (input); assert (self); assert (zre_msg_sequence (self) == 123); assert (streq (zre_msg_ipaddress (self), "Life is short but Now lasts for ever")); assert (zre_msg_mailbox (self) == 123); assert (zre_msg_groups_size (self) == 2); assert (streq (zre_msg_groups_first (self), "Name: Brutus")); assert (streq (zre_msg_groups_next (self), "Age: 43")); assert (zre_msg_status (self) == 123); assert (zre_msg_headers_size (self) == 2); assert (streq (zre_msg_headers_string (self, "Name", "?"), "Brutus")); assert (zre_msg_headers_number (self, "Age", 0) == 43); zre_msg_destroy (&self); self = zre_msg_new (ZRE_MSG_WHISPER); zre_msg_set_sequence (self, 123); zre_msg_set_content (self, zframe_new ("Captcha Diem", 12)); zre_msg_send (&self, output); self = zre_msg_recv (input); assert (self); assert (zre_msg_sequence (self) == 123); assert (zframe_streq (zre_msg_content (self), "Captcha Diem")); zre_msg_destroy (&self); self = zre_msg_new (ZRE_MSG_SHOUT); zre_msg_set_sequence (self, 123); zre_msg_set_group (self, "Life is short but Now lasts for ever"); zre_msg_set_content (self, zframe_new ("Captcha Diem", 12)); zre_msg_send (&self, output); self = zre_msg_recv (input); assert (self); assert (zre_msg_sequence (self) == 123); assert (streq (zre_msg_group (self), "Life is short but Now lasts for ever")); assert (zframe_streq (zre_msg_content (self), "Captcha Diem")); zre_msg_destroy (&self); self = zre_msg_new (ZRE_MSG_JOIN); zre_msg_set_sequence (self, 123); zre_msg_set_group (self, "Life is short but Now lasts for ever"); zre_msg_set_status (self, 123); zre_msg_send (&self, output); self = zre_msg_recv (input); assert (self); assert (zre_msg_sequence (self) == 123); assert (streq (zre_msg_group (self), "Life is short but Now lasts for ever")); assert (zre_msg_status (self) == 123); zre_msg_destroy (&self); self = zre_msg_new (ZRE_MSG_LEAVE); zre_msg_set_sequence (self, 123); zre_msg_set_group (self, "Life is short but Now lasts for ever"); zre_msg_set_status (self, 123); zre_msg_send (&self, output); self = zre_msg_recv (input); assert (self); assert (zre_msg_sequence (self) == 123); assert (streq (zre_msg_group (self), "Life is short but Now lasts for ever")); assert (zre_msg_status (self) == 123); zre_msg_destroy (&self); self = zre_msg_new (ZRE_MSG_PING); zre_msg_set_sequence (self, 123); zre_msg_send (&self, output); self = zre_msg_recv (input); assert (self); assert (zre_msg_sequence (self) == 123); zre_msg_destroy (&self); self = zre_msg_new (ZRE_MSG_PING_OK); zre_msg_set_sequence (self, 123); zre_msg_send (&self, output); self = zre_msg_recv (input); assert (self); assert (zre_msg_sequence (self) == 123); zre_msg_destroy (&self); zctx_destroy (&ctx); // @end printf ("OK\n"); return 0; }