Ejemplo n.º 1
0
static void
zyre_node_dump (zyre_node_t *self)
{
    zsys_info ("zyre_node: dump state");
    zsys_info (" - name=%s uuid=%s", self->name, zuuid_str (self->uuid));

    zsys_info (" - endpoint=%s", self->endpoint);
    if (self->beacon_port) 
        zsys_info (" - discovery=beacon port=%d interval=%zu",
                   self->beacon_port, self->interval);
    else {
        zsys_info (" - discovery=gossip");
        if (self->gossip_bind)
            zsys_info ("   - bind endpoint=%s", self->gossip_bind);
        if (self->gossip_connect)
            zsys_info ("   - connect endpoint=%s", self->gossip_connect);
    }
    zsys_info (" - headers=%zu:", zhash_size (self->headers));
    zhash_foreach (self->headers, (zhash_foreach_fn *) zyre_node_log_pair, self);
    
    zsys_info (" - peers=%zu:", zhash_size (self->peers));
    zhash_foreach (self->peers, (zhash_foreach_fn *) zyre_node_log_item, self);

    zsys_info (" - groups=%zu:", zhash_size (self->own_groups));
    zhash_foreach (self->own_groups, (zhash_foreach_fn *) zyre_node_log_item, self);
}
Ejemplo n.º 2
0
static void
zyre_node_dump (zyre_node_t *self)
{
    void *item;

    zsys_info ("zyre_node: dump state");
    zsys_info (" - name=%s uuid=%s", self->name, zuuid_str (self->uuid));

    zsys_info (" - endpoint=%s", self->endpoint);
    if (self->beacon_port)
        zsys_info (" - discovery=beacon port=%d interval=%zu",
                   self->beacon_port, self->interval);
    else {
        zsys_info (" - discovery=gossip");
        if (self->gossip_bind)
            zsys_info ("   - bind endpoint=%s", self->gossip_bind);
        if (self->gossip_connect)
            zsys_info ("   - connect endpoint=%s", self->gossip_connect);
    }
    zsys_info (" - headers=%zu:", zhash_size (self->headers));
    for (item = zhash_first (self->headers); item != NULL;
            item = zhash_next (self->headers))
        zyre_node_log_pair (zhash_cursor (self->headers), item, self);

    zsys_info (" - peers=%zu:", zhash_size (self->peers));
    for (item = zhash_first (self->peers); item != NULL;
            item = zhash_next (self->peers))
        zyre_node_log_item (zhash_cursor (self->peers), item, self);

    zsys_info (" - own groups=%zu:", zlist_size (self->own_groups));
    const char *group = (const char *) zlist_first (self->own_groups);
    while (group) {
        zsys_info ("   - %s", group);
        group = (const char *) zlist_next (self->own_groups);
    }

    zsys_info (" - peer groups=%zu:", zhash_size (self->peer_groups));
    zlist_t *groups = zhash_keys (self->peer_groups);
    group = (const char *) zlist_first (groups);
    while (group) {
        zsys_info ("   - %s", group);
        zyre_group_t *rgroup = (zyre_group_t *) zhash_lookup (self->peer_groups, group);
        zlist_t *neighbors = zyre_group_peers (rgroup);
        char *neighbor = (char *) zlist_first (neighbors);
        while (neighbor) {
            zsys_info ("     - %s", neighbor);
            neighbor = (char *) zlist_next (neighbors);
        }
        zlist_destroy (&neighbors);
        group = (const char *) zlist_next (groups);
    }
    zlist_destroy (&groups);

}
Ejemplo n.º 3
0
//  --------------------------------------------------------------------------
//  Return json format for all nodes
char*
ztask_monitor_api_json (ztask_monitor_api_t *self)
{
	assert (self);

	if (!zhash_size (self->nodes)) {
		return 0;
	}


	char *data;
	if (asprintf(&data, "{ \"cluster\" : \"myname\", \"workers\" : [ ") < 0)
		data = NULL;

	assert (data);

	char *wk = (char *) zhash_first (self->nodes);
	while (wk) {

		if (asprintf(&data, "%s %s", data, wk) < 0)
			return NULL;
		wk = (char *) zhash_next (self->nodes);
		if (wk)
			if (asprintf(&data, "%s,", data) < 0)
				return NULL;
	}

	if (asprintf(&data, " %s ] }", data) < 0)
		return NULL;
	return data;
}
Ejemplo n.º 4
0
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) zhash_size (self->tuples));
    }
    else
        zsys_error ("unknown zgossip method '%s'", method);

    return reply;
}
Ejemplo n.º 5
0
// Looks at the current state and launches the next trigger
static int handle_next_event (ctx_t *ctx)
{
    zhash_t *timers;
    sim_state_t *sim_state = ctx->sim_state;
    int rc = 0;

    // get the timer hashtable, make sure its full, and get a list of its keys
    timers = sim_state->timers;
    if (zhash_size (timers) < 1) {
        flux_log (ctx->h, LOG_ERR, "timer hashtable has no elements");
        return -1;
    }

    // Get the next occuring event time/module
    double min_event_time = -1;
    double *curr_event_time = NULL;
    const char *mod_name = NULL, *curr_name = NULL;

    for (curr_event_time = zhash_first (timers);
         curr_event_time;
         curr_event_time = zhash_next (timers)) {
        curr_name = zhash_cursor (timers);
        if (min_event_time < 0 ||
            occurs_before (*curr_event_time, min_event_time) ||
            breaks_tie (*curr_event_time, min_event_time, curr_name)) {
            min_event_time = *curr_event_time;
            mod_name = curr_name;
        }
    }

    if (min_event_time < 0) {
        return -1;
    }

    // advance time then send the trigger to the module with the next event
    if (min_event_time > sim_state->sim_time) {
        // flux_log (ctx->h, LOG_DEBUG, "Time was advanced from %f to %f while
        // triggering the next event for %s",
        //		  sim_state->sim_time, *min_event_time, mod_name);
        sim_state->sim_time = min_event_time;
    } else {
        // flux_log (ctx->h, LOG_DEBUG, "Time was not advanced while triggering
        // the next event for %s", mod_name);
    }
    flux_log (ctx->h,
              LOG_DEBUG,
              "Triggering %s.  Curr sim time: %f",
              mod_name,
              sim_state->sim_time);

    rc = send_trigger (ctx->h, mod_name, sim_state);

    return rc;
}
Ejemplo n.º 6
0
static void 
s_empty_store (zcertstore_t *self) 
{
    zcert_t *cert = (zcert_t *) zlist_pop (self->cert_list);
    while (cert) {
        zhash_delete (self->cert_hash, zcert_public_txt (cert));
        zcert_destroy (&cert);
        cert = (zcert_t *) zlist_pop (self->cert_list);
    }
    assert (zlist_size (self->cert_list) == 0);
    assert (zhash_size (self->cert_hash) == 0);
}
Ejemplo n.º 7
0
static void print_manager(vx_resc_manager_t * mgr)
{

    printf(" #mgr has  %d worlds:\n", zhash_size(mgr->allLiveSets));

    zhash_iterator_t world_itr;
    zhash_iterator_init(mgr->allLiveSets, &world_itr);
    uint32_t worldId = 0;
    zhash_t * buffer_map = NULL;
    while (zhash_iterator_next(&world_itr, &worldId, &buffer_map)) {
        zhash_iterator_t buffer_itr;
        zhash_iterator_init(buffer_map, &buffer_itr);
        printf("  >world %d contains %d buffers:\n", worldId, zhash_size(buffer_map));

        char * buffer_name = NULL;
        zhash_t * res_map = NULL;
        while(zhash_iterator_next(&buffer_itr, &buffer_name, &res_map)) {
            zhash_iterator_t res_itr;
            zhash_iterator_init(res_map, &res_itr);
            printf("  >>buffer %s (%d): ", buffer_name, zhash_size(res_map));

            uint64_t vrid = 0;
            vx_resc_t * vr = NULL;
            while (zhash_iterator_next(&res_itr, &vrid, &vr)) {
                printf("%"PRIu64" ", vrid);
            }
            printf("\n");
        }
    }

    printf(" #aggregate (%d): ", zhash_size(mgr->remoteResc));
    zhash_iterator_t res_itr;
    zhash_iterator_init(mgr->remoteResc, &res_itr);
    uint64_t vrid = 0;
    vx_resc_t * vr = NULL;
    while (zhash_iterator_next(&res_itr, &vrid, &vr)) {
        printf("%"PRIu64" ", vrid);
    }
    printf("\n");
}
Ejemplo n.º 8
0
static void barrier_destroy (void *arg)
{
    barrier_t *b = arg;

    flux_log (b->ctx->h, LOG_DEBUG,
              "destroy %s nprocs %d count %d errnum %d clients %d",
              b->name, b->nprocs, b->count, b->errnum,
              (int)zhash_size (b->clients));
    zhash_destroy (&b->clients);
    free (b->name);
    free (b);
    return;
}
Ejemplo n.º 9
0
static void
zyre_node_dump (zyre_node_t *self)
{
    fflush (stdout);
    printf ("************** zyre_node_dump *************************\n");
    printf ("node id : %s\n", zuuid_str (self->uuid));
    printf ("    endpoint = %s\n", self->endpoint);
    printf ("    headers [%zu] { \n", zhash_size (self->headers));
    zhash_foreach (self->headers, zyre_node_hash_key_dump, self);
    printf ("    }\n");
    printf ("    peers [%zu] {\n", zhash_size (self->peers));
    zhash_foreach (self->peers, zyre_node_hash_key_dump, self);
    printf ("    }\n");
    printf ("    own groups [%zu] { \n", zhash_size (self->own_groups));
    zhash_foreach (self->own_groups, zyre_node_hash_key_dump, self);
    printf ("    }\n");
    printf ("    peer groups [%zu] {\n", zhash_size (self->peer_groups));
    zhash_foreach (self->peer_groups, zyre_node_hash_key_dump, self);
    printf ("    }\n");
    printf ("*******************************************************\n");
    fflush (stdout);
}
Ejemplo n.º 10
0
void
zyre_event_print (zyre_event_t *self)
{
    zsys_info ("zyre_event:");
    zsys_info (" - from name=%s uuid=%s", zyre_event_name(self), zyre_event_sender(self));

    switch (self->type) {
        case ZYRE_EVENT_ENTER:
            zsys_info (" - type=ENTER");
            zsys_info (" - headers=%zu:", zhash_size (self->headers));
            zhash_foreach (self->headers, (zhash_foreach_fn *) zyre_event_log_pair, self);
            zsys_info (" - address=%s", zyre_event_address(self));
            break;

        case ZYRE_EVENT_EXIT:
            zsys_info (" - type=EXIT");
            break;

        case ZYRE_EVENT_STOP:
            zsys_info (" - type=STOP");
            break;

        case ZYRE_EVENT_JOIN:
            zsys_info (" - type=JOIN");
            zsys_info (" - group=%s", zyre_event_group(self));
            break;

        case ZYRE_EVENT_LEAVE:
            zsys_info (" - type=LEAVE");
            zsys_info (" - group=%s", zyre_event_group(self));
            break;

        case ZYRE_EVENT_SHOUT:
            zsys_info (" - type=SHOUT");
            zsys_info (" - message:");
            zmsg_print (self->msg);
            break;

        case ZYRE_EVENT_WHISPER:
            zsys_info (" - type=WHISPER");
            zsys_info (" - message:");
            zmsg_print (self->msg);
            break;
        case ZYRE_EVENT_EVASIVE:
            zsys_info (" - type=EVASIVE");
            break;
        default:
            zsys_info (" - type=UNKNOWN");
            break;
    }
}
Ejemplo n.º 11
0
void
zring_destroy (zring_t **self_p)
{
    assert (self_p);
    if (*self_p) {
        zring_t *self = *self_p;
        zring_purge (self);
        assert (!self->hash || zhash_size (self->hash) == 0);
        zhash_destroy (&self->hash);
        free (self->head);
        free (self);
        *self_p = NULL;
    }
}
Ejemplo n.º 12
0
static void state_destroy(state_t * state)
{

    if (state->img != NULL)
        image_u8_destroy(state->img);

    vx_world_destroy(state->world);
    vx_world_destroy(state->world2);
    vx_world_destroy(state->world3);
    assert(zhash_size(state->layers) == 0);

    zhash_destroy(state->layers);
    free(state);
}
Ejemplo n.º 13
0
Archivo: vx_demo.c Proyecto: DH-std/A3
static void state_destroy(state_t * state)
{

    if (state->img != NULL)
        image_u32_destroy(state->img);

    vx_world_destroy(state->world);
    assert(zhash_size(state->layers) == 0);

    zhash_destroy(state->layers);
    free(state);

    pthread_mutex_destroy(&state->mutex);

}
Ejemplo n.º 14
0
static vx_code_output_stream_t * make_buffer_resource_codes(vx_buffer_t * buffer, zhash_t * resources)
{
    vx_code_output_stream_t * couts = vx_code_output_stream_create(256);
    couts->write_uint32(couts, OP_BUFFER_RESOURCES); // tell the display which resources are currently in use
    couts->write_uint32(couts, buffer->world->worldID);
    couts->write_str(couts, buffer->name);
    couts->write_uint32(couts, zhash_size(resources));

    zhash_iterator_t itr;
    zhash_iterator_init(resources, &itr);

    uint64_t guid = -1;
    vx_resc_t *resc = NULL;
    while (zhash_iterator_next(&itr, &guid, &resc))
        couts->write_uint64(couts, guid);
    return couts;
}
Ejemplo n.º 15
0
static void display_finished(vx_application_t * app, vx_display_t * disp)
{
    state_t * state = app->impl;
    pthread_mutex_lock(&state->mutex);

    vx_layer_t * layer = NULL;

    // store a reference to the world and layer that we associate with each vx_display_t
    zhash_remove(state->layers, &disp, NULL, &layer);

    vx_layer_destroy(layer);

    // Exit after the last remote connection is closed
    if (zhash_size(state->layers) == 0) {
        state->running = 0;
    }

    pthread_mutex_unlock(&state->mutex);
}
Ejemplo n.º 16
0
void
ztask_job_request_dump (ztask_job_request_t *self)
{
    assert (self);
    zclock_log("ztask_job_request: Processes=%ld", zhash_size (self->processes));
    zlist_t *keys = zhash_keys (self->processes);
    char *key = (char *) zlist_first (keys);
    ztask_job_proc_t *p;
    while (key) {
        zclock_log ("ztask_job_request: key=%s", key);
        p = (ztask_job_proc_t *) zhash_lookup (self->processes, key);
        ztask_job_proc_dump (p);
        key = (char *) zlist_next (keys);
    }

    zlist_destroy (&keys);



}
Ejemplo n.º 17
0
void
zyre_event_print (zyre_event_t *self)
{
    zsys_info ("zyre_event:");
    zsys_info (" - from name=%s uuid=%s",
        zyre_event_peer_name (self),
        zyre_event_peer_uuid (self));
    zsys_info (" - type=%s", self->type);

    if (streq (self->type, "ENTER")) {
        void *item;
        zsys_info (" - headers=%zu:", zhash_size (self->headers));
        for (item = zhash_first (self->headers); item != NULL;
                item = zhash_next (self->headers))
            zyre_event_log_pair (zhash_cursor (self->headers), item, self);
        zsys_info (" - address=%s", zyre_event_peer_addr (self));
    }
    else
    if (streq (self->type, "JOIN")) {
        zsys_info (" - group=%s", zyre_event_group (self));
    }
    else
    if (streq (self->type, "LEAVE")) {
        zsys_info (" - group=%s", zyre_event_group (self));
    }
    else
    if (streq (self->type, "SHOUT")) {
        zsys_info (" - message:");
        zmsg_print (self->msg);
    }
    else
    if (streq (self->type, "WHISPER")) {
        zsys_info (" - message:");
        zmsg_print (self->msg);
    }
    else
    if (streq (self->type, "LEADER")) {
        zsys_info (" - group=%s", zyre_event_group (self));
    }
}
/**
 * Snapshot Handler
 *  This is the reactor handler for the snapshot socket; it accepts
 *  just the ICANHAZ? request and replies with a state snapshot ending
 *  with a KTHXBAI message:
 */
static int
s_snapshots (zloop_t *loop, zmq_pollitem_t *poller, void *args)
{
    clonesrv_t *self = (clonesrv_t *) args;

    zframe_t *identity = zframe_recv (poller->socket);
    if (identity) {
        //  Request is in second frame of message
        char *request = zstr_recv (poller->socket);
        char *subtree = NULL;
        if (streq (request, "ICANHAZ?")) {
            free (request);
            subtree = zstr_recv (poller->socket);
        }
        else
            printf ("E: bad request, aborting\n");

        if (subtree) {
            //  Send state socket to client
            kvroute_t routing = { poller->socket, identity, subtree };
	    DEBUG("I: hash size:%ld", zhash_size(self->kvmap));

            zhash_foreach (self->kvmap, s_send_single, &routing);

            //  Now send END message with sequence number
            DEBUG ("I: sending shapshot=%d", (int) self->sequence);
            zframe_send (&identity, poller->socket, ZFRAME_MORE);
            kvmsg_t *kvmsg = kvmsg_new (self->sequence);
            kvmsg_set_key  (kvmsg, "KTHXBAI");
            kvmsg_set_body (kvmsg, (byte *) subtree, 0);
            kvmsg_send     (kvmsg, poller->socket);
            kvmsg_destroy (&kvmsg);
            free (subtree);
        }
        zframe_destroy(&identity);
    }
    return 0;
}
Ejemplo n.º 19
0
void
zhash_test (int verbose)
{
    printf (" * zhash: ");

    //  @selftest
    zhash_t *hash = zhash_new ();
    assert (hash);
    assert (zhash_size (hash) == 0);

    //  Insert some items
    int rc;
    rc = zhash_insert (hash, "DEADBEEF", "dead beef");
    assert (rc == 0);
    rc = zhash_insert (hash, "ABADCAFE", "a bad cafe");
    assert (rc == 0);
    rc = zhash_insert (hash, "C0DEDBAD", "coded bad");
    assert (rc == 0);
    rc = zhash_insert (hash, "DEADF00D", "dead food");
    assert (rc == 0);
    assert (zhash_size (hash) == 4);

    //  Look for existing items
    char *item;
    item = (char *) zhash_lookup (hash, "DEADBEEF");
    assert (streq (item, "dead beef"));
    item = (char *) zhash_lookup (hash, "ABADCAFE");
    assert (streq (item, "a bad cafe"));
    item = (char *) zhash_lookup (hash, "C0DEDBAD");
    assert (streq (item, "coded bad"));
    item = (char *) zhash_lookup (hash, "DEADF00D");
    assert (streq (item, "dead food"));

    //  Look for non-existent items
    item = (char *) zhash_lookup (hash, "foo");
    assert (item == NULL);

    //  Try to insert duplicate items
    rc = zhash_insert (hash, "DEADBEEF", "foo");
    assert (rc == -1);
    item = (char *) zhash_lookup (hash, "DEADBEEF");
    assert (streq (item, "dead beef"));

    //  Some rename tests

    //  Valid rename, key is now LIVEBEEF
    rc = zhash_rename (hash, "DEADBEEF", "LIVEBEEF");
    assert (rc == 0);
    item = (char *) zhash_lookup (hash, "LIVEBEEF");
    assert (streq (item, "dead beef"));

    //  Trying to rename an unknown item to a non-existent key
    rc = zhash_rename (hash, "WHATBEEF", "NONESUCH");
    assert (rc == -1);

    //  Trying to rename an unknown item to an existing key
    rc = zhash_rename (hash, "WHATBEEF", "LIVEBEEF");
    assert (rc == -1);
    item = (char *) zhash_lookup (hash, "LIVEBEEF");
    assert (streq (item, "dead beef"));

    //  Trying to rename an existing item to another existing item
    rc = zhash_rename (hash, "LIVEBEEF", "ABADCAFE");
    assert (rc == -1);
    item = (char *) zhash_lookup (hash, "LIVEBEEF");
    assert (streq (item, "dead beef"));
    item = (char *) zhash_lookup (hash, "ABADCAFE");
    assert (streq (item, "a bad cafe"));

    //  Test keys method
    zlist_t *keys = zhash_keys (hash);
    assert (zlist_size (keys) == 4);
    zlist_destroy (&keys);

    //  Test dup method
    zhash_t *copy = zhash_dup (hash);
    assert (zhash_size (copy) == 4);
    item = (char *) zhash_lookup (copy, "LIVEBEEF");
    assert (item);
    assert (streq (item, "dead beef"));
    zhash_destroy (&copy);

    //  Test pack/unpack methods
    zframe_t *frame = zhash_pack (hash);
    copy = zhash_unpack (frame);
    zframe_destroy (&frame);
    assert (zhash_size (copy) == 4);
    item = (char *) zhash_lookup (copy, "LIVEBEEF");
    assert (item);
    assert (streq (item, "dead beef"));
    zhash_destroy (&copy);

    // Test foreach
    rc = zhash_foreach (hash, test_foreach, hash);
    assert (rc == 0);
    rc = zhash_foreach (hash, test_foreach_error, hash);
    assert (rc == -1);

    //  Test save and load
    zhash_comment (hash, "This is a test file");
    zhash_comment (hash, "Created by %s", "czmq_selftest");
    zhash_save (hash, ".cache");
    copy = zhash_new ();
    zhash_load (copy, ".cache");
    item = (char *) zhash_lookup (copy, "LIVEBEEF");
    assert (item);
    assert (streq (item, "dead beef"));
    zhash_destroy (&copy);
    zsys_file_delete (".cache");

    //  Delete a item
    zhash_delete (hash, "LIVEBEEF");
    item = (char *) zhash_lookup (hash, "LIVEBEEF");
    assert (item == NULL);
    assert (zhash_size (hash) == 3);

    //  Check that the queue is robust against random usage
    struct {
        char name [100];
        bool exists;
    } testset [200];
    memset (testset, 0, sizeof (testset));
    int testmax = 200, testnbr, iteration;

    srandom ((unsigned) time (NULL));
    for (iteration = 0; iteration < 25000; iteration++) {
        testnbr = randof (testmax);
        if (testset [testnbr].exists) {
            item = (char *) zhash_lookup (hash, testset [testnbr].name);
            assert (item);
            zhash_delete (hash, testset [testnbr].name);
            testset [testnbr].exists = false;
        }
        else {
            sprintf (testset [testnbr].name, "%x-%x", rand (), rand ());
            if (zhash_insert (hash, testset [testnbr].name, "") == 0)
                testset [testnbr].exists = true;
        }
    }
    //  Test 10K lookups
    for (iteration = 0; iteration < 10000; iteration++)
        item = (char *) zhash_lookup (hash, "DEADBEEFABADCAFE");

    //  Destructor should be safe to call twice
    zhash_destroy (&hash);
    zhash_destroy (&hash);
    assert (hash == NULL);

    // Test autofree; automatically copies and frees string values
    hash = zhash_new ();
    zhash_autofree (hash);
    char value [255];
    strcpy (value, "This is a string");
    rc = zhash_insert (hash, "key1", value);
    assert (rc == 0);
    strcpy (value, "Ring a ding ding");
    rc = zhash_insert (hash, "key2", value);
    assert (rc == 0);
    assert (streq ((char *) zhash_lookup (hash, "key1"), "This is a string"));
    assert (streq ((char *) zhash_lookup (hash, "key2"), "Ring a ding ding"));
    zhash_destroy (&hash);
    //  @end

    printf ("OK\n");
}
Ejemplo n.º 20
0
static int
s_agent_authenticate (agent_t *self)
{
    zap_request_t *request = zap_request_new (self->handler);
    if (request) {
        //  Is address explicitly whitelisted or blacklisted?
        bool allowed = false;
        bool denied = false;

        if (zhash_size (self->whitelist)) {
            if (zhash_lookup (self->whitelist, request->address)) {
                allowed = true;
                if (self->verbose) 
                    printf ("I: PASSED (whitelist) address=%s\n", request->address);
            }
            else {
                denied = true;
                if (self->verbose) 
                    printf ("I: DENIED (not in whitelist) address=%s\n", request->address);
            }
        }
        else
        if (zhash_size (self->blacklist)) {
            if (zhash_lookup (self->blacklist, request->address)) {
                denied = true;
                if (self->verbose) 
                    printf ("I: DENIED (blacklist) address=%s\n", request->address);
            }
            else {
                allowed = true;
                if (self->verbose) 
                    printf ("I: PASSED (not in blacklist) address=%s\n", request->address);
            }
        }
        //  Mechanism-specific checks
        if (!denied) {
            if (streq (request->mechanism, "NULL") && !allowed) {
                //  For NULL, we allow if the address wasn't blacklisted
                if (self->verbose) 
                    printf ("I: ALLOWED (NULL)\n");
                allowed = true;
            }
            else
            if (streq (request->mechanism, "PLAIN"))
                //  For PLAIN, even a whitelisted address must authenticate
                allowed = s_authenticate_plain (self, request);
            else
            if (streq (request->mechanism, "CURVE"))
                //  For CURVE, even a whitelisted address must authenticate
                allowed = s_authenticate_curve (self, request);
        }
        if (allowed)
            zap_request_reply (request, "200", "OK");
        else
            zap_request_reply (request, "400", "NO ACCESS");

        zap_request_destroy (&request);
    }
    else
        zap_request_reply (request, "500", "Internal error");
    return 0;
}
Ejemplo n.º 21
0
///
//  Return the number of keys/items in the hash table
size_t QZhash::size ()
{
    size_t rv = zhash_size (self);
    return rv;
}
Ejemplo n.º 22
0
Archivo: msg.c Proyecto: spk121/jozabad
GByteArray *
jz_msg_to_byte_array (JzMsg *self)
{
  //  Calculate size of serialized data
  size_t frame_size = JZ_MSG_PAYLOAD_HEADER_SIZE;                   //  Header: version + ID + LCN
  switch (self->id) {
  case JZ_MSG_DATA:
    //  q is a 1-byte integer
    frame_size += 1;
    //  pr is a 2-byte integer
    frame_size += 2;
    //  ps is a 2-byte integer
    frame_size += 2;
    //  Raw data
    frame_size += RAW_SIZE (self->data);
    break;

  case JZ_MSG_RR:
    //  pr is a 2-byte integer
    frame_size += 2;
    break;

  case JZ_MSG_RNR:
    //  pr is a 2-byte integer
    frame_size += 2;
    break;

  case JZ_MSG_CALL_REQUEST:
    //  calling_address is a string with 1-byte length
    frame_size++;       //  Size is one octet
    if (self->calling_address)
      frame_size += strlen (self->calling_address);
    //  called_address is a string with 1-byte length
    frame_size++;       //  Size is one octet
    if (self->called_address)
      frame_size += strlen (self->called_address);
    //  packet is a 1-byte integer
    frame_size += 1;
    //  window is a 2-byte integer
    frame_size += 2;
    //  throughput is a 1-byte integer
    frame_size += 1;
    //  Raw data
    frame_size += RAW_SIZE (self->data);
    break;

  case JZ_MSG_CALL_ACCEPTED:
    //  calling_address is a string with 1-byte length
    frame_size++;       //  Size is one octet
    if (self->calling_address)
      frame_size += strlen (self->calling_address);
    //  called_address is a string with 1-byte length
    frame_size++;       //  Size is one octet
    if (self->called_address)
      frame_size += strlen (self->called_address);
    //  packet is a 1-byte integer
    frame_size += 1;
    //  window is a 2-byte integer
    frame_size += 2;
    //  throughput is a 1-byte integer
    frame_size += 1;
    //  Raw data
    frame_size += RAW_SIZE (self->data);
    break;

  case JZ_MSG_CLEAR_REQUEST:
    //  cause is a 1-byte integer
    frame_size += 1;
    //  diagnostic is a 1-byte integer
    frame_size += 1;
    break;

  case JZ_MSG_CLEAR_CONFIRMATION:
    break;

  case JZ_MSG_RESET_REQUEST:
    //  cause is a 1-byte integer
    frame_size += 1;
    //  diagnostic is a 1-byte integer
    frame_size += 1;
    break;

  case JZ_MSG_RESET_CONFIRMATION:
    break;

  case JZ_MSG_CONNECT:
    //  calling_address is a string with 1-byte length
    frame_size++;       //  Size is one octet
    if (self->calling_address)
      frame_size += strlen (self->calling_address);
    //  iodir is a 1-byte integer
    frame_size += 1;
    break;

  case JZ_MSG_CONNECT_INDICATION:
    break;

  case JZ_MSG_DISCONNECT:
    break;

  case JZ_MSG_DISCONNECT_INDICATION:
    break;

  case JZ_MSG_DIAGNOSTIC:
    //  diagnostic is a 1-byte integer
    frame_size += 1;
    //  diagnostic_version is a 1-byte integer
    frame_size += 1;
    //  diagnostic_id is a 1-byte integer
    frame_size += 1;
    //  diagnostic_lcn is a 2-byte integer
    frame_size += 2;
    break;

  case JZ_MSG_DIRECTORY_REQUEST:
    break;

#if 0
  case JZ_MSG_DIRECTORY:
    //  workers is an array of key=value strings
    frame_size++;       //  Size is one octet
    if (self->workers) {
      self->workers_bytes = 0;
      //  Add up size of dictionary contents
      zhash_foreach (self->workers, s_workers_count, self);
    }
    frame_size += self->workers_bytes;
    break;
#endif
        
  case JZ_MSG_ENQ:
    break;

  case JZ_MSG_ACK:
    break;

  case JZ_MSG_RESTART_REQUEST:
    //  cause is a 1-byte integer
    frame_size += 1;
    //  diagnostic is a 1-byte integer
    frame_size += 1;
    break;

  case JZ_MSG_RESTART_CONFIRMATION:
    break;

  default:
    g_error ("bad message type '%s'", id_name (self->id));
  }

  size_t padding = JZ_MSG_PADDING_LENGTH(frame_size);
  
  //  Now serialize message into the message
  GByteArray *buf = g_byte_array_sized_new (JZ_MSG_ENVELOPE_SIZE + frame_size + padding);
  buf->len = JZ_MSG_ENVELOPE_SIZE + frame_size + padding;
  self->needle = buf->data;
  size_t string_size;
  PUT_NUMBER4 (self->signature);
  PUT_NUMBER4 (frame_size);
  PUT_NUMBER1 (self->version);
  PUT_NUMBER1 (self->id);
  PUT_NUMBER2 (self->lcn);

  switch (self->id) {
  case JZ_MSG_DATA:
    PUT_NUMBER1 (self->q);
    PUT_NUMBER2 (self->pr);
    PUT_NUMBER2 (self->ps);
    PUT_RAW (self->data);
    break;

  case JZ_MSG_RR:
    PUT_NUMBER2 (self->pr);
    break;

  case JZ_MSG_RNR:
    PUT_NUMBER2 (self->pr);
    break;

  case JZ_MSG_CALL_REQUEST:
    if (self->calling_address) {
      PUT_STRING (self->calling_address);
    } else
      PUT_NUMBER1 (0);    //  Empty string
    if (self->called_address) {
      PUT_STRING (self->called_address);
    } else
      PUT_NUMBER1 (0);    //  Empty string
    PUT_NUMBER1 (self->packet);
    PUT_NUMBER2 (self->window);
    PUT_NUMBER1 (self->throughput);
    PUT_RAW (self->data);
    break;

  case JZ_MSG_CALL_ACCEPTED:
    if (self->calling_address) {
      PUT_STRING (self->calling_address);
    } else
      PUT_NUMBER1 (0);    //  Empty string
    if (self->called_address) {
      PUT_STRING (self->called_address);
    } else
      PUT_NUMBER1 (0);    //  Empty string
    PUT_NUMBER1 (self->packet);
    PUT_NUMBER2 (self->window);
    PUT_NUMBER1 (self->throughput);
    PUT_RAW (self->data);
    break;

  case JZ_MSG_CLEAR_REQUEST:
    PUT_NUMBER1 (self->cause);
    PUT_NUMBER1 (self->diagnostic);
    break;

  case JZ_MSG_CLEAR_CONFIRMATION:
    break;

  case JZ_MSG_RESET_REQUEST:
    PUT_NUMBER1 (self->cause);
    PUT_NUMBER1 (self->diagnostic);
    break;

  case JZ_MSG_RESET_CONFIRMATION:
    break;

  case JZ_MSG_CONNECT:
    if (self->calling_address) {
      PUT_STRING (self->calling_address);
    } else
      PUT_NUMBER1 (0);    //  Empty string
    PUT_NUMBER1 (self->iodir);
    break;

  case JZ_MSG_CONNECT_INDICATION:
    break;

  case JZ_MSG_DISCONNECT:
    break;

  case JZ_MSG_DISCONNECT_INDICATION:
    break;

  case JZ_MSG_DIAGNOSTIC:
    PUT_NUMBER1 (self->diagnostic);
    PUT_NUMBER1 (self->diagnostic_version);
    PUT_NUMBER1 (self->diagnostic_id);
    PUT_NUMBER2 (self->diagnostic_lcn);
    break;

  case JZ_MSG_DIRECTORY_REQUEST:
    break;

#if 0
  case JZ_MSG_DIRECTORY:
    if (self->workers != NULL) {
      PUT_NUMBER1 (zhash_size (self->workers));
      zhash_foreach (self->workers, s_workers_write, self);
    } else
      PUT_NUMBER1 (0);    //  Empty dictionary
    break;
#endif
        
  case JZ_MSG_ENQ:
    break;

  case JZ_MSG_ACK:
    break;

  case JZ_MSG_RESTART_REQUEST:
    PUT_NUMBER1 (self->cause);
    PUT_NUMBER1 (self->diagnostic);
    break;

  case JZ_MSG_RESTART_CONFIRMATION:
    break;
  }

  for (int i = 0; i < padding; i ++)
    PUT_NUMBER1 (0);
  self->crc = digital_crc32(buf->data + JZ_MSG_ENVELOPE_HEADER_SIZE, frame_size);
  PUT_NUMBER4 (self->crc);
  return buf;
}
Ejemplo n.º 23
0
void ztns_test (bool verbose) {
    printf (" * ztns: ");

    // Strings
    ztns_t *tnetstr = ztns_new ();
    char *data_str = "Hello World!";
    char *tnetstr_str = "12:Hello World!,";
    int rc = ztns_append_str (tnetstr, data_str);
    assert (0 == rc);
    assert (streq (ztns_get (tnetstr), tnetstr_str));
    char * index = tnetstr_str;
    char *result_str = (char *)ztns_parse (&index);
    assert (streq (index, ""));
    assert (streq (result_str, data_str));
    free (result_str);
    ztns_destroy (&tnetstr);

    tnetstr = ztns_new ();
    char *data_empty_str = "";
    char *tnetstr_empty_str = "0:,";
    rc = ztns_append_str (tnetstr, data_empty_str);
    assert (0 == rc);
    assert (streq (ztns_get (tnetstr), tnetstr_empty_str));
    index = tnetstr_empty_str;
    result_str = (char *)ztns_parse (&index);
    assert (streq (index, ""));
    assert (streq (result_str, data_empty_str));
    free (result_str);
    ztns_destroy (&tnetstr);

    tnetstr = ztns_new ();
    char *data_tnet_str = "12:Hello World!,";
    tnetstr_str = "16:12:Hello World!,,";
    rc = ztns_append_str (tnetstr, data_tnet_str);
    assert (0 == rc);
    assert (streq (ztns_get (tnetstr), tnetstr_str));
    index = tnetstr_str;
    result_str = (char *)ztns_parse (&index);
    assert (streq (index, ""));
    assert (streq (result_str, data_tnet_str));
    free (result_str);
    ztns_destroy (&tnetstr);

    // Numbers
    tnetstr = ztns_new ();
    long long data_llong = 34;
    char *tnetstr_llong = "2:34#";
    rc = ztns_append_llong (tnetstr, data_llong);
    assert (0 == rc);
    assert (streq (ztns_get (tnetstr), tnetstr_llong));
    index = tnetstr_llong;
    long long *result_llong = (long long *)ztns_parse (&index);
    assert (streq (index, ""));
    assert (data_llong == *result_llong);
    free (result_llong);
    ztns_destroy (&tnetstr);

    tnetstr = ztns_new ();
    rc = ztns_append_llong (tnetstr, LLONG_MAX);
    assert (0 == rc);
    index = ztns_get (tnetstr);
    result_llong = (long long *)ztns_parse (&index);
    assert (streq (index, ""));
    assert (LLONG_MAX == *result_llong);
    free (result_llong);
    ztns_destroy (&tnetstr);

    tnetstr = ztns_new ();
    rc = ztns_append_llong (tnetstr, LLONG_MIN);
    assert (0 == rc);
    index = ztns_get (tnetstr);
    result_llong = (long long *)ztns_parse (&index);
    assert (streq (index, ""));
    assert (LLONG_MIN == *result_llong);
    free (result_llong);
    ztns_destroy (&tnetstr);

    char *tnetstr_llong_max_plus_one = "19:9223372036854775808#";
    index = tnetstr_llong_max_plus_one;
    result_llong = (long long *)ztns_parse (&index);
    assert (NULL == result_llong);

    char *tnetstr_llong_min_minus_one = "20:-9223372036854775809#";
    index = tnetstr_llong_min_minus_one;
    result_llong = (long long *)ztns_parse (&index);
    assert (NULL == result_llong);

    char *tnetstr_float_not_llong = "8:15.75331#";
    index = tnetstr_float_not_llong;
    result_llong = (long long *)ztns_parse (&index);
    assert (NULL == result_llong);

    // Floats
    // ### These are a bastard to test and until there's a real use
    // I've got better things to do with my time
    //tnetstr = ztns_new ();
    //float data_float = 15.75331;
    //char *tnetstr_float = "8:15.75331^";
    //rc = ztns_append_float (tnetstr, data_float);
    //assert (0 == rc);
    //assert (streq (ztns_get (tnetstr), tnetstr_float));
    //index = tnetstr_float;
    //float *result_float = (float *)ztns_parse (&index);
    //assert (streq (index, ""));
    //assert (data_float == *result_float);
    //free (result_float);
    //ztns_destroy (&tnetstr);

    // Booleans
    tnetstr = ztns_new ();
    bool data_bool = true;
    char *tnetstr_bool = "4:true!";
    rc = ztns_append_bool (tnetstr, data_bool);
    assert (0 == rc);
    assert (streq (ztns_get (tnetstr), tnetstr_bool));
    index = tnetstr_bool;
    bool *result_bool = (bool *)ztns_parse (&index);
    assert (streq (index, ""));
    assert (data_bool == *result_bool);
    free (result_bool);
    ztns_destroy (&tnetstr);

    // NULL
    tnetstr = ztns_new ();
    char *tnetstr_null = "0:~";
    rc = ztns_append_null (tnetstr);
    assert (streq (ztns_get (tnetstr), tnetstr_null));
    index = tnetstr_null;
    void *result_null = ztns_parse (&index);
    assert (streq (index, ""));
    assert (NULL == result_null);
    ztns_destroy (&tnetstr);

    // Dictionaries
    zhash_t *dict = zhash_new ();
    zhash_t *empty_hash = zhash_new ();
    zlist_t *empty_list = zlist_new ();
    zhash_insert (dict, "STRING", data_str);
    zhash_insert (dict, "INTEGER", &data_llong);
    zhash_insert (dict, "BOOLEAN", &data_bool);
    zhash_insert (dict, "HASH", empty_hash);
    zhash_freefn (dict, "HASH", &s_zhash_free_fn);
    zhash_insert (dict, "LIST", empty_list);
    zhash_freefn (dict, "LIST", &s_zlist_free_fn);

    tnetstr = ztns_new ();
    rc = ztns_append_dict (tnetstr, dict, &s_tnetstr_foreach_dict_fn_test);
    assert (0 == rc);
    zhash_destroy (&dict);
    index = ztns_get (tnetstr);
    zhash_t *result_dict = (zhash_t *)ztns_parse (&index);
    assert (streq (index, ""));
    assert (NULL != result_dict);
    zhash_autofree (result_dict);
    char *item_str = (char *)zhash_lookup (result_dict, "STRING");
    assert (streq (data_str, item_str));
    long long *item_llong = (long long *)zhash_lookup (result_dict, "INTEGER");
    assert (*item_llong == data_llong);
    bool *item_bool = (bool *)zhash_lookup (result_dict, "BOOLEAN");
    assert (*item_bool == data_bool);
    zhash_t *item_hash = (zhash_t *)zhash_lookup (result_dict, "HASH");
    assert (0 == zhash_size (item_hash));
    zlist_t *item_list = (zlist_t *)zhash_lookup (result_dict, "LIST");
    assert (0 == zlist_size (item_list));
    zhash_destroy (&result_dict);
    ztns_destroy (&tnetstr);

    // Lists
    zlist_t *list = zlist_new ();
    empty_hash = zhash_new ();
    empty_list = zlist_new ();
    zlist_append (list, data_str);
    zlist_append (list, &data_llong);
    zlist_append (list, &data_bool);
    zlist_append (list, empty_hash);
    zlist_freefn (list, empty_hash, &s_zhash_free_fn, true);
    zlist_append (list, empty_list);
    zlist_freefn (list, empty_list, &s_zlist_free_fn, true);

    tnetstr = ztns_new ();
    rc = ztns_append_list (tnetstr, list, &s_tnetstr_foreach_list_fn_test);
    assert (0 == rc);
    zlist_destroy (&list);
    index = ztns_get (tnetstr);
    zlist_t *result_list = (zlist_t *)ztns_parse (&index);
    assert (streq (index, ""));
    assert (NULL != result_list);
    item_str = (char *)zlist_pop (result_list);
    assert (streq (data_str, item_str));
    free (item_str);
    item_llong = (long long *)zlist_pop (result_list);
    assert (*item_llong == data_llong);
    free (item_llong);
    item_bool = (bool *)zlist_pop (result_list);
    assert (*item_bool == data_bool);
    free (item_bool);
    item_hash = (zhash_t *)zlist_pop (result_list);
    assert (0 == zhash_size (item_hash));
    zhash_destroy (&item_hash);
    item_list = (zlist_t *)zlist_pop (result_list);
    assert (0 == zlist_size (item_list));
    zlist_destroy (&item_list);
    zlist_destroy (&result_list);
    ztns_destroy (&tnetstr);

    printf ("OK\n");
}
Ejemplo n.º 24
0
int
zre_msg_send (zre_msg_t **self_p, void *output)
{
    assert (output);
    assert (self_p);
    assert (*self_p);

    //  Calculate size of serialized data
    zre_msg_t *self = *self_p;
    size_t frame_size = 2 + 1;          //  Signature and message ID
    switch (self->id) {
        case ZRE_MSG_HELLO:
            //  sequence is a 2-byte integer
            frame_size += 2;
            //  ipaddress is a string with 1-byte length
            frame_size++;       //  Size is one octet
            if (self->ipaddress)
                frame_size += strlen (self->ipaddress);
            //  mailbox is a 2-byte integer
            frame_size += 2;
            //  groups is an array of strings
            frame_size++;       //  Size is one octet
            if (self->groups) {
                //  Add up size of list contents
                char *groups = (char *) zlist_first (self->groups);
                while (groups) {
                    frame_size += 1 + strlen (groups);
                    groups = (char *) zlist_next (self->groups);
                }
            }
            //  status is a 1-byte integer
            frame_size += 1;
            //  headers is an array of key=value strings
            frame_size++;       //  Size is one octet
            if (self->headers) {
                self->headers_bytes = 0;
                //  Add up size of dictionary contents
                zhash_foreach (self->headers, s_headers_count, self);
            }
            frame_size += self->headers_bytes;
            break;
            
        case ZRE_MSG_WHISPER:
            //  sequence is a 2-byte integer
            frame_size += 2;
            break;
            
        case ZRE_MSG_SHOUT:
            //  sequence is a 2-byte integer
            frame_size += 2;
            //  group is a string with 1-byte length
            frame_size++;       //  Size is one octet
            if (self->group)
                frame_size += strlen (self->group);
            break;
            
        case ZRE_MSG_JOIN:
            //  sequence is a 2-byte integer
            frame_size += 2;
            //  group is a string with 1-byte length
            frame_size++;       //  Size is one octet
            if (self->group)
                frame_size += strlen (self->group);
            //  status is a 1-byte integer
            frame_size += 1;
            break;
            
        case ZRE_MSG_LEAVE:
            //  sequence is a 2-byte integer
            frame_size += 2;
            //  group is a string with 1-byte length
            frame_size++;       //  Size is one octet
            if (self->group)
                frame_size += strlen (self->group);
            //  status is a 1-byte integer
            frame_size += 1;
            break;
            
        case ZRE_MSG_PING:
            //  sequence is a 2-byte integer
            frame_size += 2;
            break;
            
        case ZRE_MSG_PING_OK:
            //  sequence is a 2-byte integer
            frame_size += 2;
            break;
            
        default:
            printf ("E: bad message type '%d', not sent\n", self->id);
            //  No recovery, this is a fatal application error
            assert (false);
    }
    //  Now serialize message into the frame
    zframe_t *frame = zframe_new (NULL, frame_size);
    self->needle = zframe_data (frame);
    size_t string_size;
    int frame_flags = 0;
    PUT_NUMBER2 (0xAAA0 | 1);
    PUT_NUMBER1 (self->id);

    switch (self->id) {
        case ZRE_MSG_HELLO:
            PUT_NUMBER2 (self->sequence);
            if (self->ipaddress) {
                PUT_STRING (self->ipaddress);
            }
            else
                PUT_NUMBER1 (0);    //  Empty string
            PUT_NUMBER2 (self->mailbox);
            if (self->groups != NULL) {
                PUT_NUMBER1 (zlist_size (self->groups));
                char *groups = (char *) zlist_first (self->groups);
                while (groups) {
                    PUT_STRING (groups);
                    groups = (char *) zlist_next (self->groups);
                }
            }
            else
                PUT_NUMBER1 (0);    //  Empty string array
            PUT_NUMBER1 (self->status);
            if (self->headers != NULL) {
                PUT_NUMBER1 (zhash_size (self->headers));
                zhash_foreach (self->headers, s_headers_write, self);
            }
            else
                PUT_NUMBER1 (0);    //  Empty dictionary
            break;
            
        case ZRE_MSG_WHISPER:
            PUT_NUMBER2 (self->sequence);
            frame_flags = ZFRAME_MORE;
            break;
            
        case ZRE_MSG_SHOUT:
            PUT_NUMBER2 (self->sequence);
            if (self->group) {
                PUT_STRING (self->group);
            }
            else
                PUT_NUMBER1 (0);    //  Empty string
            frame_flags = ZFRAME_MORE;
            break;
            
        case ZRE_MSG_JOIN:
            PUT_NUMBER2 (self->sequence);
            if (self->group) {
                PUT_STRING (self->group);
            }
            else
                PUT_NUMBER1 (0);    //  Empty string
            PUT_NUMBER1 (self->status);
            break;
            
        case ZRE_MSG_LEAVE:
            PUT_NUMBER2 (self->sequence);
            if (self->group) {
                PUT_STRING (self->group);
            }
            else
                PUT_NUMBER1 (0);    //  Empty string
            PUT_NUMBER1 (self->status);
            break;
            
        case ZRE_MSG_PING:
            PUT_NUMBER2 (self->sequence);
            break;
            
        case ZRE_MSG_PING_OK:
            PUT_NUMBER2 (self->sequence);
            break;
            
    }
    //  If we're sending to a ROUTER, we send the address first
    if (zsocket_type (output) == ZMQ_ROUTER) {
        assert (self->address);
        if (zframe_send (&self->address, output, ZFRAME_MORE)) {
            zframe_destroy (&frame);
            zre_msg_destroy (self_p);
            return -1;
        }
    }
    //  Now send the data frame
    if (zframe_send (&frame, output, frame_flags)) {
        zframe_destroy (&frame);
        zre_msg_destroy (self_p);
        return -1;
    }
    
    //  Now send any frame fields, in order
    switch (self->id) {
        case ZRE_MSG_WHISPER:
            //  If content isn't set, send an empty frame
            if (!self->content)
                self->content = zframe_new (NULL, 0);
            if (zframe_send (&self->content, output, 0)) {
                zframe_destroy (&frame);
                zre_msg_destroy (self_p);
                return -1;
            }
            break;
        case ZRE_MSG_SHOUT:
            //  If content isn't set, send an empty frame
            if (!self->content)
                self->content = zframe_new (NULL, 0);
            if (zframe_send (&self->content, output, 0)) {
                zframe_destroy (&frame);
                zre_msg_destroy (self_p);
                return -1;
            }
            break;
    }
    //  Destroy zre_msg object
    zre_msg_destroy (self_p);
    return 0;
}
Ejemplo n.º 25
0
zmsg_t *
zre_msg_encode (zre_msg_t *self, int socket_type)
{
    assert (self);
    zmsg_t *msg = zmsg_new ();

    //  If we're sending to a ROUTER, send the routing_id first
    if (socket_type == ZMQ_ROUTER)
        zmsg_prepend (msg, &self->routing_id);
        
    size_t frame_size = 2 + 1;          //  Signature and message ID
    switch (self->id) {
        case ZRE_MSG_HELLO:
            //  sequence is a 2-byte integer
            frame_size += 2;
            //  ipaddress is a string with 1-byte length
            frame_size++;       //  Size is one octet
            if (self->ipaddress)
                frame_size += strlen (self->ipaddress);
            //  mailbox is a 2-byte integer
            frame_size += 2;
            //  groups is an array of strings
            frame_size += 4;    //  Size is 4 octets
            if (self->groups) {
                //  Add up size of list contents
                char *groups = (char *) zlist_first (self->groups);
                while (groups) {
                    frame_size += 4 + strlen (groups);
                    groups = (char *) zlist_next (self->groups);
                }
            }
            //  status is a 1-byte integer
            frame_size += 1;
            //  headers is an array of key=value strings
            frame_size += 4;    //  Size is 4 octets
            if (self->headers) {
                self->headers_bytes = 0;
                //  Add up size of dictionary contents
                zhash_foreach (self->headers, s_headers_count, self);
            }
            frame_size += self->headers_bytes;
            break;
            
        case ZRE_MSG_WHISPER:
            //  sequence is a 2-byte integer
            frame_size += 2;
            break;
            
        case ZRE_MSG_SHOUT:
            //  sequence is a 2-byte integer
            frame_size += 2;
            //  group is a string with 1-byte length
            frame_size++;       //  Size is one octet
            if (self->group)
                frame_size += strlen (self->group);
            break;
            
        case ZRE_MSG_JOIN:
            //  sequence is a 2-byte integer
            frame_size += 2;
            //  group is a string with 1-byte length
            frame_size++;       //  Size is one octet
            if (self->group)
                frame_size += strlen (self->group);
            //  status is a 1-byte integer
            frame_size += 1;
            break;
            
        case ZRE_MSG_LEAVE:
            //  sequence is a 2-byte integer
            frame_size += 2;
            //  group is a string with 1-byte length
            frame_size++;       //  Size is one octet
            if (self->group)
                frame_size += strlen (self->group);
            //  status is a 1-byte integer
            frame_size += 1;
            break;
            
        case ZRE_MSG_PING:
            //  sequence is a 2-byte integer
            frame_size += 2;
            break;
            
        case ZRE_MSG_PING_OK:
            //  sequence is a 2-byte integer
            frame_size += 2;
            break;
            
        default:
            printf ("E: bad message type '%d', not sent\n", self->id);
            //  No recovery, this is a fatal application error
            assert (false);
    }
    //  Now serialize message into the frame
    zframe_t *frame = zframe_new (NULL, frame_size);
    self->needle = zframe_data (frame);
    PUT_NUMBER2 (0xAAA0 | 1);
    PUT_NUMBER1 (self->id);

    switch (self->id) {
        case ZRE_MSG_HELLO:
            PUT_NUMBER2 (self->sequence);
            if (self->ipaddress) {
                PUT_STRING (self->ipaddress);
            }
            else
                PUT_NUMBER1 (0);    //  Empty string
            PUT_NUMBER2 (self->mailbox);
            if (self->groups) {
                PUT_NUMBER4 (zlist_size (self->groups));
                char *groups = (char *) zlist_first (self->groups);
                while (groups) {
                    PUT_LONGSTR (groups);
                    groups = (char *) zlist_next (self->groups);
                }
            }
            else
                PUT_NUMBER4 (0);    //  Empty string array
            PUT_NUMBER1 (self->status);
            if (self->headers) {
                PUT_NUMBER4 (zhash_size (self->headers));
                zhash_foreach (self->headers, s_headers_write, self);
            }
            else
                PUT_NUMBER4 (0);    //  Empty dictionary
            break;

        case ZRE_MSG_WHISPER:
            PUT_NUMBER2 (self->sequence);
            break;

        case ZRE_MSG_SHOUT:
            PUT_NUMBER2 (self->sequence);
            if (self->group) {
                PUT_STRING (self->group);
            }
            else
                PUT_NUMBER1 (0);    //  Empty string
            break;

        case ZRE_MSG_JOIN:
            PUT_NUMBER2 (self->sequence);
            if (self->group) {
                PUT_STRING (self->group);
            }
            else
                PUT_NUMBER1 (0);    //  Empty string
            PUT_NUMBER1 (self->status);
            break;

        case ZRE_MSG_LEAVE:
            PUT_NUMBER2 (self->sequence);
            if (self->group) {
                PUT_STRING (self->group);
            }
            else
                PUT_NUMBER1 (0);    //  Empty string
            PUT_NUMBER1 (self->status);
            break;

        case ZRE_MSG_PING:
            PUT_NUMBER2 (self->sequence);
            break;

        case ZRE_MSG_PING_OK:
            PUT_NUMBER2 (self->sequence);
            break;

    }
    //  Now send the data frame
    if (zmsg_append (msg, &frame)) {
        zmsg_destroy (&msg);
        zre_msg_destroy (&self);
        return NULL;
    }
    //  Now send the content field if set
    if (self->id == ZRE_MSG_WHISPER) {
        zframe_t *content_part = zmsg_pop (self->content);
        while (content_part) {
            zmsg_append (msg, &content_part);
            content_part = zmsg_pop (self->content);
        }
    }
    //  Now send the content field if set
    if (self->id == ZRE_MSG_SHOUT) {
        zframe_t *content_part = zmsg_pop (self->content);
        while (content_part) {
            zmsg_append (msg, &content_part);
            content_part = zmsg_pop (self->content);
        }
    }
    //  Destroy zre_msg object
    zre_msg_destroy (&self);
    return msg;

}
Ejemplo n.º 26
0
size_t
zre_msg_headers_size (zre_msg_t *self)
{
    return zhash_size (self->headers);
}
Ejemplo n.º 27
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");
}
Ejemplo n.º 28
0
void
zhash_test (int verbose)
{
    printf (" * zhash: ");

    //  @selftest
    zhash_t *hash = zhash_new ();
    assert (hash);
    assert (zhash_size (hash) == 0);

    //  Insert some items
    int rc;
    rc = zhash_insert (hash, "DEADBEEF", "dead beef");
    assert (rc == 0);
    rc = zhash_insert (hash, "ABADCAFE", "a bad cafe");
    assert (rc == 0);
    rc = zhash_insert (hash, "C0DEDBAD", "coded bad");
    assert (rc == 0);
    rc = zhash_insert (hash, "DEADF00D", "dead food");
    assert (rc == 0);
    assert (zhash_size (hash) == 4);

    //  Look for existing items
    char *item;
    item = (char *) zhash_lookup (hash, "DEADBEEF");
    assert (streq (item, "dead beef"));
    item = (char *) zhash_lookup (hash, "ABADCAFE");
    assert (streq (item, "a bad cafe"));
    item = (char *) zhash_lookup (hash, "C0DEDBAD");
    assert (streq (item, "coded bad"));
    item = (char *) zhash_lookup (hash, "DEADF00D");
    assert (streq (item, "dead food"));

    //  Look for non-existent items
    item = (char *) zhash_lookup (hash, "foo");
    assert (item == NULL);

    //  Try to insert duplicate items
    rc = zhash_insert (hash, "DEADBEEF", "foo");
    assert (rc == -1);
    item = (char *) zhash_lookup (hash, "DEADBEEF");
    assert (streq (item, "dead beef"));

    //  Rename an item
    rc = zhash_rename (hash, "DEADBEEF", "LIVEBEEF");
    assert (rc == 0);
    rc = zhash_rename (hash, "WHATBEEF", "LIVEBEEF");
    assert (rc == -1);

    //  Test keys method
    zlist_t *keys = zhash_keys (hash);
    assert (zlist_size (keys) == 4);
    zlist_destroy (&keys);

    //  Test dup method
    zhash_t *copy = zhash_dup (hash);
    assert (zhash_size (copy) == 4);
    item = (char *) zhash_lookup (copy, "LIVEBEEF");
    assert (item);
    assert (streq (item, "dead beef"));
    zhash_destroy (&copy);

    // Test foreach
    assert (0 == zhash_foreach (hash, test_foreach, hash));
    assert (-1 == zhash_foreach (hash, test_foreach_error, hash));

    //  Test save and load
    zhash_save (hash, ".cache");
    copy = zhash_new ();
    zhash_load (copy, ".cache");
    item = (char *) zhash_lookup (copy, "LIVEBEEF");
    assert (item);
    assert (streq (item, "dead beef"));
    zhash_destroy (&copy);
#if (defined (WIN32))
    DeleteFile (".cache");
#else
    unlink (".cache");
#endif
        
    //  Delete a item
    zhash_delete (hash, "LIVEBEEF");
    item = (char *) zhash_lookup (hash, "LIVEBEEF");
    assert (item == NULL);
    assert (zhash_size (hash) == 3);

    //  Check that the queue is robust against random usage
    struct {
        char name [100];
        bool exists;
    } testset [200];
    memset (testset, 0, sizeof (testset));
    int testmax = 200, testnbr, iteration;

    srandom ((unsigned) time (NULL));
    for (iteration = 0; iteration < 25000; iteration++) {
        testnbr = randof (testmax);
        if (testset [testnbr].exists) {
            item = (char *) zhash_lookup (hash, testset [testnbr].name);
            assert (item);
            zhash_delete (hash, testset [testnbr].name);
            testset [testnbr].exists = false;
        }
        else {
            sprintf (testset [testnbr].name, "%x-%x", rand (), rand ());
            if (zhash_insert (hash, testset [testnbr].name, "") == 0)
                testset [testnbr].exists = true;
        }
    }
    //  Test 10K lookups
    for (iteration = 0; iteration < 10000; iteration++)
        item = (char *) zhash_lookup (hash, "DEADBEEFABADCAFE");

    //  Destructor should be safe to call twice
    zhash_destroy (&hash);
    zhash_destroy (&hash);
    assert (hash == NULL);
    //  @end

    printf ("OK\n");
}
Ejemplo n.º 29
0
//  TODO: allow regular expressions in addresses
static int
s_self_authenticate (self_t *self)
{
    zap_request_t *request = s_zap_request_new (self->handler, self->verbose);
    if (request) {
        //  Is address explicitly whitelisted or blacklisted?
        bool allowed = false;
        bool denied = false;

        if (zhash_size (self->whitelist)) {
            if (zhash_lookup (self->whitelist, request->address)) {
                allowed = true;
                if (self->verbose)
                    zsys_info ("zauth: - passed (whitelist) address=%s", request->address);
            }
            else {
                denied = true;
                if (self->verbose)
                    zsys_info ("zauth: - denied (not in whitelist) address=%s", request->address);
            }
        }
        else
        if (zhash_size (self->blacklist)) {
            if (zhash_lookup (self->blacklist, request->address)) {
                denied = true;
                if (self->verbose)
                    zsys_info ("zauth: - denied (blacklist) address=%s", request->address);
            }
            else {
                allowed = true;
                if (self->verbose)
                    zsys_info ("zauth: - passed (not in blacklist) address=%s", request->address);
            }
        }
        //  Mechanism-specific checks
        if (!denied) {
            if (streq (request->mechanism, "NULL") && !allowed) {
                //  For NULL, we allow if the address wasn't blacklisted
                if (self->verbose)
                    zsys_info ("zauth: - allowed (NULL)");
                allowed = true;
            }
            else
            if (streq (request->mechanism, "PLAIN"))
                //  For PLAIN, even a whitelisted address must authenticate
                allowed = s_authenticate_plain (self, request);
            else
            if (streq (request->mechanism, "CURVE"))
                //  For CURVE, even a whitelisted address must authenticate
                allowed = s_authenticate_curve (self, request);
            else
            if (streq (request->mechanism, "GSSAPI"))
                //  For GSSAPI, even a whitelisted address must authenticate
                allowed = s_authenticate_gssapi (self, request);
        }
        if (allowed)
            s_zap_request_reply (request, "200", "OK");
        else
            s_zap_request_reply (request, "400", "No access");

        s_zap_request_destroy (&request);
    }
    else
        s_zap_request_reply (request, "500", "Internal error");
    
    return 0;
}
Ejemplo n.º 30
0
int
fmq_msg_send (fmq_msg_t *self, zsock_t *output)
{
    assert (self);
    assert (output);

    if (zsock_type (output) == ZMQ_ROUTER)
        zframe_send (&self->routing_id, output, ZFRAME_MORE + ZFRAME_REUSE);

    size_t frame_size = 2 + 1;          //  Signature and message ID
    switch (self->id) {
        case FMQ_MSG_OHAI:
            frame_size += 1 + strlen ("FILEMQ");
            frame_size += 2;            //  version
            break;
        case FMQ_MSG_ICANHAZ:
            frame_size += 4;
            if (self->path)
                frame_size += strlen (self->path);
            frame_size += 4;            //  Size is 4 octets
            if (self->options) {
                self->options_bytes = 0;
                char *item = (char *) zhash_first (self->options);
                while (item) {
                    self->options_bytes += 1 + strlen (zhash_cursor (self->options));
                    self->options_bytes += 4 + strlen (item);
                    item = (char *) zhash_next (self->options);
                }
            }
            frame_size += self->options_bytes;
            frame_size += 4;            //  Size is 4 octets
            if (self->cache) {
                self->cache_bytes = 0;
                char *item = (char *) zhash_first (self->cache);
                while (item) {
                    self->cache_bytes += 1 + strlen (zhash_cursor (self->cache));
                    self->cache_bytes += 4 + strlen (item);
                    item = (char *) zhash_next (self->cache);
                }
            }
            frame_size += self->cache_bytes;
            break;
        case FMQ_MSG_NOM:
            frame_size += 8;            //  credit
            frame_size += 8;            //  sequence
            break;
        case FMQ_MSG_CHEEZBURGER:
            frame_size += 8;            //  sequence
            frame_size += 1;            //  operation
            frame_size += 4;
            if (self->filename)
                frame_size += strlen (self->filename);
            frame_size += 8;            //  offset
            frame_size += 1;            //  eof
            frame_size += 4;            //  Size is 4 octets
            if (self->headers) {
                self->headers_bytes = 0;
                char *item = (char *) zhash_first (self->headers);
                while (item) {
                    self->headers_bytes += 1 + strlen (zhash_cursor (self->headers));
                    self->headers_bytes += 4 + strlen (item);
                    item = (char *) zhash_next (self->headers);
                }
            }
            frame_size += self->headers_bytes;
            frame_size += 4;            //  Size is 4 octets
            if (self->chunk)
                frame_size += zchunk_size (self->chunk);
            break;
        case FMQ_MSG_SRSLY:
            frame_size += 1 + strlen (self->reason);
            break;
        case FMQ_MSG_RTFM:
            frame_size += 1 + strlen (self->reason);
            break;
    }
    //  Now serialize message into the frame
    zmq_msg_t frame;
    zmq_msg_init_size (&frame, frame_size);
    self->needle = (byte *) zmq_msg_data (&frame);
    PUT_NUMBER2 (0xAAA0 | 3);
    PUT_NUMBER1 (self->id);
    size_t nbr_frames = 1;              //  Total number of frames to send

    switch (self->id) {
        case FMQ_MSG_OHAI:
            PUT_STRING ("FILEMQ");
            PUT_NUMBER2 (FMQ_MSG_VERSION);
            break;

        case FMQ_MSG_ICANHAZ:
            if (self->path) {
                PUT_LONGSTR (self->path);
            }
            else
                PUT_NUMBER4 (0);    //  Empty string
            if (self->options) {
                PUT_NUMBER4 (zhash_size (self->options));
                char *item = (char *) zhash_first (self->options);
                while (item) {
                    PUT_STRING (zhash_cursor (self->options));
                    PUT_LONGSTR (item);
                    item = (char *) zhash_next (self->options);
                }
            }
            else
                PUT_NUMBER4 (0);    //  Empty hash
            if (self->cache) {
                PUT_NUMBER4 (zhash_size (self->cache));
                char *item = (char *) zhash_first (self->cache);
                while (item) {
                    PUT_STRING (zhash_cursor (self->cache));
                    PUT_LONGSTR (item);
                    item = (char *) zhash_next (self->cache);
                }
            }
            else
                PUT_NUMBER4 (0);    //  Empty hash
            break;

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

        case FMQ_MSG_CHEEZBURGER:
            PUT_NUMBER8 (self->sequence);
            PUT_NUMBER1 (self->operation);
            if (self->filename) {
                PUT_LONGSTR (self->filename);
            }
            else
                PUT_NUMBER4 (0);    //  Empty string
            PUT_NUMBER8 (self->offset);
            PUT_NUMBER1 (self->eof);
            if (self->headers) {
                PUT_NUMBER4 (zhash_size (self->headers));
                char *item = (char *) zhash_first (self->headers);
                while (item) {
                    PUT_STRING (zhash_cursor (self->headers));
                    PUT_LONGSTR (item);
                    item = (char *) zhash_next (self->headers);
                }
            }
            else
                PUT_NUMBER4 (0);    //  Empty hash
            if (self->chunk) {
                PUT_NUMBER4 (zchunk_size (self->chunk));
                memcpy (self->needle,
                        zchunk_data (self->chunk),
                        zchunk_size (self->chunk));
                self->needle += zchunk_size (self->chunk);
            }
            else
                PUT_NUMBER4 (0);    //  Empty chunk
            break;

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

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

    }
    //  Now send the data frame
    zmq_msg_send (&frame, zsock_resolve (output), --nbr_frames? ZMQ_SNDMORE: 0);

    return 0;
}