void zyre_peer_test (bool verbose) { printf (" * zyre_peer: "); zsock_t *mailbox = zsock_new_dealer ("@tcp://127.0.0.1:5551"); zhash_t *peers = zhash_new (); zuuid_t *you = zuuid_new (); zuuid_t *me = zuuid_new (); zyre_peer_t *peer = zyre_peer_new (peers, you); assert (!zyre_peer_connected (peer)); zyre_peer_connect (peer, me, "tcp://127.0.0.1:5551"); assert (zyre_peer_connected (peer)); zyre_peer_set_name (peer, "peer"); assert (streq (zyre_peer_name (peer), "peer")); zre_msg_t *msg = zre_msg_new (ZRE_MSG_HELLO); zre_msg_set_endpoint (msg, "tcp://127.0.0.1:5552"); int rc = zyre_peer_send (peer, &msg); assert (rc == 0); msg = zre_msg_recv (mailbox); assert (msg); if (verbose) zre_msg_print (msg); zre_msg_destroy (&msg); // Destroying container destroys all peers it contains zhash_destroy (&peers); zuuid_destroy (&me); zuuid_destroy (&you); zsock_destroy (&mailbox); printf ("OK\n"); }
void zuuid_test (bool verbose) { printf (" * zuuid: "); // @selftest // Simple create/destroy test zuuid_t *uuid = zuuid_new (); assert (uuid); assert (zuuid_size (uuid) == 16); assert (strlen (zuuid_str (uuid)) == 32); zuuid_t *copy = zuuid_dup (uuid); assert (streq (zuuid_str (uuid), zuuid_str (copy))); // Check set/set_str/export methods const char *myuuid = "8CB3E9A9649B4BEF8DE225E9C2CEBB38"; zuuid_set_str (uuid, myuuid); assert (streq (zuuid_str (uuid), myuuid)); byte copy_uuid [16]; zuuid_export (uuid, copy_uuid); zuuid_set (uuid, copy_uuid); assert (streq (zuuid_str (uuid), myuuid)); zuuid_destroy (&uuid); zuuid_destroy (©); // @end printf ("OK\n"); }
static zyre_node_t * zyre_node_new (zctx_t *ctx, void *pipe) { zyre_node_t *self = (zyre_node_t *) zmalloc (sizeof (zyre_node_t)); self->ctx = ctx; self->pipe = pipe; self->inbox = zsocket_new (ctx, ZMQ_ROUTER); if (self->inbox == NULL) { free (self); return NULL; // Interrupted 0MQ call } self->port = zsocket_bind (self->inbox, "tcp://*:*"); if (self->port < 0) { free (self); return NULL; // Interrupted 0MQ call } self->beacon = zbeacon_new (self->ctx, ZRE_DISCOVERY_PORT); if (!self->beacon) { free (self); return NULL; // Exhausted process sockets } self->uuid = zuuid_new (); self->peers = zhash_new (); self->peer_groups = zhash_new (); self->own_groups = zhash_new (); self->headers = zhash_new (); zhash_autofree (self->headers); return self; }
static void register_new_client (client_t *self) { self->id = zuuid_new (); zhashx_update (self->server->clients, zuuid_str (self->id), self); xrap_traffic_set_status_code (self->message, XRAP_TRAFFIC_SUCCESS); }
static zyre_node_t * zyre_node_new (zsock_t *pipe, void *args) { zyre_node_t *self = (zyre_node_t *) zmalloc (sizeof (zyre_node_t)); self->inbox = zsock_new (ZMQ_ROUTER); if (self->inbox == NULL) { free (self); return NULL; // Could not create new socket } // Use ZMQ_ROUTER_HANDOVER so that when a peer disconnects and // then reconnects, the new client connection is treated as the // canonical one, and any old trailing commands are discarded. zsock_set_router_handover (self->inbox, 1); self->pipe = pipe; self->outbox = (zsock_t *) args; self->poller = zpoller_new (self->pipe, NULL); self->beacon_port = ZRE_DISCOVERY_PORT; self->interval = 0; // Use default self->uuid = zuuid_new (); self->peers = zhash_new (); self->peer_groups = zhash_new (); self->own_groups = zhash_new (); self->headers = zhash_new (); zhash_autofree (self->headers); // Default name for node is first 6 characters of UUID: // the shorter string is more readable in logs self->name = (char *) zmalloc (7); memcpy (self->name, zuuid_str (self->uuid), 6); return self; }
static zsync_node_t * zsync_node_new () { int rc; zsync_node_t *self = (zsync_node_t *) zmalloc (sizeof (zsync_node_t)); self->ctx = zctx_new (); assert (self->ctx); self->zyre = zyre_new (self->ctx); assert (self->zyre); // Obtain permanent UUID self->own_uuid = zuuid_new (); if (zsys_file_exists (UUID_FILE)) { // Read uuid from file zfile_t *uuid_file = zfile_new (".", UUID_FILE); int rc = zfile_input (uuid_file); // open file for reading assert (rc == 0); zchunk_t *uuid_chunk = zfile_read (uuid_file, 16, 0); assert (zchunk_size (uuid_chunk) == 16); // make sure read succeeded zuuid_set (self->own_uuid, zchunk_data (uuid_chunk)); zfile_destroy (&uuid_file); } else { // Write uuid to file zfile_t *uuid_file = zfile_new (".", UUID_FILE); rc = zfile_output (uuid_file); // open file for writing assert (rc == 0); zchunk_t *uuid_bin = zchunk_new ( zuuid_data (self->own_uuid), 16); rc = zfile_write (uuid_file, uuid_bin, 0); assert (rc == 0); zfile_destroy (&uuid_file); } // Obtain peers and states self->peers = zlist_new (); if (zsys_file_exists (PEER_STATES_FILE)) { zhash_t *peer_states = zhash_new (); int rc = zhash_load (peer_states, PEER_STATES_FILE); assert (rc == 0); zlist_t *uuids = zhash_keys (peer_states); char *uuid = zlist_first (uuids); while (uuid) { char * state_str = zhash_lookup (peer_states, uuid); uint64_t state; sscanf (state_str, "%"SCNd64, &state); zlist_append (self->peers, zsync_peer_new (uuid, state)); uuid = zlist_next (uuids); } } self->zyre_peers = zhash_new (); self->terminated = false; return self; }
zuuid_t * zuuid_dup (zuuid_t *self) { if (self) { zuuid_t *copy = zuuid_new (); if (copy) zuuid_set (copy, zuuid_data (self)); return copy; } else return NULL; }
void zyre_group_test (bool verbose) { printf (" * zyre_group: "); zsock_t *mailbox = zsock_new (ZMQ_DEALER); zsock_bind (mailbox, "tcp://127.0.0.1:5552"); zhash_t *groups = zhash_new (); zyre_group_t *group = zyre_group_new ("tests", groups); zhash_t *peers = zhash_new (); zuuid_t *you = zuuid_new (); zuuid_t *me = zuuid_new (); zyre_peer_t *peer = zyre_peer_new (peers, you); assert (!zyre_peer_connected (peer)); zyre_peer_connect (peer, me, "tcp://127.0.0.1:5552"); assert (zyre_peer_connected (peer)); zyre_group_join (group, peer); zre_msg_t *msg = zre_msg_new (ZRE_MSG_HELLO); zre_msg_set_endpoint (msg, "tcp://127.0.0.1:5552"); zyre_group_send (group, &msg); msg = zre_msg_recv (mailbox); assert (msg); if (verbose) zre_msg_print (msg); zre_msg_destroy (&msg); zuuid_destroy (&me); zuuid_destroy (&you); zhash_destroy (&peers); zhash_destroy (&groups); zsock_destroy (&mailbox); printf ("OK\n"); }
void zuuid_test (bool verbose) { printf (" * zuuid: "); // @selftest // Simple create/destroy test assert (ZUUID_LEN == 16); assert (ZUUID_STR_LEN == 32); zuuid_t *uuid = zuuid_new (); assert (uuid); assert (zuuid_size (uuid) == ZUUID_LEN); assert (strlen (zuuid_str (uuid)) == ZUUID_STR_LEN); zuuid_t *copy = zuuid_dup (uuid); assert (streq (zuuid_str (uuid), zuuid_str (copy))); // Check set/set_str/export methods const char *myuuid = "8CB3E9A9649B4BEF8DE225E9C2CEBB38"; const char *myuuid2 = "8CB3E9A9-649B-4BEF-8DE2-25E9C2CEBB38"; const char *myuuid3 = "{8CB3E9A9-649B-4BEF-8DE2-25E9C2CEBB38}"; const char *myuuid4 = "8CB3E9A9649B4BEF8DE225E9C2CEBB3838"; int rc = zuuid_set_str (uuid, myuuid); assert (rc == 0); assert (streq (zuuid_str (uuid), myuuid)); rc = zuuid_set_str (uuid, myuuid2); assert (rc == 0); assert (streq (zuuid_str (uuid), myuuid)); rc = zuuid_set_str (uuid, myuuid3); assert (rc == 0); assert (streq (zuuid_str (uuid), myuuid)); rc = zuuid_set_str (uuid, myuuid4); assert (rc == -1); byte copy_uuid [ZUUID_LEN]; zuuid_export (uuid, copy_uuid); zuuid_set (uuid, copy_uuid); assert (streq (zuuid_str (uuid), myuuid)); // Check the canonical string format assert (streq (zuuid_str_canonical (uuid), "8cb3e9a9-649b-4bef-8de2-25e9c2cebb38")); zuuid_destroy (&uuid); zuuid_destroy (©); // @end printf ("OK\n"); }
static client_t * client_create (ctx_t *ctx, int fd) { client_t *c; socklen_t crlen = sizeof (c->ucred); flux_t h = ctx->h; c = xzmalloc (sizeof (*c)); c->fd = fd; if (!(c->uuid = zuuid_new ())) oom (); c->ctx = ctx; if (!(c->disconnect_notify = zhash_new ())) oom (); if (!(c->subscriptions = zlist_new ())) oom (); if (!(c->outqueue = zlist_new ())) oom (); if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &c->ucred, &crlen) < 0) { flux_log (h, LOG_ERR, "getsockopt SO_PEERCRED: %s", strerror (errno)); goto error; } assert (crlen == sizeof (c->ucred)); /* Deny connections by uid other than session owner for now. */ if (c->ucred.uid != ctx->session_owner) { flux_log (h, LOG_ERR, "connect by uid=%d pid=%d denied", c->ucred.uid, (int)c->ucred.pid); goto error; } c->inw = flux_fd_watcher_create (fd, FLUX_POLLIN, client_read_cb, c); c->outw = flux_fd_watcher_create (fd, FLUX_POLLOUT, client_write_cb, c); if (!c->inw || !c->outw) { flux_log (h, LOG_ERR, "flux_fd_watcher_create: %s", strerror (errno)); goto error; } flux_fd_watcher_start (h, c->inw); flux_msg_iobuf_init (&c->inbuf); flux_msg_iobuf_init (&c->outbuf); if (set_nonblock (c->fd, true) < 0) { flux_log (h, LOG_ERR, "set_nonblock: %s", strerror (errno)); goto error; } return (c); error: client_destroy (c); return NULL; }
book_t* shelf_add_book (shelf_t *self, const char *author, const char *title) { zuuid_t *uuid = zuuid_new (); const char *str_uuid = zuuid_str (uuid); const char* sql = "INSERT INTO book(id,author,title) VALUES($1,$2,$3);"; zpgutil_session_sql (self->session, sql); zpgutil_session_set (self->session, str_uuid); zpgutil_session_set (self->session, author); zpgutil_session_set (self->session, title); zpgutil_session_execute (self->session); zpgutil_session_commit (self->session); book_t *book = book_new (str_uuid,author,title); zuuid_destroy (&uuid); return book; }
static void zyre_node_recv_beacon (zyre_node_t *self) { // Get IP address and beacon of peer char *ipaddress = zstr_recv (self->beacon); zframe_t *frame = zframe_recv (self->beacon); if (ipaddress == NULL) return; // Interrupted // Ignore anything that isn't a valid beacon beacon_t beacon; memset (&beacon, 0, sizeof (beacon_t)); if (zframe_size (frame) == sizeof (beacon_t)) memcpy (&beacon, zframe_data (frame), zframe_size (frame)); zframe_destroy (&frame); if (beacon.version != BEACON_VERSION) return; // Garbage beacon, ignore it zuuid_t *uuid = zuuid_new (); zuuid_set (uuid, beacon.uuid); if (beacon.port) { char endpoint [100]; const char *iface = zsys_interface (); if (zsys_ipv6 () && iface && !streq (iface, "") && !streq (iface, "*")) sprintf (endpoint, "tcp://%s%%%s:%d", ipaddress, iface, ntohs (beacon.port)); else sprintf (endpoint, "tcp://%s:%d", ipaddress, ntohs (beacon.port)); zyre_peer_t *peer = zyre_node_require_peer (self, uuid, endpoint); zyre_peer_refresh (peer, self->evasive_timeout, self->expired_timeout); } else { // Zero port means peer is going away; remove it if // we had any knowledge of it already zyre_peer_t *peer = (zyre_peer_t *) zhash_lookup ( self->peers, zuuid_str (uuid)); if (peer) zyre_node_remove_peer (self, peer); } zuuid_destroy (&uuid); zstr_free (&ipaddress); }
static int zyre_node_recv_beacon (zyre_node_t *self) { // Get IP address and beacon of peer char *ipaddress = zstr_recv (zbeacon_socket (self->beacon)); zframe_t *frame = zframe_recv (zbeacon_socket (self->beacon)); // Ignore anything that isn't a valid beacon bool is_valid = true; beacon_t beacon; if (zframe_size (frame) == sizeof (beacon_t)) { memcpy (&beacon, zframe_data (frame), zframe_size (frame)); if (beacon.version != BEACON_VERSION) is_valid = false; } else is_valid = false; // Check that the peer, identified by its UUID, exists if (is_valid) { zuuid_t *uuid = zuuid_new (); zuuid_set (uuid, beacon.uuid); if (beacon.port) { char endpoint [30]; sprintf (endpoint, "tcp://%s:%d", ipaddress, ntohs (beacon.port)); zyre_peer_t *peer = zyre_node_require_peer (self, uuid, endpoint); zyre_peer_refresh (peer); } else { // Zero port means peer is going away; remove it if // we had any knowledge of it already zyre_peer_t *peer = (zyre_peer_t *) zhash_lookup ( self->peers, zuuid_str (uuid)); if (peer) zyre_node_remove_peer (self, peer); } zuuid_destroy (&uuid); } zstr_free (&ipaddress); zframe_destroy (&frame); return 0; }
static void zyre_node_recv_gossip (zyre_node_t *self) { // Get IP address and beacon of peer char *command = NULL, *uuidstr, *endpoint; zstr_recvx (self->gossip, &command, &uuidstr, &endpoint, NULL); if (command == NULL) return; // Interrupted // Any replies except DELIVER would signify an internal error; these // messages come from zgossip, not an external source assert (streq (command, "DELIVER")); // Require peer, if it's not us if (strneq (endpoint, self->endpoint)) { zuuid_t *uuid = zuuid_new (); zuuid_set_str (uuid, uuidstr); zyre_node_require_peer (self, uuid, endpoint); zuuid_destroy (&uuid); } zstr_free (&command); zstr_free (&uuidstr); zstr_free (&endpoint); }
/* step */ void zyre_bridge_step(ubx_block_t *b) { struct zyre_bridge_info *inf = (struct zyre_bridge_info*) b->private_data; /* Read data from port */ ubx_port_t* port = inf->ports.zyre_out; assert(port != 0); char * tmp_str = (char*) malloc(inf->max_msg_length*sizeof(char*)); ubx_data_t msg; checktype(port->block->ni, port->in_type, "unsigned char", port->name, 1); msg.type = port->in_type; msg.len = inf->max_msg_length; msg.data = tmp_str; //msg.data = inf->msg_buffer; int counter = 0; while (counter < inf->max_send) { int read_bytes = __port_read(port, &msg); //printf("zyrebidge: read bytes: %d\n",read_bytes); //printf("step: read strlen: %lu\n",strlen((char*) msg.data)); if (read_bytes <= 0) { //printf("zyre_bridge: No data recieved from port\n"); free(tmp_str); return; } // printf("zyrebridge: read bytes: %d\n",read_bytes); // port_read returns byte array. Need to add 0 termination manually to the string. tmp_str[read_bytes] = '\0'; // create json object and... json_t *pl; json_error_t error; pl= json_loads(tmp_str,0,&error); if(!pl) { printf("Error parsing JSON payload! line %d: %s\n", error.line, error.text); json_decref(pl); free(tmp_str); return; } // printf("[zyrebidge] retrieving msg: %s\n", json_dumps(pl, JSON_ENCODE_ANY)); // ...check for its type and embed it into msg envelope json_t *new_msg; new_msg = json_object(); json_object_set(new_msg, "payload", pl); json_object_set(new_msg, "metamodel", json_string("SHERPA")); if(json_object_get(pl, "@worldmodeltype") == 0) { printf("[zyrebidge] retrieving msg: %s\n", json_dumps(pl, JSON_ENCODE_ANY)); printf("[zyrebidge] Error parsing RSG payload! @worldmodeltype is missing.\n"); json_decref(pl); free(tmp_str); return; } std::string tmp_type = json_string_value(json_object_get(pl, "@worldmodeltype")); //can segfault char *send_msg; for (int i=0; i < inf->output_type_list.size();i++) { if (tmp_type.compare(inf->output_type_list[i])) { // need to handle exception for updates generated from RSG due to local updates if (tmp_type.compare("RSGUpdate") == 0) { json_object_set(new_msg, "model", json_string("RSGUpdate")); json_object_set(new_msg, "type", json_string("RSGUpdate_global")); // If used with mediator, add send_request envelope ubx_data_t *dmy; dmy = ubx_config_get_data(b, "mediator"); int mediator; mediator = *(int*) dmy->data; if (mediator == 1) { zuuid_t *query_uuid = zuuid_new (); assert (query_uuid); json_t *recip = json_array(); assert((recip)&&(json_array_size(recip)==0)); send_msg = send_request(zuuid_str(query_uuid),zyre_uuid(inf->node),recip,1000,"send_remote",new_msg); } else { send_msg = json_dumps(new_msg, JSON_ENCODE_ANY); } } else { json_object_set(new_msg, "model", json_string(tmp_type.c_str())); json_object_set(new_msg, "type", json_string(tmp_type.c_str())); send_msg = json_dumps(new_msg, JSON_ENCODE_ANY); } } else { printf("[zyre_bridge] Unknown output type: %s!\n",tmp_type.c_str()); } } printf("[zyrebidge] sending msg: %s\n", send_msg); zyre_shouts(inf->node, inf->group, "%s", send_msg); counter++; json_decref(pl); json_decref(new_msg); } free(tmp_str); return; }
/// // Constructor QZuuid::QZuuid (QObject *qObjParent) : QObject (qObjParent) { this->self = zuuid_new (); }
void zproto_example_test (bool verbose) { printf (" * zproto_example:"); if (verbose) printf ("\n"); // @selftest // Simple create/destroy test zproto_example_t *self = zproto_example_new (); assert (self); zproto_example_destroy (&self); // Create pair of sockets we can send through // We must bind before connect if we wish to remain compatible with ZeroMQ < v4 zsock_t *output = zsock_new (ZMQ_DEALER); assert (output); int rc = zsock_bind (output, "inproc://selftest-zproto_example"); assert (rc == 0); zsock_t *input = zsock_new (ZMQ_ROUTER); assert (input); rc = zsock_connect (input, "inproc://selftest-zproto_example"); assert (rc == 0); // Encode/send/decode and verify each message type int instance; self = zproto_example_new (); zproto_example_set_id (self, ZPROTO_EXAMPLE_LOG); zproto_example_set_sequence (self, 123); zproto_example_set_level (self, 2); zproto_example_set_event (self, 3); zproto_example_set_node (self, 45536); zproto_example_set_peer (self, 65535); zproto_example_set_time (self, 1427261426); zproto_example_set_host (self, "localhost"); zproto_example_set_data (self, "This is the message to log"); // Send twice zproto_example_send (self, output); zproto_example_send (self, output); for (instance = 0; instance < 2; instance++) { zproto_example_recv (self, input); assert (zproto_example_routing_id (self)); assert (zproto_example_sequence (self) == 123); assert (zproto_example_level (self) == 2); assert (zproto_example_event (self) == 3); assert (zproto_example_node (self) == 45536); assert (zproto_example_peer (self) == 65535); assert (zproto_example_time (self) == 1427261426); assert (streq (zproto_example_host (self), "localhost")); assert (streq (zproto_example_data (self), "This is the message to log")); } zproto_example_set_id (self, ZPROTO_EXAMPLE_STRUCTURES); zproto_example_set_sequence (self, 123); zlist_t *structures_aliases = zlist_new (); zlist_append (structures_aliases, "First alias"); zlist_append (structures_aliases, "Second alias"); zlist_append (structures_aliases, "Third alias"); zproto_example_set_aliases (self, &structures_aliases); zhash_t *structures_headers = zhash_new (); zhash_insert (structures_headers, "endpoint", "tcp://*****:*****@example.com"); zproto_example_set_supplier_forename (self, "Leslie"); zproto_example_set_supplier_surname (self, "Lamport"); zproto_example_set_supplier_mobile (self, "01987654321"); zproto_example_set_supplier_email (self, "*****@*****.**"); // Send twice zproto_example_send (self, output); zproto_example_send (self, output); for (instance = 0; instance < 2; instance++) { zproto_example_recv (self, input); assert (zproto_example_routing_id (self)); assert (zproto_example_sequence (self) == 123); assert (streq (zproto_example_client_forename (self), "Lucius Junius")); assert (streq (zproto_example_client_surname (self), "Brutus")); assert (streq (zproto_example_client_mobile (self), "01234567890")); assert (streq (zproto_example_client_email (self), "*****@*****.**")); assert (streq (zproto_example_supplier_forename (self), "Leslie")); assert (streq (zproto_example_supplier_surname (self), "Lamport")); assert (streq (zproto_example_supplier_mobile (self), "01987654321")); assert (streq (zproto_example_supplier_email (self), "*****@*****.**")); } zproto_example_destroy (&self); zsock_destroy (&input); zsock_destroy (&output); // @end printf ("OK\n"); }
module_t *module_add (modhash_t *mh, const char *path) { module_t *p; void *dso; const char **mod_namep; mod_main_f *mod_main; zfile_t *zf; int rc; dlerror (); if (!(dso = dlopen (path, RTLD_NOW | RTLD_LOCAL))) { msg ("%s", dlerror ()); errno = ENOENT; return NULL; } mod_main = dlsym (dso, "mod_main"); mod_namep = dlsym (dso, "mod_name"); if (!mod_main || !mod_namep || !*mod_namep) { dlclose (dso); errno = ENOENT; return NULL; } p = xzmalloc (sizeof (*p)); p->name = xstrdup (*mod_namep); p->magic = MODULE_MAGIC; p->main = mod_main; p->dso = dso; zf = zfile_new (NULL, path); p->digest = xstrdup (zfile_digest (zf)); p->size = (int)zfile_cursize (zf); zfile_destroy (&zf); if (!(p->uuid = zuuid_new ())) oom (); if (!(p->rmmod = zlist_new ())) oom (); if (!(p->subs = zlist_new ())) oom (); p->rank = mh->rank; p->zctx = mh->zctx; p->broker_h = mh->broker_h; p->heartbeat = mh->heartbeat; /* Broker end of PAIR socket is opened here. */ if (!(p->sock = zsocket_new (p->zctx, ZMQ_PAIR))) err_exit ("zsocket_new"); zsocket_set_hwm (p->sock, 0); if (zsocket_bind (p->sock, "inproc://%s", module_get_uuid (p)) < 0) err_exit ("zsock_bind inproc://%s", module_get_uuid (p)); if (!(p->broker_w = flux_zmq_watcher_create (flux_get_reactor (p->broker_h), p->sock, FLUX_POLLIN, module_cb, p))) err_exit ("flux_zmq_watcher_create"); /* Update the modhash. */ rc = zhash_insert (mh->zh_byuuid, module_get_uuid (p), p); assert (rc == 0); /* uuids are by definition unique */ zhash_freefn (mh->zh_byuuid, module_get_uuid (p), (zhash_free_fn *)module_destroy); return p; }
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; }
int main (int argc, char *argv []) { puts (PRODUCT); puts (COPYRIGHT); puts (NOWARRANTY); int argn = 1; bool verbose = false; if (argn < argc && streq (argv [argn], "-h")) { puts ("syntax: hydrad [ directory ]"); puts (" -- defaults to .hydra in current directory"); exit (0); } if (argn < argc && streq (argv [argn], "-v")) { verbose = true; argn++; } // By default, current node runs in .hydra directory; create this if // it's missing (don't create directory passed as argument); char *workdir = ".hydra"; if (argn < argc) workdir = argv [argn++]; else zsys_dir_create (workdir); // ---------------------------------------------------------------------- // This code eventually goes into a reusable hydra actor class // Switch to working directory zsys_info ("hydrad: data store in %s directory", workdir); if (zsys_dir_change (workdir)) { zsys_error ("hydrad: cannot access %s: %s", workdir, strerror (errno)); return 1; } // Check we are the only process currently running here if (zsys_run_as ("hydrad.lock", NULL, NULL)) { zsys_error ("hydrad: cannot start process safely, exiting"); return 1; } // Get node identity from config file, or generate new identity zconfig_t *config = zconfig_load ("hydra.cfg"); if (!config) { // Set defaults for Hydra service config = zconfig_new ("root", NULL); zconfig_put (config, "/server/timeout", "5000"); zconfig_put (config, "/server/background", "0"); zconfig_put (config, "/server/verbose", "0"); } char *identity = zconfig_resolve (config, "/hydra/identity", NULL); if (!identity) { zuuid_t *uuid = zuuid_new (); zconfig_put (config, "/hydra/identity", zuuid_str (uuid)); zconfig_put (config, "/hydra/nickname", "Anonymous"); zconfig_save (config, "hydra.cfg"); zuuid_destroy (&uuid); } // Create store structure, if necessary zsys_dir_create ("content"); zsys_dir_create ("posts"); // Start server and bind to ephemeral TCP port. We can run many // servers on the same box, for testing. zactor_t *server = zactor_new (hydra_server, NULL); if (verbose) zstr_send (server, "VERBOSE"); // Bind Hydra service to ephemeral port and get that port number char *command; int port_nbr; zsock_send (server, "ss", "CONFIGURE", "hydra.cfg"); zsock_send (server, "ss", "BIND", "tcp://*:*"); zsock_send (server, "s", "PORT"); zsock_recv (server, "si", &command, &port_nbr); zsys_info ("hydrad: TCP server started on port=%d", port_nbr); assert (streq (command, "PORT")); free (command); // We're going to use Zyre for discovery and presence, and our own // Hydra protocol for content exchange zyre_t *zyre = zyre_new (NULL); if (verbose) zyre_set_verbose (zyre); char *hostname = zsys_hostname (); char *endpoint = zsys_sprintf ("tcp://%s:%d", hostname, port_nbr); zyre_set_header (zyre, "X-HYDRA", "%s", endpoint); zstr_free (&endpoint); zstr_free (&hostname); if (zyre_start (zyre)) { zsys_info ("hydrad: can't start Zyre discovery service"); zactor_destroy (&server); zyre_destroy (&zyre); return 1; } // When we get a new peer, handle it zpoller_t *poller = zpoller_new (zyre_socket (zyre), NULL); while (!zpoller_terminated (poller)) { void *which = zpoller_wait (poller, -1); if (which == zyre_socket (zyre)) { zyre_event_t *event = zyre_event_new (zyre); if (zyre_event_type (event) == ZYRE_EVENT_ENTER) { zsys_debug ("hydrad: new peer name=%s endpoint=%s", zyre_event_name (event), zyre_event_header (event, "X-HYDRA")); s_handle_peer (zyre_event_header (event, "X-HYDRA"), verbose); } zyre_event_destroy (&event); } else break; } zsys_info ("hydrad: shutting down..."); zpoller_destroy (&poller); // Shutdown all services zactor_destroy (&server); zyre_destroy (&zyre); zconfig_destroy (&config); return 0; }
static void zsync_node_recv_from_zyre (zsync_node_t *self) { zsync_peer_t *sender; char *zyre_sender; zuuid_t *sender_uuid; zmsg_t *zyre_in, *zyre_out, *fm_msg; zlist_t *fpaths, *fmetadata; zyre_event_t *event = zyre_event_recv (self->zyre); zyre_sender = zyre_event_sender (event); // get tmp uuid switch (zyre_event_type (event)) { case ZYRE_EVENT_ENTER: printf("[ND] ZS_ENTER: %s\n", zyre_sender); zhash_insert (self->zyre_peers, zyre_sender, NULL); break; case ZYRE_EVENT_JOIN: printf ("[ND] ZS_JOIN: %s\n", zyre_sender); // Obtain own current state zsync_msg_send_req_state (self->zsync_pipe); zsync_msg_t *msg_state = zsync_msg_recv (self->zsync_pipe); assert (zsync_msg_id (msg_state) == ZSYNC_MSG_RES_STATE); uint64_t state = zsync_msg_state (msg_state); // Send GREET message zyre_out = zmsg_new (); zs_msg_pack_greet (zyre_out, zuuid_data (self->own_uuid), state); zyre_whisper (self->zyre, zyre_sender, &zyre_out); break; case ZYRE_EVENT_LEAVE: break; case ZYRE_EVENT_EXIT: /* printf("[ND] ZS_EXIT %s left the house!\n", zyre_sender); sender = zhash_lookup (self->zyre_peers, zyre_sender); if (sender) { // Reset Managers zmsg_t *reset_msg = zmsg_new (); zmsg_addstr (reset_msg, zsync_peer_uuid (sender)); zmsg_addstr (reset_msg, "ABORT"); zmsg_send (&reset_msg, self->file_pipe); reset_msg = zmsg_new (); zmsg_addstr (reset_msg, zsync_peer_uuid (sender)); zmsg_addstr (reset_msg, "ABORT"); zmsg_send (&reset_msg, self->credit_pipe); // Remove Peer from active list zhash_delete (self->zyre_peers, zyre_sender); }*/ break; case ZYRE_EVENT_WHISPER: case ZYRE_EVENT_SHOUT: printf ("[ND] ZS_WHISPER: %s\n", zyre_sender); sender = zhash_lookup (self->zyre_peers, zyre_sender); zyre_in = zyre_event_msg (event); zs_msg_t *msg = zs_msg_unpack (zyre_in); switch (zs_msg_get_cmd (msg)) { case ZS_CMD_GREET: // Get perm uuid sender_uuid = zuuid_new (); zuuid_set (sender_uuid, zs_msg_uuid (msg)); sender = zsync_node_peers_lookup (self, zuuid_str (sender_uuid)); if (!sender) { sender = zsync_peer_new (zuuid_str (sender_uuid), 0x0); zlist_append (self->peers, sender); } assert (sender); zhash_update (self->zyre_peers, zyre_sender, sender); zsync_peer_set_zyre_state (sender, ZYRE_EVENT_JOIN); // Get current state for sender uint64_t remote_current_state = zs_msg_get_state (msg); printf ("[ND] current state: %"PRId64"\n", remote_current_state); // Lookup last known state uint64_t last_state_local = zsync_peer_state (sender); printf ("[ND] last known state: %"PRId64"\n", zsync_peer_state (sender)); // Send LAST_STATE if differs if (remote_current_state >= last_state_local) { zmsg_t *lmsg = zmsg_new (); zs_msg_pack_last_state (lmsg, last_state_local); zyre_whisper (self->zyre, zyre_sender, &lmsg); } break; case ZS_CMD_LAST_STATE: assert (sender); zyre_out = zmsg_new (); // Gets updates from client uint64_t last_state_remote = zs_msg_get_state (msg); zsync_msg_send_req_update (self->zsync_pipe, last_state_remote); zsync_msg_t *msg_upd = zsync_msg_recv (self->zsync_pipe); assert (zsync_msg_id (msg_upd) == ZSYNC_MSG_UPDATE); // Send UPDATE zyre_out = zsync_msg_update_msg (msg_upd); zyre_whisper (self->zyre, zyre_sender, &zyre_out); break; case ZS_CMD_UPDATE: printf ("[ND] UPDATE\n"); assert (sender); uint64_t state = zs_msg_get_state (msg); zsync_peer_set_state (sender, state); zsync_node_save_peers (self); fmetadata = zs_msg_get_fmetadata (msg); zmsg_t *zsync_msg = zmsg_new (); zs_msg_pack_update (zsync_msg, zs_msg_get_state (msg), fmetadata); zsync_msg_send_update (self->zsync_pipe, zsync_peer_uuid (sender), zsync_msg); break; case ZS_CMD_REQUEST_FILES: printf ("[ND] REQUEST FILES\n"); fpaths = zs_msg_fpaths (msg); zmsg_t *fm_msg = zmsg_new (); zmsg_addstr (fm_msg, zsync_peer_uuid (sender)); zmsg_addstr (fm_msg, "REQUEST"); char *fpath = zs_msg_fpaths_first (msg); while (fpath) { zmsg_addstr (fm_msg, fpath); printf("[ND] %s\n", fpath); fpath = zs_msg_fpaths_next (msg); } zmsg_send (&fm_msg, self->file_pipe); break; case ZS_CMD_GIVE_CREDIT: printf("[ND] GIVE CREDIT\n"); fm_msg = zmsg_new (); zmsg_addstr (fm_msg, zsync_peer_uuid (sender)); zmsg_addstr (fm_msg, "CREDIT"); zmsg_addstrf (fm_msg, "%"PRId64, zs_msg_get_credit (msg)); zmsg_send (&fm_msg, self->file_pipe); break; case ZS_CMD_SEND_CHUNK: printf("[ND] SEND_CHUNK (RCV)\n"); // Send receival to credit manager zframe_t *zframe = zs_msg_get_chunk (msg); uint64_t chunk_size = zframe_size (zframe); zsync_credit_msg_send_update (self->credit_pipe, zsync_peer_uuid (sender), chunk_size); // Pass chunk to client byte *data = zframe_data (zframe); zchunk_t *chunk = zchunk_new (data, chunk_size); char *path = zs_msg_get_file_path (msg); uint64_t seq = zs_msg_get_sequence (msg); uint64_t off = zs_msg_get_offset (msg); zsync_msg_send_chunk (self->zsync_pipe, chunk, path, seq, off); break; case ZS_CMD_ABORT: // TODO abort protocol managed file transfer printf("[ND] ABORT\n"); break; default: assert (false); break; } zs_msg_destroy (&msg); break; default: printf("[ND] Error command not found\n"); break; } zyre_event_destroy (&event); }
static void send_email (client_t *self) { assert (self); assert (self->message); zsys_info ("sending email !"); CURL *curl; CURLcode res = CURLE_OK; struct curl_slist *recipients = NULL; zuuid_t *uuid = zuuid_new (); const char *uuid_s = zuuid_str (uuid); char filename[256]; sprintf (filename, "./data/mail-%s.txt", uuid_s); zuuid_destroy (&uuid); char fn[200]; sprintf (fn, "mail-%s.txt", uuid_s); zfile_t *zf = zfile_new ("./data", fn); zfile_output (zf); FILE *pFile = zfile_handle (zf); //FILE *pFile = fopen (filename,"w"); // date -------- time_t timer; char buffer[256]; struct tm* tm_info; time (&timer); tm_info = localtime (&timer); strftime (buffer, 60, "%a, %d %b %Y %T %z\r\n", tm_info); //--------------- fprintf (pFile, "Date: %s", buffer); zsys_info ("To: %s \r\n", zmailer_msg_to(self->message)); fprintf (pFile,"To: %s\r\n", zmailer_msg_to(self->message)); fprintf (pFile, "From: %s\r\n", zmailer_msg_from (self->message)); fprintf (pFile, "Subject: %s \r\n", zmailer_msg_subject (self->message)); fprintf (pFile, "\r\n"); fprintf (pFile, "%s Thank you. \r\n", zmailer_msg_request(self->message)); fclose (pFile); FILE * pMail; pMail = fopen (filename,"r"); assert (pMail); curl = curl_easy_init(); if(curl) { /* Set username and password */ curl_easy_setopt(curl, CURLOPT_USERNAME, zconfig_get (self->server->config, "zmailer_server/user", "")); curl_easy_setopt(curl, CURLOPT_PASSWORD, zconfig_get (self->server->config, "zmailer_server/password", "")); /* This is the URL for your mailserver. Note the use of port 587 here, * instead of the normal SMTP port (25). Port 587 is commonly used for * secure mail submission (see RFC4403), but you should use whatever * matches your server configuration. */ curl_easy_setopt(curl, CURLOPT_URL, zconfig_get (self->server->config, "zmailer_server/server", "")); /* In this example, we'll start with a plain text connection, and upgrade * to Transport Layer Security (TLS) using the STARTTLS command. Be careful * of using CURLUSESSL_TRY here, because if TLS upgrade fails, the transfer * will continue anyway - see the security discussion in the libcurl * tutorial for more details. */ curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL); /* If your server doesn't have a valid certificate, then you can disable * part of the Transport Layer Security protection by setting the * CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST options to 0 (false).*/ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); /* Note that this option isn't strictly required, omitting it will result in * libcurl sending the MAIL FROM command with empty sender data. All * autoresponses should have an empty reverse-path, and should be directed * to the address in the reverse-path which triggered them. Otherwise, they * could cause an endless loop. See RFC 5321 Section 4.5.5 for more details. */ curl_easy_setopt(curl, CURLOPT_MAIL_FROM, zmailer_msg_from (self->message)); /* Add two recipients, in this particular case they correspond to the * To: and Cc: addressees in the header, but they could be any kind of * recipient. */ recipients = curl_slist_append(recipients, zmailer_msg_to (self->message)); curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients); /* We're using a callback function to specify the payload (the headers and * body of the message). You could just use the CURLOPT_READDATA option to * specify a FILE pointer to read from. */ curl_easy_setopt(curl, CURLOPT_READDATA, pMail); curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); /* Since the traffic will be encrypted, it is very useful to turn on debug * information within libcurl to see what is happening during the transfer. */ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); /* Send the message */ res = curl_easy_perform(curl); /* Check for errors */ if(res != CURLE_OK) fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); /* Free the list of recipients */ curl_slist_free_all(recipients); /* Always cleanup */ curl_easy_cleanup(curl); } fclose (pMail); }
static void 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) return; // Interrupted // First frame is sender identity byte *peerid_data = zframe_data (zre_msg_routing_id (msg)); size_t peerid_size = zframe_size (zre_msg_routing_id (msg)); // Identity must be [1] followed by 16-byte UUID if (peerid_size != ZUUID_LEN + 1) { zre_msg_destroy (&msg); return; } zuuid_t *uuid = zuuid_new (); zuuid_set (uuid, peerid_data + 1); // 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) { if (peer) { // Remove fake peers if (zyre_peer_ready (peer)) { zyre_node_remove_peer (self, peer); assert (!(zyre_peer_t *) zhash_lookup (self->peers, zuuid_str (uuid))); } else if (streq (zyre_peer_endpoint (peer), self->endpoint)) { // We ignore HELLO, if peer has same endpoint as current node zre_msg_destroy (&msg); zuuid_destroy (&uuid); return; } } peer = zyre_node_require_peer (self, uuid, zre_msg_endpoint (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; } if (zyre_peer_messages_lost (peer, msg)) { zsys_warning ("(%s) messages lost from %s", self->name, zyre_peer_name (peer)); zyre_node_remove_peer (self, peer); zre_msg_destroy (&msg); zuuid_destroy (&uuid); return; } // Now process each command if (zre_msg_id (msg) == ZRE_MSG_HELLO) { // Store properties from HELLO command into peer zyre_peer_set_name (peer, zre_msg_name (msg)); zyre_peer_set_headers (peer, zre_msg_headers (msg)); // Tell the caller about the peer zstr_sendm (self->outbox, "ENTER"); zstr_sendm (self->outbox, zyre_peer_identity (peer)); zstr_sendm (self->outbox, zyre_peer_name (peer)); zframe_t *headers = zhash_pack (zyre_peer_headers (peer)); zframe_send (&headers, self->outbox, ZFRAME_MORE); zstr_send (self->outbox, zre_msg_endpoint (msg)); if (self->verbose) zsys_info ("(%s) ENTER name=%s endpoint=%s", self->name, zyre_peer_name (peer), zyre_peer_endpoint (peer)); // Join peer to listed groups const char *name = zre_msg_groups_first (msg); while (name) { zyre_node_join_peer_group (self, peer, name); name = zre_msg_groups_next (msg); } // Now take peer's status from HELLO, after joining groups zyre_peer_set_status (peer, zre_msg_status (msg)); } else if (zre_msg_id (msg) == ZRE_MSG_WHISPER) { // Pass up to caller API as WHISPER event zstr_sendm (self->outbox, "WHISPER"); zstr_sendm (self->outbox, zuuid_str (uuid)); zstr_sendm (self->outbox, zyre_peer_name (peer)); zmsg_t *content = zmsg_dup (zre_msg_content (msg)); zmsg_send (&content, self->outbox); } else if (zre_msg_id (msg) == ZRE_MSG_SHOUT) { // Pass up to caller as SHOUT event zstr_sendm (self->outbox, "SHOUT"); zstr_sendm (self->outbox, zuuid_str (uuid)); zstr_sendm (self->outbox, zyre_peer_name (peer)); zstr_sendm (self->outbox, zre_msg_group (msg)); zmsg_t *content = zmsg_dup (zre_msg_content (msg)); zmsg_send (&content, self->outbox); } 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, self->evasive_timeout, self->expired_timeout); }
void xrap_traffic_test (bool verbose) { printf (" * xrap_traffic:"); if (verbose) printf ("\n"); // @selftest // Simple create/destroy test xrap_traffic_t *self = xrap_traffic_new (); assert (self); xrap_traffic_destroy (&self); // Create pair of sockets we can send through // We must bind before connect if we wish to remain compatible with ZeroMQ < v4 zsock_t *output = zsock_new (ZMQ_DEALER); assert (output); int rc = zsock_bind (output, "inproc://selftest-xrap_traffic"); assert (rc == 0); zsock_t *input = zsock_new (ZMQ_ROUTER); assert (input); rc = zsock_connect (input, "inproc://selftest-xrap_traffic"); assert (rc == 0); // Encode/send/decode and verify each message type int instance; self = xrap_traffic_new (); xrap_traffic_set_id (self, XRAP_TRAFFIC_CONNECTION_OPEN); xrap_traffic_set_address (self, "Life is short but Now lasts for ever"); // Send twice xrap_traffic_send (self, output); xrap_traffic_send (self, output); for (instance = 0; instance < 2; instance++) { xrap_traffic_recv (self, input); assert (xrap_traffic_routing_id (self)); assert (streq (xrap_traffic_address (self), "Life is short but Now lasts for ever")); } xrap_traffic_set_id (self, XRAP_TRAFFIC_CONNECTION_PING); // Send twice xrap_traffic_send (self, output); xrap_traffic_send (self, output); for (instance = 0; instance < 2; instance++) { xrap_traffic_recv (self, input); assert (xrap_traffic_routing_id (self)); } xrap_traffic_set_id (self, XRAP_TRAFFIC_CONNECTION_PONG); // Send twice xrap_traffic_send (self, output); xrap_traffic_send (self, output); for (instance = 0; instance < 2; instance++) { xrap_traffic_recv (self, input); assert (xrap_traffic_routing_id (self)); } xrap_traffic_set_id (self, XRAP_TRAFFIC_CONNECTION_CLOSE); // Send twice xrap_traffic_send (self, output); xrap_traffic_send (self, output); for (instance = 0; instance < 2; instance++) { xrap_traffic_recv (self, input); assert (xrap_traffic_routing_id (self)); } xrap_traffic_set_id (self, XRAP_TRAFFIC_XRAP_SEND); xrap_traffic_set_timeout (self, 123); zmsg_t *xrap_send_content = zmsg_new (); xrap_traffic_set_content (self, &xrap_send_content); zmsg_addstr (xrap_traffic_content (self), "Captcha Diem"); // Send twice xrap_traffic_send (self, output); xrap_traffic_send (self, output); for (instance = 0; instance < 2; instance++) { xrap_traffic_recv (self, input); assert (xrap_traffic_routing_id (self)); assert (xrap_traffic_timeout (self) == 123); assert (zmsg_size (xrap_traffic_content (self)) == 1); char *content = zmsg_popstr (xrap_traffic_content (self)); assert (streq (content, "Captcha Diem")); zstr_free (&content); if (instance == 1) zmsg_destroy (&xrap_send_content); } xrap_traffic_set_id (self, XRAP_TRAFFIC_XRAP_OFFER); xrap_traffic_set_route (self, "Life is short but Now lasts for ever"); xrap_traffic_set_method (self, "Life is short but Now lasts for ever"); // Send twice xrap_traffic_send (self, output); xrap_traffic_send (self, output); for (instance = 0; instance < 2; instance++) { xrap_traffic_recv (self, input); assert (xrap_traffic_routing_id (self)); assert (streq (xrap_traffic_route (self), "Life is short but Now lasts for ever")); assert (streq (xrap_traffic_method (self), "Life is short but Now lasts for ever")); } xrap_traffic_set_id (self, XRAP_TRAFFIC_XRAP_DELIVER); zuuid_t *xrap_deliver_sender = zuuid_new (); xrap_traffic_set_sender (self, xrap_deliver_sender); zmsg_t *xrap_deliver_content = zmsg_new (); xrap_traffic_set_content (self, &xrap_deliver_content); zmsg_addstr (xrap_traffic_content (self), "Captcha Diem"); // Send twice xrap_traffic_send (self, output); xrap_traffic_send (self, output); for (instance = 0; instance < 2; instance++) { xrap_traffic_recv (self, input); assert (xrap_traffic_routing_id (self)); assert (zuuid_eq (xrap_deliver_sender, zuuid_data (xrap_traffic_sender (self)))); if (instance == 1) zuuid_destroy (&xrap_deliver_sender); assert (zmsg_size (xrap_traffic_content (self)) == 1); char *content = zmsg_popstr (xrap_traffic_content (self)); assert (streq (content, "Captcha Diem")); zstr_free (&content); if (instance == 1) zmsg_destroy (&xrap_deliver_content); } xrap_traffic_set_id (self, XRAP_TRAFFIC_OK); xrap_traffic_set_status_code (self, 123); xrap_traffic_set_status_reason (self, "Life is short but Now lasts for ever"); // Send twice xrap_traffic_send (self, output); xrap_traffic_send (self, output); for (instance = 0; instance < 2; instance++) { xrap_traffic_recv (self, input); assert (xrap_traffic_routing_id (self)); assert (xrap_traffic_status_code (self) == 123); assert (streq (xrap_traffic_status_reason (self), "Life is short but Now lasts for ever")); } xrap_traffic_set_id (self, XRAP_TRAFFIC_FAIL); xrap_traffic_set_status_code (self, 123); xrap_traffic_set_status_reason (self, "Life is short but Now lasts for ever"); // Send twice xrap_traffic_send (self, output); xrap_traffic_send (self, output); for (instance = 0; instance < 2; instance++) { xrap_traffic_recv (self, input); assert (xrap_traffic_routing_id (self)); assert (xrap_traffic_status_code (self) == 123); assert (streq (xrap_traffic_status_reason (self), "Life is short but Now lasts for ever")); } xrap_traffic_set_id (self, XRAP_TRAFFIC_ERROR); xrap_traffic_set_status_code (self, 123); xrap_traffic_set_status_reason (self, "Life is short but Now lasts for ever"); // Send twice xrap_traffic_send (self, output); xrap_traffic_send (self, output); for (instance = 0; instance < 2; instance++) { xrap_traffic_recv (self, input); assert (xrap_traffic_routing_id (self)); assert (xrap_traffic_status_code (self) == 123); assert (streq (xrap_traffic_status_reason (self), "Life is short but Now lasts for ever")); } xrap_traffic_destroy (&self); zsock_destroy (&input); zsock_destroy (&output); // @end printf ("OK\n"); }