コード例 #1
0
ファイル: prob_client.c プロジェクト: Meijuh/ltsmin
ProBInitialResponse
prob_init(prob_client_t pc, int is_por)
{
    Debugf("initializing ProB Zocket\n")
    zmsg_t *request = zmsg_new();
    zmsg_addstr(request, "init");
    zmsg_addstrf(request, "%d", pc->id_count);
    zmsg_addstrf(request, "%d", is_por);

    Debugf("sending message with length %zu, contents are:\n", zmsg_content_size(request));
#ifdef LTSMIN_DEBUG
    if (log_active(debug)) zmsg_print(request);
#endif

    if (zmsg_send(&request, pc->zocket) != 0) Abort("Could not send message");
    zmsg_destroy(&request);

    zmsg_t *response = zmsg_recv(pc->zocket);
    if (response == NULL) Abort("Did not receive valid response");

    Debugf("received message with length %zu, contents are:\n", zmsg_content_size(response));
#ifdef LTSMIN_DEBUG
    if (log_active(debug)) zmsg_print(response);
#endif


    ProBInitialResponse resp = prob_get_init_response(response);

    if (zmsg_size(response) != 0) Abort("Did not receive valid reponse size");

//    puts("transition groups:");
//    print_chunk_array(resp.transition_groups);
//    puts("variables");
//    print_chunk_array(resp.variables);
//    for (size_t i = 0; i < resp.variables.size; i++) {
//        printf("%s (%s)\n", resp.variables.chunks[i].data, resp.variable_types.chunks[i].data);
//    }
//    puts("state labels");
//    print_chunk_array(resp.state_labels);
//
//    puts("May Write Matrix:");
//    print_matrix(resp.may_write);
//    puts("Must Write Matrix:");
//    print_matrix(resp.must_write);
//    puts("Reads Action Matrix:");
//    print_matrix(resp.reads_action);
//    puts("Reads Guard Matrix:");
//    print_matrix(resp.reads_guard);

    zmsg_destroy(&response);
    return resp;
}
コード例 #2
0
ファイル: zgossip.c プロジェクト: Cargo-Labs/czmq
static zmsg_t *
server_method (server_t *self, const char *method, zmsg_t *msg)
{
    //  Connect to a remote
    zmsg_t *reply = NULL;
    if (streq (method, "CONNECT")) {
        char *endpoint = zmsg_popstr (msg);
        assert (endpoint);
        server_connect (self, endpoint);
        zstr_free (&endpoint);
    }
    else
    if (streq (method, "PUBLISH")) {
        char *key = zmsg_popstr (msg);
        char *value = zmsg_popstr (msg);
        server_accept (self, key, value);
        zstr_free (&key);
        zstr_free (&value);
    }
    else
    if (streq (method, "STATUS")) {
        //  Return number of tuples we have stored
        reply = zmsg_new ();
        assert (reply);
        zmsg_addstr (reply, "STATUS");
        zmsg_addstrf (reply, "%d", (int) zhashx_size (self->tuples));
    }
    else
        zsys_error ("unknown zgossip method '%s'", method);

    return reply;
}
コード例 #3
0
ファイル: prob_client.c プロジェクト: Meijuh/ltsmin
void
prob_terminate(prob_client_t pc)
{
    zmsg_t *request = zmsg_new();
    zmsg_addstr(request, "terminate");
    zmsg_addstrf(request, "%d", pc->id_count);
    zmsg_send(&request, pc->zocket);
    zmsg_t *response = zmsg_recv(pc->zocket);
    zmsg_destroy(&response);
    zmsg_destroy(&request);
}
コード例 #4
0
ファイル: zuid.c プロジェクト: majidazimi/zUID
void worker(void *args, zctx_t *ctx, void *pipe) {
	long mashine_number =  ((setting_t *) args)->mashine_number;
	long thread_number = ((setting_t *) args)->thread_number;	
	long auto_increment = 0;
    struct timeval tp;
	
	void *worker = zsocket_new(ctx, ZMQ_DEALER);
	zsocket_connect(worker, "inproc://zid");
	
	while (!zctx_interrupted) {
		zmsg_t *request = zmsg_recv(worker);
		
		/* drop message if its size is less than 2 */
		if (zmsg_size(request) != 2) {
			zmsg_destroy(&request);
			continue;
		}
		/* sender id */
		zframe_t *sender = zmsg_pop(request);
		
		/* number of id to generate */
		char *num = zmsg_popstr(request);
		int n = atoi(num);
		free(num);
		
		if (n > 0) {
		
			/* response message */
			zmsg_t *response = zmsg_new();
		
			int i;
			for (i = 0; i < n; i++) {
				gettimeofday(&tp, NULL);
			
				zmsg_addstrf(response, "%ld", ((mashine_number << 59) | (thread_number << 56) | (auto_increment << 45) | (tp.tv_sec << 10) | (tp.tv_usec / 1000)));
			
				auto_increment++;
				if (auto_increment == 2048) {
					auto_increment = 0;
				}
			}
		
			/* push sender id */
			zmsg_push(response, sender);
			/* send back reply */
			zmsg_send(&response, worker);
		} else {
			zframe_destroy(&sender);
		}
		
		zmsg_destroy(&request);
	}
}
コード例 #5
0
ファイル: prob_client.c プロジェクト: Meijuh/ltsmin
void prob_get_label_group(prob_client_t pc, ProBState s, int group, int *res) {
    zmsg_t *request = zmsg_new();
    zmsg_addstr(request, "get-state-label-group");
    zmsg_addstrf(request, "%d", pc->id_count);
    zmsg_addstrf(request, "DA%d", group);
    prob_put_state(request, s);
    zmsg_send(&request, pc->zocket);
    zmsg_destroy(&request);
    zmsg_t *response = zmsg_recv(pc->zocket);
    drop_frame(response);
    drop_frame(response);

    char *result_s;
    for (int i = 0; (result_s = zmsg_popstr(response)) != NULL; i++) {
        int r;
        sscanf(result_s, "%d", &r);
        res[i] = r;
        RTfree(result_s);
    }

    zmsg_destroy(&response);
}
コード例 #6
0
ファイル: prob_client.c プロジェクト: Meijuh/ltsmin
int
prob_get_state_label(prob_client_t pc, ProBState s, char *label)
{
    zmsg_t *request = zmsg_new();
    zmsg_addstr(request, "get-state-label");
    zmsg_addstrf(request, "%d", pc->id_count);
    zmsg_addstrf(request, "DA%s", label);
    prob_put_state(request, s);
    zmsg_send(&request, pc->zocket);
    zmsg_destroy(&request);
    zmsg_t *response = zmsg_recv(pc->zocket);
    drop_frame(response);
    drop_frame(response);

    char *result_s = zmsg_popstr(response);
    int res;
    sscanf(result_s, "%d", &res);

    RTfree(result_s);
    zmsg_destroy(&response);
    return res;
}
コード例 #7
0
ファイル: test_publisher.c プロジェクト: skaes/logjam-tools
int timer_event(zloop_t *loop, int timer_id, void *pusher)
{
  int rc;
  static int message_count = 0;
  zmsg_t *message = zmsg_new();
  zmsg_addstr(message, "request-stream-test-development");
  zmsg_addstr(message, "routing-key");
  zmsg_addstrf(message, "message-body %d", message_count++);
  rc = zmsg_send(&message, pusher);
  if (!zsys_interrupted) {
    assert(rc==0);
  }
  return 0;
}
コード例 #8
0
static
void subscriber_publish_duplicate(zmsg_t *msg, void *socket)
{
    static size_t seq = 0;
    zmsg_t *msg_copy = zmsg_dup(msg);
    zmsg_addstrf(msg_copy, "%zu", ++seq);
    zframe_t *frame = zmsg_pop(msg_copy);
    while (frame != NULL) {
        zframe_t *next_frame = zmsg_pop(msg_copy);
        int more = next_frame ? ZFRAME_MORE : 0;
        if (zframe_send(&frame, socket, ZFRAME_DONTWAIT|more) == -1)
            break;
        frame = next_frame;
    }
    zmsg_destroy(&msg_copy);
}
コード例 #9
0
ファイル: prob_client.c プロジェクト: Meijuh/ltsmin
static ProBState *
prob_next_x(prob_client_t pc, ProBState s, char *transitiongroup, int *size, char *header) {
    zmsg_t *request = zmsg_new();
    zmsg_addstr(request, header);
    zmsg_addstrf(request, "%d", pc->id_count);
    zmsg_addstr(request, transitiongroup);

    prob_put_state(request, s);

    Debugf("requesting next-state, contents:\n");
#ifdef LTSMIN_DEBUG
    if (log_active(debug)) zmsg_print(request);
#endif

    zmsg_send(&request, pc->zocket);
    zmsg_destroy(&request);
    zmsg_t *response = zmsg_recv(pc->zocket);

    Debugf("response for next-state, contents:\n");
#ifdef LTSMIN_DEBUG
    if (log_active(debug)) zmsg_print(response);
#endif

    drop_frame(response);
    drop_frame(response);

    char *nr_of_states_s = zmsg_popstr(response);
    sscanf(nr_of_states_s, "%d", size);
    RTfree(nr_of_states_s);

    ProBState *successors = RTmalloc(sizeof(ProBState) * (*size));
    int i;
    for (i = 0; i < (*size); i++) {
        successors[i] = prob_get_state(response);
    }
    zmsg_destroy(&response);
    return successors;
}
コード例 #10
0
int main(int argc, char const * const *argv)
{
  int socket_count  = argc>1 ? atoi(argv[1]) : 1;
  int message_count = argc>2 ? atoi(argv[2]) : 100000;
  int rc;

  zctx_t *context = zctx_new();
  assert(context);
  zctx_set_sndhwm(context, 1);
  zctx_set_linger(context, 100);

  // zmq 2.2 only supports up to 512 sockets
  assert_x(ZMQ_VERSION <= 20200 && socket_count > 512,
           "zeromq < 3.2 only supports up to 512 sockets");

  void **sockets = zmalloc(socket_count * sizeof(void*));

  int j;
  for (j=0; j<socket_count; j++) {
    void *socket = zsocket_new(context, ZMQ_PUSH);
    if (NULL==socket) {
      printf("Error occurred during %dth call to zsocket_new: %s\n", j, zmq_strerror (errno));
      exit(1);
    }
    // zsocket_set_sndtimeo(socket, 10);
    zsocket_set_sndhwm(socket, 10);
    zsocket_set_linger(socket, 50);
    zsocket_set_reconnect_ivl(socket, 100); // 100 ms
    zsocket_set_reconnect_ivl_max(socket, 10 * 1000); // 10 s
    // printf("hwm %d\n", zsocket_hwm(socket));
    // printf("sndbuf %d\n", zsocket_sndbuf(socket));
    // printf("swap %d\n", zsocket_swap(socket));
    // printf("linger %d\n", zsocket_linger(socket));
    // printf("sndtimeo %d\n", zsocket_sndtimeo(socket));
    // printf("reconnect_ivl %d\n", zsocket_reconnect_ivl(socket));
    // printf("reconnect_ivl_max %d\n", zsocket_reconnect_ivl_max(socket));

    rc = zsocket_connect(socket, "tcp://localhost:12345");
    assert(rc==0);
    sockets[j] = socket;
    zclock_sleep(10); // sleep 10 ms
  }

  char data[MESSAGE_BODY_SIZE];
  memset(data, 'a', MESSAGE_BODY_SIZE);

  char *exchanges[2] = {"zmq-device-1", "zmq-device-2"};
  // char *keys[2] = {"1","2"};

  int i = 0, queued = 0, rejected = 0;
  for (i=0; i<message_count; i++) {
    if (zsys_interrupted)
      break;
    zmsg_t *message = zmsg_new();
    zmsg_addstr(message, exchanges[i%2]);
    zmsg_addstrf(message, "logjam.zmq.test.%d.%d", i%2, i);
    zmsg_addmem(message, data, MESSAGE_BODY_SIZE);
    // zmsg_dump(message);
    rc = zmsg_send_dont_wait(&message, sockets[i%socket_count]);
    assert(message == NULL);
    if (rc == 0) {
      queued++;
    } else {
      rejected++;
    }
    // usleep(20);
    usleep(1000);
  }

  printf("queued:   %8d\n", queued);
  printf("rejected: %8d\n", rejected);

  for (i=0;i<socket_count;i++) {
    zsocket_destroy(context, sockets[i]);
  }
  free(sockets);
  zctx_destroy(&context);

  return 0;
}
コード例 #11
0
ファイル: QmlZmsg.cpp プロジェクト: dadavita/stalk
///
//  Push formatted string as new frame to end of message.
//  Returns 0 on success, -1 on error.                   
int QmlZmsg::addstrf (const QString &format) {
    return zmsg_addstrf (self, "%s", format.toUtf8().data());
};
コード例 #12
0
ファイル: qzmsg.cpp プロジェクト: chsticksel/ocamlczmq
///
//  Push formatted string as new frame to end of message.
//  Returns 0 on success, -1 on error.                   
int QZmsg::addstrf (const QString &param)
{
    int rv = zmsg_addstrf (self, "%s", param.toUtf8().data());
    return rv;
}
コード例 #13
0
ファイル: zgossip.c プロジェクト: taotetek/czmq
static zmsg_t *
server_method (server_t *self, const char *method, zmsg_t *msg)
{
    //  Connect to a remote
    zmsg_t *reply = NULL;
    if (streq (method, "CONNECT")) {
        char *endpoint = zmsg_popstr (msg);
        assert (endpoint);
#ifdef CZMQ_BUILD_DRAFT_API
        //  DRAFT-API: Security
        // leaving this in here for now because if/def changes the server_connect
        // function args. it doesn't look like server_connect is used anywhere else
        // but want to leave this in until we're sure this is stable..
        char *public_key = zmsg_popstr (msg);
        server_connect (self, endpoint, public_key);
        zstr_free (&public_key);
#else
        server_connect (self, endpoint);
#endif
        zstr_free (&endpoint);
    }
    else
    if (streq (method, "PUBLISH")) {
        char *key = zmsg_popstr (msg);
        char *value = zmsg_popstr (msg);
        server_accept (self, key, value);
        zstr_free (&key);
        zstr_free (&value);
    }
    else
    if (streq (method, "STATUS")) {
        //  Return number of tuples we have stored
        reply = zmsg_new ();
        assert (reply);
        zmsg_addstr (reply, "STATUS");
        zmsg_addstrf (reply, "%d", (int) zhashx_size (self->tuples));
    }
#ifdef CZMQ_BUILD_DRAFT_API
    //  DRAFT-API: Security
    else
    if (streq (method, "SET PUBLICKEY")) {
        char *key = zmsg_popstr (msg);
        self->public_key = strdup (key);
        assert (self->public_key);
        zstr_free (&key);
    }
    else
    if (streq (method, "SET SECRETKEY")) {
        char *key = zmsg_popstr (msg);
        self->secret_key = strdup(key);
        assert (self->secret_key);
        zstr_free (&key);
    }
    else
    if (streq (method, "ZAP DOMAIN")) {
        char *value = zmsg_popstr (msg);
        zstr_free(&self->zap_domain);
        self->zap_domain = strdup(value);
        assert (self->zap_domain);
        zstr_free (&value);
    }
#endif
    else
        zsys_error ("unknown zgossip method '%s'", method);

    return reply;
}
コード例 #14
0
ファイル: zmonitor.c プロジェクト: TangCheng/czmq
static void
s_socket_event (agent_t *self)
{
    zframe_t *frame;
    zmq_event_t event;
    char *description = "Unknown";
    char address [1025];

    //  Copy event data into event struct
    frame = zframe_recv (self->socket);

    //  Extract id of the event as bitfield
    memcpy (&(event.event), zframe_data (frame), sizeof (event.event));

    //  Extract value which is either error code, fd, or reconnect interval
    memcpy (&(event.value), zframe_data (frame) + sizeof (event.event),
           sizeof (event.value));
    zframe_destroy (&frame);

    //  Copy address part
    frame = zframe_recv (self->socket);
    memcpy (address, zframe_data (frame), zframe_size (frame));
    address [zframe_size (frame)] = 0;  // Terminate address string
    zframe_destroy (&frame);

    switch (event.event) {
        case ZMQ_EVENT_ACCEPTED:
            description = "Accepted";
            break;
        case ZMQ_EVENT_ACCEPT_FAILED:
            description = "Accept failed";
            break;
        case ZMQ_EVENT_BIND_FAILED:
            description = "Bind failed";
            break;
        case ZMQ_EVENT_CLOSED:
            description = "Closed";
            break;
        case ZMQ_EVENT_CLOSE_FAILED:
            description = "Close failed";
            break;
        case ZMQ_EVENT_DISCONNECTED:
            description = "Disconnected";
            break;
        case ZMQ_EVENT_CONNECTED:
            description = "Connected";
            break;
        case ZMQ_EVENT_CONNECT_DELAYED:
            description = "Connect delayed";
            break;
        case ZMQ_EVENT_CONNECT_RETRIED:
            description = "Connect retried";
            break;
        case ZMQ_EVENT_LISTENING:
            description = "Listening";
            break;
        case ZMQ_EVENT_MONITOR_STOPPED:
            description = "Monitor stopped";
            break;
        default:
            if (self->verbose)
                printf ("Unknown socket monitor event: %d", event.event);
            break;
    }
    if (self->verbose)
        printf ("I: zmonitor: %s - %s\n", description, address);

    zmsg_t *msg = zmsg_new();
    zmsg_addstrf (msg, "%d", (int) event.event);
    zmsg_addstrf (msg, "%d", (int) event.value);
    zmsg_addstrf (msg, "%s", address);
    zmsg_addstrf (msg, "%s", description);
    zmsg_send (&msg, self->pipe);
}
コード例 #15
0
ファイル: ztask_run_manager.c プロジェクト: savke/ztask0
void
ztask_run_manager_loop (ztask_run_manager_t *self)
{
    assert (self);

    if (!self->packetizer) {
        zclock_log ("E: No packetizer set !!!");
        return;
    }

    //  Setting network interface if neede
    if (self->node_interface)
        zyre_set_interface(self->node, self->node_interface);

    zyre_set_header (self->node, "X-ZTASK-RUN", "ZTASK RUN");

    zyre_start (self->node);
    zyre_dump (self->node);
    zclock_sleep (10);
//    ztask_packetizer_dump (self->packetizer);

    ztask_packet_t *packet;
    int request_sent = 0;
    zyre_event_t *event;
    while (!zsys_interrupted) {

        if (ztask_packetizer_is_finished (self->packetizer))
            break;

        event = zyre_event_new (self->node);
        if (!event)
            break;
        if (zyre_event_type (event) == ZYRE_EVENT_ENTER) {
            //  Ignoring nodes which don't have service X-ZTASK-NODE defined
            if (zyre_event_header (event, "X-ZTASK-NODE")) {
                zhash_insert (self->nodes, zyre_event_sender (event),"");
                ztask_log_debug (self->log, "Adding node -> workers=%ld", zhash_size (self->nodes));
            } else {
                //  TODO disconnect worker (zyre peer) somehow
            }
        }
        else
        if (zyre_event_type (event) == ZYRE_EVENT_EXIT) {
            if (zhash_lookup (self->nodes, zyre_event_sender (event))) {
                ztask_log_debug (self->log, "Removing node -> workers=%ld", zhash_size (self->nodes));
                zhash_delete (self->nodes, zyre_event_sender (event));
                //  Cleanup packetizer in case ztask_node was killed
                request_sent -= ztask_packetizer_running_node_cleanup (self->packetizer, zyre_event_sender (event));
            }
        }
        else
        if (zyre_event_type (event) == ZYRE_EVENT_WHISPER) {

            //  Ingoring whispers when they are not from our nodes
            if (!zhash_lookup(self->nodes, zyre_event_sender (event))) {
                ztask_log_warning (self->log, "W: Ingoring whisper from %s", zyre_event_sender (event));
                zyre_event_destroy (&event);
                continue;
            }
            zmsg_t *msg_report = zyre_event_msg(event);
            char *str_msg = zmsg_popstr (msg_report);
            if (streq(str_msg, "REQUEST")) {
                //  Let's handle request
                packet = ztask_packetizer_next_packet (self->packetizer);
                if (packet) {
                    char *cmd;
                    if ( asprintf (&cmd, "%s", ztask_packet_cmd (packet)) < 0)
                         cmd = NULL;
                    assert (cmd);
                    zmsg_t *msg = zmsg_new ();
                    zmsg_addstr (msg, "REQUEST");
                    zmsg_addstrf (msg, "%s_%ld", zyre_uuid (self->node), ztask_packet_id (packet));
                    zmsg_addstr (msg, cmd);
                    zyre_whisper (self->node, zyre_event_sender (event), &msg);
                    ztask_packet_set_node (packet, zyre_event_sender (event));
                    request_sent++;
                    ztask_packetizer_info (self->packetizer, request_sent);
                    ztask_log_debug (self->log, "ID=%s_%ld cmd='%s' running=%d", zyre_uuid (self->node), ztask_packet_id (packet), cmd, request_sent);
                    free (cmd);
                }
                else {
                    zmsg_t *msg = zmsg_new ();
                    zmsg_addstr (msg, "NO_PACKETS");
                    zyre_whisper (self->node, zyre_event_sender (event), &msg);
                }

            }
            else
            if (streq(str_msg, "REPORT")) {
                //  It's report
                char *str_id = zmsg_popstr (msg_report);
                char *str_pid_rc = zmsg_popstr (msg_report);

                ztask_log_debug (self->log, "REPORT ID=%s rc=%s", str_id, str_pid_rc);
                ztask_packetizer_report (self->packetizer, str_id, str_pid_rc);
                request_sent--;
                ztask_packetizer_info (self->packetizer, request_sent);
                free (str_id);
                free (str_pid_rc);
            }
            else {
                ztask_log_error (self->log, "E: ztask_run_manager_loop : Wrong message %s", str_msg);
                assert (false);
            }
            free (str_msg);
        }

        zyre_event_destroy (&event);
    }

    //  FIXME : simplify zhash_foreach()
    zlist_t *keys = zhash_keys (self->nodes);
    char *key = (char *) zlist_first (keys);
    while (key) {
        zmsg_t *msg = zmsg_new ();
        zmsg_addstr (msg, "END");
        zyre_whisper (self->node, key, &msg);
        key = (char *) zlist_next (keys);
    }
    zlist_destroy (&keys);

    // wait for shout to be delivered
    zclock_sleep (100);

    ztask_packetizer_summary(self->packetizer, 0);

    zyre_stop (self->node);
}
コード例 #16
0
ファイル: zsync_node.c プロジェクト: skyformat99/protocol
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);
}