Example #1
0
zre_log_msg_t *
zre_log_msg_decode (zmsg_t **msg_p)
{
    assert (msg_p);
    zmsg_t *msg = *msg_p;
    if (msg == NULL)
        return NULL;
        
    zre_log_msg_t *self = zre_log_msg_new (0);
    //  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 | 2))
        goto empty;             //  Invalid signature

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

    switch (self->id) {
        case ZRE_LOG_MSG_LOG:
            GET_NUMBER1 (self->level);
            GET_NUMBER1 (self->event);
            GET_NUMBER2 (self->node);
            GET_NUMBER2 (self->peer);
            GET_NUMBER8 (self->time);
            GET_STRING (self->data);
            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_log_msg_destroy (&self);
        return (NULL);
}
Example #2
0
zgossip_msg_t *
zgossip_msg_decode (zmsg_t **msg_p)
{
    assert (msg_p);
    zmsg_t *msg = *msg_p;
    if (msg == NULL)
        return NULL;
        
    zgossip_msg_t *self = zgossip_msg_new (0);
    //  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 | 0))
        goto empty;             //  Invalid signature

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

    switch (self->id) {
        case ZGOSSIP_MSG_HELLO:
            break;

        case ZGOSSIP_MSG_ANNOUNCE:
            GET_STRING (self->endpoint);
            GET_STRING (self->service);
            break;

        case ZGOSSIP_MSG_PING:
            break;

        case ZGOSSIP_MSG_PONG:
            break;

        case ZGOSSIP_MSG_INVALID:
            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);
        zgossip_msg_destroy (&self);
        return (NULL);
}
Example #3
0
int
zmailer_msg_recv (zmailer_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 ("zmailer_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 ("zmailer_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 | 0)) {
        zsys_warning ("zmailer_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 ZMAILER_MSG_MAIL:
            {
                uint16_t version;
                GET_NUMBER2 (version);
                if (version != 1) {
                    zsys_warning ("zmailer_msg: version is invalid");
                    goto malformed;
                }
            }
            GET_STRING (self->from);
            GET_LONGSTR (self->to);
            GET_LONGSTR (self->subject);
            GET_LONGSTR (self->request);
            break;

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

    //  Error returns
    malformed:
        zsys_warning ("zmailer_msg: zmailer_msg malformed message, fail");
        zmq_msg_close (&frame);
        return -1;              //  Invalid message
}
Example #4
0
int
zpubsub_filter_recv (zpubsub_filter_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 ("zpubsub_filter: 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 ("zpubsub_filter: 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 | 7)) {
        zsys_warning ("zpubsub_filter: 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 ZPUBSUB_FILTER_FILTER:
            {
                uint16_t magic;
                GET_NUMBER2 (magic);
                if (magic != ZPUBSUB_FILTER_MAGIC_NUMBER) {
                    zsys_warning ("zpubsub_filter: magic is invalid");
                    goto malformed;
                }
            }
            {
                uint16_t version;
                GET_NUMBER2 (version);
                if (version != ZPUBSUB_FILTER_VERSION) {
                    zsys_warning ("zpubsub_filter: version is invalid");
                    goto malformed;
                }
            }
            GET_STRING (self->partition);
            GET_STRING (self->topic);
            break;

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

    //  Error returns
    malformed:
        zsys_warning ("zpubsub_filter: zpubsub_filter malformed message, fail");
        zmq_msg_close (&frame);
        return -1;              //  Invalid message
}
Example #5
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);
}
int
mdp_client_msg_recv (mdp_client_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 ("mdp_client_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 ("mdp_client_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 | 4)) {
        zsys_warning ("mdp_client_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 MDP_CLIENT_MSG_CLIENT_REQUEST:
            {
                char version [256];
                GET_STRING (version);
                if (strneq (version, "MDPC02")) {
                    zsys_warning ("mdp_client_msg: version is invalid");
                    goto malformed;
                }
            }
            {
                byte messageid;
                GET_NUMBER1 (messageid);
                if (messageid != 1) {
                    zsys_warning ("mdp_client_msg: messageid is invalid");
                    goto malformed;
                }
            }
            GET_STRING (self->service);
            //  Get zero or more remaining frames
            zmsg_destroy (&self->body);
            if (zsock_rcvmore (input))
                self->body = zmsg_recv (input);
            else
                self->body = zmsg_new ();
            break;

        case MDP_CLIENT_MSG_CLIENT_PARTIAL:
            {
                char version [256];
                GET_STRING (version);
                if (strneq (version, "MDPC02")) {
                    zsys_warning ("mdp_client_msg: version is invalid");
                    goto malformed;
                }
            }
            {
                byte messageid;
                GET_NUMBER1 (messageid);
                if (messageid != 2) {
                    zsys_warning ("mdp_client_msg: messageid is invalid");
                    goto malformed;
                }
            }
            GET_STRING (self->service);
            //  Get zero or more remaining frames
            zmsg_destroy (&self->body);
            if (zsock_rcvmore (input))
                self->body = zmsg_recv (input);
            else
                self->body = zmsg_new ();
            break;

        case MDP_CLIENT_MSG_CLIENT_FINAL:
            {
                char version [256];
                GET_STRING (version);
                if (strneq (version, "MDPC02")) {
                    zsys_warning ("mdp_client_msg: version is invalid");
                    goto malformed;
                }
            }
            {
                byte messageid;
                GET_NUMBER1 (messageid);
                if (messageid != 3) {
                    zsys_warning ("mdp_client_msg: messageid is invalid");
                    goto malformed;
                }
            }
            GET_STRING (self->service);
            //  Get zero or more remaining frames
            zmsg_destroy (&self->body);
            if (zsock_rcvmore (input))
                self->body = zmsg_recv (input);
            else
                self->body = zmsg_new ();
            break;

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

    //  Error returns
    malformed:
        zsys_warning ("mdp_client_msg: mdp_client_msg malformed message, fail");
        zmq_msg_close (&frame);
        return -1;              //  Invalid message
}
Example #7
0
zre_log_msg_t *
zre_log_msg_recv (void *input)
{
    assert (input);
    zre_log_msg_t *self = zre_log_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 | 2))
            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_LOG_MSG_LOG:
            GET_NUMBER1 (self->level);
            GET_NUMBER1 (self->event);
            GET_NUMBER2 (self->node);
            GET_NUMBER2 (self->peer);
            GET_NUMBER8 (self->time);
            free (self->data);
            GET_STRING (self->data);
            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_log_msg_destroy (&self);
        return (NULL);
}
Example #8
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
}
Example #9
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);
}
Example #10
0
File: msg.c Project: 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;
}
Example #11
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
}
Example #12
0
int
xrap_traffic_recv (xrap_traffic_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 ("xrap_traffic: 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 ("xrap_traffic: 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 | 9)) {
        zsys_warning ("xrap_traffic: 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 XRAP_TRAFFIC_CONNECTION_OPEN:
            {
                char protocol [256];
                GET_STRING (protocol);
                if (strneq (protocol, "MALAMUTE")) {
                    zsys_warning ("xrap_traffic: protocol is invalid");
                    goto malformed;
                }
            }
            {
                uint16_t version;
                GET_NUMBER2 (version);
                if (version != 1) {
                    zsys_warning ("xrap_traffic: version is invalid");
                    goto malformed;
                }
            }
            GET_STRING (self->address);
            break;

        case XRAP_TRAFFIC_CONNECTION_PING:
            break;

        case XRAP_TRAFFIC_CONNECTION_PONG:
            break;

        case XRAP_TRAFFIC_CONNECTION_CLOSE:
            break;

        case XRAP_TRAFFIC_XRAP_SEND:
            GET_NUMBER4 (self->timeout);
            //  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 XRAP_TRAFFIC_XRAP_OFFER:
            GET_STRING (self->route);
            GET_STRING (self->method);
            break;

        case XRAP_TRAFFIC_XRAP_DELIVER:
            if (self->needle + ZUUID_LEN > (self->ceiling)) {
                zsys_warning ("xrap_traffic: sender is invalid");
                goto malformed;
            }
            zuuid_destroy (&self->sender);
            self->sender = zuuid_new_from (self->needle);
            self->needle += ZUUID_LEN;
            //  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 XRAP_TRAFFIC_OK:
            GET_NUMBER2 (self->status_code);
            GET_STRING (self->status_reason);
            break;

        case XRAP_TRAFFIC_FAIL:
            GET_NUMBER2 (self->status_code);
            GET_STRING (self->status_reason);
            break;

        case XRAP_TRAFFIC_ERROR:
            GET_NUMBER2 (self->status_code);
            GET_STRING (self->status_reason);
            break;

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

    //  Error returns
    malformed:
        zsys_warning ("xrap_traffic: xrap_traffic malformed message, fail");
        zmq_msg_close (&frame);
        return -1;              //  Invalid message
}