Esempio n. 1
0
zcert_t *
zcert_new_from (byte *public_key, byte *secret_key)
{
    zcert_t *self = (zcert_t *) zmalloc (sizeof (zcert_t));
    if (!self)
        return NULL;
    assert (public_key);
    assert (secret_key);

    self->metadata = zhash_new ();
    if (self->metadata) {
        zhash_autofree (self->metadata);
        memcpy (self->public_key, public_key, 32);
        memcpy (self->secret_key, secret_key, 32);
#if (ZMQ_VERSION_MAJOR == 4)
        zmq_z85_encode (self->public_txt, self->public_key, 32);
        zmq_z85_encode (self->secret_txt, self->secret_key, 32);
#else
        strcpy (self->public_txt, FORTY_ZEROES);
        strcpy (self->secret_txt, FORTY_ZEROES);
#endif
    }
    else
        zcert_destroy (&self);
    return self;
}
Esempio n. 2
0
File: zhash.c Progetto: dnaeon/czmq
int
zhash_load (zhash_t *self, char *filename)
{
    assert (self);
    zhash_autofree (self);

    FILE *handle = fopen (filename, "r");
    if (!handle)
        return -1;              //  Failed to create file

    char buffer [1024];
    while (fgets (buffer, 1024, handle)) {
        //  Skip lines starting with "#"
        if (buffer [0] == '#')
            continue;
        //  Buffer may end in newline, which we don't want
        if (buffer [strlen (buffer) - 1] == '\n')
            buffer [strlen (buffer) - 1] = 0;
        //  Split at equals, if any
        char *equals = strchr (buffer, '=');
        if (!equals)
            break;              //  Some error, stop parsing it
        *equals++ = 0;
        zhash_update (self, buffer, equals);
    }
    fclose (handle);
    return 0;
}
Esempio n. 3
0
static agent_t *
s_agent_new (zctx_t *ctx, void *control)
{
    agent_t *self = (agent_t *) zmalloc (sizeof (agent_t));
    self->ctx = ctx;
    self->control = control;
    self->router = zsocket_new (ctx, ZMQ_ROUTER);

    //  Connect our data socket to caller's endpoint
    self->data = zsocket_new (ctx, ZMQ_PAIR);
    char *endpoint = zstr_recv (self->control);
    int rc = zsocket_connect (self->data, "%s", endpoint);
    assert (rc != -1);
    free (endpoint);

    //  Create new client codec using cert from API
    byte public_key [32];
    byte secret_key [32];
    rc = zmq_recv (self->control, public_key, 32, 0);
    assert (rc == 32);
    rc = zmq_recv (self->control, secret_key, 32, 0);
    assert (rc == 32);
    self->cert = zcert_new_from (public_key, secret_key);
        
    self->metadata = zhash_new ();
    zhash_autofree (self->metadata);
    self->clients = zhash_new ();
    self->max_clients = 100;
    self->max_pending = 10;
    self->client_ttl = 3600;    //  60 minutes
    self->pending_ttl = 60;     //  60 seconds
    return self;
}
Esempio n. 4
0
static zyre_node_t *
zyre_node_new (zctx_t *ctx, void *pipe)
{
    zyre_node_t *self = (zyre_node_t *) zmalloc (sizeof (zyre_node_t));
    self->ctx = ctx;
    self->pipe = pipe;
    self->inbox = zsocket_new (ctx, ZMQ_ROUTER);
    if (self->inbox == NULL) {
        free (self);
        return NULL;            //  Interrupted 0MQ call
    }
    self->port = zsocket_bind (self->inbox, "tcp://*:*");
    if (self->port < 0) {
        free (self);
        return NULL;            //  Interrupted 0MQ call
    }
    self->beacon = zbeacon_new (self->ctx, ZRE_DISCOVERY_PORT);
    if (!self->beacon) {
        free (self);
        return NULL;            //  Exhausted process sockets
    }
    self->uuid = zuuid_new ();
    self->peers = zhash_new ();
    self->peer_groups = zhash_new ();
    self->own_groups = zhash_new ();
    self->headers = zhash_new ();
    zhash_autofree (self->headers);

    return self;
}
Esempio n. 5
0
static zyre_node_t *
zyre_node_new (zsock_t *pipe, void *args)
{
    zyre_node_t *self = (zyre_node_t *) zmalloc (sizeof (zyre_node_t));
    self->inbox = zsock_new (ZMQ_ROUTER);
    if (self->inbox == NULL) {
        free (self);
        return NULL;            //  Could not create new socket
    }
    //  Use ZMQ_ROUTER_HANDOVER so that when a peer disconnects and
    //  then reconnects, the new client connection is treated as the
    //  canonical one, and any old trailing commands are discarded.
    zsock_set_router_handover (self->inbox, 1);
    
    self->pipe = pipe;
    self->outbox = (zsock_t *) args;
    self->poller = zpoller_new (self->pipe, NULL);
    self->beacon_port = ZRE_DISCOVERY_PORT;
    self->interval = 0;         //  Use default
    self->uuid = zuuid_new ();
    self->peers = zhash_new ();
    self->peer_groups = zhash_new ();
    self->own_groups = zhash_new ();
    self->headers = zhash_new ();
    zhash_autofree (self->headers);

    //  Default name for node is first 6 characters of UUID:
    //  the shorter string is more readable in logs
    self->name = (char *) zmalloc (7);
    memcpy (self->name, zuuid_str (self->uuid), 6);
    return self;
}
Esempio n. 6
0
static agent_t *
agent_new (zctx_t *ctx, void *pipe)
{
    void *inbox = zsocket_new (ctx, ZMQ_ROUTER);
    if (!inbox)                 //  Interrupted
        return NULL;

    agent_t *self = (agent_t *) zmalloc (sizeof (agent_t));
    self->ctx = ctx;
    self->pipe = pipe;
    self->udp = zre_udp_new (ZRE_DISCOVERY_PORT);
    self->inbox = inbox;
    self->host = zre_udp_host (self->udp);
    self->port = zsocket_bind (self->inbox, "tcp://*:*");
    sprintf (self->endpoint, "%s:%d", self->host, self->port);
    if (self->port < 0) {       //  Interrupted
        zre_udp_destroy (&self->udp);
        free (self);
        return NULL;
    }
    self->uuid = zre_uuid_new ();
    self->identity = strdup (zre_uuid_str (self->uuid));
    self->peers = zhash_new ();
    self->peer_groups = zhash_new ();
    self->own_groups = zhash_new ();
    self->headers = zhash_new ();
    zhash_autofree (self->headers);
    self->log = zre_log_new (self->endpoint);

    //  Set up content distribution network: Each server binds to an
    //  ephemeral port and publishes a temporary directory that acts
    //  as the outbox for this node.
    //
    sprintf (self->fmq_outbox, "%s/send/%s", s_tmpdir (), self->identity);
    zfile_mkdir (self->fmq_outbox);
    sprintf (self->fmq_inbox, "%s/recv/%s", s_tmpdir (), self->identity);
    zfile_mkdir (self->fmq_inbox);

    self->fmq_server = fmq_server_new ();
    self->fmq_service = fmq_server_bind (self->fmq_server, "tcp://*:*");
    fmq_server_publish (self->fmq_server, self->fmq_outbox, "/");
    fmq_server_set_anonymous (self->fmq_server, true);
    char publisher [32];
    sprintf (publisher, "tcp://%s:%d", self->host, self->fmq_service);
    zhash_update (self->headers, "X-FILEMQ", publisher);

    //  Client will connect as it discovers new nodes
    self->fmq_client = fmq_client_new ();
    fmq_client_set_inbox (self->fmq_client, self->fmq_inbox);
    fmq_client_set_resync (self->fmq_client, true);
    fmq_client_subscribe (self->fmq_client, "/");
    
    return self;
}
Esempio n. 7
0
int
zhash_load (zhash_t *self, const char *filename)
{
    assert (self);
    zhash_autofree (self);

    //  Whether or not file exists, we'll track the filename and last
    //  modification date (0 for unknown files), so that zhash_refresh ()
    //  will always work after zhash_load (), to load a newly-created
    //  file.

    //  Take copy of filename in case self->filename is same string.
    char *filename_copy = strdup (filename);
    if (filename_copy) {
        free (self->filename);
        self->filename = filename_copy;
        self->modified = zsys_file_modified (self->filename);
        FILE *handle = fopen (self->filename, "r");
        if (handle) {
            char *buffer = (char *) zmalloc (1024);
            if (buffer) {
                while (fgets (buffer, 1024, handle)) {
                    //  Skip lines starting with "#" or that do not look like
                    //  name=value data.
                    char *equals = strchr (buffer, '=');
                    if (buffer [0] == '#' || equals == buffer || !equals)
                        continue;

                    //  Buffer may end in newline, which we don't want
                    if (buffer [strlen (buffer) - 1] == '\n')
                        buffer [strlen (buffer) - 1] = 0;
                    *equals++ = 0;
                    zhash_update (self, buffer, equals);
                }
                free (buffer);
            }
            else {
                fclose (handle);
                return -1; // Out of memory
            }
            fclose (handle);
        }
        else
            return -1; // Failed to open file for reading
    }
    else
        return -1; // Out of memory

    return 0;
}
Esempio n. 8
0
zhash_t *
zhash_unpack (zframe_t *frame)
{
    zhash_t *self = zhash_new ();
    if (!self)
        return NULL;
    assert (frame);
    if (zframe_size (frame) < 4)
        return self;            //  Arguable...

    byte *needle = zframe_data (frame);
    byte *ceiling = needle + zframe_size (frame);
    size_t nbr_items = ntohl (*(uint32_t *) needle);
    needle += 4;
    while (nbr_items && needle < ceiling) {
        //  Get key as string
        size_t key_size = *needle++;
        if (needle + key_size <= ceiling) {
            char key [256];
            memcpy (key, needle, key_size);
            key [key_size] = 0;
            needle += key_size;

            //  Get value as longstr
            if (needle + 4 <= ceiling) {
                size_t value_size = ntohl (*(uint32_t *) needle);
                needle += 4;
                //  Be wary of malformed frames
                if (needle + value_size <= ceiling) {
                    char *value = (char *) malloc (value_size + 1);
                    memcpy (value, needle, value_size);
                    value [value_size] = 0;
                    needle += value_size;

                    //  Hash takes ownership of value
                    if (zhash_insert (self, key, value)) {
                        zhash_destroy (&self);
                        break;
                    }
                }
            }
        }
    }
    //  Hash will free values in destructor
    if (self)
        zhash_autofree (self);
    return self;
}
Esempio n. 9
0
void
zre_msg_headers_insert (zre_msg_t *self, const char *key, const char *format, ...)
{
    //  Format into newly allocated string
    assert (self);
    va_list argptr;
    va_start (argptr, format);
    char *string = zsys_vprintf (format, argptr);
    va_end (argptr);

    //  Store string in hash table
    if (!self->headers) {
        self->headers = zhash_new ();
        zhash_autofree (self->headers);
    }
    zhash_update (self->headers, key, string);
    free (string);
}
Esempio n. 10
0
void
zre_msg_headers_insert (zre_msg_t *self, char *key, char *format, ...)
{
    //  Format string into buffer
    assert (self);
    va_list argptr;
    va_start (argptr, format);
    char *string = (char *) malloc (STRING_MAX + 1);
    assert (string);
    vsnprintf (string, STRING_MAX, format, argptr);
    va_end (argptr);

    //  Store string in hash table
    if (!self->headers) {
        self->headers = zhash_new ();
        zhash_autofree (self->headers);
    }
    zhash_update (self->headers, key, string);
}
Esempio n. 11
0
File: zdir.c Progetto: diorcety/czmq
zhash_t *
zdir_cache (zdir_t *self)
{
    assert (self);

    //  Load any previous cache from disk
    zhash_t *cache = zhash_new ();
    if (!cache)
        return NULL;
    zhash_autofree (cache);
    char *cache_file = (char *) zmalloc (strlen (self->path) + strlen ("/.cache") + 1);
    if (!cache_file) {
        zhash_destroy (&cache);
        return NULL;
    }
    sprintf (cache_file, "%s/.cache", self->path);
    zhash_load (cache, cache_file);

    //  Recalculate digest for any new files
    zfile_t **files = zdir_flatten (self);
    uint index;
    for (index = 0;; index++) {
        zfile_t *file = files [index];
        if (!file)
            break;
        const char *filename = zfile_filename (file, self->path);
        if (zhash_lookup (cache, zfile_filename (file, self->path)) == NULL) {
            int rc = zhash_insert (cache, filename, (void *) zfile_digest (file));
            if (rc != 0) {
                zhash_destroy (&cache);
                break;
            }
        }
    }
    freen (files);

    //  Save cache to disk for future reference
    if (cache)
        zhash_save (cache, cache_file);
    freen (cache_file);
    return cache;
}
Esempio n. 12
0
zhash_t *
zhash_dup (zhash_t *self)
{
    if (!self)
        return NULL;

    zhash_t *copy = zhash_new ();
    zhash_autofree (copy);
    if (copy) {
        uint index;
        for (index = 0; index != self->limit; index++) {
            item_t *item = self->items [index];
            while (item) {
                zhash_insert (copy, item->key, item->value);
                item = item->next;
            }
        }
    }
    return copy;
}
Esempio n. 13
0
zcert_t *
zcert_new (void)
{
    zcert_t *self = (zcert_t *) zmalloc (sizeof (zcert_t));
    assert (self);

    //  Initialize metadata, even if keys aren't working
    self->metadata = zhash_new ();
    zhash_autofree (self->metadata);
    
#if (ZMQ_VERSION_MAJOR == 4)
    int rc = zmq_curve_keypair (self->public_txt, self->secret_txt);
    assert (rc == 0);
    zmq_z85_decode (self->public_key, self->public_txt);
    zmq_z85_decode (self->secret_key, self->secret_txt);
#else
    strcpy (self->public_txt, "0000000000000000000000000000000000000000");
    strcpy (self->secret_txt, "0000000000000000000000000000000000000000");
#endif
    return self;
}
Esempio n. 14
0
zcert_t *
zcert_new_from (byte *public_key, byte *secret_key)
{
    zcert_t *self = (zcert_t *) zmalloc (sizeof (zcert_t));
    assert (self);
    assert (public_key);
    assert (secret_key);

    self->metadata = zhash_new ();
    zhash_autofree (self->metadata);
    memcpy (self->public_key, public_key, 32);
    memcpy (self->secret_key, secret_key, 32);
    
#if (ZMQ_VERSION_MAJOR == 4)
    zmq_z85_encode (self->public_txt, self->public_key, 32);
    zmq_z85_encode (self->secret_txt, self->secret_key, 32);
#else
    strcpy (self->public_txt, "0000000000000000000000000000000000000000");
    strcpy (self->secret_txt, "0000000000000000000000000000000000000000");
#endif
    return self;
}
Esempio n. 15
0
zhash_t *
zhash_dup_v2 (zhash_t *self)
{
    if (!self)
        return NULL;

    zhash_t *copy = zhash_new ();
    if (copy) {
        zhash_autofree (copy);
        uint index;
        size_t limit = primes [self->prime_index];
        for (index = 0; index < limit; index++) {
            item_t *item = self->items [index];
            while (item) {
                if (zhash_insert (copy, item->key, item->value)) {
                    zhash_destroy (&copy);
                    break;
                }
                item = item->next;
            }
        }
    }
    return copy;
}
Esempio n. 16
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");
}
Esempio n. 17
0
///
//  Set hash for automatic value destruction
void QZhash::autofree ()
{
    zhash_autofree (self);
    
}
Esempio n. 18
0
File: msg.c Progetto: spk121/jozabad
diag_t
jz_msg_validate (JzMsg *self)
{
  g_assert (self);
  
  if (self->signature != JZ_MSG_SIGNATURE)
    return d_invalid_signature;
  else if (self->version != 1)
    return d_unknown_version;
  else if (self->id < 0 || self->id >= JZ_MSG_COUNT)
    return d_unknown_message_type;
#if 0
  // Try to keep this alphabetized
  else if (self->id == JZ_MSG_CALL_ACCEPTED
           || self->id == JZ_MSG_CALL_REQUEST
           || self->id == JZ_MSG_CLEAR_REQUEST)
    {
      if (self->lcn <= 0 || self->lcn > JZ_MSG_MAX_LCN)
        return d_invalid_lcn;
    }
  else if (self->id == JZ_MSG_CALL_ACCEPTED
           || self->id == JZ_MSG_CALL_REQUEST
           )
    {
      if (packet_rngchk (self->packet) < 0)
        return d_invalid_packet_facility;
      else if (packet_rngchk (self->packet) > 0)
        return d_invalid_packet_facility;

      else if (tput_rngchk (self->throughput) < 0)
        return d_invalid_throughput_facility;
      else if (tput_rngchk (self->throughput) > 0)
        return d_invalid_throughput_facility;

      else if (window_rngchk (self->window) < 0)
        return d_invalid_window_facility;
      else if (window_rngchk (self->window) > 0)
        return d_invalid_window_facility;
    }
  else if (self->id == JZ_MSG_CALL_ACCEPTED
           || self->id == JZ_MSG_CALL_REQUEST
           )
    {
      if (!address_validate(self->called_address))
        return d_invalid_called_address;
    }
  
  else if  (self->id == JZ_MSG_CALL_ACCEPTED
            || self->id == JZ_MSG_CALL_REQUEST
            || self->id == JZ_MSG_CLEAR_CONFIRMATION
            || self->id == JZ_MSG_CONNECT
            )
    {
      if (!address_validate(self->calling_address))
        return d_invalid_calling_address;
    }
  
  else if (self->id == JZ_MSG_CALL_ACCEPTED
           || self->id == JZ_MSG_CALL_REQUEST)
    {
      // Zero-length data frames are OK!!
      if (self->data->len > JZ_MSG_MAX_CALL_REQUEST_DATA_SIZE)
        return d_data_too_long;
    }

  else if (self->id == JZ_MSG_DATA)
    {
      // zero-length data frames are not allowed!!
      if (self->data->len == 0)
        return d_data_too_short;
      else if (self->data->len > JZ_MSG_MAX_DATA_SIZE)
        return d_data_too_long;
    }
  
  else if (self->id == JZ_MSG_CLEAR_REQUEST
           || self->id == JZ_MSG_DIAGNOSTIC
           || self->id == JZ_MSG_RESET_REQUEST)
    {
      if (!cause_validate (self->cause))
        return d_invalid_cause;
      if (!diag_validate (self->diagnostic))
        return d_invalid_diagnostic;
    }

  else if (self->id == JZ_MSG_DATA)
    {
      if (!q_validate (self->q))
        return d_invalid_q;
      else if (seq_rngchk (self->ps) != 0)
        return d_invalid_ps;
    }
  
  else if (self->id == JZ_MSG_DATA
           || self->id == JZ_MSG_RR
           || self->id == JZ_MSG_RNR)
    {
      if (seq_rngchk (self->pr) != 0)
        return d_invalid_pr;
    }
  
  else if (self->id == JZ_MSG_CONNECT)
    {
      if (!iodir_validate (self->iodir))
        return d_invalid_directionality_facility;
      
      else if (self->hostname != NULL)
        {
          if (!g_utf8_validate (self->hostname, -1, NULL)
              || g_utf8_strlen (self->hostname, -1) > JZ_MSG_MAX_HOSTNAME_LENGTH)
            return d_invalid_hostname;
        }
    }
#if 0
 case JZ_MSG_DIRECTORY:
   GET_NUMBER1 (hash_size);
   self->workers = zhash_new ();
   zhash_autofree (self->workers);
   while (hash_size--) {
     char *string;
     GET_STRING (string);
     char *value = strchr (string, '=');
     if (value)
       *value++ = 0;
     zhash_insert (self->workers, string, value);
     free (string);
   }
#endif
#endif
   return d_ok;
}
Esempio n. 19
0
File: msg.c Progetto: spk121/jozabad
JzMsg *
jz_msg_new_from_data (gpointer buf, gsize len)
{
  g_assert (buf);
  JzMsg *self = g_new0(JzMsg, 1);
  self->data = g_byte_array_new ();
  size_t string_size;
  size_t frame_length;
  
  g_assert (len > JZ_MSG_ENVELOPE_SIZE);
  
  //  Get and check protocol signature
  self->needle = buf;

  // Initially we don't know enough to properly set the ceiling
  self->ceiling = buf + len;
  
  GET_NUMBER4 (self->signature);
  g_assert (self->signature == JZ_MSG_SIGNATURE);
  //  Get message id and parse per message type
  GET_NUMBER4 (frame_length);

  // Now that we have a frame size, we can properly set the ceiling
  guint32 padding = JZ_MSG_PADDING_LENGTH (frame_length);
  self->ceiling = buf + JZ_MSG_ENVELOPE_SIZE + frame_length + padding;
  
  GET_NUMBER1 (self->version);
  GET_NUMBER1 (self->id);
  GET_NUMBER2 (self->lcn);
  
  if (self->version != 1)
    {
      self->invalidity = d_unknown_version;
      goto malformed;
    }
  
  switch (self->id)
    {
    case JZ_MSG_DATA:
      GET_NUMBER1 (self->q);
      GET_NUMBER2 (self->pr);
      GET_NUMBER2 (self->ps);
      g_byte_array_set_size (self->data, 0);
      GET_RAW (self->data);
      break;
      
    case JZ_MSG_RR:
      GET_NUMBER2 (self->pr);
      break;
      
    case JZ_MSG_RNR:
      GET_NUMBER2 (self->pr);
      break;
      
    case JZ_MSG_CALL_REQUEST:
      // Address block
      g_free (self->calling_address);
      GET_STRING (self->calling_address);
      g_free (self->called_address);
      GET_STRING (self->called_address);

      // Facilities
      GET_NUMBER1 (self->packet);
      GET_NUMBER2 (self->window);
      GET_NUMBER1 (self->throughput);

      // User data
      g_byte_array_set_size (self->data, 0);
      GET_RAW (self->data);
      break;
      
    case JZ_MSG_CALL_ACCEPTED:
      // Address block
      g_free (self->calling_address);
      GET_STRING (self->calling_address);
      g_free (self->called_address);
      GET_STRING (self->called_address);

      // Facilities
      GET_NUMBER1 (self->packet);
      GET_NUMBER2 (self->window);
      GET_NUMBER1 (self->throughput);

      // User data
      g_byte_array_set_size (self->data, 0);
      GET_RAW (self->data);
      break;
      
    case JZ_MSG_CLEAR_REQUEST:
      GET_NUMBER1 (self->cause);
      GET_NUMBER1 (self->diagnostic);
      break;
      
    case JZ_MSG_CLEAR_CONFIRMATION:
      break;
      
    case JZ_MSG_RESET_REQUEST:
      GET_NUMBER1 (self->cause);
      GET_NUMBER1 (self->diagnostic);
      break;
      
    case JZ_MSG_RESET_CONFIRMATION:
      break;
      
    case JZ_MSG_CONNECT:
      g_free (self->calling_address);
      GET_STRING (self->calling_address);
      GET_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:
      GET_NUMBER1 (self->diagnostic);
      GET_NUMBER1 (self->diagnostic_version);
      GET_NUMBER1 (self->diagnostic_id);
      GET_NUMBER2 (self->diagnostic_lcn);
      break;
      
    case JZ_MSG_DIRECTORY_REQUEST:
      break;
      
    case JZ_MSG_DIRECTORY:
#if 0
      GET_NUMBER1 (hash_size);
      self->workers = zhash_new ();
      zhash_autofree (self->workers);
      while (hash_size--) {
        char *string;
        GET_STRING (string);
        char *value = strchr (string, '=');
        if (value)
          *value++ = 0;
        zhash_insert (self->workers, string, value);
        free (string);
      }
#endif
      break;
      
    case JZ_MSG_ENQ:
      break;
      
    case JZ_MSG_ACK:
      break;
      
    case JZ_MSG_RESTART_REQUEST:
      GET_NUMBER1 (self->cause);
      GET_NUMBER1 (self->diagnostic);
      break;
      
    case JZ_MSG_RESTART_CONFIRMATION:
      break;
    default:
      self->invalidity = d_unknown_message_type;
      goto malformed;
    }

  for (int i = 0; i < padding; i ++)
    {
      guint8 padding;
      GET_NUMBER1 (padding);
    }

  GET_NUMBER4 (self->crc);
  //  Successful unpacking
  self->packed_size = self->needle - (guint8 *) buf;

  // If the message is shorter than expected
  if (self->packed_size < JZ_MSG_ENVELOPE_SIZE + frame_length + padding)
    {
      g_critical ("message payload smaller than envelope '%s'\n", id_name (self->id));
      self->valid = FALSE;
      self->invalidity = d_packet_too_long;
    }
  else
    self->valid = TRUE;
  return self;
    
  //  Error returns
 malformed:
  g_critical ("malformed message '%s'\n", id_name (self->id));
  self->valid = FALSE;
  self->packed_size = self->needle - (guint8 *) buf;
  return self;
  
 premature:
  g_critical ("message payload too big for envelope '%s'\n", id_name (self->id));
  self->invalidity = d_packet_too_short;
  self->packed_size = self->needle - (guint8 *) buf;
  return self;
}
Esempio n. 20
0
zre_msg_t *
zre_msg_recv (void *input)
{
    assert (input);
    zre_msg_t *self = zre_msg_new (0);
    zframe_t *frame = NULL;
    size_t string_size;
    size_t list_size;
    size_t hash_size;

    //  Read valid message frame from socket; we loop over any
    //  garbage data we might receive from badly-connected peers
    while (true) {
        //  If we're reading from a ROUTER socket, get address
        if (zsocket_type (input) == ZMQ_ROUTER) {
            zframe_destroy (&self->address);
            self->address = zframe_recv (input);
            if (!self->address)
                goto empty;         //  Interrupted
            if (!zsocket_rcvmore (input))
                goto malformed;
        }
        //  Read and parse command in frame
        frame = zframe_recv (input);
        if (!frame)
            goto empty;             //  Interrupted

        //  Get and check protocol signature
        self->needle = zframe_data (frame);
        self->ceiling = self->needle + zframe_size (frame);
        uint16_t signature;
        GET_NUMBER2 (signature);
        if (signature == (0xAAA0 | 1))
            break;                  //  Valid signature

        //  Protocol assertion, drop message
        while (zsocket_rcvmore (input)) {
            zframe_destroy (&frame);
            frame = zframe_recv (input);
        }
        zframe_destroy (&frame);
    }
    //  Get message id and parse per message type
    GET_NUMBER1 (self->id);

    switch (self->id) {
        case ZRE_MSG_HELLO:
            GET_NUMBER2 (self->sequence);
            free (self->ipaddress);
            GET_STRING (self->ipaddress);
            GET_NUMBER2 (self->mailbox);
            GET_NUMBER1 (list_size);
            self->groups = zlist_new ();
            zlist_autofree (self->groups);
            while (list_size--) {
                char *string;
                GET_STRING (string);
                zlist_append (self->groups, string);
                free (string);
            }
            GET_NUMBER1 (self->status);
            GET_NUMBER1 (hash_size);
            self->headers = zhash_new ();
            zhash_autofree (self->headers);
            while (hash_size--) {
                char *string;
                GET_STRING (string);
                char *value = strchr (string, '=');
                if (value)
                    *value++ = 0;
                zhash_insert (self->headers, string, value);
                free (string);
            }
            break;

        case ZRE_MSG_WHISPER:
            GET_NUMBER2 (self->sequence);
            //  Get next frame, leave current untouched
            if (!zsocket_rcvmore (input))
                goto malformed;
            self->content = zframe_recv (input);
            break;

        case ZRE_MSG_SHOUT:
            GET_NUMBER2 (self->sequence);
            free (self->group);
            GET_STRING (self->group);
            //  Get next frame, leave current untouched
            if (!zsocket_rcvmore (input))
                goto malformed;
            self->content = zframe_recv (input);
            break;

        case ZRE_MSG_JOIN:
            GET_NUMBER2 (self->sequence);
            free (self->group);
            GET_STRING (self->group);
            GET_NUMBER1 (self->status);
            break;

        case ZRE_MSG_LEAVE:
            GET_NUMBER2 (self->sequence);
            free (self->group);
            GET_STRING (self->group);
            GET_NUMBER1 (self->status);
            break;

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

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

        default:
            goto malformed;
    }
    //  Successful return
    zframe_destroy (&frame);
    return self;

    //  Error returns
    malformed:
        printf ("E: malformed message '%d'\n", self->id);
    empty:
        zframe_destroy (&frame);
        zre_msg_destroy (&self);
        return (NULL);
}
Esempio n. 21
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");
}
Esempio n. 22
0
zre_msg_t *
zre_msg_decode (zmsg_t **msg_p, int socket_type)
{
    assert (msg_p);
    zmsg_t *msg = *msg_p;
    if (msg == NULL)
        return NULL;
        
    zre_msg_t *self = zre_msg_new (0);
    //  If message came from a router socket, first frame is routing_id
    if (socket_type == ZMQ_ROUTER) {
        self->routing_id = zmsg_pop (msg);
        //  If message was not valid, forget about it
        if (!self->routing_id || !zmsg_next (msg)) {
            zre_msg_destroy (&self);
            return (NULL);      //  Malformed or empty
        }
    }
    //  Read and parse command in frame
    zframe_t *frame = zmsg_pop (msg);
    if (!frame) 
        goto empty;             //  Malformed or empty

    //  Get and check protocol signature
    self->needle = zframe_data (frame);
    self->ceiling = self->needle + zframe_size (frame);
    uint16_t signature;
    GET_NUMBER2 (signature);
    if (signature != (0xAAA0 | 1))
        goto empty;             //  Invalid signature

    //  Get message id and parse per message type
    GET_NUMBER1 (self->id);

    switch (self->id) {
        case ZRE_MSG_HELLO:
            GET_NUMBER2 (self->sequence);
            GET_STRING (self->ipaddress);
            GET_NUMBER2 (self->mailbox);
            {
                size_t list_size;
                GET_NUMBER4 (list_size);
                self->groups = zlist_new ();
                zlist_autofree (self->groups);
                while (list_size--) {
                    char *string;
                    GET_LONGSTR (string);
                    zlist_append (self->groups, string);
                    free (string);
                }
            }
            GET_NUMBER1 (self->status);
            {
                size_t hash_size;
                GET_NUMBER4 (hash_size);
                self->headers = zhash_new ();
                zhash_autofree (self->headers);
                while (hash_size--) {
                    char *key, *value;
                    GET_STRING (key);
                    GET_LONGSTR (value);
                    zhash_insert (self->headers, key, value);
                    free (key);
                    free (value);
                }
            }
            break;

        case ZRE_MSG_WHISPER:
            GET_NUMBER2 (self->sequence);
            //  Get zero or more remaining frames, leaving current
            //  frame untouched
            self->content = zmsg_new ();
            while (zmsg_size (msg))
                zmsg_add (self->content, zmsg_pop (msg));
            break;

        case ZRE_MSG_SHOUT:
            GET_NUMBER2 (self->sequence);
            GET_STRING (self->group);
            //  Get zero or more remaining frames, leaving current
            //  frame untouched
            self->content = zmsg_new ();
            while (zmsg_size (msg))
                zmsg_add (self->content, zmsg_pop (msg));
            break;

        case ZRE_MSG_JOIN:
            GET_NUMBER2 (self->sequence);
            GET_STRING (self->group);
            GET_NUMBER1 (self->status);
            break;

        case ZRE_MSG_LEAVE:
            GET_NUMBER2 (self->sequence);
            GET_STRING (self->group);
            GET_NUMBER1 (self->status);
            break;

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

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

        default:
            goto malformed;
    }
    //  Successful return
    zframe_destroy (&frame);
    zmsg_destroy (msg_p);
    return self;

    //  Error returns
    malformed:
        printf ("E: malformed message '%d'\n", self->id);
    empty:
        zframe_destroy (&frame);
        zmsg_destroy (msg_p);
        zre_msg_destroy (&self);
        return (NULL);
}
Esempio n. 23
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
}
Esempio n. 24
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
}