コード例 #1
0
ファイル: zyre_node.c プロジェクト: opedroso/zyre
static zyre_peer_t *
zyre_node_require_peer (zyre_node_t *self, zuuid_t *uuid, const char *endpoint)
{
    assert (self);
    assert (endpoint);

    zyre_peer_t *peer = (zyre_peer_t *) zhash_lookup (self->peers, zuuid_str (uuid));
    if (!peer) {
        //  Purge any previous peer on same endpoint
        void *item;
        for (item = zhash_first (self->peers); item != NULL;
                item = zhash_next (self->peers))
            zyre_node_purge_peer (zhash_cursor (self->peers), item, (char *) endpoint);

        peer = zyre_peer_new (self->peers, uuid);
        assert (peer);
        zyre_peer_set_origin (peer, self->name);
        zyre_peer_set_verbose (peer, self->verbose);
        zyre_peer_connect (peer, self->uuid, endpoint, self->expired_timeout);

        //  Handshake discovery by sending HELLO as first message
        zlist_t *groups = zlist_dup (self->own_groups);
        zhash_t *headers = zhash_dup (self->headers);
        zre_msg_t *msg = zre_msg_new (ZRE_MSG_HELLO);
        zre_msg_set_endpoint (msg, self->endpoint);
        zre_msg_set_groups (msg, &groups);
        zre_msg_set_status (msg, self->status);
        zre_msg_set_name (msg, self->name);
        zre_msg_set_headers (msg, &headers);
        zyre_peer_send (peer, &msg);
    }
    return peer;
}
コード例 #2
0
ファイル: zyre_node.c プロジェクト: opedroso/zyre
static int
zyre_node_ping_peer (const char *key, void *item, void *argument)
{
    zyre_peer_t *peer = (zyre_peer_t *) item;
    zyre_node_t *self = (zyre_node_t *) argument;
    if (zclock_mono () >= zyre_peer_expired_at (peer)) {
        if (self->verbose)
            zsys_info ("(%s) peer expired name=%s endpoint=%s",
                self->name, zyre_peer_name (peer), zyre_peer_endpoint (peer));
        zyre_node_remove_peer (self, peer);
    }
    else
    if (zclock_mono () >= zyre_peer_evasive_at (peer)) {
        //  If peer is being evasive, force a TCP ping.
        //  TODO: do this only once for a peer in this state;
        //  it would be nicer to use a proper state machine
        //  for peer management.
        if (self->verbose)
            zsys_info ("(%s) peer seems dead/slow name=%s endpoint=%s",
                self->name, zyre_peer_name (peer), zyre_peer_endpoint (peer));
        zre_msg_t *msg = zre_msg_new (ZRE_MSG_PING);
        zyre_peer_send (peer, &msg);
        // Inform the calling application this peer is being evasive
    	zstr_sendm (self->outbox, "EVASIVE");
	zstr_sendm (self->outbox, zyre_peer_identity (peer));
    	zstr_send (self->outbox, zyre_peer_name (peer));
    }
    return 0;
}
コード例 #3
0
ファイル: zre_node.c プロジェクト: Aluminus/zyre
static int
agent_ping_peer (const char *key, void *item, void *argument)
{
    agent_t *self = (agent_t *) argument;
    zre_peer_t *peer = (zre_peer_t *) item;
    char *identity = zre_peer_identity (peer);
    if (zclock_time () >= zre_peer_expired_at (peer)) {
        zre_log_info (self->log, ZRE_LOG_MSG_EVENT_EXIT,
                      zre_peer_endpoint (peer),
                      zre_peer_endpoint (peer));
        //  If peer has really vanished, expire it
        zstr_sendm (self->pipe, "EXIT");
        zstr_send (self->pipe, identity);
        zhash_foreach (self->peer_groups, agent_peer_delete, peer);
        zhash_delete (self->peers, identity);
    }
    else
    if (zclock_time () >= zre_peer_evasive_at (peer)) {
        //  If peer is being evasive, force a TCP ping.
        //  TODO: do this only once for a peer in this state;
        //  it would be nicer to use a proper state machine
        //  for peer management.
        zre_msg_t *msg = zre_msg_new (ZRE_MSG_PING);
        zre_peer_send (peer, &msg);
    }
    return 0;
}
コード例 #4
0
ファイル: zyre_peer.c プロジェクト: Muraad/zyre
void
zyre_peer_test (bool verbose)
{
    printf (" * zyre_peer: ");

    zsock_t *mailbox = zsock_new_dealer ("@tcp://127.0.0.1:5551");
    zhash_t *peers = zhash_new ();
    zuuid_t *you = zuuid_new ();
    zuuid_t *me = zuuid_new ();
    zyre_peer_t *peer = zyre_peer_new (peers, you);
    assert (!zyre_peer_connected (peer));
    zyre_peer_connect (peer, me, "tcp://127.0.0.1:5551");
    assert (zyre_peer_connected (peer));
    zyre_peer_set_name (peer, "peer");
    assert (streq (zyre_peer_name (peer), "peer"));

    zre_msg_t *msg = zre_msg_new (ZRE_MSG_HELLO);
    zre_msg_set_endpoint (msg, "tcp://127.0.0.1:5552");
    int rc = zyre_peer_send (peer, &msg);
    assert (rc == 0);

    msg = zre_msg_recv (mailbox);
    assert (msg);
    if (verbose)
        zre_msg_print (msg);
    zre_msg_destroy (&msg);

    //  Destroying container destroys all peers it contains
    zhash_destroy (&peers);
    zuuid_destroy (&me);
    zuuid_destroy (&you);
    zsock_destroy (&mailbox);

    printf ("OK\n");
}
コード例 #5
0
ファイル: zre_node.c プロジェクト: Aluminus/zyre
static zre_peer_t *
s_require_peer (agent_t *self, char *identity, char *address, uint16_t port)
{
    zre_peer_t *peer = (zre_peer_t *) zhash_lookup (self->peers, identity);
    if (!peer) {
        //  Purge any previous peer on same endpoint
        char endpoint [100];
        snprintf (endpoint, 100, "%s:%hu", address, port);
        zhash_foreach (self->peers, agent_peer_purge, endpoint);

        peer = zre_peer_new (identity, self->peers, self->ctx);
        zre_peer_connect (peer, self->identity, endpoint);

        //  Handshake discovery by sending HELLO as first message
        zre_msg_t *msg = zre_msg_new (ZRE_MSG_HELLO);
        zre_msg_ipaddress_set (msg, zre_udp_host (self->udp));
        zre_msg_mailbox_set (msg, self->port);
        zre_msg_groups_set (msg, zhash_keys (self->own_groups));
        zre_msg_status_set (msg, self->status);
        zre_msg_headers_set (msg, zhash_dup (self->headers));
        zre_peer_send (peer, &msg);
        
        zre_log_info (self->log, ZRE_LOG_MSG_EVENT_ENTER,
                      zre_peer_endpoint (peer), endpoint);

        //  Now tell the caller about the peer
        zstr_sendm (self->pipe, "ENTER");
        zstr_send (self->pipe, identity);
    }
    return peer;
}
コード例 #6
0
ファイル: zyre_node.c プロジェクト: codebrainz/zyre
static zyre_peer_t *
zyre_node_require_peer (zyre_node_t *self, zuuid_t *uuid, char *address, uint16_t port)
{
    zyre_peer_t *peer = (zyre_peer_t *) zhash_lookup (self->peers, zuuid_str (uuid));
    if (!peer) {
        //  Purge any previous peer on same endpoint
        char endpoint [100];
        snprintf (endpoint, 100, "tcp://%s:%hu", address, port);
        zhash_foreach (self->peers, zyre_node_purge_peer, endpoint);

        peer = zyre_peer_new (self->ctx, self->peers, uuid);
        zyre_peer_connect (peer, self->uuid, endpoint);

        //  Handshake discovery by sending HELLO as first message
        zre_msg_t *msg = zre_msg_new (ZRE_MSG_HELLO);
        zre_msg_set_ipaddress (msg, self->host);
        zre_msg_set_mailbox (msg, self->port);
        zre_msg_set_groups (msg, zhash_keys (self->own_groups));
        zre_msg_set_status (msg, self->status);
        zre_msg_set_headers (msg, zhash_dup (self->headers));
        zyre_peer_send (peer, &msg);

        //  Send new peer event to logger, if any
        zyre_log_info (self->log, ZRE_LOG_MSG_EVENT_ENTER,
                      zyre_peer_endpoint (peer), endpoint);
    }
    return peer;
}
コード例 #7
0
ファイル: zre_msg.c プロジェクト: karinies/coast
int
zre_msg_send_ping_ok (
    void *output,
    uint16_t sequence)
{
    zre_msg_t *self = zre_msg_new (ZRE_MSG_PING_OK);
    zre_msg_set_sequence (self, sequence);
    return zre_msg_send (&self, output);
}
コード例 #8
0
ファイル: zre_msg.c プロジェクト: UIKit0/zyre
int
zre_msg_send_whisper (
    void *output,
    uint16_t sequence,
    zframe_t *content)
{
    zre_msg_t *self = zre_msg_new (ZRE_MSG_WHISPER);
    zre_msg_set_sequence (self, sequence);
    zre_msg_set_content (self, zframe_dup (content));
    return zre_msg_send (&self, output);
}
コード例 #9
0
ファイル: zre_msg.c プロジェクト: karinies/coast
zre_msg_t *
zre_msg_dup (zre_msg_t *self)
{
    if (!self)
        return NULL;
        
    zre_msg_t *copy = zre_msg_new (self->id);
    if (self->routing_id)
        copy->routing_id = zframe_dup (self->routing_id);
    switch (self->id) {
        case ZRE_MSG_HELLO:
            copy->sequence = self->sequence;
            copy->ipaddress = self->ipaddress? strdup (self->ipaddress): NULL;
            copy->mailbox = self->mailbox;
            copy->groups = self->groups? zlist_dup (self->groups): NULL;
            copy->status = self->status;
            copy->headers = self->headers? zhash_dup (self->headers): NULL;
            break;

        case ZRE_MSG_WHISPER:
            copy->sequence = self->sequence;
            copy->content = self->content? zmsg_dup (self->content): NULL;
            break;

        case ZRE_MSG_SHOUT:
            copy->sequence = self->sequence;
            copy->group = self->group? strdup (self->group): NULL;
            copy->content = self->content? zmsg_dup (self->content): NULL;
            break;

        case ZRE_MSG_JOIN:
            copy->sequence = self->sequence;
            copy->group = self->group? strdup (self->group): NULL;
            copy->status = self->status;
            break;

        case ZRE_MSG_LEAVE:
            copy->sequence = self->sequence;
            copy->group = self->group? strdup (self->group): NULL;
            copy->status = self->status;
            break;

        case ZRE_MSG_PING:
            copy->sequence = self->sequence;
            break;

        case ZRE_MSG_PING_OK:
            copy->sequence = self->sequence;
            break;

    }
    return copy;
}
コード例 #10
0
ファイル: zre_msg.c プロジェクト: UIKit0/zyre
int
zre_msg_send_join (
    void *output,
    uint16_t sequence,
    char *group,
    byte status)
{
    zre_msg_t *self = zre_msg_new (ZRE_MSG_JOIN);
    zre_msg_set_sequence (self, sequence);
    zre_msg_set_group (self, group);
    zre_msg_set_status (self, status);
    return zre_msg_send (&self, output);
}
コード例 #11
0
ファイル: zre_msg.c プロジェクト: UIKit0/zyre
int
zre_msg_send_shout (
    void *output,
    uint16_t sequence,
    char *group,
    zframe_t *content)
{
    zre_msg_t *self = zre_msg_new (ZRE_MSG_SHOUT);
    zre_msg_set_sequence (self, sequence);
    zre_msg_set_group (self, group);
    zre_msg_set_content (self, zframe_dup (content));
    return zre_msg_send (&self, output);
}
コード例 #12
0
ファイル: zre_msg.c プロジェクト: karinies/coast
int
zre_msg_send_leave (
    void *output,
    uint16_t sequence,
    const char *group,
    byte status)
{
    zre_msg_t *self = zre_msg_new (ZRE_MSG_LEAVE);
    zre_msg_set_sequence (self, sequence);
    zre_msg_set_group (self, group);
    zre_msg_set_status (self, status);
    return zre_msg_send (&self, output);
}
コード例 #13
0
ファイル: zyre_node.c プロジェクト: codebrainz/zyre
static int
zyre_node_ping_peer (const char *key, void *item, void *argument)
{
    zyre_peer_t *peer = (zyre_peer_t *) item;
    zyre_node_t *self = (zyre_node_t *) argument;
    if (zclock_time () >= zyre_peer_expired_at (peer))
        zyre_node_remove_peer (self, peer);
    else
    if (zclock_time () >= zyre_peer_evasive_at (peer)) {
        //  If peer is being evasive, force a TCP ping.
        //  TODO: do this only once for a peer in this state;
        //  it would be nicer to use a proper state machine
        //  for peer management.
        zre_msg_t *msg = zre_msg_new (ZRE_MSG_PING);
        zyre_peer_send (peer, &msg);
    }
    return 0;
}
コード例 #14
0
ファイル: zre_msg.c プロジェクト: UIKit0/zyre
int
zre_msg_send_hello (
    void *output,
    uint16_t sequence,
    char *ipaddress,
    uint16_t mailbox,
    zlist_t *groups,
    byte status,
    zhash_t *headers)
{
    zre_msg_t *self = zre_msg_new (ZRE_MSG_HELLO);
    zre_msg_set_sequence (self, sequence);
    zre_msg_set_ipaddress (self, ipaddress);
    zre_msg_set_mailbox (self, mailbox);
    zre_msg_set_groups (self, zlist_dup (groups));
    zre_msg_set_status (self, status);
    zre_msg_set_headers (self, zhash_dup (headers));
    return zre_msg_send (&self, output);
}
コード例 #15
0
ファイル: zyre_group.c プロジェクト: Muraad/zyre
void
zyre_group_test (bool verbose)
{
    printf (" * zyre_group: ");
    zsock_t *mailbox = zsock_new (ZMQ_DEALER);
    zsock_bind (mailbox, "tcp://127.0.0.1:5552");

    zhash_t *groups = zhash_new ();
    zyre_group_t *group = zyre_group_new ("tests", groups);

    zhash_t *peers = zhash_new ();
    zuuid_t *you = zuuid_new ();
    zuuid_t *me = zuuid_new ();
    zyre_peer_t *peer = zyre_peer_new (peers, you);
    assert (!zyre_peer_connected (peer));
    zyre_peer_connect (peer, me, "tcp://127.0.0.1:5552");
    assert (zyre_peer_connected (peer));

    zyre_group_join (group, peer);
    
    zre_msg_t *msg = zre_msg_new (ZRE_MSG_HELLO);
    zre_msg_set_endpoint (msg, "tcp://127.0.0.1:5552");
    zyre_group_send (group, &msg);

    msg = zre_msg_recv (mailbox);
    assert (msg);
    if (verbose)
        zre_msg_print (msg);
    zre_msg_destroy (&msg);

    zuuid_destroy (&me);
    zuuid_destroy (&you);
    zhash_destroy (&peers);
    zhash_destroy (&groups);
    zsock_destroy (&mailbox);
    printf ("OK\n");
}
コード例 #16
0
ファイル: zyre_node.c プロジェクト: codebrainz/zyre
static int
zyre_node_recv_peer (zyre_node_t *self)
{
    //  Router socket tells us the identity of this peer
    zre_msg_t *msg = zre_msg_recv (self->inbox);
    if (msg == NULL)
        return 0;               //  Interrupted

    //  First frame is sender identity, holding binary UUID
    zuuid_t *uuid = zuuid_new ();
    zuuid_set (uuid, zframe_data (zre_msg_address (msg)));

    //  On HELLO we may create the peer if it's unknown
    //  On other commands the peer must already exist
    zyre_peer_t *peer = (zyre_peer_t *) zhash_lookup (self->peers, zuuid_str (uuid));
    if (zre_msg_id (msg) == ZRE_MSG_HELLO) {
        peer = zyre_node_require_peer (self, uuid, zre_msg_ipaddress (msg), zre_msg_mailbox (msg));
        assert (peer);
        zyre_peer_set_ready (peer, true);
    }
    //  Ignore command if peer isn't ready
    if (peer == NULL || !zyre_peer_ready (peer)) {
        zre_msg_destroy (&msg);
        zuuid_destroy (&uuid);
        return 0;
    }
    if (!zyre_peer_check_message (peer, msg)) {
        zclock_log ("W: [%s] lost messages from %s", zuuid_str (self->uuid), zuuid_str (uuid));
        assert (false);
    }

    //  Now process each command
    if (zre_msg_id (msg) == ZRE_MSG_HELLO) {
        //  Tell the caller about the peer
        zstr_sendm (self->pipe, "ENTER");
        zstr_sendm (self->pipe, zuuid_str (uuid));
        zframe_t *headers = zhash_pack (zre_msg_headers (msg));
        zframe_send (&headers, self->pipe, 0);
        
        //  Join peer to listed groups
        char *name = zre_msg_groups_first (msg);
        while (name) {
            zyre_node_join_peer_group (self, peer, name);
            name = zre_msg_groups_next (msg);
        }
        //  Hello command holds latest status of peer
        zyre_peer_set_status (peer, zre_msg_status (msg));
        
        //  Store peer headers for future reference
        zyre_peer_set_headers (peer, zre_msg_headers (msg));

        //  If peer is a ZRE/LOG collector, connect to it
        char *collector = zre_msg_headers_string (msg, "X-ZRELOG", NULL);
        if (collector)
            zyre_log_connect (self->log, collector);
    }
    else
    if (zre_msg_id (msg) == ZRE_MSG_WHISPER) {
        //  Pass up to caller API as WHISPER event
        zstr_sendm (self->pipe, "WHISPER");
        zstr_sendm (self->pipe, zuuid_str (uuid));
        zmsg_t *content = zmsg_dup (zre_msg_content (msg));
        zmsg_send (&content, self->pipe);
    }
    else
    if (zre_msg_id (msg) == ZRE_MSG_SHOUT) {
        //  Pass up to caller as SHOUT event
        zstr_sendm (self->pipe, "SHOUT");
        zstr_sendm (self->pipe, zuuid_str (uuid));
        zstr_sendm (self->pipe, zre_msg_group (msg));
        zmsg_t *content = zmsg_dup (zre_msg_content (msg));
        zmsg_send (&content, self->pipe);
    }
    else
    if (zre_msg_id (msg) == ZRE_MSG_PING) {
        zre_msg_t *msg = zre_msg_new (ZRE_MSG_PING_OK);
        zyre_peer_send (peer, &msg);
    }
    else
    if (zre_msg_id (msg) == ZRE_MSG_JOIN) {
        zyre_node_join_peer_group (self, peer, zre_msg_group (msg));
        assert (zre_msg_status (msg) == zyre_peer_status (peer));
    }
    else
    if (zre_msg_id (msg) == ZRE_MSG_LEAVE) {
        zyre_node_leave_peer_group (self, peer, zre_msg_group (msg));
        assert (zre_msg_status (msg) == zyre_peer_status (peer));
    }
    zuuid_destroy (&uuid);
    zre_msg_destroy (&msg);
    
    //  Activity from peer resets peer timers
    zyre_peer_refresh (peer);
    return 0;
}
コード例 #17
0
ファイル: zre_msg.c プロジェクト: karinies/coast
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);
}
コード例 #18
0
ファイル: zyre_node.c プロジェクト: codebrainz/zyre
static int
zyre_node_recv_api (zyre_node_t *self)
{
    //  Get the whole message off the pipe in one go
    zmsg_t *request = zmsg_recv (self->pipe);
    char *command = zmsg_popstr (request);
    if (!command)
        return -1;                  //  Interrupted

    if (streq (command, "SET")) {
        char *name = zmsg_popstr (request);
        char *value = zmsg_popstr (request);
        zhash_update (self->headers, name, value);
        zstr_free (&name);
        zstr_free (&value);
    }
    else
    if (streq (command, "START")) {
        zyre_node_start (self);
        zstr_send (self->pipe, "OK");
    }
    else
    if (streq (command, "STOP")) {
        zyre_node_stop (self);
        zstr_send (self->pipe, "OK");
    }
    else
    if (streq (command, "WHISPER")) {
        //  Get peer to send message to
        char *identity = zmsg_popstr (request);
        zyre_peer_t *peer = (zyre_peer_t *) zhash_lookup (self->peers, identity);
        
        //  Send frame on out to peer's mailbox, drop message
        //  if peer doesn't exist (may have been destroyed)
        if (peer) {
            zre_msg_t *msg = zre_msg_new (ZRE_MSG_WHISPER);
            zre_msg_set_content (msg, request);
            zyre_peer_send (peer, &msg);
            request = NULL;
        }
        zstr_free (&identity);
    }
    else
    if (streq (command, "SHOUT")) {
        //  Get group to send message to
        char *name = zmsg_popstr (request);
        zyre_group_t *group = (zyre_group_t *) zhash_lookup (self->peer_groups, name);
        if (group) {
            zre_msg_t *msg = zre_msg_new (ZRE_MSG_SHOUT);
            zre_msg_set_group (msg, name);
            zre_msg_set_content (msg, request);
            zyre_group_send (group, &msg);
            request = NULL;
        }
        zstr_free (&name);
    }
    else
    if (streq (command, "JOIN")) {
        char *name = zmsg_popstr (request);
        zyre_group_t *group = (zyre_group_t *) zhash_lookup (self->own_groups, name);
        if (!group) {
            //  Only send if we're not already in group
            group = zyre_group_new (name, self->own_groups);
            zre_msg_t *msg = zre_msg_new (ZRE_MSG_JOIN);
            zre_msg_set_group (msg, name);
            //  Update status before sending command
            zre_msg_set_status (msg, ++(self->status));
            zhash_foreach (self->peers, zyre_node_send_peer, msg);
            zre_msg_destroy (&msg);
            zyre_log_info (self->log, ZRE_LOG_MSG_EVENT_JOIN, NULL, name);
        }
        zstr_free (&name);
    }
    else
    if (streq (command, "LEAVE")) {
        char *name = zmsg_popstr (request);
        zyre_group_t *group = (zyre_group_t *) zhash_lookup (self->own_groups, name);
        if (group) {
            //  Only send if we are actually in group
            zre_msg_t *msg = zre_msg_new (ZRE_MSG_LEAVE);
            zre_msg_set_group (msg, name);
            //  Update status before sending command
            zre_msg_set_status (msg, ++(self->status));
            zhash_foreach (self->peers, zyre_node_send_peer, msg);
            zre_msg_destroy (&msg);
            zhash_delete (self->own_groups, name);
            zyre_log_info (self->log, ZRE_LOG_MSG_EVENT_LEAVE, NULL, name);
        }
        zstr_free (&name);
    }
    else
    if (streq (command, "TERMINATE")) {
        self->terminated = true;
        zstr_send (self->pipe, "OK");
    }
    zstr_free (&command);
    zmsg_destroy (&request);
    return 0;
}
コード例 #19
0
ファイル: zre_msg.c プロジェクト: UIKit0/zyre
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);
}
コード例 #20
0
ファイル: zre_node.c プロジェクト: Aluminus/zyre
static int
agent_recv_from_peer (agent_t *self)
{
    //  Router socket tells us the identity of this peer
    zre_msg_t *msg = zre_msg_recv (self->inbox);
    if (msg == NULL)
        return 0;               //  Interrupted

    char *identity = zframe_strdup (zre_msg_address (msg));
        
    //  On HELLO we may create the peer if it's unknown
    //  On other commands the peer must already exist
    zre_peer_t *peer = (zre_peer_t *) zhash_lookup (self->peers, identity);
    if (zre_msg_id (msg) == ZRE_MSG_HELLO) {
        peer = s_require_peer (
            self, identity, zre_msg_ipaddress (msg), zre_msg_mailbox (msg));
        assert (peer);
        zre_peer_ready_set (peer, true);
    }
    //  Ignore command if peer isn't ready
    if (peer == NULL || !zre_peer_ready (peer)) {
				free(identity);
        zre_msg_destroy (&msg);
        return 0;
    }
    if (!zre_peer_check_message (peer, msg)) {
        zclock_log ("W: [%s] lost messages from %s", self->identity, identity);
        assert (false);
    }

    //  Now process each command
    if (zre_msg_id (msg) == ZRE_MSG_HELLO) {
        //  Join peer to listed groups
        char *name = zre_msg_groups_first (msg);
        while (name) {
            s_join_peer_group (self, peer, name);
            name = zre_msg_groups_next (msg);
        }
        //  Hello command holds latest status of peer
        zre_peer_status_set (peer, zre_msg_status (msg));
        
        //  Store peer headers for future reference
        zre_peer_headers_set (peer, zre_msg_headers (msg));

        //  If peer is a ZRE/LOG collector, connect to it
        char *collector = zre_msg_headers_string (msg, "X-ZRELOG", NULL);
        if (collector)
            zre_log_connect (self->log, collector);
        
        //  If peer is a FileMQ publisher, connect to it
        char *publisher = zre_msg_headers_string (msg, "X-FILEMQ", NULL);
        if (publisher)
            fmq_client_connect (self->fmq_client, publisher);
    }
    else
    if (zre_msg_id (msg) == ZRE_MSG_WHISPER) {
        //  Pass up to caller API as WHISPER event
        zframe_t *cookie = zre_msg_content (msg);
        zstr_sendm (self->pipe, "WHISPER");
        zstr_sendm (self->pipe, identity);
        zframe_send (&cookie, self->pipe, ZFRAME_REUSE); // let msg free the frame
    }
    else
    if (zre_msg_id (msg) == ZRE_MSG_SHOUT) {
        //  Pass up to caller as SHOUT event
        zframe_t *cookie = zre_msg_content (msg);
        zstr_sendm (self->pipe, "SHOUT");
        zstr_sendm (self->pipe, identity);
        zstr_sendm (self->pipe, zre_msg_group (msg));
        zframe_send (&cookie, self->pipe, ZFRAME_REUSE); // let msg free the frame
    }
    else
    if (zre_msg_id (msg) == ZRE_MSG_PING) {
        zre_msg_t *msg = zre_msg_new (ZRE_MSG_PING_OK);
        zre_peer_send (peer, &msg);
    }
    else
    if (zre_msg_id (msg) == ZRE_MSG_JOIN) {
        s_join_peer_group (self, peer, zre_msg_group (msg));
        assert (zre_msg_status (msg) == zre_peer_status (peer));
    }
    else
    if (zre_msg_id (msg) == ZRE_MSG_LEAVE) {
        s_leave_peer_group (self, peer, zre_msg_group (msg));
        assert (zre_msg_status (msg) == zre_peer_status (peer));
    }
    free (identity);
    zre_msg_destroy (&msg);
    
    //  Activity from peer resets peer timers
    zre_peer_refresh (peer);
    return 0;
}
コード例 #21
0
ファイル: zre_node.c プロジェクト: Aluminus/zyre
static int
agent_recv_from_api (agent_t *self)
{
    //  Get the whole message off the pipe in one go
    zmsg_t *request = zmsg_recv (self->pipe);
    char *command = zmsg_popstr (request);
    if (!command)
        return -1;                  //  Interrupted

    if (streq (command, "WHISPER")) {
        //  Get peer to send message to
        char *identity = zmsg_popstr (request);
        zre_peer_t *peer = (zre_peer_t *) zhash_lookup (self->peers, identity);
        
        //  Send frame on out to peer's mailbox, drop message
        //  if peer doesn't exist (may have been destroyed)
        if (peer) {
            zre_msg_t *msg = zre_msg_new (ZRE_MSG_WHISPER);
            zre_msg_content_set (msg, zmsg_pop (request));
            zre_peer_send (peer, &msg);
        }
        free (identity);
    }
    else
    if (streq (command, "SHOUT")) {
        //  Get group to send message to
        char *name = zmsg_popstr (request);
        zre_group_t *group = (zre_group_t *) zhash_lookup (self->peer_groups, name);
        if (group) {
            zre_msg_t *msg = zre_msg_new (ZRE_MSG_SHOUT);
            zre_msg_group_set (msg, name);
            zre_msg_content_set (msg, zmsg_pop (request));
            zre_group_send (group, &msg);
        }
        free (name);
    }
    else
    if (streq (command, "JOIN")) {
        char *name = zmsg_popstr (request);
        zre_group_t *group = (zre_group_t *) zhash_lookup (self->own_groups, name);
        if (!group) {
            //  Only send if we're not already in group
            group = zre_group_new (name, self->own_groups);
            zre_msg_t *msg = zre_msg_new (ZRE_MSG_JOIN);
            zre_msg_group_set (msg, name);
            //  Update status before sending command
            zre_msg_status_set (msg, ++(self->status));
            zhash_foreach (self->peers, s_peer_send, msg);
            zre_msg_destroy (&msg);
            zre_log_info (self->log, ZRE_LOG_MSG_EVENT_JOIN, NULL, name);
        }
        free (name);
    }
    else
    if (streq (command, "LEAVE")) {
        char *name = zmsg_popstr (request);
        zre_group_t *group = (zre_group_t *) zhash_lookup (self->own_groups, name);
        if (group) {
            //  Only send if we are actually in group
            zre_msg_t *msg = zre_msg_new (ZRE_MSG_LEAVE);
            zre_msg_group_set (msg, name);
            //  Update status before sending command
            zre_msg_status_set (msg, ++(self->status));
            zhash_foreach (self->peers, s_peer_send, msg);
            zre_msg_destroy (&msg);
            zhash_delete (self->own_groups, name);
            zre_log_info (self->log, ZRE_LOG_MSG_EVENT_LEAVE, NULL, name);
        }
        free (name);
    }
    else
    if (streq (command, "SET")) {
        char *name = zmsg_popstr (request);
        char *value = zmsg_popstr (request);
        zhash_update (self->headers, name, value);
        free (name);
        free (value);
    }
    else
    if (streq (command, "PUBLISH")) {
        char *logical = zmsg_popstr (request);
        char *physical = zmsg_popstr (request);
        //  Virtual filename must start with slash
        assert (logical [0] == '/');
        //  We create symbolic link pointing to real file
        char *symlink = malloc (strlen (logical) + 3);
        sprintf (symlink, "%s.ln", logical + 1);
        fmq_file_t *file = fmq_file_new (self->fmq_outbox, symlink);
        int rc = fmq_file_output (file);
        assert (rc == 0);
        fprintf (fmq_file_handle (file), "%s\n", physical);
        fmq_file_destroy (&file);
        free (symlink);
        free (logical);
        free (physical);
    }
    else
    if (streq (command, "RETRACT")) {
        char *logical = zmsg_popstr (request);
        //  Logical filename must start with slash
        assert (logical [0] == '/');
        //  We create symbolic link pointing to real file
        char *symlink = malloc (strlen (logical) + 3);
        sprintf (symlink, "%s.ln", logical + 1);
        fmq_file_t *file = fmq_file_new (self->fmq_outbox, symlink);
        fmq_file_remove (file);
        free (symlink);
        free (logical);
    }
    free (command);
    zmsg_destroy (&request);
    return 0;
}
コード例 #22
0
ファイル: zyre_node.c プロジェクト: opedroso/zyre
static void
zyre_node_recv_peer (zyre_node_t *self)
{
    //  Router socket tells us the identity of this peer
    zre_msg_t *msg = zre_msg_recv (self->inbox);
    if (!msg)
        return;                 //  Interrupted

    //  First frame is sender identity
    byte *peerid_data = zframe_data (zre_msg_routing_id (msg));
    size_t peerid_size = zframe_size (zre_msg_routing_id (msg));

    //  Identity must be [1] followed by 16-byte UUID
    if (peerid_size != ZUUID_LEN + 1) {
        zre_msg_destroy (&msg);
        return;
    }
    zuuid_t *uuid = zuuid_new ();
    zuuid_set (uuid, peerid_data + 1);

    //  On HELLO we may create the peer if it's unknown
    //  On other commands the peer must already exist
    zyre_peer_t *peer = (zyre_peer_t *) zhash_lookup (self->peers, zuuid_str (uuid));
    if (zre_msg_id (msg) == ZRE_MSG_HELLO) {
        if (peer) {
            //  Remove fake peers
            if (zyre_peer_ready (peer)) {
                zyre_node_remove_peer (self, peer);
                assert (!(zyre_peer_t *) zhash_lookup (self->peers, zuuid_str (uuid)));
            }
            else
            if (streq (zyre_peer_endpoint (peer), self->endpoint)) {
                //  We ignore HELLO, if peer has same endpoint as current node
                zre_msg_destroy (&msg);
                zuuid_destroy (&uuid);
                return;
            }
        }
        peer = zyre_node_require_peer (self, uuid, zre_msg_endpoint (msg));
        assert (peer);
        zyre_peer_set_ready (peer, true);
    }
    //  Ignore command if peer isn't ready
    if (peer == NULL || !zyre_peer_ready (peer)) {
        zre_msg_destroy (&msg);
        zuuid_destroy (&uuid);
        return;
    }
    if (zyre_peer_messages_lost (peer, msg)) {
        zsys_warning ("(%s) messages lost from %s", self->name, zyre_peer_name (peer));
        zyre_node_remove_peer (self, peer);
        zre_msg_destroy (&msg);
        zuuid_destroy (&uuid);
        return;
    }
    //  Now process each command
    if (zre_msg_id (msg) == ZRE_MSG_HELLO) {
        //  Store properties from HELLO command into peer
        zyre_peer_set_name (peer, zre_msg_name (msg));
        zyre_peer_set_headers (peer, zre_msg_headers (msg));

        //  Tell the caller about the peer
        zstr_sendm (self->outbox, "ENTER");
        zstr_sendm (self->outbox, zyre_peer_identity (peer));
        zstr_sendm (self->outbox, zyre_peer_name (peer));
        zframe_t *headers = zhash_pack (zyre_peer_headers (peer));
        zframe_send (&headers, self->outbox, ZFRAME_MORE);
        zstr_send (self->outbox, zre_msg_endpoint (msg));

        if (self->verbose)
            zsys_info ("(%s) ENTER name=%s endpoint=%s",
                self->name, zyre_peer_name (peer), zyre_peer_endpoint (peer));

        //  Join peer to listed groups
        const char *name = zre_msg_groups_first (msg);
        while (name) {
            zyre_node_join_peer_group (self, peer, name);
            name = zre_msg_groups_next (msg);
        }
        //  Now take peer's status from HELLO, after joining groups
        zyre_peer_set_status (peer, zre_msg_status (msg));
    }
    else
    if (zre_msg_id (msg) == ZRE_MSG_WHISPER) {
        //  Pass up to caller API as WHISPER event
        zstr_sendm (self->outbox, "WHISPER");
        zstr_sendm (self->outbox, zuuid_str (uuid));
        zstr_sendm (self->outbox, zyre_peer_name (peer));
        zmsg_t *content = zmsg_dup (zre_msg_content (msg));
        zmsg_send (&content, self->outbox);
    }
    else
    if (zre_msg_id (msg) == ZRE_MSG_SHOUT) {
        //  Pass up to caller as SHOUT event
        zstr_sendm (self->outbox, "SHOUT");
        zstr_sendm (self->outbox, zuuid_str (uuid));
        zstr_sendm (self->outbox, zyre_peer_name (peer));
        zstr_sendm (self->outbox, zre_msg_group (msg));
        zmsg_t *content = zmsg_dup (zre_msg_content (msg));
        zmsg_send (&content, self->outbox);
    }
    else
    if (zre_msg_id (msg) == ZRE_MSG_PING) {
        zre_msg_t *msg = zre_msg_new (ZRE_MSG_PING_OK);
        zyre_peer_send (peer, &msg);
    }
    else
    if (zre_msg_id (msg) == ZRE_MSG_JOIN) {
        zyre_node_join_peer_group (self, peer, zre_msg_group (msg));
        assert (zre_msg_status (msg) == zyre_peer_status (peer));
    }
    else
    if (zre_msg_id (msg) == ZRE_MSG_LEAVE) {
        zyre_node_leave_peer_group (self, peer, zre_msg_group (msg));
        assert (zre_msg_status (msg) == zyre_peer_status (peer));
    }
    zuuid_destroy (&uuid);
    zre_msg_destroy (&msg);

    //  Activity from peer resets peer timers
    zyre_peer_refresh (peer, self->evasive_timeout, self->expired_timeout);
}
コード例 #23
0
ファイル: zyre_node.c プロジェクト: mvala/zyre
static int
zyre_node_recv_api (zyre_node_t *self)
{
    //  Get the whole message off the pipe in one go
    zmsg_t *request = zmsg_recv (self->pipe);
    char *command = zmsg_popstr (request);
    if (!command)
        return -1;                  //  Interrupted

    if (streq (command, "SET NAME")) {
        free (self->name);
        self->name = zmsg_popstr (request);
        assert (self->name);
    }
    else
    if (streq (command, "SET HEADER")) {
        char *name = zmsg_popstr (request);
        char *value = zmsg_popstr (request);
        zhash_update (self->headers, name, value);
        zstr_free (&name);
        zstr_free (&value);
    }
    else
    if (streq (command, "SET VERBOSE"))
        self->verbose = true;
    else
    if (streq (command, "SET PORT")) {
        char *value = zmsg_popstr (request);
        self->beacon_port = atoi (value);
        zstr_free (&value);
    }
    else
    if (streq (command, "SET INTERVAL")) {
        char *value = zmsg_popstr (request);
        self->interval = atol (value);
        zstr_free (&value);
    }
    else
    if (streq (command, "UUID"))
        zstr_send (self->pipe, zuuid_str (self->uuid));
    else
    if (streq (command, "NAME"))
        zstr_send (self->pipe, self->name);
    else
    if (streq (command, "BIND")) {
        char *endpoint = zmsg_popstr (request);
        zsock_signal (self->pipe, zyre_node_bind (self, endpoint));
        zstr_free (&endpoint);
    }
    else
    if (streq (command, "CONNECT")) {
        char *endpoint = zmsg_popstr (request);
        zsock_signal (self->pipe, zyre_node_connect (self, endpoint));
        zstr_free (&endpoint);
    }
    else
    if (streq (command, "START"))
        zsock_signal (self->pipe, zyre_node_start (self));
    else
    if (streq (command, "STOP"))
        zsock_signal (self->pipe, zyre_node_stop (self));
    else
    if (streq (command, "WHISPER")) {
        //  Get peer to send message to
        char *identity = zmsg_popstr (request);
        zyre_peer_t *peer = (zyre_peer_t *) zhash_lookup (self->peers, identity);
        
        //  Send frame on out to peer's mailbox, drop message
        //  if peer doesn't exist (may have been destroyed)
        if (peer) {
            zre_msg_t *msg = zre_msg_new (ZRE_MSG_WHISPER);
            zre_msg_set_content (msg, &request);
            zyre_peer_send (peer, &msg);
        }
        zstr_free (&identity);
    }
    else
    if (streq (command, "SHOUT")) {
        //  Get group to send message to
        char *name = zmsg_popstr (request);
        zyre_group_t *group = (zyre_group_t *) zhash_lookup (self->peer_groups, name);
        if (group) {
            zre_msg_t *msg = zre_msg_new (ZRE_MSG_SHOUT);
            zre_msg_set_group (msg, name);
            zre_msg_set_content (msg, &request);
            zyre_group_send (group, &msg);
        }
        zstr_free (&name);
    }
    else
    if (streq (command, "JOIN")) {
        char *name = zmsg_popstr (request);
        zyre_group_t *group = (zyre_group_t *) zhash_lookup (self->own_groups, name);
        if (!group) {
            //  Only send if we're not already in group
            group = zyre_group_new (name, self->own_groups);
            zre_msg_t *msg = zre_msg_new (ZRE_MSG_JOIN);
            zre_msg_set_group (msg, name);
            //  Update status before sending command
            zre_msg_set_status (msg, ++(self->status));
            zhash_foreach (self->peers, zyre_node_send_peer, msg);
            zre_msg_destroy (&msg);
            if (self->verbose)
                zsys_info ("(%s) JOIN group=%s", self->name, name);
        }
        zstr_free (&name);
    }
    else
    if (streq (command, "LEAVE")) {
        char *name = zmsg_popstr (request);
        zyre_group_t *group = (zyre_group_t *) zhash_lookup (self->own_groups, name);
        if (group) {
            //  Only send if we are actually in group
            zre_msg_t *msg = zre_msg_new (ZRE_MSG_LEAVE);
            zre_msg_set_group (msg, name);
            //  Update status before sending command
            zre_msg_set_status (msg, ++(self->status));
            zhash_foreach (self->peers, zyre_node_send_peer, msg);
            zre_msg_destroy (&msg);
            zhash_delete (self->own_groups, name);
            if (self->verbose)
                zsys_info ("(%s) LEAVE group=%s", self->name, name);
        }
        zstr_free (&name);
    }
    else
    if (streq (command, "DUMP"))
        zyre_node_dump (self);
    else
    if (streq (command, "$TERM"))
        self->terminated = true;
    else {
        zsys_error ("invalid command '%s'\n", command);
        assert (false);
    }
    zstr_free (&command);
    zmsg_destroy (&request);
    return 0;
}
コード例 #24
0
ファイル: zyre_node.c プロジェクト: opedroso/zyre
static void
zyre_node_recv_api (zyre_node_t *self)
{
    //  Get the whole message off the pipe in one go
    zmsg_t *request = zmsg_recv (self->pipe);
    if (!request)
        return;                 //  Interrupted

    char *command = zmsg_popstr (request);
    if (streq (command, "UUID"))
        zstr_send (self->pipe, zuuid_str (self->uuid));
    else
    if (streq (command, "NAME"))
        zstr_send (self->pipe, self->name);
    else
    if (streq (command, "SET NAME")) {
        free (self->name);
        self->name = zmsg_popstr (request);
        assert (self->name);
    }
    else
    if (streq (command, "SET HEADER")) {
        char *name = zmsg_popstr (request);
        char *value = zmsg_popstr (request);
        zhash_update (self->headers, name, value);
        zstr_free (&name);
        zstr_free (&value);
    }
    else
    if (streq (command, "SET VERBOSE"))
        self->verbose = true;
    else
    if (streq (command, "SET PORT")) {
        char *value = zmsg_popstr (request);
        self->beacon_port = atoi (value);
        zstr_free (&value);
    }
    else
    if (streq (command, "SET EVASIVE TIMEOUT")) {
        char *value = zmsg_popstr (request);
        self->evasive_timeout = atoi (value);
        zstr_free (&value);
    }
    else
    if (streq (command, "SET EXPIRED TIMEOUT")) {
        char *value = zmsg_popstr (request);
        self->expired_timeout = atoi (value);
        zstr_free (&value);
    }
    else
    if (streq (command, "SET INTERVAL")) {
        char *value = zmsg_popstr (request);
        self->interval = atol (value);
        zstr_free (&value);
    }
    else
    if (streq (command, "SET ENDPOINT")) {
        zyre_node_gossip_start (self);
        char *endpoint = zmsg_popstr (request);
        if (zsock_bind (self->inbox, "%s", endpoint) != -1) {
            zstr_free (&self->endpoint);
            self->endpoint = endpoint;
            zsock_signal (self->pipe, 0);
        }
        else {
            zstr_free (&endpoint);
            zsock_signal (self->pipe, 1);
        }
    }
    else
    if (streq (command, "GOSSIP BIND")) {
        zyre_node_gossip_start (self);
        zstr_free (&self->gossip_bind);
        self->gossip_bind = zmsg_popstr (request);
        zstr_sendx (self->gossip, "BIND", self->gossip_bind, NULL);
    }
    else
    if (streq (command, "GOSSIP CONNECT")) {
        zyre_node_gossip_start (self);
        zstr_free (&self->gossip_connect);
        self->gossip_connect = zmsg_popstr (request);
        zstr_sendx (self->gossip, "CONNECT", self->gossip_connect, NULL);
    }
    else
    if (streq (command, "START"))
        zsock_signal (self->pipe, zyre_node_start (self));
    else
    if (streq (command, "STOP"))
        zsock_signal (self->pipe, zyre_node_stop (self));
    else
    if (streq (command, "WHISPER")) {
        //  Get peer to send message to
        char *identity = zmsg_popstr (request);
        zyre_peer_t *peer = (zyre_peer_t *) zhash_lookup (self->peers, identity);

        //  Send frame on out to peer's mailbox, drop message
        //  if peer doesn't exist (may have been destroyed)
        if (peer) {
            zre_msg_t *msg = zre_msg_new (ZRE_MSG_WHISPER);
            zre_msg_set_content (msg, &request);
            zyre_peer_send (peer, &msg);
        }
        zstr_free (&identity);
    }
    else
    if (streq (command, "SHOUT")) {
        //  Get group to send message to
        char *name = zmsg_popstr (request);
        zyre_group_t *group = (zyre_group_t *) zhash_lookup (self->peer_groups, name);
        if (group) {
            zre_msg_t *msg = zre_msg_new (ZRE_MSG_SHOUT);
            zre_msg_set_group (msg, name);
            zre_msg_set_content (msg, &request);
            zyre_group_send (group, &msg);
        }
        zstr_free (&name);
    }
    else
    if (streq (command, "JOIN")) {
        char *name = zmsg_popstr (request);
        if (!zlist_exists (self->own_groups, name)) {
            void *item;
            //  Only send if we're not already in group
            zlist_append (self->own_groups, name);
            zre_msg_t *msg = zre_msg_new (ZRE_MSG_JOIN);
            zre_msg_set_group (msg, name);
            //  Update status before sending command
            zre_msg_set_status (msg, ++(self->status));
            for (item = zhash_first (self->peers); item != NULL;
                    item = zhash_next (self->peers))
                zyre_node_send_peer (zhash_cursor (self->peers), item, msg);
            zre_msg_destroy (&msg);
            if (self->verbose)
                zsys_info ("(%s) JOIN group=%s", self->name, name);
        }
        zstr_free (&name);
    }
    else
    if (streq (command, "LEAVE")) {
        char *name = zmsg_popstr (request);
        if (zlist_exists (self->own_groups, name)) {
            void *item;
            //  Only send if we are actually in group
            zre_msg_t *msg = zre_msg_new (ZRE_MSG_LEAVE);
            zre_msg_set_group (msg, name);
            //  Update status before sending command
            zre_msg_set_status (msg, ++(self->status));
            for (item = zhash_first (self->peers); item != NULL;
                    item = zhash_next (self->peers))
                zyre_node_send_peer (zhash_cursor (self->peers), item, msg);
            zre_msg_destroy (&msg);
            zlist_remove (self->own_groups, name);
            if (self->verbose)
                zsys_info ("(%s) LEAVE group=%s", self->name, name);
        }
        zstr_free (&name);
    }
    else
    if (streq (command, "PEERS"))
        zsock_send (self->pipe, "p", zhash_keys (self->peers));
    else
    if (streq (command, "GROUP PEERS")) {
        char *name = zmsg_popstr (request);
        zyre_group_t *group = (zyre_group_t *) zhash_lookup (self->peer_groups, name);
        if (group)
            zsock_send (self->pipe, "p", zyre_group_peers (group));
        else
            zsock_send (self->pipe, "p", NULL);

        zstr_free (&name);
    }
    else
    if (streq (command, "PEER ENDPOINT")) {
        char *uuid = zmsg_popstr (request);
        zyre_peer_t *peer = (zyre_peer_t *) zhash_lookup (self->peers, uuid);
        assert (peer);
        zsock_send (self->pipe, "s", zyre_peer_endpoint (peer));
        zstr_free (&uuid);
    }
    else
    if (streq (command, "PEER NAME")) {
        char *uuid = zmsg_popstr (request);
        zyre_peer_t *peer = (zyre_peer_t *) zhash_lookup (self->peers, uuid);
        assert (peer);
        zsock_send (self->pipe, "s", zyre_peer_name (peer));
        zstr_free (&uuid);
    }
    else
    if (streq (command, "PEER HEADER")) {
        char *uuid = zmsg_popstr (request);
        char *key = zmsg_popstr (request);
        zyre_peer_t *peer = (zyre_peer_t *) zhash_lookup (self->peers, uuid);
        if (!peer)
            zstr_send (self->pipe, "");
        else
            zstr_send (self->pipe, zyre_peer_header (peer, key, NULL));
        zstr_free (&uuid);
        zstr_free (&key);
    }
    else
    if (streq (command, "PEER GROUPS"))
        zsock_send (self->pipe, "p", zhash_keys (self->peer_groups));
    else
    if (streq (command, "OWN GROUPS"))
        zsock_send (self->pipe, "p", zlist_dup (self->own_groups));
    else
    if (streq (command, "DUMP"))
        zyre_node_dump (self);
    else
    if (streq (command, "$TERM"))
        self->terminated = true;
    else {
        zsys_error ("invalid command '%s'", command);
        assert (false);
    }
    zstr_free (&command);
    zmsg_destroy (&request);
}
コード例 #25
0
ファイル: zre_msg.c プロジェクト: karinies/coast
int
zre_msg_test (bool verbose)
{
    printf (" * zre_msg: ");

    //  @selftest
    //  Simple create/destroy test
    zre_msg_t *self = zre_msg_new (0);
    assert (self);
    zre_msg_destroy (&self);

    //  Create pair of sockets we can send through
    zctx_t *ctx = zctx_new ();
    assert (ctx);

    void *output = zsocket_new (ctx, ZMQ_DEALER);
    assert (output);
    zsocket_bind (output, "inproc://selftest");

    void *input = zsocket_new (ctx, ZMQ_ROUTER);
    assert (input);
    zsocket_connect (input, "inproc://selftest");
    
    //  Encode/send/decode and verify each message type
    int instance;
    zre_msg_t *copy;
    self = zre_msg_new (ZRE_MSG_HELLO);
    
    //  Check that _dup works on empty message
    copy = zre_msg_dup (self);
    assert (copy);
    zre_msg_destroy (&copy);

    zre_msg_set_sequence (self, 123);
    zre_msg_set_ipaddress (self, "Life is short but Now lasts for ever");
    zre_msg_set_mailbox (self, 123);
    zre_msg_groups_append (self, "Name: %s", "Brutus");
    zre_msg_groups_append (self, "Age: %d", 43);
    zre_msg_set_status (self, 123);
    zre_msg_headers_insert (self, "Name", "Brutus");
    zre_msg_headers_insert (self, "Age", "%d", 43);
    //  Send twice from same object
    zre_msg_send_again (self, output);
    zre_msg_send (&self, output);

    for (instance = 0; instance < 2; instance++) {
        self = zre_msg_recv (input);
        assert (self);
        assert (zre_msg_routing_id (self));
        
        assert (zre_msg_sequence (self) == 123);
        assert (streq (zre_msg_ipaddress (self), "Life is short but Now lasts for ever"));
        assert (zre_msg_mailbox (self) == 123);
        assert (zre_msg_groups_size (self) == 2);
        assert (streq (zre_msg_groups_first (self), "Name: Brutus"));
        assert (streq (zre_msg_groups_next (self), "Age: 43"));
        assert (zre_msg_status (self) == 123);
        assert (zre_msg_headers_size (self) == 2);
        assert (streq (zre_msg_headers_string (self, "Name", "?"), "Brutus"));
        assert (zre_msg_headers_number (self, "Age", 0) == 43);
        zre_msg_destroy (&self);
    }
    self = zre_msg_new (ZRE_MSG_WHISPER);
    
    //  Check that _dup works on empty message
    copy = zre_msg_dup (self);
    assert (copy);
    zre_msg_destroy (&copy);

    zre_msg_set_sequence (self, 123);
    zmsg_t *whisper_content = zmsg_new ();
    zre_msg_set_content (self, &whisper_content);
    zmsg_addstr (zre_msg_content (self), "Hello, World");
    //  Send twice from same object
    zre_msg_send_again (self, output);
    zre_msg_send (&self, output);

    for (instance = 0; instance < 2; instance++) {
        self = zre_msg_recv (input);
        assert (self);
        assert (zre_msg_routing_id (self));
        
        assert (zre_msg_sequence (self) == 123);
        assert (zmsg_size (zre_msg_content (self)) == 1);
        zre_msg_destroy (&self);
    }
    self = zre_msg_new (ZRE_MSG_SHOUT);
    
    //  Check that _dup works on empty message
    copy = zre_msg_dup (self);
    assert (copy);
    zre_msg_destroy (&copy);

    zre_msg_set_sequence (self, 123);
    zre_msg_set_group (self, "Life is short but Now lasts for ever");
    zmsg_t *shout_content = zmsg_new ();
    zre_msg_set_content (self, &shout_content);
    zmsg_addstr (zre_msg_content (self), "Hello, World");
    //  Send twice from same object
    zre_msg_send_again (self, output);
    zre_msg_send (&self, output);

    for (instance = 0; instance < 2; instance++) {
        self = zre_msg_recv (input);
        assert (self);
        assert (zre_msg_routing_id (self));
        
        assert (zre_msg_sequence (self) == 123);
        assert (streq (zre_msg_group (self), "Life is short but Now lasts for ever"));
        assert (zmsg_size (zre_msg_content (self)) == 1);
        zre_msg_destroy (&self);
    }
    self = zre_msg_new (ZRE_MSG_JOIN);
    
    //  Check that _dup works on empty message
    copy = zre_msg_dup (self);
    assert (copy);
    zre_msg_destroy (&copy);

    zre_msg_set_sequence (self, 123);
    zre_msg_set_group (self, "Life is short but Now lasts for ever");
    zre_msg_set_status (self, 123);
    //  Send twice from same object
    zre_msg_send_again (self, output);
    zre_msg_send (&self, output);

    for (instance = 0; instance < 2; instance++) {
        self = zre_msg_recv (input);
        assert (self);
        assert (zre_msg_routing_id (self));
        
        assert (zre_msg_sequence (self) == 123);
        assert (streq (zre_msg_group (self), "Life is short but Now lasts for ever"));
        assert (zre_msg_status (self) == 123);
        zre_msg_destroy (&self);
    }
    self = zre_msg_new (ZRE_MSG_LEAVE);
    
    //  Check that _dup works on empty message
    copy = zre_msg_dup (self);
    assert (copy);
    zre_msg_destroy (&copy);

    zre_msg_set_sequence (self, 123);
    zre_msg_set_group (self, "Life is short but Now lasts for ever");
    zre_msg_set_status (self, 123);
    //  Send twice from same object
    zre_msg_send_again (self, output);
    zre_msg_send (&self, output);

    for (instance = 0; instance < 2; instance++) {
        self = zre_msg_recv (input);
        assert (self);
        assert (zre_msg_routing_id (self));
        
        assert (zre_msg_sequence (self) == 123);
        assert (streq (zre_msg_group (self), "Life is short but Now lasts for ever"));
        assert (zre_msg_status (self) == 123);
        zre_msg_destroy (&self);
    }
    self = zre_msg_new (ZRE_MSG_PING);
    
    //  Check that _dup works on empty message
    copy = zre_msg_dup (self);
    assert (copy);
    zre_msg_destroy (&copy);

    zre_msg_set_sequence (self, 123);
    //  Send twice from same object
    zre_msg_send_again (self, output);
    zre_msg_send (&self, output);

    for (instance = 0; instance < 2; instance++) {
        self = zre_msg_recv (input);
        assert (self);
        assert (zre_msg_routing_id (self));
        
        assert (zre_msg_sequence (self) == 123);
        zre_msg_destroy (&self);
    }
    self = zre_msg_new (ZRE_MSG_PING_OK);
    
    //  Check that _dup works on empty message
    copy = zre_msg_dup (self);
    assert (copy);
    zre_msg_destroy (&copy);

    zre_msg_set_sequence (self, 123);
    //  Send twice from same object
    zre_msg_send_again (self, output);
    zre_msg_send (&self, output);

    for (instance = 0; instance < 2; instance++) {
        self = zre_msg_recv (input);
        assert (self);
        assert (zre_msg_routing_id (self));
        
        assert (zre_msg_sequence (self) == 123);
        zre_msg_destroy (&self);
    }

    zctx_destroy (&ctx);
    //  @end

    printf ("OK\n");
    return 0;
}
コード例 #26
0
ファイル: zre_msg.c プロジェクト: UIKit0/zyre
int
zre_msg_test (bool verbose)
{
    printf (" * zre_msg: ");

    //  @selftest
    //  Simple create/destroy test
    zre_msg_t *self = zre_msg_new (0);
    assert (self);
    zre_msg_destroy (&self);

    //  Create pair of sockets we can send through
    zctx_t *ctx = zctx_new ();
    assert (ctx);

    void *output = zsocket_new (ctx, ZMQ_DEALER);
    assert (output);
    zsocket_bind (output, "inproc://selftest");
    void *input = zsocket_new (ctx, ZMQ_ROUTER);
    assert (input);
    zsocket_connect (input, "inproc://selftest");
    
    //  Encode/send/decode and verify each message type

    self = zre_msg_new (ZRE_MSG_HELLO);
    zre_msg_set_sequence (self, 123);
    zre_msg_set_ipaddress (self, "Life is short but Now lasts for ever");
    zre_msg_set_mailbox (self, 123);
    zre_msg_groups_append (self, "Name: %s", "Brutus");
    zre_msg_groups_append (self, "Age: %d", 43);
    zre_msg_set_status (self, 123);
    zre_msg_headers_insert (self, "Name", "Brutus");
    zre_msg_headers_insert (self, "Age", "%d", 43);
    zre_msg_send (&self, output);
    
    self = zre_msg_recv (input);
    assert (self);
    assert (zre_msg_sequence (self) == 123);
    assert (streq (zre_msg_ipaddress (self), "Life is short but Now lasts for ever"));
    assert (zre_msg_mailbox (self) == 123);
    assert (zre_msg_groups_size (self) == 2);
    assert (streq (zre_msg_groups_first (self), "Name: Brutus"));
    assert (streq (zre_msg_groups_next (self), "Age: 43"));
    assert (zre_msg_status (self) == 123);
    assert (zre_msg_headers_size (self) == 2);
    assert (streq (zre_msg_headers_string (self, "Name", "?"), "Brutus"));
    assert (zre_msg_headers_number (self, "Age", 0) == 43);
    zre_msg_destroy (&self);

    self = zre_msg_new (ZRE_MSG_WHISPER);
    zre_msg_set_sequence (self, 123);
    zre_msg_set_content (self, zframe_new ("Captcha Diem", 12));
    zre_msg_send (&self, output);
    
    self = zre_msg_recv (input);
    assert (self);
    assert (zre_msg_sequence (self) == 123);
    assert (zframe_streq (zre_msg_content (self), "Captcha Diem"));
    zre_msg_destroy (&self);

    self = zre_msg_new (ZRE_MSG_SHOUT);
    zre_msg_set_sequence (self, 123);
    zre_msg_set_group (self, "Life is short but Now lasts for ever");
    zre_msg_set_content (self, zframe_new ("Captcha Diem", 12));
    zre_msg_send (&self, output);
    
    self = zre_msg_recv (input);
    assert (self);
    assert (zre_msg_sequence (self) == 123);
    assert (streq (zre_msg_group (self), "Life is short but Now lasts for ever"));
    assert (zframe_streq (zre_msg_content (self), "Captcha Diem"));
    zre_msg_destroy (&self);

    self = zre_msg_new (ZRE_MSG_JOIN);
    zre_msg_set_sequence (self, 123);
    zre_msg_set_group (self, "Life is short but Now lasts for ever");
    zre_msg_set_status (self, 123);
    zre_msg_send (&self, output);
    
    self = zre_msg_recv (input);
    assert (self);
    assert (zre_msg_sequence (self) == 123);
    assert (streq (zre_msg_group (self), "Life is short but Now lasts for ever"));
    assert (zre_msg_status (self) == 123);
    zre_msg_destroy (&self);

    self = zre_msg_new (ZRE_MSG_LEAVE);
    zre_msg_set_sequence (self, 123);
    zre_msg_set_group (self, "Life is short but Now lasts for ever");
    zre_msg_set_status (self, 123);
    zre_msg_send (&self, output);
    
    self = zre_msg_recv (input);
    assert (self);
    assert (zre_msg_sequence (self) == 123);
    assert (streq (zre_msg_group (self), "Life is short but Now lasts for ever"));
    assert (zre_msg_status (self) == 123);
    zre_msg_destroy (&self);

    self = zre_msg_new (ZRE_MSG_PING);
    zre_msg_set_sequence (self, 123);
    zre_msg_send (&self, output);
    
    self = zre_msg_recv (input);
    assert (self);
    assert (zre_msg_sequence (self) == 123);
    zre_msg_destroy (&self);

    self = zre_msg_new (ZRE_MSG_PING_OK);
    zre_msg_set_sequence (self, 123);
    zre_msg_send (&self, output);
    
    self = zre_msg_recv (input);
    assert (self);
    assert (zre_msg_sequence (self) == 123);
    zre_msg_destroy (&self);

    zctx_destroy (&ctx);
    //  @end

    printf ("OK\n");
    return 0;
}