static void s_self_switch (self_t *self, zsock_t *input, zsock_t *output) { // We use the low-level libzmq API for best performance void *zmq_input = zsock_resolve (input); void *zmq_output = zsock_resolve (output); void *zmq_capture = self->capture ? zsock_resolve (self->capture) : NULL; zmq_msg_t msg; zmq_msg_init (&msg); while (true) { if (zmq_recvmsg (zmq_input, &msg, ZMQ_DONTWAIT) == -1) break; // Presumably EAGAIN int send_flags = zsock_rcvmore (zmq_input) ? ZMQ_SNDMORE : 0; if (zmq_capture) { zmq_msg_t dup; zmq_msg_init (&dup); zmq_msg_copy (&dup, &msg); if (zmq_sendmsg (zmq_capture, &dup, send_flags) == -1) zmq_msg_close (&dup); } if (zmq_sendmsg (zmq_output, &msg, send_flags) == -1) { zmq_msg_close (&msg); break; } } }
zmsg_t * zmsg_recv (void *source) { assert (source); zmsg_t *self = zmsg_new (); if (!self) return NULL; while (true) { zframe_t *frame = zframe_recv (source); if (!frame) { if (errno == EINTR && zlist_head (self->frames)) continue; else { zmsg_destroy (&self); break; // Interrupted or terminated } } if (zmsg_append (self, &frame)) { zmsg_destroy (&self); break; } if (!zsock_rcvmore (source)) break; // Last message frame } return self; }
static int s_stream_engine_handle_command (stream_engine_t *self) { char *method = zstr_recv (self->cmdpipe); if (!method) return -1; // Interrupted; exit zloop if (self->verbose) zsys_debug ("mlm_stream_simple: API command=%s", method); if (streq (method, "VERBOSE")) self->verbose = true; // Start verbose logging else if (streq (method, "$TERM")) self->terminated = true; // Shutdown the engine else if (streq (method, "COMPILE")) { void *client; char *pattern; zsock_recv (self->cmdpipe, "ps", &client, &pattern); s_stream_engine_compile (self, client, pattern); zstr_free (&pattern); } else if (streq (method, "CANCEL")) { void *client; zsock_recv (self->cmdpipe, "p", &client); s_stream_engine_cancel (self, client); } // Cleanup pipe if any argument frames are still waiting to be eaten if (zsock_rcvmore (self->cmdpipe)) { zsys_error ("mlm_stream_simple: trailing API command frames (%s)", method); zmsg_t *more = zmsg_recv (self->cmdpipe); zmsg_print (more); zmsg_destroy (&more); } zstr_free (&method); return self->terminated? -1: 0; }
zmsg_t * zmsg_recv (void *source) { assert (source); zmsg_t *self = zmsg_new (); if (!self) return NULL; while (true) { zframe_t *frame = zframe_recv (source); if (!frame) { zmsg_destroy (&self); break; // Interrupted or terminated } if (zmsg_append (self, &frame)) { zmsg_destroy (&self); break; } if (!zsock_rcvmore (source)) break; // Last message frame } return self; }
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 }
/// // Get socket option `rcvmore`. int QZsock::rcvmore () { int rv = zsock_rcvmore (self); return rv; }
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 }
JNIEXPORT jint JNICALL Java_org_zeromq_czmq_Zsock__1_1rcvmore (JNIEnv *env, jclass c, jlong self) { jint rcvmore_ = (jint) zsock_rcvmore ((zsock_t *) (intptr_t) self); return rcvmore_; }
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 }
static int read_zmq_message_and_forward(zloop_t *loop, zsock_t *sock, void *callback_data) { int i = 0; zmq_msg_t message_parts[4]; publisher_state_t *state = (publisher_state_t*)callback_data; void *socket = zsock_resolve(sock); // read the message parts, possibly including the message meta info while (!zsys_interrupted) { // printf("[D] receiving part %d\n", i+1); if (i>3) { zmq_msg_t dummy_msg; zmq_msg_init(&dummy_msg); zmq_recvmsg(socket, &dummy_msg, 0); zmq_msg_close(&dummy_msg); } else { zmq_msg_init(&message_parts[i]); zmq_recvmsg(socket, &message_parts[i], 0); } if (!zsock_rcvmore(socket)) break; i++; } if (i<2) { if (!zsys_interrupted) { fprintf(stderr, "[E] received only %d message parts\n", i); } goto cleanup; } else if (i>3) { fprintf(stderr, "[E] received more than 4 message parts\n"); goto cleanup; } zmq_msg_t *body = &message_parts[2]; msg_meta_t meta = META_INFO_EMPTY; if (i==3) zmq_msg_extract_meta_info(&message_parts[3], &meta); // const char *prefix = socket == state->compressor_output ? "EXTERNAL MESSAGE" : "INTERNAL MESSAGE"; // my_zmq_msg_fprint(&message_parts[0], 3, prefix, stdout); // dump_meta_info(prefix, &meta); if (meta.created_ms) msg_meta.created_ms = meta.created_ms; else msg_meta.created_ms = global_time; size_t msg_bytes = zmq_msg_size(body); if (socket == state->compressor_output) { decompressed_messages_count++; decompressed_messages_bytes += msg_bytes; if (msg_bytes > decompressed_messages_max_bytes) decompressed_messages_max_bytes = msg_bytes; } else { received_messages_count++; received_messages_bytes += msg_bytes; if (msg_bytes > received_messages_max_bytes) received_messages_max_bytes = msg_bytes; } msg_meta.compression_method = meta.compression_method; if (meta.compression_method) { // decompress publish_on_zmq_transport(&message_parts[0], state->compressor_input, &msg_meta, 0); } else { // forward to comsumer msg_meta.sequence_number++; if (debug) { my_zmq_msg_fprint(&message_parts[0], 3, "[D]", stdout); dump_meta_info("[D]", &msg_meta); } char *pub_spec = NULL; bool is_heartbeat = zmq_msg_size(&message_parts[0]) == 9 && strncmp("heartbeat", zmq_msg_data(&message_parts[0]), 9) == 0; if (is_heartbeat) { if (debug) printf("[D] received heartbeat message from device %u\n", msg_meta.device_number); pub_spec = strndup(zmq_msg_data(&message_parts[1]), zmq_msg_size(&message_parts[1])); } device_tracker_calculate_gap(tracker, &msg_meta, pub_spec); if (!is_heartbeat) { int rc = publish_on_zmq_transport(&message_parts[0], state->publisher, &msg_meta, ZMQ_DONTWAIT); if (rc == -1) { dropped_messages_count++; } } } cleanup: for (;i>=0;i--) { zmq_msg_close(&message_parts[i]); } return 0; }
/// // Get socket option `rcvmore`. int QmlZsock::rcvmore () { return zsock_rcvmore (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 }