Exemplo n.º 1
0
void
zchunk_test (bool verbose)
{
    printf (" * zchunk: ");

    //  @selftest
    zchunk_t *chunk = zchunk_new ("1234567890", 10);
    assert (chunk);
    assert (zchunk_size (chunk) == 10);
    assert (memcmp (zchunk_data (chunk), "1234567890", 10) == 0);
    zchunk_destroy (&chunk);

    chunk = zchunk_new (NULL, 10);
    zchunk_append (chunk, "12345678", 8);
    zchunk_append (chunk, "90ABCDEF", 8);
    zchunk_append (chunk, "GHIJKLMN", 8);
    assert (memcmp (zchunk_data (chunk), "1234567890", 10) == 0);
    assert (zchunk_size (chunk) == 10);

    zframe_t *frame = zchunk_pack (chunk);
    assert(frame);

    zchunk_t *chunk2 = zchunk_unpack (frame);
    assert (memcmp (zchunk_data (chunk2), "1234567890", 10) == 0);
    zframe_destroy(&frame);
    zchunk_destroy(&chunk2);

    zchunk_t *copy = zchunk_dup (chunk);
    assert (memcmp (zchunk_data (copy), "1234567890", 10) == 0);
    assert (zchunk_size (copy) == 10);
    zchunk_destroy (&copy);
    zchunk_destroy (&chunk);

    copy = zchunk_new ("1234567890abcdefghij", 20);
    chunk = zchunk_new (NULL, 8);
    zchunk_consume (chunk, copy);
    assert (!zchunk_exhausted (copy));
    assert (memcmp (zchunk_data (chunk), "12345678", 8) == 0);
    zchunk_set (chunk, NULL, 0);
    zchunk_consume (chunk, copy);
    assert (!zchunk_exhausted (copy));
    assert (memcmp (zchunk_data (chunk), "90abcdef", 8) == 0);
    zchunk_set (chunk, NULL, 0);
    zchunk_consume (chunk, copy);
    assert (zchunk_exhausted (copy));
    assert (zchunk_size (chunk) == 4);
    assert (memcmp (zchunk_data (chunk), "ghij", 4) == 0);
    zchunk_destroy (&copy);
    zchunk_destroy (&chunk);
    //  @end

    printf ("OK\n");
}
Exemplo n.º 2
0
zchunk_t *
zchunk_unpack (zframe_t *frame)
{
    assert(frame);
    assert(zframe_is(frame));

    return zchunk_new (zframe_data (frame), zframe_size (frame) );
}
Exemplo n.º 3
0
zchunk_t *
zchunk_read (FILE *handle, size_t bytes)
{
    assert (handle);
    zchunk_t *self = zchunk_new (NULL, bytes);
    self->size = fread (self->data, 1, bytes, handle);
    return self;
}
Exemplo n.º 4
0
zchunk_t *
zchunk_dup (zchunk_t *self)
{
    assert (self);
    assert (zchunk_is (self));

    return zchunk_new (self->data, self->max_size);
}
Exemplo n.º 5
0
zconfig_t *
zconfig_str_load (const char *string)
{
    zchunk_t *chunk = zchunk_new (string, strlen (string));
    zconfig_t *config = zconfig_chunk_load (chunk);
    zchunk_destroy (&chunk);
    return config;
}
Exemplo n.º 6
0
static void
server_process_cluster_command (
    server_t *self,
    const char *peer_id,
    const char *peer_name,
    zmsg_t *msg,
    bool unicast)
{
    char *request = zmsg_popstr (msg);
    char *pipename = zmsg_popstr (msg);
    zsys_info ("peer=%s command=%s pipe=%s unicast=%d",
                peer_name, request, pipename? pipename: "-", unicast);

    //  Lookup or create pipe
    //  TODO: remote pipes need cleaning up with some timeout
    pipe_t *pipe = NULL;
    if (pipename) {
        pipe = (pipe_t *) zhash_lookup (self->pipes, pipename);
        if (!pipe)
            pipe = pipe_new (self, pipename);
    }
    if (pipe && streq (request, "HAVE WRITER"))
        pipe_attach_remote_writer (pipe, peer_id, unicast);
    else
    if (pipe && streq (request, "HAVE READER"))
        pipe_attach_remote_reader (pipe, peer_id, unicast);
    else
    if (pipe && streq (request, "DATA")) {
        //  TODO encode these commands as proper protocol
        zframe_t *frame = zmsg_pop (msg);
        zchunk_t *chunk = zchunk_new (zframe_data (frame), zframe_size (frame));
        if (pipe->writer == REMOTE_NODE && pipe->reader) {
            zsys_info ("send %d bytes to pipe", (int) zchunk_size (chunk));
            pipe_send_data (pipe, &chunk); 
        }
        else
            zsys_info ("discard %d bytes, unroutable", (int) zchunk_size (chunk));
            
        zframe_destroy (&frame);
        zchunk_destroy (&chunk);
    }
    else
    if (pipe && streq (request, "DROP READER"))
        pipe_drop_remote_reader (&pipe, peer_id);
    else
    if (pipe && streq (request, "DROP WRITER"))
        pipe_drop_remote_writer (&pipe, peer_id);
    else
    if (streq (request, "DUMP"))
        zyre_dump (self->zyre);
    else
        zsys_warning ("bad request %s from %s", request, peer_name);

    zstr_free (&pipename);
    zstr_free (&request);
}
Exemplo n.º 7
0
JNIEXPORT jlong JNICALL
Java_org_zeromq_czmq_Zchunk__1_1new (JNIEnv *env, jclass c, jbyteArray data, jlong size)
{
    jbyte *data_ = (byte *) (*env)->GetByteArrayElements (env, data, 0);
    //  Disable CZMQ signal handling; allow Java to deal with it
    zsys_handler_set (NULL);
    jlong new_ = (jlong) (intptr_t) zchunk_new (data_, (size_t) size);
    (*env)->ReleaseByteArrayElements (env, data, (jbyte *) data_, 0);
    return new_;
}
Exemplo n.º 8
0
void
hydra_post_set_data (hydra_post_t *self, const void *data, size_t size)
{
    assert (self);
    zstr_free (&self->location);
    zchunk_destroy (&self->content);
    self->content = zchunk_new (data, size);
    strcpy (self->digest, zchunk_digest (self->content));
    self->content_size = zchunk_size (self->content);
}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
0
Arquivo: zfile.c Projeto: TTimo/czmq
int
zfile_test (bool verbose)
{
    printf (" * zfile: ");

    //  @selftest
    zfile_t *file = zfile_new (".", "bilbo");
    assert (streq (zfile_filename (file, "."), "bilbo"));
    assert (zfile_is_readable (file) == false);
    zfile_destroy (&file);

    //  Create a test file in some random subdirectory
    file = zfile_new ("./this/is/a/test", "bilbo");
    int rc = zfile_output (file);
    assert (rc == 0);
    zchunk_t *chunk = zchunk_new (NULL, 100);
    zchunk_fill (chunk, 0, 100);
    //  Write 100 bytes at position 1,000,000 in the file
    rc = zfile_write (file, chunk, 1000000);
    assert (rc == 0);
    zfile_close (file);
    assert (zfile_is_readable (file));
    assert (zfile_cursize (file) == 1000100);
    assert (!zfile_is_stable (file));
    zchunk_destroy (&chunk);
    zclock_sleep (1001);
    assert (zfile_is_stable (file));

    //  Check we can read from file
    rc = zfile_input (file);
    assert (rc == 0);
    chunk = zfile_read (file, 1000100, 0);
    assert (chunk);
    assert (zchunk_size (chunk) == 1000100);
    zchunk_destroy (&chunk);

    //  Remove file and directory
    zdir_t *dir = zdir_new ("./this", NULL);
    assert (zdir_cursize (dir) == 1000100);
    zdir_remove (dir, true);
    assert (zdir_cursize (dir) == 0);
    zdir_destroy (&dir);

    //  Check we can no longer read from file
    assert (!zfile_is_readable (file));
    rc = zfile_input (file);
    assert (rc == -1);
    zfile_destroy (&file);
    //  @end

    printf ("OK\n");
    return 0;
}
Exemplo n.º 11
0
static
parser_state_t* parser_state_new(zconfig_t* config, size_t id)
{
    parser_state_t *state = zmalloc(sizeof(*state));
    state->config = config;
    state->id = id;
    snprintf(state->me, 16, "parser[%zu]", id);
    state->pull_socket = parser_pull_socket_new();
    state->push_socket = parser_push_socket_new();
    state->decompression_buffer = zchunk_new(NULL, INITIAL_DECOMPRESSION_BUFFER_SIZE);
    return state;
}
Exemplo n.º 12
0
zchunk_t *
zconfig_chunk_save (zconfig_t *self)
{
    assert (self);

    int size = s_config_execute (self, s_config_save, NULL, 0);
    //  Allow an extra byte so we can null-terminate the data
    zchunk_t *chunk = zchunk_new (NULL, size + 1);
    if (chunk) {
        s_config_execute (self, s_config_save, chunk, 0);
        //  This lets us treat the chunk data as a string
        zchunk_data (chunk) [zchunk_size (chunk)] = 0;
    }
    return chunk;
}
Exemplo n.º 13
0
static void
collect_data_to_send (client_t *self)
{
    zsys_info ("read %d bytes", (int) zpipes_msg_size (self->request));
    //  Do we have enough data to satisfy the read request?
    size_t required = zpipes_msg_size (self->request);
    
    //  If pipe was closed, we'll do a short read with as much
    //  data as we have pending
    if (required > self->pending && self->pipe == NULL)
        required = self->pending;

    if (self->pipe == NULL && self->pending == 0)
        engine_set_exception (self, pipe_shut_event);
    else
    if (self->pending >= required) {
        //  Create a bucket chunk with the required max size
        zchunk_t *bucket = zchunk_new (NULL, required);

        //  Now fill the bucket with chunks from our queue
        while (zchunk_size (bucket) < required) {
            //  Get next chunk and consume as much of it as possible
            zchunk_t *chunk = (zchunk_t *) zlist_pop (self->queue);
            assert (chunk);
            zchunk_consume (bucket, chunk);
            //  If chunk is exhausted, destroy it
            if (zchunk_exhausted (chunk))
                zchunk_destroy (&chunk);
            else {
                //  Push chunk back for next time
                zlist_push (self->queue, chunk);
                assert (zchunk_size (bucket) == required);
            }
        }
        zpipes_msg_set_chunk (self->reply, &bucket);
        self->pending -= required;
    }
    else
        engine_set_exception (self, not_enough_data_event);
}
Exemplo n.º 14
0
ssize_t
zpipes_client_write (zpipes_client_t *self, void *data, size_t size, int timeout)
{
    assert (self);
    zchunk_t *chunk = zchunk_new (data, size);
    assert (chunk);
    zpipes_msg_t *request = zpipes_msg_new (ZPIPES_MSG_WRITE);
    zpipes_msg_set_chunk (request, &chunk);
    zpipes_msg_set_timeout (request, timeout);
    zpipes_msg_send (&request, self->dealer);

    zpipes_msg_t *reply = zpipes_msg_recv (self->dealer);
    if (!reply) {
        self->error = EINTR;
        return -1;              //  Interrupted
    }
    ssize_t rc = size;
    if (zpipes_msg_id (reply) == ZPIPES_MSG_WRITE_TIMEOUT) {
        self->error = EAGAIN;
        rc = -1;
    }
    else
    if (zpipes_msg_id (reply) == ZPIPES_MSG_WRITE_FAILED) {
        //  TODO: better error code?
        //  This happens if we close a pipe while there's a pending write
        self->error = EINTR;
        rc = -1;
    }
    else
    if (zpipes_msg_id (reply) == ZPIPES_MSG_INVALID) {
        self->error = EBADF;
        rc = -1;
    }
    zpipes_msg_destroy (&reply);
    return rc;
}
Exemplo n.º 15
0
int
fmq_msg_recv (fmq_msg_t *self, zsock_t *input)
{
    assert (input);

    if (zsock_type (input) == ZMQ_ROUTER) {
        zframe_destroy (&self->routing_id);
        self->routing_id = zframe_recv (input);
        if (!self->routing_id || !zsock_rcvmore (input)) {
            zsys_warning ("fmq_msg: no routing ID");
            return -1;          //  Interrupted or malformed
        }
    }
    zmq_msg_t frame;
    zmq_msg_init (&frame);
    int size = zmq_msg_recv (&frame, zsock_resolve (input), 0);
    if (size == -1) {
        zsys_warning ("fmq_msg: interrupted");
        goto malformed;         //  Interrupted
    }
    //  Get and check protocol signature
    self->needle = (byte *) zmq_msg_data (&frame);
    self->ceiling = self->needle + zmq_msg_size (&frame);

    uint16_t signature;
    GET_NUMBER2 (signature);
    if (signature != (0xAAA0 | 3)) {
        zsys_warning ("fmq_msg: invalid signature");
        //  TODO: discard invalid messages and loop, and return
        //  -1 only on interrupt
        goto malformed;         //  Interrupted
    }
    //  Get message id and parse per message type
    GET_NUMBER1 (self->id);

    switch (self->id) {
        case FMQ_MSG_OHAI:
            {
                char protocol [256];
                GET_STRING (protocol);
                if (strneq (protocol, "FILEMQ")) {
                    zsys_warning ("fmq_msg: protocol is invalid");
                    goto malformed;
                }
            }
            {
                uint16_t version;
                GET_NUMBER2 (version);
                if (version != FMQ_MSG_VERSION) {
                    zsys_warning ("fmq_msg: version is invalid");
                    goto malformed;
                }
            }
            break;

        case FMQ_MSG_OHAI_OK:
            break;

        case FMQ_MSG_ICANHAZ:
            GET_LONGSTR (self->path);
            {
                size_t hash_size;
                GET_NUMBER4 (hash_size);
                self->options = zhash_new ();
                zhash_autofree (self->options);
                while (hash_size--) {
                    char key [256];
                    char *value = NULL;
                    GET_STRING (key);
                    GET_LONGSTR (value);
                    zhash_insert (self->options, key, value);
                    free (value);
                }
            }
            {
                size_t hash_size;
                GET_NUMBER4 (hash_size);
                self->cache = zhash_new ();
                zhash_autofree (self->cache);
                while (hash_size--) {
                    char key [256];
                    char *value = NULL;
                    GET_STRING (key);
                    GET_LONGSTR (value);
                    zhash_insert (self->cache, key, value);
                    free (value);
                }
            }
            break;

        case FMQ_MSG_ICANHAZ_OK:
            break;

        case FMQ_MSG_NOM:
            GET_NUMBER8 (self->credit);
            GET_NUMBER8 (self->sequence);
            break;

        case FMQ_MSG_CHEEZBURGER:
            GET_NUMBER8 (self->sequence);
            GET_NUMBER1 (self->operation);
            GET_LONGSTR (self->filename);
            GET_NUMBER8 (self->offset);
            GET_NUMBER1 (self->eof);
            {
                size_t hash_size;
                GET_NUMBER4 (hash_size);
                self->headers = zhash_new ();
                zhash_autofree (self->headers);
                while (hash_size--) {
                    char key [256];
                    char *value = NULL;
                    GET_STRING (key);
                    GET_LONGSTR (value);
                    zhash_insert (self->headers, key, value);
                    free (value);
                }
            }
            {
                size_t chunk_size;
                GET_NUMBER4 (chunk_size);
                if (self->needle + chunk_size > (self->ceiling)) {
                    zsys_warning ("fmq_msg: chunk is missing data");
                    goto malformed;
                }
                zchunk_destroy (&self->chunk);
                self->chunk = zchunk_new (self->needle, chunk_size);
                self->needle += chunk_size;
            }
            break;

        case FMQ_MSG_HUGZ:
            break;

        case FMQ_MSG_HUGZ_OK:
            break;

        case FMQ_MSG_KTHXBAI:
            break;

        case FMQ_MSG_SRSLY:
            GET_STRING (self->reason);
            break;

        case FMQ_MSG_RTFM:
            GET_STRING (self->reason);
            break;

        default:
            zsys_warning ("fmq_msg: bad message ID");
            goto malformed;
    }
    //  Successful return
    zmq_msg_close (&frame);
    return 0;

    //  Error returns
    malformed:
        zsys_warning ("fmq_msg: fmq_msg malformed message, fail");
        zmq_msg_close (&frame);
        return -1;              //  Invalid message
}
Exemplo n.º 16
0
Arquivo: zfile.c Projeto: DeanHH/czmq
void
zfile_test (bool verbose)
{
    printf (" * zfile: ");

    //  @selftest
    zfile_t *file = zfile_new (NULL, "bilbo");
    assert (streq (zfile_filename (file, "."), "bilbo"));
    assert (zfile_is_readable (file) == false);
    zfile_destroy (&file);

    //  Create a test file in some random subdirectory
    file = zfile_new ("./this/is/a/test", "bilbo");
    int rc = zfile_output (file);
    assert (rc == 0);
    zchunk_t *chunk = zchunk_new (NULL, 100);
    zchunk_fill (chunk, 0, 100);
    
    //  Write 100 bytes at position 1,000,000 in the file
    rc = zfile_write (file, chunk, 1000000);
    assert (rc == 0);
    zchunk_destroy (&chunk);
    zfile_close (file);
    assert (zfile_is_readable (file));
    assert (zfile_cursize (file) == 1000100);
    assert (!zfile_is_stable (file));
    
    //  Now append one byte to file from outside
    int handle = open ("./this/is/a/test/bilbo", O_WRONLY | O_TRUNC | O_BINARY, 0);
    assert (handle >= 0);
    rc = write (handle, "Hello, World\n", 13);
    assert (rc == 13);
    close (handle);
    assert (zfile_has_changed (file));
    zclock_sleep (1001);
    assert (zfile_has_changed (file));
    
    assert (!zfile_is_stable (file));
    zfile_restat (file);
    assert (zfile_is_stable (file));
    assert (streq (zfile_digest (file), "4AB299C8AD6ED14F31923DD94F8B5F5CB89DFB54"));
    
    //  Check we can read from file
    rc = zfile_input (file);
    assert (rc == 0);
    chunk = zfile_read (file, 1000100, 0);
    assert (chunk);
    assert (zchunk_size (chunk) == 13);
    zchunk_destroy (&chunk);
    zfile_close (file);

    //  Try some fun with symbolic links
    zfile_t *link = zfile_new ("./this/is/a/test", "bilbo.ln");
    rc = zfile_output (link);
    assert (rc == 0);
    fprintf (zfile_handle (link), "./this/is/a/test/bilbo\n");
    zfile_destroy (&link);

    link = zfile_new ("./this/is/a/test", "bilbo.ln");
    rc = zfile_input (link);
    assert (rc == 0);
    chunk = zfile_read (link, 1000100, 0);
    assert (chunk);
    assert (zchunk_size (chunk) == 13);
    zchunk_destroy (&chunk);
    zfile_destroy (&link);

    //  Remove file and directory
    zdir_t *dir = zdir_new ("./this", NULL);
    assert (zdir_cursize (dir) == 26);
    zdir_remove (dir, true);
    assert (zdir_cursize (dir) == 0);
    zdir_destroy (&dir);

    //  Check we can no longer read from file
    assert (zfile_is_readable (file));
    zfile_restat (file);
    assert (!zfile_is_readable (file));
    rc = zfile_input (file);
    assert (rc == -1);
    zfile_destroy (&file);
    //  @end

    printf ("OK\n");
}
Exemplo n.º 17
0
///
//  Create a new chunk of the specified size. If you specify the data, it
//  is copied into the chunk. If you do not specify the data, the chunk is
//  allocated and left empty, and you can then add data using zchunk_append.
QZchunk::QZchunk (const void *data, size_t size, QObject *qObjParent) : QObject (qObjParent)
{
    this->self = zchunk_new (data, size);
}
Exemplo n.º 18
0
void
zhttp_client_test (bool verbose) {
#if defined(HAVE_LIBCURL) && defined(ZMQ_STREAM)
    printf (" * zhttp_client: ");
    zsock_t *server = zsock_new_stream (NULL);
    int port = zsock_bind (server, "tcp://127.0.0.1:*");
    char url[255];
    sprintf (url, "http://127.0.0.1:%d", port);

    //  @selftest
    //  Simple create/destroy test
    zhttp_client_t *self = zhttp_client_new (verbose);
    assert (self);

    //  Send the get request
    bool event = false;
    zlistx_t *headers = zlistx_new ();
    zlistx_add_end (headers, "Host: zeromq.org");
    zhttp_client_get (self, url, headers, -1, test_handler, &event);
    zlistx_destroy (&headers);

    //  Receive request on the server
    zchunk_t *routing_id = recv_http_request (server);

    //  Send the response
    char* response = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\nHello";
    zsock_send (server, "cs", routing_id, response);
    zchunk_destroy (&routing_id);

    //  Receive the response on the http client
    int rc = zhttp_client_wait (self, -1);
    assert (rc == 0);
    zhttp_client_execute (self);
    assert (event);

    // Send a POST request
    event = false;
    zchunk_t *body = zchunk_new ("World", 5);
    zhttp_client_post (self, url, NULL, body, -1, test_handler, &event);

    //  Receive request on the server
    routing_id = recv_http_request (server);

    //  Send the response
    zsock_send (server, "cs", routing_id, response);
    zchunk_destroy (&routing_id);

    //  Receive the response on the http client
    rc = zhttp_client_wait (self, -1);
    assert (rc == 0);
    zhttp_client_execute (self);
    assert (event);

    //  Timeout check
    event = false;
    zhttp_client_get (self, url, NULL, 1000, test_handler, &event);
    rc = zhttp_client_wait (self, 1200);
    assert (rc == 0);
    zhttp_client_execute (self);
    assert (event);

    //  Sending another request, without being answer
    //  Checking the client ability to stop while request are inprogres
    zhttp_client_get (self, url, NULL, -1, test_handler, NULL);

    zchunk_destroy (&body);
    zhttp_client_destroy (&self);
    zsock_destroy (&server);

    //  @end
    printf ("OK\n");
#endif
}
Exemplo n.º 19
0
void
zpipes_server_test (bool verbose)
{
    printf (" * zpipes_server: \n");
    if (verbose)
        printf ("\n");

    //  @selftest
    //  Prepare test cases
    const char *endpoint = "ipc://@/zpipes/local";
    zactor_t *server = zactor_new (zpipes_server, NULL);
    if (verbose)
        zstr_send (server, "VERBOSE");
    zstr_sendx (server, "BIND", endpoint, NULL);

    zsock_t *writer = zsock_new_dealer (endpoint);
    assert (writer);
    zsock_t *writer2 = zsock_new_dealer (endpoint);
    assert (writer2);
    zsock_t *reader = zsock_new_dealer (endpoint);
    assert (reader);
    zsock_t *reader2 = zsock_new_dealer (endpoint);
    assert (reader2);
    
    zchunk_t *chunk = zchunk_new ("Hello, World", 12);
    int32_t timeout = 100;
    
    //  --------------------------------------------------------------------
    //  Basic tests

    //  Open writer on pipe
    zpipes_msg_send_output (writer, "test pipe");
    if (s_expect_reply (writer, ZPIPES_MSG_OUTPUT_OK))
        assert (false);

    //  Write will timeout if there's no reader
    zpipes_msg_send_write (writer, chunk, timeout);
    if (s_expect_reply (writer, ZPIPES_MSG_WRITE_TIMEOUT))
        assert (false);

    //  Now open reader on pipe
    zpipes_msg_send_input (reader, "test pipe");
    if (s_expect_reply (reader, ZPIPES_MSG_INPUT_OK))
        assert (false);

    //  Read will timeout if there's no data
    zpipes_msg_send_read (reader, 12, timeout);
    if (s_expect_reply (reader, ZPIPES_MSG_READ_TIMEOUT))
        assert (false);

    //  Write should now be successful
    zpipes_msg_send_write (writer, chunk, 0);
    if (s_expect_reply (writer, ZPIPES_MSG_WRITE_OK))
        assert (false);

    //  Read should now be successful
    zpipes_msg_send_read (reader, 12, 0);
    if (s_expect_reply (reader, ZPIPES_MSG_READ_OK))
        assert (false);

    //  Zero read request returns "end of pipe"
    zpipes_msg_send_read (reader, 0, 0);
    if (s_expect_reply (reader, ZPIPES_MSG_READ_END))
        assert (false);

    //  Close writer
    zpipes_msg_send_close (writer);
    if (s_expect_reply (writer, ZPIPES_MSG_CLOSE_OK))
        assert (false);

    //  Any read request returns "end of pipe"
    zpipes_msg_send_read (reader, 12, timeout);
    if (s_expect_reply (reader, ZPIPES_MSG_READ_END))
        assert (false);

    //  Close reader
    zpipes_msg_send_close (reader);
    if (s_expect_reply (reader, ZPIPES_MSG_CLOSE_OK))
        assert (false);

    //  --------------------------------------------------------------------
    //  Test pipelining (request queuing & filtering)

    //  Open reader on pipe
    zpipes_msg_send_input (reader, "test pipe");
    if (s_expect_reply (reader, ZPIPES_MSG_INPUT_OK))
        assert (false);

    //  Open writer on pipe
    zpipes_msg_send_output (writer, "test pipe");
    if (s_expect_reply (writer, ZPIPES_MSG_OUTPUT_OK))
        assert (false);

    //  Pipeline three read requests
    zpipes_msg_send_read (reader, 12, timeout);
    zpipes_msg_send_read (reader, 12, timeout);
    zpipes_msg_send_read (reader, 12, timeout);

    //  First read will return with a timeout
    if (s_expect_reply (reader, ZPIPES_MSG_READ_TIMEOUT))
        assert (false);

    //  Write chunk to pipe
    zpipes_msg_send_write (writer, chunk, 0);
    if (s_expect_reply (writer, ZPIPES_MSG_WRITE_OK))
        assert (false);

    //  Second read will succeed
    if (s_expect_reply (reader, ZPIPES_MSG_READ_OK))
        assert (false);

    //  Send PING, expect PING-OK back
    zpipes_msg_send_ping (reader);
    if (s_expect_reply (reader, ZPIPES_MSG_PING_OK))
        assert (false);

    //  Close writer
    zpipes_msg_send_close (writer);
    if (s_expect_reply (writer, ZPIPES_MSG_CLOSE_OK))
        assert (false);

    //  Third read will report end of pipe
    if (s_expect_reply (reader, ZPIPES_MSG_READ_END))
        assert (false);

    //  Close reader
    zpipes_msg_send_close (reader);
    if (s_expect_reply (reader, ZPIPES_MSG_CLOSE_OK))
        assert (false);

    //  Read now fails as pipe is closed
    zpipes_msg_send_read (reader, 12, timeout);
    if (s_expect_reply (reader, ZPIPES_MSG_INVALID))
        assert (false);

    //  Closing an already closed pipe is an error
    zpipes_msg_send_close (reader);
    if (s_expect_reply (reader, ZPIPES_MSG_INVALID))
        assert (false);

    //  --------------------------------------------------------------------
    //  Test read/close pipelining

    //  Open reader on pipe
    zpipes_msg_send_input (reader, "test pipe");
    if (s_expect_reply (reader, ZPIPES_MSG_INPUT_OK))
        assert (false);

    //  Open writer on pipe
    zpipes_msg_send_output (writer, "test pipe");
    if (s_expect_reply (writer, ZPIPES_MSG_OUTPUT_OK))
        assert (false);

    //  Pipeline two read requests
    zpipes_msg_send_read (reader, 12, timeout);
    zpipes_msg_send_read (reader, 12, timeout);

    //  Send PING, expect PING-OK back
    zpipes_msg_send_ping (reader);
    if (s_expect_reply (reader, ZPIPES_MSG_PING_OK))
        assert (false);

    //  Close reader
    zpipes_msg_send_close (reader);
    
    //  First read now fails
    if (s_expect_reply (reader, ZPIPES_MSG_READ_FAILED))
        assert (false);
    
    if (s_expect_reply (reader, ZPIPES_MSG_CLOSE_OK))
        assert (false);

    //  Second read is now invalid
    if (s_expect_reply (reader, ZPIPES_MSG_INVALID))
        assert (false);
    
    //  Close writer
    zpipes_msg_send_close (writer);
    if (s_expect_reply (writer, ZPIPES_MSG_CLOSE_OK))
        assert (false);

    //  --------------------------------------------------------------------
    //  Test reads and writes of different sizes

    //  Open reader on pipe
    zpipes_msg_send_input (reader, "test pipe");
    if (s_expect_reply (reader, ZPIPES_MSG_INPUT_OK))
        assert (false);

    //  Open writer on pipe
    zpipes_msg_send_output (writer, "test pipe");
    if (s_expect_reply (writer, ZPIPES_MSG_OUTPUT_OK))
        assert (false);

    //  Write chunk to pipe
    zpipes_msg_send_write (writer, chunk, 0);
    if (s_expect_reply (writer, ZPIPES_MSG_WRITE_OK))
        assert (false);

    //  Close writer
    zpipes_msg_send_close (writer);
    if (s_expect_reply (writer, ZPIPES_MSG_CLOSE_OK))
        assert (false);

    //  Read back in several steps
    zpipes_msg_send_read (reader, 1, 0);
    if (s_expect_reply (reader, ZPIPES_MSG_READ_OK))
        assert (false);
    zpipes_msg_send_read (reader, 2, 0);
    if (s_expect_reply (reader, ZPIPES_MSG_READ_OK))
        assert (false);
    zpipes_msg_send_read (reader, 3, 0);
    if (s_expect_reply (reader, ZPIPES_MSG_READ_OK))
        assert (false);
    zpipes_msg_send_read (reader, 3, 0);
    if (s_expect_reply (reader, ZPIPES_MSG_READ_OK))
        assert (false);
    
    //  We get a short read (3 bytes)
    zpipes_msg_send_read (reader, 100, 0);
    if (s_expect_reply (reader, ZPIPES_MSG_READ_OK))
        assert (false);
    
    //  Pipe is now empty
    zpipes_msg_send_read (reader, 100, 0);
    if (s_expect_reply (reader, ZPIPES_MSG_READ_END))
        assert (false);
    
    //  Close reader
    zpipes_msg_send_close (reader);
    if (s_expect_reply (reader, ZPIPES_MSG_CLOSE_OK))
        assert (false);

    //  --------------------------------------------------------------------
    //  Test connection expiry

    //  Set connection timeout to 200 msecs
    zstr_sendx (server, "SET", "server/timeout", "200", NULL);

    //  Open reader on pipe
    zpipes_msg_send_input (reader, "test pipe");
    if (s_expect_reply (reader, ZPIPES_MSG_INPUT_OK))
        assert (false);

    //  Read will expire, we don't expect any response for this command
    zpipes_msg_send_read (reader, 12, 0);

    //  Do nothing for long enough for the timeout to hit
    zclock_sleep (300);

    //  Try again, server should now treat the client as disconnected
    zpipes_msg_send_read (reader, 12, 0);
    if (s_expect_reply (reader, ZPIPES_MSG_INVALID))
        assert (false);

    //  Now check that disconnection erases pipe contents

    //  Open reader on pipe
    zpipes_msg_send_input (reader, "test pipe");
    if (s_expect_reply (reader, ZPIPES_MSG_INPUT_OK))
        assert (false);

    //  Open writer on pipe
    zpipes_msg_send_output (writer, "test pipe");
    if (s_expect_reply (writer, ZPIPES_MSG_OUTPUT_OK))
        assert (false);

    //  Write chunk to pipe
    zpipes_msg_send_write (writer, chunk, 0);
    if (s_expect_reply (writer, ZPIPES_MSG_WRITE_OK))
        assert (false);

    //  Do nothing for long enough for the timeout to hit
    //  Both writer and reader should be disconnected
    zclock_sleep (300);

    //  Open reader on pipe
    zpipes_msg_send_input (reader, "test pipe");
    if (s_expect_reply (reader, ZPIPES_MSG_INPUT_OK))
        assert (false);

    //  Open writer on pipe
    zpipes_msg_send_output (writer, "test pipe");
    if (s_expect_reply (writer, ZPIPES_MSG_OUTPUT_OK))
        assert (false);

    //  This read should timeout, as pipe is empty
    zpipes_msg_send_read (reader, 12, timeout);
    if (s_expect_reply (reader, ZPIPES_MSG_READ_TIMEOUT))
        assert (false);

    //  Close writer
    zpipes_msg_send_close (writer);
    if (s_expect_reply (writer, ZPIPES_MSG_CLOSE_OK))
        assert (false);

    //  Close reader
    zpipes_msg_send_close (reader);
    if (s_expect_reply (reader, ZPIPES_MSG_CLOSE_OK))
        assert (false);
    
    //  --------------------------------------------------------------------
    //  Test writer closing while reader still active

    //  Open writer on pipe
    zpipes_msg_send_output (writer, "test pipe");
    if (s_expect_reply (writer, ZPIPES_MSG_OUTPUT_OK))
        assert (false);

    //  Open reader on pipe
    zpipes_msg_send_input (reader, "test pipe");
    if (s_expect_reply (reader, ZPIPES_MSG_INPUT_OK))
        assert (false);

    //  Write one chunk to pipe
    zpipes_msg_send_write (writer, chunk, 0);
    if (s_expect_reply (writer, ZPIPES_MSG_WRITE_OK))
        assert (false);

    //  Close writer, before reader has read data
    zpipes_msg_send_close (writer);
    if (s_expect_reply (writer, ZPIPES_MSG_CLOSE_OK))
        assert (false);

    //  Open writer on same pipe name
    zpipes_msg_send_output (writer, "test pipe");
    if (s_expect_reply (writer, ZPIPES_MSG_OUTPUT_OK))
        assert (false);

    //  Read should still be successful
    zpipes_msg_send_read (reader, 12, 0);
    if (s_expect_reply (reader, ZPIPES_MSG_READ_OK))
        assert (false);

    //  Create second reader and open pipe for input
    zpipes_msg_send_input (reader2, "test pipe");
    if (s_expect_reply (reader2, ZPIPES_MSG_INPUT_OK))
        assert (false);

    //  Write one chunk to pipe, will go to second instance
    zpipes_msg_send_write (writer, chunk, 0);
    if (s_expect_reply (writer, ZPIPES_MSG_WRITE_OK))
        assert (false);

    //  Pipe is terminated and empty
    zpipes_msg_send_read (reader, 0, 0);
    if (s_expect_reply (reader, ZPIPES_MSG_READ_END))
        assert (false);

    //  Reader2 should be successful
    zpipes_msg_send_read (reader2, 12, 0);
    if (s_expect_reply (reader2, ZPIPES_MSG_READ_OK))
        assert (false);

    //  Close reader 
    zpipes_msg_send_close (reader);
    if (s_expect_reply (reader, ZPIPES_MSG_CLOSE_OK))
        assert (false);

    //  Close writer
    zpipes_msg_send_close (writer);
    if (s_expect_reply (writer, ZPIPES_MSG_CLOSE_OK))
        assert (false);
    
    //  Pipe is terminated and empty
    zpipes_msg_send_read (reader2, 0, 0);
    if (s_expect_reply (reader2, ZPIPES_MSG_READ_END))
        assert (false);

    //  Do that again to be sure it wasn't a coincidence :)
    zpipes_msg_send_read (reader2, 0, 0);
    if (s_expect_reply (reader2, ZPIPES_MSG_READ_END))
        assert (false);

    //  Close reader2
    zpipes_msg_send_close (reader2);
    if (s_expect_reply (reader2, ZPIPES_MSG_CLOSE_OK))
        assert (false);

    //  --------------------------------------------------------------------
    //  Test reader closing while writer still active

    //  Open writer on pipe
    zpipes_msg_send_output (writer, "test pipe");
    if (s_expect_reply (writer, ZPIPES_MSG_OUTPUT_OK))
        assert (false);

    //  Open reader on pipe
    zpipes_msg_send_input (reader, "test pipe");
    if (s_expect_reply (reader, ZPIPES_MSG_INPUT_OK))
        assert (false);

    //  Write one chunk to pipe
    zpipes_msg_send_write (writer, chunk, 0);
    if (s_expect_reply (writer, ZPIPES_MSG_WRITE_OK))
        assert (false);

    //  Read should be successful
    zpipes_msg_send_read (reader, 12, 0);
    if (s_expect_reply (reader, ZPIPES_MSG_READ_OK))
        assert (false);

    //  Close reader
    zpipes_msg_send_close (reader);
    if (s_expect_reply (reader, ZPIPES_MSG_CLOSE_OK))
        assert (false);

    //  Write should fail
    zpipes_msg_send_write (writer, chunk, 0);
    if (s_expect_reply (writer, ZPIPES_MSG_WRITE_FAILED))
        assert (false);

    //  Close writer
    zpipes_msg_send_close (writer);
    if (s_expect_reply (writer, ZPIPES_MSG_CLOSE_OK))
        assert (false);

    //  --------------------------------------------------------------------
    //  Two readers or writers on same pipe are not allowed

    //  Open writer on pipe
    zpipes_msg_send_output (writer, "test pipe");
    if (s_expect_reply (writer, ZPIPES_MSG_OUTPUT_OK))
        assert (false);

    //  Open second writer on pipe
    zpipes_msg_send_output (writer2, "test pipe");
    if (s_expect_reply (writer2, ZPIPES_MSG_OUTPUT_FAILED))
        assert (false);

    //  Open reader on pipe
    zpipes_msg_send_input (reader, "test pipe");
    if (s_expect_reply (reader, ZPIPES_MSG_INPUT_OK))
        assert (false);

    //  Open second reader on pipe
    zpipes_msg_send_input (reader2, "test pipe");
    if (s_expect_reply (reader2, ZPIPES_MSG_INPUT_FAILED))
        assert (false);

    //  Close reader
    zpipes_msg_send_close (reader);
    if (s_expect_reply (reader, ZPIPES_MSG_CLOSE_OK))
        assert (false);

    //  Close writer
    zpipes_msg_send_close (writer);
    if (s_expect_reply (writer, ZPIPES_MSG_CLOSE_OK))
        assert (false);
    
    //  --------------------------------------------------------------------
    //  Test short read when writer closes

    //  Open writer on pipe
    zpipes_msg_send_output (writer, "test pipe");
    if (s_expect_reply (writer, ZPIPES_MSG_OUTPUT_OK))
        assert (false);

    //  Open reader on pipe
    zpipes_msg_send_input (reader, "test pipe");
    if (s_expect_reply (reader, ZPIPES_MSG_INPUT_OK))
        assert (false);

    //  Write one chunk to pipe
    zpipes_msg_send_write (writer, chunk, 0);
    if (s_expect_reply (writer, ZPIPES_MSG_WRITE_OK))
        assert (false);

    //  Try to read large amount of data, will block
    zpipes_msg_send_read (reader, 1000, 0);
    
    //  Close writer
    zpipes_msg_send_close (writer);
    if (s_expect_reply (writer, ZPIPES_MSG_CLOSE_OK))
        assert (false);

    //  Reader should now return short read
    if (s_expect_reply (reader, ZPIPES_MSG_READ_OK))
        assert (false);

    //  Pipe is terminated and empty
    zpipes_msg_send_read (reader, 0, 0);
    if (s_expect_reply (reader, ZPIPES_MSG_READ_END))
        assert (false);

    //  Close reader
    zpipes_msg_send_close (reader);
    if (s_expect_reply (reader, ZPIPES_MSG_CLOSE_OK))
        assert (false);

    //  --------------------------------------------------------------------
    zchunk_destroy (&chunk);
    zactor_destroy (&server);
    zsock_destroy (&reader);
    zsock_destroy (&writer);
    zsock_destroy (&reader2);
    zsock_destroy (&writer2);
    //  @end

    printf ("OK\n");
}
Exemplo n.º 20
0
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");
}
Exemplo n.º 21
0
void
fmq_msg_test (bool verbose)
{
    printf (" * fmq_msg:");

    if (verbose)
        printf ("\n");

    //  @selftest
    //  Simple create/destroy test
    fmq_msg_t *self = fmq_msg_new ();
    assert (self);
    fmq_msg_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-fmq_msg");
    assert (rc == 0);

    zsock_t *input = zsock_new (ZMQ_ROUTER);
    assert (input);
    rc = zsock_connect (input, "inproc://selftest-fmq_msg");
    assert (rc == 0);


    //  Encode/send/decode and verify each message type
    int instance;
    self = fmq_msg_new ();
    fmq_msg_set_id (self, FMQ_MSG_OHAI);

    //  Send twice
    fmq_msg_send (self, output);
    fmq_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
    }
    fmq_msg_set_id (self, FMQ_MSG_OHAI_OK);

    //  Send twice
    fmq_msg_send (self, output);
    fmq_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
    }
    fmq_msg_set_id (self, FMQ_MSG_ICANHAZ);

    fmq_msg_set_path (self, "Life is short but Now lasts for ever");
    zhash_t *icanhaz_options = zhash_new ();
    zhash_insert (icanhaz_options, "Name", "Brutus");
    fmq_msg_set_options (self, &icanhaz_options);
    zhash_t *icanhaz_cache = zhash_new ();
    zhash_insert (icanhaz_cache, "Name", "Brutus");
    fmq_msg_set_cache (self, &icanhaz_cache);
    //  Send twice
    fmq_msg_send (self, output);
    fmq_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
        assert (streq (fmq_msg_path (self), "Life is short but Now lasts for ever"));
        zhash_t *options = fmq_msg_get_options (self);
        assert (zhash_size (options) == 2);
        assert (streq ((char *) zhash_first (options), "Brutus"));
        assert (streq ((char *) zhash_cursor (options), "Name"));
        zhash_destroy (&options);
        if (instance == 1)
            zhash_destroy (&icanhaz_options);
        zhash_t *cache = fmq_msg_get_cache (self);
        assert (zhash_size (cache) == 2);
        assert (streq ((char *) zhash_first (cache), "Brutus"));
        assert (streq ((char *) zhash_cursor (cache), "Name"));
        zhash_destroy (&cache);
        if (instance == 1)
            zhash_destroy (&icanhaz_cache);
    }
    fmq_msg_set_id (self, FMQ_MSG_ICANHAZ_OK);

    //  Send twice
    fmq_msg_send (self, output);
    fmq_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
    }
    fmq_msg_set_id (self, FMQ_MSG_NOM);

    fmq_msg_set_credit (self, 123);
    fmq_msg_set_sequence (self, 123);
    //  Send twice
    fmq_msg_send (self, output);
    fmq_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
        assert (fmq_msg_credit (self) == 123);
        assert (fmq_msg_sequence (self) == 123);
    }
    fmq_msg_set_id (self, FMQ_MSG_CHEEZBURGER);

    fmq_msg_set_sequence (self, 123);
    fmq_msg_set_operation (self, 123);
    fmq_msg_set_filename (self, "Life is short but Now lasts for ever");
    fmq_msg_set_offset (self, 123);
    fmq_msg_set_eof (self, 123);
    zhash_t *cheezburger_headers = zhash_new ();
    zhash_insert (cheezburger_headers, "Name", "Brutus");
    fmq_msg_set_headers (self, &cheezburger_headers);
    zchunk_t *cheezburger_chunk = zchunk_new ("Captcha Diem", 12);
    fmq_msg_set_chunk (self, &cheezburger_chunk);
    //  Send twice
    fmq_msg_send (self, output);
    fmq_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
        assert (fmq_msg_sequence (self) == 123);
        assert (fmq_msg_operation (self) == 123);
        assert (streq (fmq_msg_filename (self), "Life is short but Now lasts for ever"));
        assert (fmq_msg_offset (self) == 123);
        assert (fmq_msg_eof (self) == 123);
        zhash_t *headers = fmq_msg_get_headers (self);
        assert (zhash_size (headers) == 2);
        assert (streq ((char *) zhash_first (headers), "Brutus"));
        assert (streq ((char *) zhash_cursor (headers), "Name"));
        zhash_destroy (&headers);
        if (instance == 1)
            zhash_destroy (&cheezburger_headers);
        assert (memcmp (zchunk_data (fmq_msg_chunk (self)), "Captcha Diem", 12) == 0);
        if (instance == 1)
            zchunk_destroy (&cheezburger_chunk);
    }
    fmq_msg_set_id (self, FMQ_MSG_HUGZ);

    //  Send twice
    fmq_msg_send (self, output);
    fmq_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
    }
    fmq_msg_set_id (self, FMQ_MSG_HUGZ_OK);

    //  Send twice
    fmq_msg_send (self, output);
    fmq_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
    }
    fmq_msg_set_id (self, FMQ_MSG_KTHXBAI);

    //  Send twice
    fmq_msg_send (self, output);
    fmq_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
    }
    fmq_msg_set_id (self, FMQ_MSG_SRSLY);

    fmq_msg_set_reason (self, "Life is short but Now lasts for ever");
    //  Send twice
    fmq_msg_send (self, output);
    fmq_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
        assert (streq (fmq_msg_reason (self), "Life is short but Now lasts for ever"));
    }
    fmq_msg_set_id (self, FMQ_MSG_RTFM);

    fmq_msg_set_reason (self, "Life is short but Now lasts for ever");
    //  Send twice
    fmq_msg_send (self, output);
    fmq_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
        assert (streq (fmq_msg_reason (self), "Life is short but Now lasts for ever"));
    }

    fmq_msg_destroy (&self);
    zsock_destroy (&input);
    zsock_destroy (&output);
    //  @end

    printf ("OK\n");
}
Exemplo n.º 22
0
int
zproto_example_recv (zproto_example_t *self, zsock_t *input)
{
    assert (input);

    if (zsock_type (input) == ZMQ_ROUTER) {
        zframe_destroy (&self->routing_id);
        self->routing_id = zframe_recv (input);
        if (!self->routing_id || !zsock_rcvmore (input)) {
            zsys_warning ("zproto_example: no routing ID");
            return -1;          //  Interrupted or malformed
        }
    }
    zmq_msg_t frame;
    zmq_msg_init (&frame);
    int size = zmq_msg_recv (&frame, zsock_resolve (input), 0);
    if (size == -1) {
        zsys_warning ("zproto_example: interrupted");
        goto malformed;         //  Interrupted
    }
    //  Get and check protocol signature
    self->needle = (byte *) zmq_msg_data (&frame);
    self->ceiling = self->needle + zmq_msg_size (&frame);

    uint16_t signature;
    GET_NUMBER2 (signature);
    if (signature != (0xAAA0 | 0)) {
        zsys_warning ("zproto_example: invalid signature");
        //  TODO: discard invalid messages and loop, and return
        //  -1 only on interrupt
        goto malformed;         //  Interrupted
    }
    //  Get message id and parse per message type
    GET_NUMBER1 (self->id);

    switch (self->id) {
        case ZPROTO_EXAMPLE_LOG:
            GET_NUMBER2 (self->sequence);
            {
                uint16_t version;
                GET_NUMBER2 (version);
                if (version != 3) {
                    zsys_warning ("zproto_example: version is invalid");
                    goto malformed;
                }
            }
            GET_NUMBER1 (self->level);
            GET_NUMBER1 (self->event);
            GET_NUMBER2 (self->node);
            GET_NUMBER2 (self->peer);
            GET_NUMBER8 (self->time);
            GET_STRING (self->host);
            GET_LONGSTR (self->data);
            break;

        case ZPROTO_EXAMPLE_STRUCTURES:
            GET_NUMBER2 (self->sequence);
            {
                size_t list_size;
                GET_NUMBER4 (list_size);
                self->aliases = zlist_new ();
                zlist_autofree (self->aliases);
                while (list_size--) {
                    char *string = NULL;
                    GET_LONGSTR (string);
                    zlist_append (self->aliases, string);
                    free (string);
                }
            }
            {
                size_t hash_size;
                GET_NUMBER4 (hash_size);
                self->headers = zhash_new ();
                zhash_autofree (self->headers);
                while (hash_size--) {
                    char key [256];
                    char *value = NULL;
                    GET_STRING (key);
                    GET_LONGSTR (value);
                    zhash_insert (self->headers, key, value);
                    free (value);
                }
            }
            break;

        case ZPROTO_EXAMPLE_BINARY:
            GET_NUMBER2 (self->sequence);
            GET_OCTETS (self->flags, 4);
            {
                size_t chunk_size;
                GET_NUMBER4 (chunk_size);
                if (self->needle + chunk_size > (self->ceiling)) {
                    zsys_warning ("zproto_example: public_key is missing data");
                    goto malformed;
                }
                zchunk_destroy (&self->public_key);
                self->public_key = zchunk_new (self->needle, chunk_size);
                self->needle += chunk_size;
            }
            if (self->needle + ZUUID_LEN > (self->ceiling)) {
                zsys_warning ("zproto_example: identifier is invalid");
                goto malformed;
            }
            zuuid_destroy (&self->identifier);
            self->identifier = zuuid_new_from (self->needle);
            self->needle += ZUUID_LEN;
            //  Get next frame off socket
            if (!zsock_rcvmore (input)) {
                zsys_warning ("zproto_example: address is missing");
                goto malformed;
            }
            zframe_destroy (&self->address);
            self->address = zframe_recv (input);
            //  Get zero or more remaining frames
            zmsg_destroy (&self->content);
            if (zsock_rcvmore (input))
                self->content = zmsg_recv (input);
            else
                self->content = zmsg_new ();
            break;

        case ZPROTO_EXAMPLE_TYPES:
            GET_NUMBER2 (self->sequence);
            GET_STRING (self->client_forename);
            GET_STRING (self->client_surname);
            GET_STRING (self->client_mobile);
            GET_STRING (self->client_email);
            GET_STRING (self->supplier_forename);
            GET_STRING (self->supplier_surname);
            GET_STRING (self->supplier_mobile);
            GET_STRING (self->supplier_email);
            break;

        default:
            zsys_warning ("zproto_example: bad message ID");
            goto malformed;
    }
    //  Successful return
    zmq_msg_close (&frame);
    return 0;

    //  Error returns
    malformed:
        zsys_warning ("zproto_example: zproto_example malformed message, fail");
        zmq_msg_close (&frame);
        return -1;              //  Invalid message
}
Exemplo n.º 23
0
void
zfile_test (bool verbose)
{
    printf (" * zfile: ");

    //  @selftest

    const char *SELFTEST_DIR_RW = "src/selftest-rw";

    const char *testbasedir  = "this";
    const char *testsubdir  = "is/a/test";
    const char *testfile = "bilbo";
    const char *testlink = "bilbo.ln";
    char *basedirpath = NULL;   // subdir in a test, under SELFTEST_DIR_RW
    char *dirpath = NULL;       // subdir in a test, under basedirpath
    char *filepath = NULL;      // pathname to testfile in a test, in dirpath
    char *linkpath = NULL;      // pathname to testlink in a test, in dirpath

    basedirpath = zsys_sprintf ("%s/%s", SELFTEST_DIR_RW, testbasedir);
    assert (basedirpath);
    dirpath = zsys_sprintf ("%s/%s", basedirpath, testsubdir);
    assert (dirpath);
    filepath = zsys_sprintf ("%s/%s", dirpath, testfile);
    assert (filepath);
    linkpath = zsys_sprintf ("%s/%s", dirpath, testlink);
    assert (linkpath);

    // This subtest is specifically for NULL as current directory, so
    // no SELFTEST_DIR_RW here; testfile should have no slashes inside.
    // Normally tests clean up in zfile_destroy(), but if a selftest run
    // dies e.g. on assert(), workspace remains dirty. Better clean it up.
    if (zfile_exists (testfile) ) {
        if (verbose)
            zsys_debug ("zfile_test() has to remove ./%s that should not have been here", testfile);
        zfile_delete (testfile);
    }
    zfile_t *file = zfile_new (NULL, testfile);
    assert (file);
    assert (streq (zfile_filename (file, "."), testfile));
    assert (zfile_is_readable (file) == false);
    zfile_destroy (&file);

    //  Create a test file in some random subdirectory
    if (verbose)
        zsys_debug ("zfile_test() at timestamp %" PRIi64 ": "
            "Creating new zfile %s",
            zclock_time(), filepath );

    if (zfile_exists (filepath) ) {
        if (verbose)
            zsys_debug ("zfile_test() has to remove %s that should not have been here", filepath);
        zfile_delete (filepath);
    }

    file = zfile_new (dirpath, testfile);
    assert (file);
    int rc = zfile_output (file);
    assert (rc == 0);
    zchunk_t *chunk = zchunk_new (NULL, 100);
    assert (chunk);
    zchunk_fill (chunk, 0, 100);

    //  Write 100 bytes at position 1,000,000 in the file
    if (verbose)
        zsys_debug ("zfile_test() at timestamp %" PRIi64 ": "
            "Writing 100 bytes at position 1,000,000 in the file",
            zclock_time() );
    rc = zfile_write (file, chunk, 1000000);
    if (verbose)
        zsys_debug ("zfile_test() at timestamp %" PRIi64 ": "
            "Wrote 100 bytes at position 1,000,000 in the file, result code %d",
            zclock_time(), rc );
    assert (rc == 0);
    zchunk_destroy (&chunk);
    zfile_close (file);
    assert (zfile_is_readable (file));
    assert (zfile_cursize (file) == 1000100);
    if (verbose)
        zsys_debug ("zfile_test() at timestamp %" PRIi64 ": "
            "Testing if file is NOT stable (is younger than 1 sec)",
            zclock_time() );
    assert (!zfile_is_stable (file));
    if (verbose)
        zsys_debug ("zfile_test() at timestamp %" PRIi64 ": "
            "Passed the lag-dependent tests",
            zclock_time() );
    assert (zfile_digest (file));

    //  Now truncate file from outside
    int handle = open (filepath, O_WRONLY | O_TRUNC | O_BINARY, 0);
    assert (handle >= 0);
    rc = write (handle, "Hello, World\n", 13);
    assert (rc == 13);
    close (handle);
    assert (zfile_has_changed (file));
#ifdef CZMQ_BUILD_DRAFT_API
    zclock_sleep ((int)zsys_file_stable_age_msec() + 50);
#else
    zclock_sleep (5050);
#endif
    assert (zfile_has_changed (file));

    assert (!zfile_is_stable (file));
    zfile_restat (file);
    assert (zfile_is_stable (file));
    assert (streq (zfile_digest (file), "4AB299C8AD6ED14F31923DD94F8B5F5CB89DFB54"));

    //  Check we can read from file
    rc = zfile_input (file);
    assert (rc == 0);
    chunk = zfile_read (file, 1000100, 0);
    assert (chunk);
    assert (zchunk_size (chunk) == 13);
    zchunk_destroy (&chunk);
    zfile_close (file);

    //  Check we can read lines from file
    rc = zfile_input (file);
    assert (rc == 0);
    const char *line = zfile_readln (file);
    assert (streq (line, "Hello, World"));
    line = zfile_readln (file);
    assert (line == NULL);
    zfile_close (file);

    //  Try some fun with symbolic links
    zfile_t *link = zfile_new (dirpath, testlink);
    assert (link);
    rc = zfile_output (link);
    assert (rc == 0);
    fprintf (zfile_handle (link), "%s\n", filepath);
    zfile_destroy (&link);

    link = zfile_new (dirpath, testlink);
    assert (link);
    rc = zfile_input (link);
    assert (rc == 0);
    chunk = zfile_read (link, 1000100, 0);
    assert (chunk);
    assert (zchunk_size (chunk) == 13);
    zchunk_destroy (&chunk);
    zfile_destroy (&link);

    //  Remove file and directory
    zdir_t *dir = zdir_new (basedirpath, NULL);
    assert (dir);
    assert (zdir_cursize (dir) == 26);
    zdir_remove (dir, true);
    assert (zdir_cursize (dir) == 0);
    zdir_destroy (&dir);

    //  Check we can no longer read from file
    assert (zfile_is_readable (file));
    zfile_restat (file);
    assert (!zfile_is_readable (file));
    rc = zfile_input (file);
    assert (rc == -1);
    zfile_destroy (&file);

    // This set of tests is done, free the strings for reuse
    zstr_free (&basedirpath);
    zstr_free (&dirpath);
    zstr_free (&filepath);
    zstr_free (&linkpath);

    const char *eof_checkfile = "eof_checkfile";
    filepath = zsys_sprintf ("%s/%s", SELFTEST_DIR_RW, eof_checkfile);
    assert (filepath);

    if (zfile_exists (filepath) ) {
        if (verbose)
            zsys_debug ("zfile_test() has to remove %s that should not have been here", filepath);
        zfile_delete (filepath);
    }
    zstr_free (&filepath);

    file = zfile_new (SELFTEST_DIR_RW, eof_checkfile);
    assert (file);

    //  1. Write something first
    rc = zfile_output (file);
    assert (rc == 0);
    chunk = zchunk_new ("123456789", 9);
    assert (chunk);

    rc = zfile_write (file, chunk, 0);
    assert (rc == 0);
    zchunk_destroy (&chunk);
    zfile_close (file);
    assert (zfile_cursize (file) == 9);

    // 2. Read the written something
    rc = zfile_input (file);
    assert (rc != -1);
    // try to read more bytes than there is in the file
    chunk = zfile_read (file, 1000, 0);
    assert (zfile_eof(file));
    assert (zchunk_streq (chunk, "123456789"));
    zchunk_destroy (&chunk);

    // reading is ok
    chunk = zfile_read (file, 5, 0);
    assert (!zfile_eof(file));
    assert (zchunk_streq (chunk, "12345"));
    zchunk_destroy (&chunk);

    // read from non zero offset until the end
    chunk = zfile_read (file, 5, 5);
    assert (zfile_eof(file));
    assert (zchunk_streq (chunk, "6789"));
    zchunk_destroy (&chunk);
    zfile_remove (file);
    zfile_close (file);
    zfile_destroy (&file);

#ifdef CZMQ_BUILD_DRAFT_API
    zfile_t *tempfile = zfile_tmp ();
    assert (tempfile);
    assert (zfile_filename (tempfile, NULL));
    assert (zsys_file_exists (zfile_filename (tempfile, NULL)));
    zchunk_t *tchunk = zchunk_new ("HELLO", 6);
    assert (zfile_write (tempfile, tchunk, 0) == 0);
    zchunk_destroy (&tchunk);

    char *filename = strdup (zfile_filename (tempfile, NULL));
    zfile_destroy (&tempfile);
    assert (!zsys_file_exists (filename));
    zstr_free (&filename);
#endif // CZMQ_BUILD_DRAFT_API

#if defined (__WINDOWS__)
    zsys_shutdown();
#endif

    //  @end

    printf ("OK\n");
}
Exemplo n.º 24
0
static void handler (zsock_t *pipe, void *args) {
    curl_global_init(CURL_GLOBAL_ALL);
    CURLM *multi = curl_multi_init ();
    CURLSH *share = curl_share_init ();
    curl_share_setopt (share, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
    curl_share_setopt (share, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION);
    curl_share_setopt (share, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT);

    long verbose = (*(bool *) args) ? 1L : 0L;
    long timeout = 30;
    CURLMcode code;

    SOCKET pipefd = zsock_fd (pipe);
    struct curl_waitfd waitfd = {pipefd, CURL_WAIT_POLLIN};

    //  List to hold pending curl handles, in case we are destroy the client
    //  while request are inprogress
    zlistx_t *pending_handles = zlistx_new ();
    zlistx_set_destructor (pending_handles, (zlistx_destructor_fn *) curl_destructor);

    zsock_signal (pipe, 0);

    bool terminated = false;
    while (!terminated) {
        int events = zsock_events (pipe);
        if ((events & ZMQ_POLLIN) == 0) {
            code = curl_multi_wait (multi, &waitfd, 1, 1000, NULL);
            assert (code == CURLM_OK);
        }

        events = zsock_events (pipe);
        if (events & ZMQ_POLLIN) {
            char* command = zstr_recv (pipe);
            if (!command)
                break;          //  Interrupted

            //  All actors must handle $TERM in this way
            if (streq (command, "$TERM"))
                terminated = true;
            else if (streq (command, "GET")) {
                char *url;
                zlistx_t *headers;
                void *userp;
                int rc = zsock_recv (pipe, "slp", &url, &headers, &userp);
                assert (rc == 0);

                zchunk_t *data = zchunk_new (NULL, 100);
                assert (data);
                struct curl_slist *curl_headers = zlistx_to_slist (headers);
                CURL *curl = curl_easy_init ();
                zlistx_add_end (pending_handles, curl);
                http_request *request = (http_request *) zmalloc (sizeof (http_request));
                assert (request);
                request->userp = userp;
                request->curl = curl;
                request->data = data;
                request->headers = curl_headers;

                curl_easy_setopt (curl, CURLOPT_SHARE, share);
                curl_easy_setopt (curl, CURLOPT_TIMEOUT, timeout);
                curl_easy_setopt (curl, CURLOPT_VERBOSE, verbose);
                curl_easy_setopt (curl, CURLOPT_HTTPHEADER, curl_headers);
                curl_easy_setopt (curl, CURLOPT_URL, url);
                curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, write_data);
                curl_easy_setopt (curl, CURLOPT_WRITEDATA, data);
                curl_easy_setopt (curl, CURLOPT_PRIVATE, request);

                code = curl_multi_add_handle (multi, curl);
                assert (code == CURLM_OK);
                zlistx_destroy (&headers);
                zstr_free (&url);
           }
           else {
               puts ("E: invalid message to actor");
               assert (false);
           }
           zstr_free (&command);
        }

        int still_running;
        code = curl_multi_perform (multi, &still_running);
        assert (code == CURLM_OK);

        int msgq = 0;
        struct CURLMsg *msg = curl_multi_info_read(multi, &msgq);

        while (msg) {
            if(msg->msg == CURLMSG_DONE) {
                CURL *curl = msg->easy_handle;
                http_request *request;
                curl_easy_getinfo(curl, CURLINFO_PRIVATE, &request);

                long response_code_long;
                curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &response_code_long);
                int response_code = (int)response_code_long;

                int rc = zsock_send (pipe, "icp", response_code, request->data, request->userp);
                assert (rc == 0);

                curl_multi_remove_handle (multi, curl);

                //  Remove curl from the pending handles and delete it
                void *handle = zlistx_find (pending_handles, curl);
                assert (handle);
                rc = zlistx_delete (pending_handles, handle);
                assert (rc == 0);
            }

            msg = curl_multi_info_read(multi, &msgq);
        }
    }

    zlistx_destroy (&pending_handles);
    curl_share_cleanup (share);
    curl_multi_cleanup (multi);
    curl_global_cleanup ();
}
Exemplo n.º 25
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);
}