int zgossip_msg_send (zgossip_msg_t **self_p, void *output) { assert (self_p); assert (*self_p); assert (output); // Save routing_id if any, as encode will destroy it zgossip_msg_t *self = *self_p; zframe_t *routing_id = self->routing_id; self->routing_id = NULL; // Encode zgossip_msg message to a single zmsg zmsg_t *msg = zgossip_msg_encode (&self); // If we're sending to a ROUTER, send the routing_id first if (zsocket_type (zsock_resolve (output)) == ZMQ_ROUTER) { assert (routing_id); zmsg_prepend (msg, &routing_id); } else zframe_destroy (&routing_id); if (msg && zmsg_send (&msg, output) == 0) return 0; else return -1; // Failed to encode, or send }
int mdp_client_send (mdp_client_t **self_p, void *socket) { assert (socket); assert (self_p); assert (*self_p); mdp_client_t *self = *self_p; // If we're sending to a ROUTER, we send the address first zmsg_t *msg = zmsg_new (); if (zsocket_type (socket) == ZMQ_ROUTER) { assert (self->address); zmsg_add (msg, self->address); self->address = NULL; // Owned by msg now } // Send header fields zmsg_addstr (msg, ""); zmsg_addstr (msg, "MDPC01"); // All messages have the same structure zmsg_addstr (msg, self->service); zmsg_add (msg, self->body); self->body = NULL; // Send the message and destroy mdp_client object int rc = zmsg_send (&msg, socket); mdp_client_destroy (self_p); return rc; }
zre_msg_t * zre_msg_recv_nowait (void *input) { assert (input); zmsg_t *msg = zmsg_recv_nowait (input); return zre_msg_decode (&msg, zsocket_type (input)); }
zgossip_msg_t * zgossip_msg_recv_nowait (void *input) { assert (input); zmsg_t *msg = zmsg_recv_nowait (input); // If message came from a router socket, first frame is routing_id zframe_t *routing_id = NULL; if (zsocket_type (zsock_resolve (input)) == ZMQ_ROUTER) { routing_id = zmsg_pop (msg); // If message was not valid, forget about it if (!routing_id || !zmsg_next (msg)) return NULL; // Malformed or empty } zgossip_msg_t * zgossip_msg = zgossip_msg_decode (&msg); if (zsocket_type (zsock_resolve (input)) == ZMQ_ROUTER) zgossip_msg->routing_id = routing_id; return zgossip_msg; }
int zre_msg_send (zre_msg_t **self_p, void *output) { assert (self_p); assert (*self_p); assert (output); zre_msg_t *self = *self_p; zmsg_t *msg = zre_msg_encode (self, zsocket_type (output)); if (msg && zmsg_send (&msg, output) == 0) return 0; else return -1; // Failed to encode, or send }
mdp_client_t * mdp_client_recv (void *socket) { // Read all frames off socket assert (socket); zmsg_t *msg = zmsg_recv (socket); if (!msg) return NULL; // Interrupted // Create and populate new mdp_client instance mdp_client_t *self = mdp_client_new (); // If we're reading from a ROUTER socket, get address if (zsocket_type (socket) == ZMQ_ROUTER) { self->address = zmsg_pop (msg); if (!self->address) goto empty; // Interrupted } // Read and check header zframe_t *empty_frame = zmsg_pop (msg); if (!empty_frame || !zframe_streq (empty_frame, "")) goto malformed; zframe_destroy (&empty_frame); zframe_t *protocol_frame = zmsg_pop (msg); if (!protocol_frame || !zframe_streq (protocol_frame, "MDPC01")) goto malformed; zframe_destroy (&protocol_frame); // All messages have the same structure self->service = zmsg_popstr (msg); if (!self->service) goto malformed; self->body = zmsg_pop (msg); if (!self->body) goto malformed; // Successful return zmsg_destroy (&msg); return self; // Error returns malformed: printf ("E: malformed message '%d'\n", self->id); empty: zmsg_destroy (&msg); mdp_client_destroy (&self); return (NULL); }
const char * zsocket_type_str (void *self) { char *type_name [] = { "PAIR", "PUB", "SUB", "REQ", "REP", "DEALER", "ROUTER", "PULL", "PUSH", "XPUB", "XSUB", "STREAM" }; int type = zsocket_type (self); #if ZMQ_VERSION_MAJOR == 4 if (type < 0 || type > ZMQ_STREAM) #else if (type < 0 || type > ZMQ_XSUB) #endif return "UNKNOWN"; else return type_name [type]; }
const char * zsocket_type_str (void *self) { assert (self); return zsys_sockname (zsocket_type (self)); }
int zsockopt_test (bool verbose) { printf (" * zsockopt: "); // @selftest zctx_t *ctx = zctx_new (); assert (ctx); void *zocket; #if (ZMQ_VERSION_MAJOR == 2) # if defined (ZMQ_HWM) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_hwm (zocket, 1); assert (zsocket_hwm (zocket) == 1); zsocket_hwm (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_SWAP) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_swap (zocket, 1); assert (zsocket_swap (zocket) == 1); zsocket_swap (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_AFFINITY) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_affinity (zocket, 1); assert (zsocket_affinity (zocket) == 1); zsocket_affinity (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_IDENTITY) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_identity (zocket, "test"); char *identity = zsocket_identity (zocket); assert (identity); free (identity); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_RATE) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_rate (zocket, 1); assert (zsocket_rate (zocket) == 1); zsocket_rate (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_RECOVERY_IVL) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_recovery_ivl (zocket, 1); assert (zsocket_recovery_ivl (zocket) == 1); zsocket_recovery_ivl (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_RECOVERY_IVL_MSEC) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_recovery_ivl_msec (zocket, 1); assert (zsocket_recovery_ivl_msec (zocket) == 1); zsocket_recovery_ivl_msec (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_MCAST_LOOP) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_mcast_loop (zocket, 1); assert (zsocket_mcast_loop (zocket) == 1); zsocket_mcast_loop (zocket); zsocket_destroy (ctx, zocket); # endif # if (ZMQ_VERSION_MINOR == 2) # if defined (ZMQ_RCVTIMEO) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_rcvtimeo (zocket, 1); assert (zsocket_rcvtimeo (zocket) == 1); zsocket_rcvtimeo (zocket); zsocket_destroy (ctx, zocket); # endif # endif # if (ZMQ_VERSION_MINOR == 2) # if defined (ZMQ_SNDTIMEO) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_sndtimeo (zocket, 1); assert (zsocket_sndtimeo (zocket) == 1); zsocket_sndtimeo (zocket); zsocket_destroy (ctx, zocket); # endif # endif # if defined (ZMQ_SNDBUF) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_sndbuf (zocket, 1); assert (zsocket_sndbuf (zocket) == 1); zsocket_sndbuf (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_RCVBUF) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_rcvbuf (zocket, 1); assert (zsocket_rcvbuf (zocket) == 1); zsocket_rcvbuf (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_LINGER) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_linger (zocket, 1); assert (zsocket_linger (zocket) == 1); zsocket_linger (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_RECONNECT_IVL) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_reconnect_ivl (zocket, 1); assert (zsocket_reconnect_ivl (zocket) == 1); zsocket_reconnect_ivl (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_RECONNECT_IVL_MAX) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_reconnect_ivl_max (zocket, 1); assert (zsocket_reconnect_ivl_max (zocket) == 1); zsocket_reconnect_ivl_max (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_BACKLOG) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_backlog (zocket, 1); assert (zsocket_backlog (zocket) == 1); zsocket_backlog (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_SUBSCRIBE) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_subscribe (zocket, "test"); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_UNSUBSCRIBE) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_unsubscribe (zocket, "test"); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_TYPE) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_type (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_RCVMORE) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_rcvmore (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_FD) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_fd (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_EVENTS) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_events (zocket); zsocket_destroy (ctx, zocket); # endif #endif #if (ZMQ_VERSION_MAJOR == 3) # if defined (ZMQ_TYPE) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_type (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_SNDHWM) zocket = zsocket_new (ctx, ZMQ_PUB); assert (zocket); zsocket_set_sndhwm (zocket, 1); assert (zsocket_sndhwm (zocket) == 1); zsocket_sndhwm (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_RCVHWM) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_rcvhwm (zocket, 1); assert (zsocket_rcvhwm (zocket) == 1); zsocket_rcvhwm (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_AFFINITY) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_affinity (zocket, 1); assert (zsocket_affinity (zocket) == 1); zsocket_affinity (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_SUBSCRIBE) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_subscribe (zocket, "test"); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_UNSUBSCRIBE) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_unsubscribe (zocket, "test"); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_IDENTITY) zocket = zsocket_new (ctx, ZMQ_DEALER); assert (zocket); zsocket_set_identity (zocket, "test"); char *identity = zsocket_identity (zocket); assert (identity); free (identity); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_RATE) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_rate (zocket, 1); assert (zsocket_rate (zocket) == 1); zsocket_rate (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_RECOVERY_IVL) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_recovery_ivl (zocket, 1); assert (zsocket_recovery_ivl (zocket) == 1); zsocket_recovery_ivl (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_SNDBUF) zocket = zsocket_new (ctx, ZMQ_PUB); assert (zocket); zsocket_set_sndbuf (zocket, 1); assert (zsocket_sndbuf (zocket) == 1); zsocket_sndbuf (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_RCVBUF) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_rcvbuf (zocket, 1); assert (zsocket_rcvbuf (zocket) == 1); zsocket_rcvbuf (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_LINGER) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_linger (zocket, 1); assert (zsocket_linger (zocket) == 1); zsocket_linger (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_RECONNECT_IVL) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_reconnect_ivl (zocket, 1); assert (zsocket_reconnect_ivl (zocket) == 1); zsocket_reconnect_ivl (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_RECONNECT_IVL_MAX) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_reconnect_ivl_max (zocket, 1); assert (zsocket_reconnect_ivl_max (zocket) == 1); zsocket_reconnect_ivl_max (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_BACKLOG) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_backlog (zocket, 1); assert (zsocket_backlog (zocket) == 1); zsocket_backlog (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_MAXMSGSIZE) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_maxmsgsize (zocket, 1); assert (zsocket_maxmsgsize (zocket) == 1); zsocket_maxmsgsize (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_MULTICAST_HOPS) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_multicast_hops (zocket, 1); assert (zsocket_multicast_hops (zocket) == 1); zsocket_multicast_hops (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_RCVTIMEO) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_rcvtimeo (zocket, 1); assert (zsocket_rcvtimeo (zocket) == 1); zsocket_rcvtimeo (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_SNDTIMEO) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_sndtimeo (zocket, 1); assert (zsocket_sndtimeo (zocket) == 1); zsocket_sndtimeo (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_IPV4ONLY) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_set_ipv4only (zocket, 1); assert (zsocket_ipv4only (zocket) == 1); zsocket_ipv4only (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_DELAY_ATTACH_ON_CONNECT) zocket = zsocket_new (ctx, ZMQ_PUB); assert (zocket); zsocket_set_delay_attach_on_connect (zocket, 1); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_ROUTER_MANDATORY) zocket = zsocket_new (ctx, ZMQ_ROUTER); assert (zocket); zsocket_set_router_mandatory (zocket, 1); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_ROUTER_RAW) zocket = zsocket_new (ctx, ZMQ_ROUTER); assert (zocket); zsocket_set_router_raw (zocket, 1); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_XPUB_VERBOSE) zocket = zsocket_new (ctx, ZMQ_XPUB); assert (zocket); zsocket_set_xpub_verbose (zocket, 1); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_RCVMORE) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_rcvmore (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_FD) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_fd (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_EVENTS) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); zsocket_events (zocket); zsocket_destroy (ctx, zocket); # endif # if defined (ZMQ_LAST_ENDPOINT) zocket = zsocket_new (ctx, ZMQ_SUB); assert (zocket); char *last_endpoint = zsocket_last_endpoint (zocket); assert (last_endpoint); free (last_endpoint); zsocket_destroy (ctx, zocket); # endif zocket = zsocket_new (ctx, ZMQ_SUB); zsocket_set_hwm (zocket, 1); #endif zctx_destroy (&ctx); // @end printf ("OK\n"); return 0; }
int zre_log_msg_send (zre_log_msg_t **self_p, void *output) { assert (output); assert (self_p); assert (*self_p); // Calculate size of serialized data zre_log_msg_t *self = *self_p; size_t frame_size = 2 + 1; // Signature and message ID switch (self->id) { case ZRE_LOG_MSG_LOG: // level is a 1-byte integer frame_size += 1; // event is a 1-byte integer frame_size += 1; // node is a 2-byte integer frame_size += 2; // peer is a 2-byte integer frame_size += 2; // time is a 8-byte integer frame_size += 8; // data is a string with 1-byte length frame_size++; // Size is one octet if (self->data) frame_size += strlen (self->data); break; default: printf ("E: bad message type '%d', not sent\n", self->id); // No recovery, this is a fatal application error assert (false); } // Now serialize message into the frame zframe_t *frame = zframe_new (NULL, frame_size); self->needle = zframe_data (frame); size_t string_size; int frame_flags = 0; PUT_NUMBER2 (0xAAA0 | 2); PUT_NUMBER1 (self->id); switch (self->id) { case ZRE_LOG_MSG_LOG: PUT_NUMBER1 (self->level); PUT_NUMBER1 (self->event); PUT_NUMBER2 (self->node); PUT_NUMBER2 (self->peer); PUT_NUMBER8 (self->time); if (self->data) { PUT_STRING (self->data); } else PUT_NUMBER1 (0); // Empty string break; } // If we're sending to a ROUTER, we send the address first if (zsocket_type (output) == ZMQ_ROUTER) { assert (self->address); if (zframe_send (&self->address, output, ZFRAME_MORE)) { zframe_destroy (&frame); zre_log_msg_destroy (self_p); return -1; } } // Now send the data frame if (zframe_send (&frame, output, frame_flags)) { zframe_destroy (&frame); zre_log_msg_destroy (self_p); return -1; } // Destroy zre_log_msg object zre_log_msg_destroy (self_p); return 0; }
zre_log_msg_t * zre_log_msg_recv (void *input) { assert (input); zre_log_msg_t *self = zre_log_msg_new (0); zframe_t *frame = NULL; size_t string_size; size_t list_size; size_t hash_size; // Read valid message frame from socket; we loop over any // garbage data we might receive from badly-connected peers while (true) { // If we're reading from a ROUTER socket, get address if (zsocket_type (input) == ZMQ_ROUTER) { zframe_destroy (&self->address); self->address = zframe_recv (input); if (!self->address) goto empty; // Interrupted if (!zsocket_rcvmore (input)) goto malformed; } // Read and parse command in frame frame = zframe_recv (input); if (!frame) goto empty; // Interrupted // Get and check protocol signature self->needle = zframe_data (frame); self->ceiling = self->needle + zframe_size (frame); uint16_t signature; GET_NUMBER2 (signature); if (signature == (0xAAA0 | 2)) break; // Valid signature // Protocol assertion, drop message while (zsocket_rcvmore (input)) { zframe_destroy (&frame); frame = zframe_recv (input); } zframe_destroy (&frame); } // Get message id and parse per message type GET_NUMBER1 (self->id); switch (self->id) { case ZRE_LOG_MSG_LOG: GET_NUMBER1 (self->level); GET_NUMBER1 (self->event); GET_NUMBER2 (self->node); GET_NUMBER2 (self->peer); GET_NUMBER8 (self->time); free (self->data); GET_STRING (self->data); break; default: goto malformed; } // Successful return zframe_destroy (&frame); return self; // Error returns malformed: printf ("E: malformed message '%d'\n", self->id); empty: zframe_destroy (&frame); zre_log_msg_destroy (&self); return (NULL); }
int zre_msg_send (zre_msg_t **self_p, void *output) { assert (output); assert (self_p); assert (*self_p); // Calculate size of serialized data zre_msg_t *self = *self_p; size_t frame_size = 2 + 1; // Signature and message ID switch (self->id) { case ZRE_MSG_HELLO: // sequence is a 2-byte integer frame_size += 2; // ipaddress is a string with 1-byte length frame_size++; // Size is one octet if (self->ipaddress) frame_size += strlen (self->ipaddress); // mailbox is a 2-byte integer frame_size += 2; // groups is an array of strings frame_size++; // Size is one octet if (self->groups) { // Add up size of list contents char *groups = (char *) zlist_first (self->groups); while (groups) { frame_size += 1 + strlen (groups); groups = (char *) zlist_next (self->groups); } } // status is a 1-byte integer frame_size += 1; // headers is an array of key=value strings frame_size++; // Size is one octet if (self->headers) { self->headers_bytes = 0; // Add up size of dictionary contents zhash_foreach (self->headers, s_headers_count, self); } frame_size += self->headers_bytes; break; case ZRE_MSG_WHISPER: // sequence is a 2-byte integer frame_size += 2; break; case ZRE_MSG_SHOUT: // sequence is a 2-byte integer frame_size += 2; // group is a string with 1-byte length frame_size++; // Size is one octet if (self->group) frame_size += strlen (self->group); break; case ZRE_MSG_JOIN: // sequence is a 2-byte integer frame_size += 2; // group is a string with 1-byte length frame_size++; // Size is one octet if (self->group) frame_size += strlen (self->group); // status is a 1-byte integer frame_size += 1; break; case ZRE_MSG_LEAVE: // sequence is a 2-byte integer frame_size += 2; // group is a string with 1-byte length frame_size++; // Size is one octet if (self->group) frame_size += strlen (self->group); // status is a 1-byte integer frame_size += 1; break; case ZRE_MSG_PING: // sequence is a 2-byte integer frame_size += 2; break; case ZRE_MSG_PING_OK: // sequence is a 2-byte integer frame_size += 2; break; default: printf ("E: bad message type '%d', not sent\n", self->id); // No recovery, this is a fatal application error assert (false); } // Now serialize message into the frame zframe_t *frame = zframe_new (NULL, frame_size); self->needle = zframe_data (frame); size_t string_size; int frame_flags = 0; PUT_NUMBER2 (0xAAA0 | 1); PUT_NUMBER1 (self->id); switch (self->id) { case ZRE_MSG_HELLO: PUT_NUMBER2 (self->sequence); if (self->ipaddress) { PUT_STRING (self->ipaddress); } else PUT_NUMBER1 (0); // Empty string PUT_NUMBER2 (self->mailbox); if (self->groups != NULL) { PUT_NUMBER1 (zlist_size (self->groups)); char *groups = (char *) zlist_first (self->groups); while (groups) { PUT_STRING (groups); groups = (char *) zlist_next (self->groups); } } else PUT_NUMBER1 (0); // Empty string array PUT_NUMBER1 (self->status); if (self->headers != NULL) { PUT_NUMBER1 (zhash_size (self->headers)); zhash_foreach (self->headers, s_headers_write, self); } else PUT_NUMBER1 (0); // Empty dictionary break; case ZRE_MSG_WHISPER: PUT_NUMBER2 (self->sequence); frame_flags = ZFRAME_MORE; break; case ZRE_MSG_SHOUT: PUT_NUMBER2 (self->sequence); if (self->group) { PUT_STRING (self->group); } else PUT_NUMBER1 (0); // Empty string frame_flags = ZFRAME_MORE; break; case ZRE_MSG_JOIN: PUT_NUMBER2 (self->sequence); if (self->group) { PUT_STRING (self->group); } else PUT_NUMBER1 (0); // Empty string PUT_NUMBER1 (self->status); break; case ZRE_MSG_LEAVE: PUT_NUMBER2 (self->sequence); if (self->group) { PUT_STRING (self->group); } else PUT_NUMBER1 (0); // Empty string PUT_NUMBER1 (self->status); break; case ZRE_MSG_PING: PUT_NUMBER2 (self->sequence); break; case ZRE_MSG_PING_OK: PUT_NUMBER2 (self->sequence); break; } // If we're sending to a ROUTER, we send the address first if (zsocket_type (output) == ZMQ_ROUTER) { assert (self->address); if (zframe_send (&self->address, output, ZFRAME_MORE)) { zframe_destroy (&frame); zre_msg_destroy (self_p); return -1; } } // Now send the data frame if (zframe_send (&frame, output, frame_flags)) { zframe_destroy (&frame); zre_msg_destroy (self_p); return -1; } // Now send any frame fields, in order switch (self->id) { case ZRE_MSG_WHISPER: // If content isn't set, send an empty frame if (!self->content) self->content = zframe_new (NULL, 0); if (zframe_send (&self->content, output, 0)) { zframe_destroy (&frame); zre_msg_destroy (self_p); return -1; } break; case ZRE_MSG_SHOUT: // If content isn't set, send an empty frame if (!self->content) self->content = zframe_new (NULL, 0); if (zframe_send (&self->content, output, 0)) { zframe_destroy (&frame); zre_msg_destroy (self_p); return -1; } break; } // Destroy zre_msg object zre_msg_destroy (self_p); return 0; }
zre_msg_t * zre_msg_recv (void *input) { assert (input); zre_msg_t *self = zre_msg_new (0); zframe_t *frame = NULL; size_t string_size; size_t list_size; size_t hash_size; // Read valid message frame from socket; we loop over any // garbage data we might receive from badly-connected peers while (true) { // If we're reading from a ROUTER socket, get address if (zsocket_type (input) == ZMQ_ROUTER) { zframe_destroy (&self->address); self->address = zframe_recv (input); if (!self->address) goto empty; // Interrupted if (!zsocket_rcvmore (input)) goto malformed; } // Read and parse command in frame frame = zframe_recv (input); if (!frame) goto empty; // Interrupted // Get and check protocol signature self->needle = zframe_data (frame); self->ceiling = self->needle + zframe_size (frame); uint16_t signature; GET_NUMBER2 (signature); if (signature == (0xAAA0 | 1)) break; // Valid signature // Protocol assertion, drop message while (zsocket_rcvmore (input)) { zframe_destroy (&frame); frame = zframe_recv (input); } zframe_destroy (&frame); } // Get message id and parse per message type GET_NUMBER1 (self->id); switch (self->id) { case ZRE_MSG_HELLO: GET_NUMBER2 (self->sequence); free (self->ipaddress); GET_STRING (self->ipaddress); GET_NUMBER2 (self->mailbox); GET_NUMBER1 (list_size); self->groups = zlist_new (); zlist_autofree (self->groups); while (list_size--) { char *string; GET_STRING (string); zlist_append (self->groups, string); free (string); } GET_NUMBER1 (self->status); GET_NUMBER1 (hash_size); self->headers = zhash_new (); zhash_autofree (self->headers); while (hash_size--) { char *string; GET_STRING (string); char *value = strchr (string, '='); if (value) *value++ = 0; zhash_insert (self->headers, string, value); free (string); } break; case ZRE_MSG_WHISPER: GET_NUMBER2 (self->sequence); // Get next frame, leave current untouched if (!zsocket_rcvmore (input)) goto malformed; self->content = zframe_recv (input); break; case ZRE_MSG_SHOUT: GET_NUMBER2 (self->sequence); free (self->group); GET_STRING (self->group); // Get next frame, leave current untouched if (!zsocket_rcvmore (input)) goto malformed; self->content = zframe_recv (input); break; case ZRE_MSG_JOIN: GET_NUMBER2 (self->sequence); free (self->group); GET_STRING (self->group); GET_NUMBER1 (self->status); break; case ZRE_MSG_LEAVE: GET_NUMBER2 (self->sequence); free (self->group); GET_STRING (self->group); GET_NUMBER1 (self->status); break; case ZRE_MSG_PING: GET_NUMBER2 (self->sequence); break; case ZRE_MSG_PING_OK: GET_NUMBER2 (self->sequence); break; default: goto malformed; } // Successful return zframe_destroy (&frame); return self; // Error returns malformed: printf ("E: malformed message '%d'\n", self->id); empty: zframe_destroy (&frame); zre_msg_destroy (&self); return (NULL); }