コード例 #1
0
ファイル: zproxy.c プロジェクト: claws/czmq
static void
s_self_switch (self_t *self, zsock_t *input, zsock_t *output)
{
    //  We use the low-level libzmq API for best performance
    void *zmq_input = zsock_resolve (input);
    void *zmq_output = zsock_resolve (output);
    void *zmq_capture = self->capture ? zsock_resolve (self->capture) : NULL;

    zmq_msg_t msg;
    zmq_msg_init (&msg);
    while (true) {
        if (zmq_recvmsg (zmq_input, &msg, ZMQ_DONTWAIT) == -1)
            break;      //  Presumably EAGAIN
        int send_flags = zsock_rcvmore (zmq_input) ? ZMQ_SNDMORE : 0;
        if (zmq_capture) {
            zmq_msg_t dup;
            zmq_msg_init (&dup);
            zmq_msg_copy (&dup, &msg);
            if (zmq_sendmsg (zmq_capture, &dup, send_flags) == -1)
                zmq_msg_close (&dup);
        }
        if (zmq_sendmsg (zmq_output, &msg, send_flags) == -1) {
            zmq_msg_close (&msg);
            break;
        }
    }
}
コード例 #2
0
ファイル: zmailer_msg.c プロジェクト: oikosdev/zmailer
int
zmailer_msg_send (zmailer_msg_t *self, zsock_t *output)
{
    assert (self);
    assert (output);

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

    size_t frame_size = 2 + 1;          //  Signature and message ID
    switch (self->id) {
        case ZMAILER_MSG_MAIL:
            frame_size += 2;            //  version
            frame_size += 1 + strlen (self->from);
            frame_size += 4;
            if (self->to)
                frame_size += strlen (self->to);
            frame_size += 4;
            if (self->subject)
                frame_size += strlen (self->subject);
            frame_size += 4;
            if (self->request)
                frame_size += strlen (self->request);
            break;
    }
    //  Now serialize message into the frame
    zmq_msg_t frame;
    zmq_msg_init_size (&frame, frame_size);
    self->needle = (byte *) zmq_msg_data (&frame);
    PUT_NUMBER2 (0xAAA0 | 0);
    PUT_NUMBER1 (self->id);
    size_t nbr_frames = 1;              //  Total number of frames to send

    switch (self->id) {
        case ZMAILER_MSG_MAIL:
            PUT_NUMBER2 (1);
            PUT_STRING (self->from);
            if (self->to) {
                PUT_LONGSTR (self->to);
            }
            else
                PUT_NUMBER4 (0);    //  Empty string
            if (self->subject) {
                PUT_LONGSTR (self->subject);
            }
            else
                PUT_NUMBER4 (0);    //  Empty string
            if (self->request) {
                PUT_LONGSTR (self->request);
            }
            else
                PUT_NUMBER4 (0);    //  Empty string
            break;

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

    return 0;
}
コード例 #3
0
ファイル: zmsg.c プロジェクト: HunterChen/czmq
int
zmsg_send (zmsg_t **self_p, void *dest)
{
    assert (self_p);
    assert (dest);
    zmsg_t *self = *self_p;

    int rc = 0;
    void *handle = zsock_resolve (dest);
    if (self) {
        assert (zmsg_is (self));
        if (zlist_size (self->frames) == 0)
            return -1;          //  Sending an empty message is an error
        
        zframe_t *frame = (zframe_t *) zlist_pop (self->frames);
        while (frame) {
            rc = zframe_send (&frame, handle,
                zlist_size (self->frames)? ZFRAME_MORE: 0);
            if (rc != 0)
                break;
            frame = (zframe_t *) zlist_pop (self->frames);
        }
        zmsg_destroy (self_p);
    }
    return rc;
}
コード例 #4
0
ファイル: zpoller.c プロジェクト: evoskuil/czmq
int
zpoller_remove (zpoller_t *self, void *reader)
{
    assert (self);
    assert (reader);
    int rc = 0;
#ifdef ZMQ_HAVE_POLLER
    void *socket = zsock_resolve (reader);
    if (socket)
        rc = zmq_poller_remove (self->zmq_poller, socket);
    else
        rc = zmq_poller_remove_fd (self->zmq_poller, *(SOCKET *) reader);
#else
    size_t num_readers_before = zlist_size (self->reader_list);
    zlist_remove (self->reader_list, reader); // won't fail with non-existent reader
    size_t num_readers_after = zlist_size (self->reader_list);
    if (num_readers_before != num_readers_after)
        self->need_rebuild = true;
    else {
        errno = EINVAL;
        rc    = -1;
    }
#endif
    return rc;
}
コード例 #5
0
ファイル: zstr.c プロジェクト: Asmod4n/czmq
int
zstr_recvx (void *source, char **string_p, ...)
{
    assert (source);
    void *handle = zsock_resolve (source);

    zmsg_t *msg = zmsg_recv (handle);
    if (!msg)
        return -1;

    //  Filter a signal that may come from a dying actor
    if (zmsg_signal (msg) >= 0) {
        zmsg_destroy (&msg);
        return -1;
    }
    int count = 0;
    va_list args;
    va_start (args, string_p);
    while (string_p) {
        *string_p = zmsg_popstr (msg);
        string_p = va_arg (args, char **);
        count++;
    }
    va_end (args);
    zmsg_destroy (&msg);
    return count;
}
コード例 #6
0
ファイル: mdp_client.c プロジェクト: zeromq/majordomo
int
mdp_client_getsockopt (mdp_client_t *self, 	int option, void *optval, size_t *optvallen)
{
    assert (self);
    assert (self->client);
    return zmq_getsockopt (zsock_resolve(self->client), option, optval, optvallen);
}
コード例 #7
0
ファイル: zpoller.c プロジェクト: evoskuil/czmq
static int
s_rebuild_poll_set (zpoller_t *self)
{
    freen (self->poll_set);
    self->poll_set = NULL;
    freen (self->poll_readers);
    self->poll_readers = NULL;

    self->poll_size = zlist_size (self->reader_list);
    self->poll_set = (zmq_pollitem_t *)
                      zmalloc (self->poll_size * sizeof (zmq_pollitem_t));
    self->poll_readers = (void **) zmalloc (self->poll_size * sizeof (void *));
    if (!self->poll_set || !self->poll_readers)
        return -1;

    uint reader_nbr = 0;
    void *reader = zlist_first (self->reader_list);
    while (reader) {
        self->poll_readers [reader_nbr] = reader;
        void *socket = zsock_resolve (reader);
        if (socket == NULL) {
            self->poll_set [reader_nbr].socket = NULL;
            self->poll_set [reader_nbr].fd = *(SOCKET *) reader;
        }
        else
            self->poll_set [reader_nbr].socket = socket;
        self->poll_set [reader_nbr].events = ZMQ_POLLIN;

        reader_nbr++;
        reader = zlist_next (self->reader_list);
    }
    self->need_rebuild = false;
    return 0;
}
コード例 #8
0
ファイル: zgossip_msg.c プロジェクト: jricher42/czmq
int
zgossip_msg_send (zgossip_msg_t **self_p, void *output)
{
    assert (self_p);
    assert (*self_p);
    assert (output);

    //  Save routing_id if any, as encode will destroy it
    zgossip_msg_t *self = *self_p;
    zframe_t *routing_id = self->routing_id;
    self->routing_id = NULL;

    //  Encode zgossip_msg message to a single zmsg
    zmsg_t *msg = zgossip_msg_encode (&self);
    
    //  If we're sending to a ROUTER, send the routing_id first
    if (zsocket_type (zsock_resolve (output)) == ZMQ_ROUTER) {
        assert (routing_id);
        zmsg_prepend (msg, &routing_id);
    }
    else
        zframe_destroy (&routing_id);
        
    if (msg && zmsg_send (&msg, output) == 0)
        return 0;
    else
        return -1;              //  Failed to encode, or send
}
コード例 #9
0
ファイル: zactor.c プロジェクト: Cargo-Labs/czmq
void *
zactor_resolve (void *self)
{
    assert (self);
    if (zactor_is (self))
        return zsock_resolve (((zactor_t *) self)->pipe);
    else
        return self;
}
コード例 #10
0
ファイル: zmonitor.c プロジェクト: reqshark/czmq
static self_t *
s_self_new (zsock_t *pipe, zsock_t *sock)
{
    self_t *self = (self_t *) zmalloc (sizeof (self_t));
    self->pipe = pipe;
    self->monitored = zsock_resolve (sock);
    self->poller = zpoller_new (self->pipe, NULL);
    return self;
}
コード例 #11
0
ファイル: zgossip_msg.c プロジェクト: jricher42/czmq
zgossip_msg_t *
zgossip_msg_recv_nowait (void *input)
{
    assert (input);
    zmsg_t *msg = zmsg_recv_nowait (input);
    //  If message came from a router socket, first frame is routing_id
    zframe_t *routing_id = NULL;
    if (zsocket_type (zsock_resolve (input)) == ZMQ_ROUTER) {
        routing_id = zmsg_pop (msg);
        //  If message was not valid, forget about it
        if (!routing_id || !zmsg_next (msg))
            return NULL;        //  Malformed or empty
    }
    zgossip_msg_t * zgossip_msg = zgossip_msg_decode (&msg);
    if (zsocket_type (zsock_resolve (input)) == ZMQ_ROUTER)
        zgossip_msg->routing_id = routing_id;

    return zgossip_msg;
}
コード例 #12
0
ファイル: zcert.c プロジェクト: PSG-Luna/czmq
void
zcert_apply (zcert_t *self, void *zocket)
{
    assert (self);
#if (ZMQ_VERSION_MAJOR == 4)
    void *handle = zsock_resolve (zocket);
    if (zsys_has_curve ()) {
        zsocket_set_curve_secretkey_bin (handle, self->secret_key);
        zsocket_set_curve_publickey_bin (handle, self->public_key);
    }
#endif
}
コード例 #13
0
ファイル: zmonitor.c プロジェクト: Q-Leap-Networks/czmq
static self_t *
s_self_new (zsock_t *pipe, void *sock)
{
    self_t *self = (self_t *) zmalloc (sizeof (self_t));
    if (!self)
        return NULL;

    self->pipe = pipe;
    self->monitored = zsock_resolve (sock);
    self->poller = zpoller_new (self->pipe, NULL);
    if (!self->poller)
        s_self_destroy (&self);
    return self;
}
コード例 #14
0
ファイル: zyre_peer.c プロジェクト: Muraad/zyre
void
zyre_peer_connect (zyre_peer_t *self, zuuid_t *from, const char *endpoint)
{
    assert (self);
    assert (!self->connected);

    //  Create new outgoing socket (drop any messages in transit)
    self->mailbox = zsock_new (ZMQ_DEALER);
    if (!self->mailbox)
        return;             //  Null when we're shutting down
    
    //  Set our own identity on the socket so that receiving node
    //  knows who each message came from. Note that we cannot use
    //  the UUID directly as the identity since it may contain a
    //  zero byte at the start, which libzmq does not like for
    //  historical and arguably bogus reasons that it nonetheless
    //  enforces.
    byte routing_id [ZUUID_LEN + 1] = { 1 };
    memcpy (routing_id + 1, zuuid_data (from), ZUUID_LEN);
    int rc = zmq_setsockopt (zsock_resolve (self->mailbox),
                             ZMQ_IDENTITY, routing_id, ZUUID_LEN + 1);
    assert (rc == 0);

    //  Set a high-water mark that allows for reasonable activity
    zsock_set_sndhwm (self->mailbox, PEER_EXPIRED * 100);

    //  Send messages immediately or return EAGAIN
    zsock_set_sndtimeo (self->mailbox, 0);

    //  Connect through to peer node
    rc = zsock_connect (self->mailbox, "%s", endpoint);
    if (rc != 0) {
        zsys_error ("(%s) cannot connect to endpoint=%s",
                    self->origin, endpoint);
        //  Don't really have any error handling yet; if connect
        //  fails, there's something wrong with connect endpoint?
        assert (false);
    }
    assert (rc == 0);
    if (self->verbose)
        zsys_info ("(%s) connect to peer: endpoint=%s",
                   self->origin, endpoint);

    self->endpoint = strdup (endpoint);
    self->connected = true;
    self->ready = false;
}
コード例 #15
0
ファイル: zstr.c プロジェクト: Asmod4n/czmq
static int
s_send_string (void *dest, bool more, char *string)
{
    assert (dest);
    void *handle = zsock_resolve (dest);

    size_t len = strlen (string);
    zmq_msg_t message;
    zmq_msg_init_size (&message, len);
    memcpy (zmq_msg_data (&message), string, len);
    if (zmq_sendmsg (handle, &message, more ? ZMQ_SNDMORE : 0) == -1) {
        zmq_msg_close (&message);
        return -1;
    }
    else
        return 0;
}
コード例 #16
0
ファイル: zstr.c プロジェクト: DeanHH/czmq
char *
zstr_recv_nowait (void *dest)
{
    assert (dest);
    void *handle = zsock_resolve (dest);

    zmq_msg_t message;
    zmq_msg_init (&message);
    if (zmq_recvmsg (handle, &message, ZMQ_DONTWAIT) < 0)
        return NULL;

    size_t size = zmq_msg_size (&message);
    char *string = (char *) malloc (size + 1);
    memcpy (string, zmq_msg_data (&message), size);
    zmq_msg_close (&message);
    string [size] = 0;
    return string;
}
コード例 #17
0
ファイル: zstr.c プロジェクト: DeanHH/czmq
char *
zstr_recv (void *source)
{
    assert (source);
    void *handle = zsock_resolve (source);

    zmq_msg_t message;
    zmq_msg_init (&message);
    if (zmq_recvmsg (handle, &message, 0) < 0)
        return NULL;

    size_t size = zmq_msg_size (&message);
    char *string = (char *) malloc (size + 1);
    memcpy (string, zmq_msg_data (&message), size);
    zmq_msg_close (&message);
    string [size] = 0;
    return string;
}
コード例 #18
0
ファイル: zpoller.c プロジェクト: evoskuil/czmq
int
zpoller_add (zpoller_t *self, void *reader)
{
    assert (self);
    assert (reader);
    int rc = 0;
#ifdef ZMQ_HAVE_POLLER
    void *socket = zsock_resolve (reader);
    if (socket)
        rc = zmq_poller_add (self->zmq_poller, socket, reader, ZMQ_POLLIN);
    else
        rc = zmq_poller_add_fd (self->zmq_poller, *(SOCKET *) reader, reader, ZMQ_POLLIN);
#else
    zlist_append (self->reader_list, reader);
    self->need_rebuild = true;
#endif
    return rc;
}
コード例 #19
0
ファイル: zloop.c プロジェクト: Cargo-Labs/czmq
static int
s_rebuild_pollset (zloop_t *self)
{
    free (self->pollset);
    free (self->readact);
    free (self->pollact);
    self->pollset = NULL;
    self->readact = NULL;
    self->pollact = NULL;

    self->poll_size = zlistx_size (self->readers) + zlistx_size (self->pollers);
    self->pollset = (zmq_pollitem_t *) zmalloc (self->poll_size * sizeof (zmq_pollitem_t));
    if (!self->pollset)
        return -1;

    self->readact = (s_reader_t *) zmalloc (self->poll_size * sizeof (s_reader_t));
    if (!self->readact)
        return -1;

    self->pollact = (s_poller_t *) zmalloc (self->poll_size * sizeof (s_poller_t));
    if (!self->pollact)
        return -1;

    s_reader_t *reader = (s_reader_t *) zlistx_first (self->readers);
    uint item_nbr = 0;
    while (reader) {
        zmq_pollitem_t poll_item = { zsock_resolve (reader->sock), 0, ZMQ_POLLIN };
        self->pollset [item_nbr] = poll_item;
        self->readact [item_nbr] = *reader;
        item_nbr++;
        reader = (s_reader_t *) zlistx_next (self->readers);
    }
    s_poller_t *poller = (s_poller_t *) zlistx_first (self->pollers);
    while (poller) {
        self->pollset [item_nbr] = poller->item;
        self->pollact [item_nbr] = *poller;
        item_nbr++;
        poller = (s_poller_t *) zlistx_next (self->pollers);
    }
    self->need_rebuild = false;
    return 0;
}
コード例 #20
0
ファイル: zstr.c プロジェクト: DeanHH/czmq
int
zstr_recvx (void *source, char **string_p, ...)
{
    assert (source);
    void *handle = zsock_resolve (source);
    
    zmsg_t *msg = zmsg_recv (handle);
    if (!msg)
        return -1;
        
    va_list args;
    va_start (args, string_p);
    while (string_p) {
        *string_p = zmsg_popstr (msg);
        string_p = va_arg (args, char **);
    }
    va_end (args);
    zmsg_destroy (&msg);
    return 0;
}
コード例 #21
0
ファイル: zbeacon.c プロジェクト: minhoryang/czmq
void
zbeacon (zsock_t *pipe, void *args)
{
    self_t *self = s_self_new (pipe);
    assert (self);
    //  Signal successful initialization
    zsock_signal (pipe, 0);

    while (!self->terminated) {
        //  Poll on API pipe and on UDP socket
        zmq_pollitem_t pollitems [] = {
            { zsock_resolve (self->pipe), 0, ZMQ_POLLIN, 0 },
            { NULL, self->udpsock, ZMQ_POLLIN, 0 }
        };
        long timeout = -1;
        if (self->transmit) {
            timeout = (long) (self->ping_at - zclock_mono ());
            if (timeout < 0)
                timeout = 0;
        }
        int pollset_size = self->udpsock? 2: 1;
        if (zmq_poll (pollitems, pollset_size, timeout * ZMQ_POLL_MSEC) == -1)
            break;              //  Interrupted

        if (pollitems [0].revents & ZMQ_POLLIN)
            s_self_handle_pipe (self);
        if (pollitems [1].revents & ZMQ_POLLIN)
            s_self_handle_udp (self);

        if (self->transmit
        &&  zclock_mono () >= self->ping_at) {
            //  Send beacon to any listening peers
            if (zsys_udp_send (self->udpsock, self->transmit, &self->broadcast, sizeof (inaddr_t)))
                //  Try to recreate UDP socket on interface
                s_self_prepare_udp (self);
            self->ping_at = zclock_mono () + self->interval;
        }
    }
    s_self_destroy (&self);
}
コード例 #22
0
ファイル: zpubsub_filter.c プロジェクト: lovmoen/zlabs
int
zpubsub_filter_send (zpubsub_filter_t *self, zsock_t *output)
{
    assert (self);
    assert (output);

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

    size_t frame_size = 2 + 1;          //  Signature and message ID
    switch (self->id) {
        case ZPUBSUB_FILTER_FILTER:
            frame_size += 2;            //  magic
            frame_size += 2;            //  version
            frame_size += 1 + strlen (self->partition);
            frame_size += 1 + strlen (self->topic);
            break;
    }
    //  Now serialize message into the frame
    zmq_msg_t frame;
    zmq_msg_init_size (&frame, frame_size);
    self->needle = (byte *) zmq_msg_data (&frame);
    PUT_NUMBER2 (0xAAA0 | 7);
    PUT_NUMBER1 (self->id);
    size_t nbr_frames = 1;              //  Total number of frames to send
    
    switch (self->id) {
        case ZPUBSUB_FILTER_FILTER:
            PUT_NUMBER2 (ZPUBSUB_FILTER_MAGIC_NUMBER);
            PUT_NUMBER2 (ZPUBSUB_FILTER_VERSION);
            PUT_STRING (self->partition);
            PUT_STRING (self->topic);
            break;

    }
    //  Now send the data frame
    zmq_msg_send (&frame, zsock_resolve (output), --nbr_frames? ZMQ_SNDMORE: 0);
    
    return 0;
}
コード例 #23
0
ファイル: zmsg.c プロジェクト: dadavita/stalk
//  --------------------------------------------------------------------------
//  Send (More) message to destination socket, and destroy the message after sending
//  it successfully. If the message has no frames, sends nothing but destroys
//  the message anyhow. Nullifies the caller's reference to the message (as
//  it is a destructor).
CZMQ_EXPORT int
    zmsg_sendm (zmsg_t **self_p, void *dest)
{
    assert (self_p);
    assert (dest);
    zmsg_t *self = *self_p;

    int rc = 0;
    void *handle = zsock_resolve (dest);
    if (self) {
        assert (zmsg_is (self));
        zframe_t *frame = (zframe_t *) zlist_pop (self->frames);
        while (frame) {
            rc = zframe_send (&frame, handle,ZFRAME_MORE);
            if (rc != 0)
                break;
            frame = (zframe_t *) zlist_pop (self->frames);
        }
        if (rc == 0)
            zmsg_destroy (self_p);
    }
    return rc;
}
コード例 #24
0
ファイル: zmsg.c プロジェクト: dadavita/stalk
zmsg_t *
zmsg_recv (void *source)
{
    assert (source);
    zmsg_t *self = zmsg_new ();
    if (!self)
        return NULL;

    void *handle = zsock_resolve (source);
    while (true) {
        zframe_t *frame = zframe_recv (handle);
        if (!frame) {
            zmsg_destroy (&self);
            break;              //  Interrupted or terminated
        }
        if (zmsg_append (self, &frame)) {
            zmsg_destroy (&self);
            break;
        }
        if (!zsock_rcvmore (handle))
            break;              //  Last message frame
    }
    return self;
}
コード例 #25
0
ファイル: zmailer_msg.c プロジェクト: oikosdev/zmailer
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
}
コード例 #26
0
ファイル: zpubsub_filter.c プロジェクト: lovmoen/zlabs
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
}
コード例 #27
0
static int read_zmq_message_and_forward(zloop_t *loop, zsock_t *sock, void *callback_data)
{
    int i = 0;
    zmq_msg_t message_parts[4];
    publisher_state_t *state = (publisher_state_t*)callback_data;
    void *socket = zsock_resolve(sock);

    // read the message parts, possibly including the message meta info
    while (!zsys_interrupted) {
        // printf("[D] receiving part %d\n", i+1);
        if (i>3) {
            zmq_msg_t dummy_msg;
            zmq_msg_init(&dummy_msg);
            zmq_recvmsg(socket, &dummy_msg, 0);
            zmq_msg_close(&dummy_msg);
        } else {
            zmq_msg_init(&message_parts[i]);
            zmq_recvmsg(socket, &message_parts[i], 0);
        }
        if (!zsocket_rcvmore(socket))
            break;
        i++;
    }
    if (i<2) {
        if (!zsys_interrupted) {
            fprintf(stderr, "[E] received only %d message parts\n", i);
        }
        goto cleanup;
    } else if (i>3) {
        fprintf(stderr, "[E] received more than 4 message parts\n");
        goto cleanup;
    }

    zmq_msg_t *body = &message_parts[2];
    msg_meta_t meta = META_INFO_EMPTY;
    if (i==3)
        zmq_msg_extract_meta_info(&message_parts[3], &meta);

    // const char *prefix = socket == state->compressor_output ? "EXTERNAL MESSAGE" : "INTERNAL MESSAGE";
    // my_zmq_msg_fprint(&message_parts[0], 3, prefix, stdout);
    // dump_meta_info(prefix, &meta);

    if (meta.created_ms)
        msg_meta.created_ms = meta.created_ms;
    else
        msg_meta.created_ms = global_time;

    size_t msg_bytes = zmq_msg_size(body);
    if (socket == state->compressor_output) {
        decompressed_messages_count++;
        decompressed_messages_bytes += msg_bytes;
        if (msg_bytes > decompressed_messages_max_bytes)
            decompressed_messages_max_bytes = msg_bytes;
    } else {
        received_messages_count++;
        received_messages_bytes += msg_bytes;
        if (msg_bytes > received_messages_max_bytes)
            received_messages_max_bytes = msg_bytes;
    }

    msg_meta.compression_method = meta.compression_method;
    if (meta.compression_method) {
        // decompress
        publish_on_zmq_transport(&message_parts[0], state->compressor_input, &msg_meta, 0);
    } else {
        // forward to comsumer
        msg_meta.sequence_number++;
        if (debug) {
            my_zmq_msg_fprint(&message_parts[0], 3, "[D]", stdout);
            dump_meta_info("[D]", &msg_meta);
        }
        char *pub_spec = NULL;
        bool is_heartbeat = zmq_msg_size(&message_parts[0]) == 9 && strncmp("heartbeat", zmq_msg_data(&message_parts[0]), 9) == 0;
        if (is_heartbeat) {
            if (debug)
                printf("[D] received heartbeat message from device %u\n", msg_meta.device_number);
            pub_spec = strndup(zmq_msg_data(&message_parts[1]), zmq_msg_size(&message_parts[1]));
        }
        device_tracker_calculate_gap(tracker, &msg_meta, pub_spec);
        if (!is_heartbeat)
            publish_on_zmq_transport(&message_parts[0], state->publisher, &msg_meta, ZMQ_DONTWAIT);
    }

 cleanup:
    for (;i>=0;i--) {
        zmq_msg_close(&message_parts[i]);
    }

    return 0;
}
コード例 #28
0
ファイル: zgossip_msg.c プロジェクト: AxelVoitier/czmq
int
zgossip_msg_send (zgossip_msg_t *self, zsock_t *output)
{
    assert (self);
    assert (output);

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

    size_t frame_size = 2 + 1;          //  Signature and message ID
    switch (self->id) {
        case ZGOSSIP_MSG_HELLO:
            frame_size += 1;            //  version
            break;
        case ZGOSSIP_MSG_PUBLISH:
            frame_size += 1;            //  version
            frame_size += 1 + strlen (self->key);
            frame_size += 4;
            if (self->value)
                frame_size += strlen (self->value);
            frame_size += 4;            //  ttl
            break;
        case ZGOSSIP_MSG_PING:
            frame_size += 1;            //  version
            break;
        case ZGOSSIP_MSG_PONG:
            frame_size += 1;            //  version
            break;
        case ZGOSSIP_MSG_INVALID:
            frame_size += 1;            //  version
            break;
    }
    //  Now serialize message into the frame
    zmq_msg_t frame;
    zmq_msg_init_size (&frame, frame_size);
    self->needle = (byte *) zmq_msg_data (&frame);
    PUT_NUMBER2 (0xAAA0 | 0);
    PUT_NUMBER1 (self->id);
    size_t nbr_frames = 1;              //  Total number of frames to send

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

        case ZGOSSIP_MSG_PUBLISH:
            PUT_NUMBER1 (1);
            PUT_STRING (self->key);
            if (self->value) {
                PUT_LONGSTR (self->value);
            }
            else
                PUT_NUMBER4 (0);    //  Empty string
            PUT_NUMBER4 (self->ttl);
            break;

        case ZGOSSIP_MSG_PING:
            PUT_NUMBER1 (1);
            break;

        case ZGOSSIP_MSG_PONG:
            PUT_NUMBER1 (1);
            break;

        case ZGOSSIP_MSG_INVALID:
            PUT_NUMBER1 (1);
            break;

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

    return 0;
}
コード例 #29
0
ファイル: qzsock.cpp プロジェクト: digideskio/zebra
///
//  Probe the supplied reference. If it looks like a zsock_t instance, return
//  the underlying libzmq socket handle; else if it looks like a file        
//  descriptor, return NULL; else if it looks like a libzmq socket handle,   
//  return the supplied value. Takes a polymorphic socket reference.         
void * QZsock::resolve (void *self)
{
    void * rv = zsock_resolve (self);
    return rv;
}
コード例 #30
0
ファイル: zyre_peer.c プロジェクト: jossgray/zyre
int
zyre_peer_connect (zyre_peer_t *self, zuuid_t *from, const char *endpoint, uint64_t expired_timeout)
{
    assert (self);
    assert (!self->connected);

    //  Create new outgoing socket (drop any messages in transit)
    self->mailbox = zsock_new (ZMQ_DEALER);
    if (!self->mailbox)
        return -1;             //  Null when we're shutting down

    //  Set our own identity on the socket so that receiving node
    //  knows who each message came from. Note that we cannot use
    //  the UUID directly as the identity since it may contain a
    //  zero byte at the start, which libzmq does not like for
    //  historical and arguably bogus reasons that it nonetheless
    //  enforces.
    byte routing_id [ZUUID_LEN + 1] = { 1 };
    memcpy (routing_id + 1, zuuid_data (from), ZUUID_LEN);
    int rc = zmq_setsockopt (zsock_resolve (self->mailbox),
                             ZMQ_IDENTITY, routing_id, ZUUID_LEN + 1);
    assert (rc == 0);

    //  Set a high-water mark that allows for reasonable activity
    zsock_set_sndhwm (self->mailbox, expired_timeout * 100);

    //  Send messages immediately or return EAGAIN
    zsock_set_sndtimeo (self->mailbox, 0);

    //  If the peer is a link-local IPv6 address but the interface is not set,
    //  use ZSYS_INTERFACE_ADDRESS if provided
    zrex_t *rex = zrex_new (NULL);
    char endpoint_iface [NI_MAXHOST] = {0};
    if (zsys_ipv6 () && zsys_interface () && strlen(zsys_interface ()) &&
            !streq (zsys_interface (), "*") &&
            zrex_eq (rex, endpoint, "^tcp://(fe80[^%]+)(:\\d+)$")) {
        const char *hostname, *port;
        zrex_fetch (rex, &hostname, &port, NULL);
        strcat (endpoint_iface, "tcp://");
        strcat (endpoint_iface, hostname);
        strcat (endpoint_iface, "%");
        strcat (endpoint_iface, zsys_interface ());
        strcat (endpoint_iface, port);
    } else
        strcat (endpoint_iface, endpoint);
    zrex_destroy (&rex);

    //  Connect through to peer node
    rc = zsock_connect (self->mailbox, "%s", endpoint_iface);
    if (rc != 0) {
        zsys_debug ("(%s) cannot connect to endpoint=%s",
                    self->origin, endpoint_iface);
        zsock_destroy (&self->mailbox);
        return -1;
    }
    if (self->verbose)
        zsys_info ("(%s) connect to peer: endpoint=%s",
                   self->origin, endpoint_iface);

    self->endpoint = strdup (endpoint_iface);
    self->connected = true;
    self->ready = false;

    return 0;
}