zre_log_msg_t * zre_log_msg_decode (zmsg_t **msg_p) { assert (msg_p); zmsg_t *msg = *msg_p; if (msg == NULL) return NULL; zre_log_msg_t *self = zre_log_msg_new (0); // Read and parse command in frame zframe_t *frame = zmsg_pop (msg); if (!frame) goto empty; // Malformed or empty // 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)) goto empty; // Invalid signature // 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); GET_STRING (self->data); break; default: goto malformed; } // Successful return zframe_destroy (&frame); zmsg_destroy (msg_p); return self; // Error returns malformed: printf ("E: malformed message '%d'\n", self->id); empty: zframe_destroy (&frame); zmsg_destroy (msg_p); zre_log_msg_destroy (&self); return (NULL); }
zgossip_msg_t * zgossip_msg_decode (zmsg_t **msg_p) { assert (msg_p); zmsg_t *msg = *msg_p; if (msg == NULL) return NULL; zgossip_msg_t *self = zgossip_msg_new (0); // Read and parse command in frame zframe_t *frame = zmsg_pop (msg); if (!frame) goto empty; // Malformed or empty // 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 | 0)) goto empty; // Invalid signature // Get message id and parse per message type GET_NUMBER1 (self->id); switch (self->id) { case ZGOSSIP_MSG_HELLO: break; case ZGOSSIP_MSG_ANNOUNCE: GET_STRING (self->endpoint); GET_STRING (self->service); break; case ZGOSSIP_MSG_PING: break; case ZGOSSIP_MSG_PONG: break; case ZGOSSIP_MSG_INVALID: break; default: goto malformed; } // Successful return zframe_destroy (&frame); zmsg_destroy (msg_p); return self; // Error returns malformed: printf ("E: malformed message '%d'\n", self->id); empty: zframe_destroy (&frame); zmsg_destroy (msg_p); zgossip_msg_destroy (&self); return (NULL); }
int zmailer_msg_recv (zmailer_msg_t *self, zsock_t *input) { assert (input); if (zsock_type (input) == ZMQ_ROUTER) { zframe_destroy (&self->routing_id); self->routing_id = zframe_recv (input); if (!self->routing_id || !zsock_rcvmore (input)) { zsys_warning ("zmailer_msg: no routing ID"); return -1; // Interrupted or malformed } } zmq_msg_t frame; zmq_msg_init (&frame); int size = zmq_msg_recv (&frame, zsock_resolve (input), 0); if (size == -1) { zsys_warning ("zmailer_msg: interrupted"); goto malformed; // Interrupted } // Get and check protocol signature self->needle = (byte *) zmq_msg_data (&frame); self->ceiling = self->needle + zmq_msg_size (&frame); uint16_t signature; GET_NUMBER2 (signature); if (signature != (0xAAA0 | 0)) { zsys_warning ("zmailer_msg: invalid signature"); // TODO: discard invalid messages and loop, and return // -1 only on interrupt goto malformed; // Interrupted } // Get message id and parse per message type GET_NUMBER1 (self->id); switch (self->id) { case ZMAILER_MSG_MAIL: { uint16_t version; GET_NUMBER2 (version); if (version != 1) { zsys_warning ("zmailer_msg: version is invalid"); goto malformed; } } GET_STRING (self->from); GET_LONGSTR (self->to); GET_LONGSTR (self->subject); GET_LONGSTR (self->request); break; default: zsys_warning ("zmailer_msg: bad message ID"); goto malformed; } // Successful return zmq_msg_close (&frame); return 0; // Error returns malformed: zsys_warning ("zmailer_msg: zmailer_msg malformed message, fail"); zmq_msg_close (&frame); return -1; // Invalid message }
int zpubsub_filter_recv (zpubsub_filter_t *self, zsock_t *input) { assert (input); if (zsock_type (input) == ZMQ_ROUTER) { zframe_destroy (&self->routing_id); self->routing_id = zframe_recv (input); if (!self->routing_id || !zsock_rcvmore (input)) { zsys_warning ("zpubsub_filter: no routing ID"); return -1; // Interrupted or malformed } } zmq_msg_t frame; zmq_msg_init (&frame); int size = zmq_msg_recv (&frame, zsock_resolve (input), 0); if (size == -1) { zsys_warning ("zpubsub_filter: interrupted"); goto malformed; // Interrupted } // Get and check protocol signature self->needle = (byte *) zmq_msg_data (&frame); self->ceiling = self->needle + zmq_msg_size (&frame); uint16_t signature; GET_NUMBER2 (signature); if (signature != (0xAAA0 | 7)) { zsys_warning ("zpubsub_filter: invalid signature"); // TODO: discard invalid messages and loop, and return // -1 only on interrupt goto malformed; // Interrupted } // Get message id and parse per message type GET_NUMBER1 (self->id); switch (self->id) { case ZPUBSUB_FILTER_FILTER: { uint16_t magic; GET_NUMBER2 (magic); if (magic != ZPUBSUB_FILTER_MAGIC_NUMBER) { zsys_warning ("zpubsub_filter: magic is invalid"); goto malformed; } } { uint16_t version; GET_NUMBER2 (version); if (version != ZPUBSUB_FILTER_VERSION) { zsys_warning ("zpubsub_filter: version is invalid"); goto malformed; } } GET_STRING (self->partition); GET_STRING (self->topic); break; default: zsys_warning ("zpubsub_filter: bad message ID"); goto malformed; } // Successful return zmq_msg_close (&frame); return 0; // Error returns malformed: zsys_warning ("zpubsub_filter: zpubsub_filter malformed message, fail"); zmq_msg_close (&frame); return -1; // Invalid message }
zre_msg_t * zre_msg_decode (zmsg_t **msg_p, int socket_type) { assert (msg_p); zmsg_t *msg = *msg_p; if (msg == NULL) return NULL; zre_msg_t *self = zre_msg_new (0); // If message came from a router socket, first frame is routing_id if (socket_type == ZMQ_ROUTER) { self->routing_id = zmsg_pop (msg); // If message was not valid, forget about it if (!self->routing_id || !zmsg_next (msg)) { zre_msg_destroy (&self); return (NULL); // Malformed or empty } } // Read and parse command in frame zframe_t *frame = zmsg_pop (msg); if (!frame) goto empty; // Malformed or empty // 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)) goto empty; // Invalid signature // Get message id and parse per message type GET_NUMBER1 (self->id); switch (self->id) { case ZRE_MSG_HELLO: GET_NUMBER2 (self->sequence); GET_STRING (self->ipaddress); GET_NUMBER2 (self->mailbox); { size_t list_size; GET_NUMBER4 (list_size); self->groups = zlist_new (); zlist_autofree (self->groups); while (list_size--) { char *string; GET_LONGSTR (string); zlist_append (self->groups, string); free (string); } } GET_NUMBER1 (self->status); { size_t hash_size; GET_NUMBER4 (hash_size); self->headers = zhash_new (); zhash_autofree (self->headers); while (hash_size--) { char *key, *value; GET_STRING (key); GET_LONGSTR (value); zhash_insert (self->headers, key, value); free (key); free (value); } } break; case ZRE_MSG_WHISPER: GET_NUMBER2 (self->sequence); // Get zero or more remaining frames, leaving current // frame untouched self->content = zmsg_new (); while (zmsg_size (msg)) zmsg_add (self->content, zmsg_pop (msg)); break; case ZRE_MSG_SHOUT: GET_NUMBER2 (self->sequence); GET_STRING (self->group); // Get zero or more remaining frames, leaving current // frame untouched self->content = zmsg_new (); while (zmsg_size (msg)) zmsg_add (self->content, zmsg_pop (msg)); break; case ZRE_MSG_JOIN: GET_NUMBER2 (self->sequence); GET_STRING (self->group); GET_NUMBER1 (self->status); break; case ZRE_MSG_LEAVE: GET_NUMBER2 (self->sequence); 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); zmsg_destroy (msg_p); return self; // Error returns malformed: printf ("E: malformed message '%d'\n", self->id); empty: zframe_destroy (&frame); zmsg_destroy (msg_p); zre_msg_destroy (&self); return (NULL); }
int mdp_client_msg_recv (mdp_client_msg_t *self, zsock_t *input) { assert (input); if (zsock_type (input) == ZMQ_ROUTER) { zframe_destroy (&self->routing_id); self->routing_id = zframe_recv (input); if (!self->routing_id || !zsock_rcvmore (input)) { zsys_warning ("mdp_client_msg: no routing ID"); return -1; // Interrupted or malformed } } zmq_msg_t frame; zmq_msg_init (&frame); int size = zmq_msg_recv (&frame, zsock_resolve (input), 0); if (size == -1) { zsys_warning ("mdp_client_msg: interrupted"); goto malformed; // Interrupted } // Get and check protocol signature self->needle = (byte *) zmq_msg_data (&frame); self->ceiling = self->needle + zmq_msg_size (&frame); uint16_t signature; GET_NUMBER2 (signature); if (signature != (0xAAA0 | 4)) { zsys_warning ("mdp_client_msg: invalid signature"); // TODO: discard invalid messages and loop, and return // -1 only on interrupt goto malformed; // Interrupted } // Get message id and parse per message type GET_NUMBER1 (self->id); switch (self->id) { case MDP_CLIENT_MSG_CLIENT_REQUEST: { char version [256]; GET_STRING (version); if (strneq (version, "MDPC02")) { zsys_warning ("mdp_client_msg: version is invalid"); goto malformed; } } { byte messageid; GET_NUMBER1 (messageid); if (messageid != 1) { zsys_warning ("mdp_client_msg: messageid is invalid"); goto malformed; } } GET_STRING (self->service); // Get zero or more remaining frames zmsg_destroy (&self->body); if (zsock_rcvmore (input)) self->body = zmsg_recv (input); else self->body = zmsg_new (); break; case MDP_CLIENT_MSG_CLIENT_PARTIAL: { char version [256]; GET_STRING (version); if (strneq (version, "MDPC02")) { zsys_warning ("mdp_client_msg: version is invalid"); goto malformed; } } { byte messageid; GET_NUMBER1 (messageid); if (messageid != 2) { zsys_warning ("mdp_client_msg: messageid is invalid"); goto malformed; } } GET_STRING (self->service); // Get zero or more remaining frames zmsg_destroy (&self->body); if (zsock_rcvmore (input)) self->body = zmsg_recv (input); else self->body = zmsg_new (); break; case MDP_CLIENT_MSG_CLIENT_FINAL: { char version [256]; GET_STRING (version); if (strneq (version, "MDPC02")) { zsys_warning ("mdp_client_msg: version is invalid"); goto malformed; } } { byte messageid; GET_NUMBER1 (messageid); if (messageid != 3) { zsys_warning ("mdp_client_msg: messageid is invalid"); goto malformed; } } GET_STRING (self->service); // Get zero or more remaining frames zmsg_destroy (&self->body); if (zsock_rcvmore (input)) self->body = zmsg_recv (input); else self->body = zmsg_new (); break; default: zsys_warning ("mdp_client_msg: bad message ID"); goto malformed; } // Successful return zmq_msg_close (&frame); return 0; // Error returns malformed: zsys_warning ("mdp_client_msg: mdp_client_msg malformed message, fail"); zmq_msg_close (&frame); return -1; // Invalid message }
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 fmq_msg_recv (fmq_msg_t *self, zsock_t *input) { assert (input); if (zsock_type (input) == ZMQ_ROUTER) { zframe_destroy (&self->routing_id); self->routing_id = zframe_recv (input); if (!self->routing_id || !zsock_rcvmore (input)) { zsys_warning ("fmq_msg: no routing ID"); return -1; // Interrupted or malformed } } zmq_msg_t frame; zmq_msg_init (&frame); int size = zmq_msg_recv (&frame, zsock_resolve (input), 0); if (size == -1) { zsys_warning ("fmq_msg: interrupted"); goto malformed; // Interrupted } // Get and check protocol signature self->needle = (byte *) zmq_msg_data (&frame); self->ceiling = self->needle + zmq_msg_size (&frame); uint16_t signature; GET_NUMBER2 (signature); if (signature != (0xAAA0 | 3)) { zsys_warning ("fmq_msg: invalid signature"); // TODO: discard invalid messages and loop, and return // -1 only on interrupt goto malformed; // Interrupted } // Get message id and parse per message type GET_NUMBER1 (self->id); switch (self->id) { case FMQ_MSG_OHAI: { char protocol [256]; GET_STRING (protocol); if (strneq (protocol, "FILEMQ")) { zsys_warning ("fmq_msg: protocol is invalid"); goto malformed; } } { uint16_t version; GET_NUMBER2 (version); if (version != FMQ_MSG_VERSION) { zsys_warning ("fmq_msg: version is invalid"); goto malformed; } } break; case FMQ_MSG_OHAI_OK: break; case FMQ_MSG_ICANHAZ: GET_LONGSTR (self->path); { size_t hash_size; GET_NUMBER4 (hash_size); self->options = zhash_new (); zhash_autofree (self->options); while (hash_size--) { char key [256]; char *value = NULL; GET_STRING (key); GET_LONGSTR (value); zhash_insert (self->options, key, value); free (value); } } { size_t hash_size; GET_NUMBER4 (hash_size); self->cache = zhash_new (); zhash_autofree (self->cache); while (hash_size--) { char key [256]; char *value = NULL; GET_STRING (key); GET_LONGSTR (value); zhash_insert (self->cache, key, value); free (value); } } break; case FMQ_MSG_ICANHAZ_OK: break; case FMQ_MSG_NOM: GET_NUMBER8 (self->credit); GET_NUMBER8 (self->sequence); break; case FMQ_MSG_CHEEZBURGER: GET_NUMBER8 (self->sequence); GET_NUMBER1 (self->operation); GET_LONGSTR (self->filename); GET_NUMBER8 (self->offset); GET_NUMBER1 (self->eof); { size_t hash_size; GET_NUMBER4 (hash_size); self->headers = zhash_new (); zhash_autofree (self->headers); while (hash_size--) { char key [256]; char *value = NULL; GET_STRING (key); GET_LONGSTR (value); zhash_insert (self->headers, key, value); free (value); } } { size_t chunk_size; GET_NUMBER4 (chunk_size); if (self->needle + chunk_size > (self->ceiling)) { zsys_warning ("fmq_msg: chunk is missing data"); goto malformed; } zchunk_destroy (&self->chunk); self->chunk = zchunk_new (self->needle, chunk_size); self->needle += chunk_size; } break; case FMQ_MSG_HUGZ: break; case FMQ_MSG_HUGZ_OK: break; case FMQ_MSG_KTHXBAI: break; case FMQ_MSG_SRSLY: GET_STRING (self->reason); break; case FMQ_MSG_RTFM: GET_STRING (self->reason); break; default: zsys_warning ("fmq_msg: bad message ID"); goto malformed; } // Successful return zmq_msg_close (&frame); return 0; // Error returns malformed: zsys_warning ("fmq_msg: fmq_msg malformed message, fail"); zmq_msg_close (&frame); return -1; // Invalid message }
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); }
JzMsg * jz_msg_new_from_data (gpointer buf, gsize len) { g_assert (buf); JzMsg *self = g_new0(JzMsg, 1); self->data = g_byte_array_new (); size_t string_size; size_t frame_length; g_assert (len > JZ_MSG_ENVELOPE_SIZE); // Get and check protocol signature self->needle = buf; // Initially we don't know enough to properly set the ceiling self->ceiling = buf + len; GET_NUMBER4 (self->signature); g_assert (self->signature == JZ_MSG_SIGNATURE); // Get message id and parse per message type GET_NUMBER4 (frame_length); // Now that we have a frame size, we can properly set the ceiling guint32 padding = JZ_MSG_PADDING_LENGTH (frame_length); self->ceiling = buf + JZ_MSG_ENVELOPE_SIZE + frame_length + padding; GET_NUMBER1 (self->version); GET_NUMBER1 (self->id); GET_NUMBER2 (self->lcn); if (self->version != 1) { self->invalidity = d_unknown_version; goto malformed; } switch (self->id) { case JZ_MSG_DATA: GET_NUMBER1 (self->q); GET_NUMBER2 (self->pr); GET_NUMBER2 (self->ps); g_byte_array_set_size (self->data, 0); GET_RAW (self->data); break; case JZ_MSG_RR: GET_NUMBER2 (self->pr); break; case JZ_MSG_RNR: GET_NUMBER2 (self->pr); break; case JZ_MSG_CALL_REQUEST: // Address block g_free (self->calling_address); GET_STRING (self->calling_address); g_free (self->called_address); GET_STRING (self->called_address); // Facilities GET_NUMBER1 (self->packet); GET_NUMBER2 (self->window); GET_NUMBER1 (self->throughput); // User data g_byte_array_set_size (self->data, 0); GET_RAW (self->data); break; case JZ_MSG_CALL_ACCEPTED: // Address block g_free (self->calling_address); GET_STRING (self->calling_address); g_free (self->called_address); GET_STRING (self->called_address); // Facilities GET_NUMBER1 (self->packet); GET_NUMBER2 (self->window); GET_NUMBER1 (self->throughput); // User data g_byte_array_set_size (self->data, 0); GET_RAW (self->data); break; case JZ_MSG_CLEAR_REQUEST: GET_NUMBER1 (self->cause); GET_NUMBER1 (self->diagnostic); break; case JZ_MSG_CLEAR_CONFIRMATION: break; case JZ_MSG_RESET_REQUEST: GET_NUMBER1 (self->cause); GET_NUMBER1 (self->diagnostic); break; case JZ_MSG_RESET_CONFIRMATION: break; case JZ_MSG_CONNECT: g_free (self->calling_address); GET_STRING (self->calling_address); GET_NUMBER1 (self->iodir); break; case JZ_MSG_CONNECT_INDICATION: break; case JZ_MSG_DISCONNECT: break; case JZ_MSG_DISCONNECT_INDICATION: break; case JZ_MSG_DIAGNOSTIC: GET_NUMBER1 (self->diagnostic); GET_NUMBER1 (self->diagnostic_version); GET_NUMBER1 (self->diagnostic_id); GET_NUMBER2 (self->diagnostic_lcn); break; case JZ_MSG_DIRECTORY_REQUEST: break; case JZ_MSG_DIRECTORY: #if 0 GET_NUMBER1 (hash_size); self->workers = zhash_new (); zhash_autofree (self->workers); while (hash_size--) { char *string; GET_STRING (string); char *value = strchr (string, '='); if (value) *value++ = 0; zhash_insert (self->workers, string, value); free (string); } #endif break; case JZ_MSG_ENQ: break; case JZ_MSG_ACK: break; case JZ_MSG_RESTART_REQUEST: GET_NUMBER1 (self->cause); GET_NUMBER1 (self->diagnostic); break; case JZ_MSG_RESTART_CONFIRMATION: break; default: self->invalidity = d_unknown_message_type; goto malformed; } for (int i = 0; i < padding; i ++) { guint8 padding; GET_NUMBER1 (padding); } GET_NUMBER4 (self->crc); // Successful unpacking self->packed_size = self->needle - (guint8 *) buf; // If the message is shorter than expected if (self->packed_size < JZ_MSG_ENVELOPE_SIZE + frame_length + padding) { g_critical ("message payload smaller than envelope '%s'\n", id_name (self->id)); self->valid = FALSE; self->invalidity = d_packet_too_long; } else self->valid = TRUE; return self; // Error returns malformed: g_critical ("malformed message '%s'\n", id_name (self->id)); self->valid = FALSE; self->packed_size = self->needle - (guint8 *) buf; return self; premature: g_critical ("message payload too big for envelope '%s'\n", id_name (self->id)); self->invalidity = d_packet_too_short; self->packed_size = self->needle - (guint8 *) buf; return self; }
int zproto_example_recv (zproto_example_t *self, zsock_t *input) { assert (input); if (zsock_type (input) == ZMQ_ROUTER) { zframe_destroy (&self->routing_id); self->routing_id = zframe_recv (input); if (!self->routing_id || !zsock_rcvmore (input)) { zsys_warning ("zproto_example: no routing ID"); return -1; // Interrupted or malformed } } zmq_msg_t frame; zmq_msg_init (&frame); int size = zmq_msg_recv (&frame, zsock_resolve (input), 0); if (size == -1) { zsys_warning ("zproto_example: interrupted"); goto malformed; // Interrupted } // Get and check protocol signature self->needle = (byte *) zmq_msg_data (&frame); self->ceiling = self->needle + zmq_msg_size (&frame); uint16_t signature; GET_NUMBER2 (signature); if (signature != (0xAAA0 | 0)) { zsys_warning ("zproto_example: invalid signature"); // TODO: discard invalid messages and loop, and return // -1 only on interrupt goto malformed; // Interrupted } // Get message id and parse per message type GET_NUMBER1 (self->id); switch (self->id) { case ZPROTO_EXAMPLE_LOG: GET_NUMBER2 (self->sequence); { uint16_t version; GET_NUMBER2 (version); if (version != 3) { zsys_warning ("zproto_example: version is invalid"); goto malformed; } } GET_NUMBER1 (self->level); GET_NUMBER1 (self->event); GET_NUMBER2 (self->node); GET_NUMBER2 (self->peer); GET_NUMBER8 (self->time); GET_STRING (self->host); GET_LONGSTR (self->data); break; case ZPROTO_EXAMPLE_STRUCTURES: GET_NUMBER2 (self->sequence); { size_t list_size; GET_NUMBER4 (list_size); self->aliases = zlist_new (); zlist_autofree (self->aliases); while (list_size--) { char *string = NULL; GET_LONGSTR (string); zlist_append (self->aliases, string); free (string); } } { size_t hash_size; GET_NUMBER4 (hash_size); self->headers = zhash_new (); zhash_autofree (self->headers); while (hash_size--) { char key [256]; char *value = NULL; GET_STRING (key); GET_LONGSTR (value); zhash_insert (self->headers, key, value); free (value); } } break; case ZPROTO_EXAMPLE_BINARY: GET_NUMBER2 (self->sequence); GET_OCTETS (self->flags, 4); { size_t chunk_size; GET_NUMBER4 (chunk_size); if (self->needle + chunk_size > (self->ceiling)) { zsys_warning ("zproto_example: public_key is missing data"); goto malformed; } zchunk_destroy (&self->public_key); self->public_key = zchunk_new (self->needle, chunk_size); self->needle += chunk_size; } if (self->needle + ZUUID_LEN > (self->ceiling)) { zsys_warning ("zproto_example: identifier is invalid"); goto malformed; } zuuid_destroy (&self->identifier); self->identifier = zuuid_new_from (self->needle); self->needle += ZUUID_LEN; // Get next frame off socket if (!zsock_rcvmore (input)) { zsys_warning ("zproto_example: address is missing"); goto malformed; } zframe_destroy (&self->address); self->address = zframe_recv (input); // Get zero or more remaining frames zmsg_destroy (&self->content); if (zsock_rcvmore (input)) self->content = zmsg_recv (input); else self->content = zmsg_new (); break; case ZPROTO_EXAMPLE_TYPES: GET_NUMBER2 (self->sequence); GET_STRING (self->client_forename); GET_STRING (self->client_surname); GET_STRING (self->client_mobile); GET_STRING (self->client_email); GET_STRING (self->supplier_forename); GET_STRING (self->supplier_surname); GET_STRING (self->supplier_mobile); GET_STRING (self->supplier_email); break; default: zsys_warning ("zproto_example: bad message ID"); goto malformed; } // Successful return zmq_msg_close (&frame); return 0; // Error returns malformed: zsys_warning ("zproto_example: zproto_example malformed message, fail"); zmq_msg_close (&frame); return -1; // Invalid message }
int xrap_traffic_recv (xrap_traffic_t *self, zsock_t *input) { assert (input); if (zsock_type (input) == ZMQ_ROUTER) { zframe_destroy (&self->routing_id); self->routing_id = zframe_recv (input); if (!self->routing_id || !zsock_rcvmore (input)) { zsys_warning ("xrap_traffic: no routing ID"); return -1; // Interrupted or malformed } } zmq_msg_t frame; zmq_msg_init (&frame); int size = zmq_msg_recv (&frame, zsock_resolve (input), 0); if (size == -1) { zsys_warning ("xrap_traffic: interrupted"); goto malformed; // Interrupted } // Get and check protocol signature self->needle = (byte *) zmq_msg_data (&frame); self->ceiling = self->needle + zmq_msg_size (&frame); uint16_t signature; GET_NUMBER2 (signature); if (signature != (0xAAA0 | 9)) { zsys_warning ("xrap_traffic: invalid signature"); // TODO: discard invalid messages and loop, and return // -1 only on interrupt goto malformed; // Interrupted } // Get message id and parse per message type GET_NUMBER1 (self->id); switch (self->id) { case XRAP_TRAFFIC_CONNECTION_OPEN: { char protocol [256]; GET_STRING (protocol); if (strneq (protocol, "MALAMUTE")) { zsys_warning ("xrap_traffic: protocol is invalid"); goto malformed; } } { uint16_t version; GET_NUMBER2 (version); if (version != 1) { zsys_warning ("xrap_traffic: version is invalid"); goto malformed; } } GET_STRING (self->address); break; case XRAP_TRAFFIC_CONNECTION_PING: break; case XRAP_TRAFFIC_CONNECTION_PONG: break; case XRAP_TRAFFIC_CONNECTION_CLOSE: break; case XRAP_TRAFFIC_XRAP_SEND: GET_NUMBER4 (self->timeout); // Get zero or more remaining frames zmsg_destroy (&self->content); if (zsock_rcvmore (input)) self->content = zmsg_recv (input); else self->content = zmsg_new (); break; case XRAP_TRAFFIC_XRAP_OFFER: GET_STRING (self->route); GET_STRING (self->method); break; case XRAP_TRAFFIC_XRAP_DELIVER: if (self->needle + ZUUID_LEN > (self->ceiling)) { zsys_warning ("xrap_traffic: sender is invalid"); goto malformed; } zuuid_destroy (&self->sender); self->sender = zuuid_new_from (self->needle); self->needle += ZUUID_LEN; // Get zero or more remaining frames zmsg_destroy (&self->content); if (zsock_rcvmore (input)) self->content = zmsg_recv (input); else self->content = zmsg_new (); break; case XRAP_TRAFFIC_OK: GET_NUMBER2 (self->status_code); GET_STRING (self->status_reason); break; case XRAP_TRAFFIC_FAIL: GET_NUMBER2 (self->status_code); GET_STRING (self->status_reason); break; case XRAP_TRAFFIC_ERROR: GET_NUMBER2 (self->status_code); GET_STRING (self->status_reason); break; default: zsys_warning ("xrap_traffic: bad message ID"); goto malformed; } // Successful return zmq_msg_close (&frame); return 0; // Error returns malformed: zsys_warning ("xrap_traffic: xrap_traffic malformed message, fail"); zmq_msg_close (&frame); return -1; // Invalid message }