zuuid_t * zuuid_new (void) { zuuid_t *self = (zuuid_t *) zmalloc (sizeof (zuuid_t)); if (self) { #if defined (HAVE_LIBUUID) # if defined (__WINDOWS__) UUID uuid; assert (sizeof (uuid) == ZUUID_LEN); UuidCreate (&uuid); zuuid_set (self, (byte *) &uuid); # else uuid_t uuid; assert (sizeof (uuid) == ZUUID_LEN); uuid_generate (uuid); zuuid_set (self, (byte *) uuid); # endif #else // No UUID system calls, so generate a random string byte uuid [ZUUID_LEN]; int fd = open ("/dev/urandom", O_RDONLY); if (fd != -1) { ssize_t bytes_read = read (fd, uuid, ZUUID_LEN); assert (bytes_read == ZUUID_LEN); close (fd); } zuuid_set (self, uuid); #endif } return self; }
zuuid_t * zuuid_new (void) { zuuid_t *self = (zuuid_t *) zmalloc (sizeof (zuuid_t)); assert (self); #if defined (__WINDOWS__) // Windows always has UUID support UUID uuid; assert (sizeof (uuid) == ZUUID_LEN); UuidCreate (&uuid); zuuid_set (self, (byte *) &uuid); #elif defined (__UTYPE_ANDROID) || !defined (HAVE_UUID) // No UUID system calls, so generate a random string byte uuid [ZUUID_LEN]; int fd = open ("/dev/urandom", O_RDONLY); if (fd != -1) { ssize_t bytes_read = read (fd, uuid, ZUUID_LEN); assert (bytes_read == ZUUID_LEN); close (fd); zuuid_set (self, uuid); } else { // We couldn't read /dev/urandom and we have no alternative // strategy zsys_error (strerror (errno)); assert (false); } #elif defined (__UTYPE_OPENBSD) || defined (__UTYPE_FREEBSD) || defined (__UTYPE_NETBSD) uuid_t uuid; uint32_t status = 0; uuid_create (&uuid, &status); if (status != uuid_s_ok) { zuuid_destroy (&self); return NULL; } byte buffer [ZUUID_LEN]; uuid_enc_be (&buffer, &uuid); zuuid_set (self, buffer); #elif defined (__UTYPE_LINUX) || defined (__UTYPE_OSX) || defined (__UTYPE_SUNOS) || defined (__UTYPE_SUNSOLARIS) || defined (__UTYPE_GNU) uuid_t uuid; assert (sizeof (uuid) == ZUUID_LEN); uuid_generate (uuid); zuuid_set (self, (byte *) uuid); #else # error "Unknown UNIX TYPE" #endif return self; }
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"); }
zuuid_t * zuuid_new_from (const byte *source) { zuuid_t *self = (zuuid_t *) zmalloc (sizeof (zuuid_t)); assert (self); zuuid_set (self, source); 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 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 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; }
/// // Set UUID to new supplied ZUUID_LEN-octet value. void QZuuid::set (const byte *source) { zuuid_set (self, source); }
static int zyre_node_recv_peer (zyre_node_t *self) { // Router socket tells us the identity of this peer zre_msg_t *msg = zre_msg_recv (self->inbox); if (msg == NULL) return 0; // Interrupted // First frame is sender identity, holding binary UUID zuuid_t *uuid = zuuid_new (); zuuid_set (uuid, zframe_data (zre_msg_address (msg))); // On HELLO we may create the peer if it's unknown // On other commands the peer must already exist zyre_peer_t *peer = (zyre_peer_t *) zhash_lookup (self->peers, zuuid_str (uuid)); if (zre_msg_id (msg) == ZRE_MSG_HELLO) { peer = zyre_node_require_peer (self, uuid, zre_msg_ipaddress (msg), zre_msg_mailbox (msg)); assert (peer); zyre_peer_set_ready (peer, true); } // Ignore command if peer isn't ready if (peer == NULL || !zyre_peer_ready (peer)) { zre_msg_destroy (&msg); zuuid_destroy (&uuid); return 0; } if (!zyre_peer_check_message (peer, msg)) { zclock_log ("W: [%s] lost messages from %s", zuuid_str (self->uuid), zuuid_str (uuid)); assert (false); } // Now process each command if (zre_msg_id (msg) == ZRE_MSG_HELLO) { // Tell the caller about the peer zstr_sendm (self->pipe, "ENTER"); zstr_sendm (self->pipe, zuuid_str (uuid)); zframe_t *headers = zhash_pack (zre_msg_headers (msg)); zframe_send (&headers, self->pipe, 0); // Join peer to listed groups char *name = zre_msg_groups_first (msg); while (name) { zyre_node_join_peer_group (self, peer, name); name = zre_msg_groups_next (msg); } // Hello command holds latest status of peer zyre_peer_set_status (peer, zre_msg_status (msg)); // Store peer headers for future reference zyre_peer_set_headers (peer, zre_msg_headers (msg)); // If peer is a ZRE/LOG collector, connect to it char *collector = zre_msg_headers_string (msg, "X-ZRELOG", NULL); if (collector) zyre_log_connect (self->log, collector); } else if (zre_msg_id (msg) == ZRE_MSG_WHISPER) { // Pass up to caller API as WHISPER event zstr_sendm (self->pipe, "WHISPER"); zstr_sendm (self->pipe, zuuid_str (uuid)); zmsg_t *content = zmsg_dup (zre_msg_content (msg)); zmsg_send (&content, self->pipe); } else if (zre_msg_id (msg) == ZRE_MSG_SHOUT) { // Pass up to caller as SHOUT event zstr_sendm (self->pipe, "SHOUT"); zstr_sendm (self->pipe, zuuid_str (uuid)); zstr_sendm (self->pipe, zre_msg_group (msg)); zmsg_t *content = zmsg_dup (zre_msg_content (msg)); zmsg_send (&content, self->pipe); } else if (zre_msg_id (msg) == ZRE_MSG_PING) { zre_msg_t *msg = zre_msg_new (ZRE_MSG_PING_OK); zyre_peer_send (peer, &msg); } else if (zre_msg_id (msg) == ZRE_MSG_JOIN) { zyre_node_join_peer_group (self, peer, zre_msg_group (msg)); assert (zre_msg_status (msg) == zyre_peer_status (peer)); } else if (zre_msg_id (msg) == ZRE_MSG_LEAVE) { zyre_node_leave_peer_group (self, peer, zre_msg_group (msg)); assert (zre_msg_status (msg) == zyre_peer_status (peer)); } zuuid_destroy (&uuid); zre_msg_destroy (&msg); // Activity from peer resets peer timers zyre_peer_refresh (peer); return 0; }
static 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); }
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); }