示例#1
0
文件: zgossip.c 项目: Cargo-Labs/czmq
static void
server_connect (server_t *self, const char *endpoint)
{
    zsock_t *remote = zsock_new (ZMQ_DEALER);
    assert (remote);          //  No recovery if exhausted

    //  Never block on sending; we use an infinite HWM and buffer as many
    //  messages as needed in outgoing pipes. Note that the maximum number
    //  is the overall tuple set size.
    zsock_set_unbounded (remote);
    if (zsock_connect (remote, "%s", endpoint)) {
        zsys_warning ("bad zgossip endpoint '%s'", endpoint);
        zsock_destroy (&remote);
        return;
    }
    //  Send HELLO and then PUBLISH for each tuple we have
    zgossip_msg_t *gossip = zgossip_msg_new ();
    zgossip_msg_set_id (gossip, ZGOSSIP_MSG_HELLO);
    zgossip_msg_send (gossip, remote);
    
    tuple_t *tuple = (tuple_t *) zhashx_first (self->tuples);
    while (tuple) {
        zgossip_msg_set_id (gossip, ZGOSSIP_MSG_PUBLISH);
        zgossip_msg_set_key (gossip, tuple->key);
        zgossip_msg_set_value (gossip, tuple->value);
        zgossip_msg_send (gossip, remote);
        tuple = (tuple_t *) zhashx_next (self->tuples);
    }
    //  Now monitor this remote for incoming messages
    zgossip_msg_destroy (&gossip);
    engine_handle_socket (self, remote, remote_handler);
    zlistx_add_end (self->remotes, remote);
}
示例#2
0
文件: zgossip.c 项目: taotetek/czmq
server_connect (server_t *self, const char *endpoint)
#endif
{
    zsock_t *remote = zsock_new (ZMQ_DEALER);
    assert (remote);          //  No recovery if exhausted

#ifdef CZMQ_BUILD_DRAFT_API
    //  DRAFT-API: Security
    if (public_key){
        zcert_t *cert = zcert_new_from_txt (self->public_key, self->secret_key);
        zcert_apply(cert, remote);
        zsock_set_curve_serverkey (remote, public_key);
#ifndef ZMQ_CURVE
        // legacy ZMQ support
        // inline incase the underlying assert is removed
        bool ZMQ_CURVE = false;
#endif
        assert (zsock_mechanism (remote) == ZMQ_CURVE);
        zcert_destroy(&cert);
    }
#endif
    //  Never block on sending; we use an infinite HWM and buffer as many
    //  messages as needed in outgoing pipes. Note that the maximum number
    //  is the overall tuple set size.
    zsock_set_unbounded (remote);

    if (zsock_connect (remote, "%s", endpoint)) {
        zsys_warning ("bad zgossip endpoint '%s'", endpoint);
        zsock_destroy (&remote);
        return;
    }
    //  Send HELLO and then PUBLISH for each tuple we have
    zgossip_msg_t *gossip = zgossip_msg_new ();
    zgossip_msg_set_id (gossip, ZGOSSIP_MSG_HELLO);
    zgossip_msg_send (gossip, remote);

    tuple_t *tuple = (tuple_t *) zhashx_first (self->tuples);
    while (tuple) {
        zgossip_msg_set_id (gossip, ZGOSSIP_MSG_PUBLISH);
        zgossip_msg_set_key (gossip, tuple->key);
        zgossip_msg_set_value (gossip, tuple->value);
        zgossip_msg_send (gossip, remote);
        tuple = (tuple_t *) zhashx_next (self->tuples);
    }
    //  Now monitor this remote for incoming messages
    zgossip_msg_destroy (&gossip);
    engine_handle_socket (self, remote, remote_handler);
    zlistx_add_end (self->remotes, remote);
}
示例#3
0
文件: zgossip.c 项目: Cargo-Labs/czmq
static int
remote_handler (zloop_t *loop, zsock_t *remote, void *argument)
{
    server_t *self = (server_t *) argument;
    if (zgossip_msg_recv (self->message, remote))
        return -1;          //  Interrupted

    if (zgossip_msg_id (self->message) == ZGOSSIP_MSG_PUBLISH)
        server_accept (self,
                       zgossip_msg_key (self->message),
                       zgossip_msg_value (self->message));
    else
    if (zgossip_msg_id (self->message) == ZGOSSIP_MSG_INVALID) {
        //  Connection was reset, so send HELLO again
        zgossip_msg_set_id (self->message, ZGOSSIP_MSG_HELLO);
        zgossip_msg_send (self->message, remote);
    }
    else
    if (zgossip_msg_id (self->message) == ZGOSSIP_MSG_PONG)
        assert (true);   //  Do nothing with PONGs

    return 0;
}
示例#4
0
文件: zgossip.c 项目: Cargo-Labs/czmq
static void
server_accept (server_t *self, const char *key, const char *value)
{
    tuple_t *tuple = (tuple_t *) zhashx_lookup (self->tuples, key);
    if (tuple && streq (tuple->value, value))
        return;                 //  Duplicate tuple, do nothing

    //  Create new tuple
    tuple = (tuple_t *) zmalloc (sizeof (tuple_t));
    assert (tuple);
    tuple->container = self->tuples;
    tuple->key = strdup (key);
    tuple->value = strdup (value);

    //  Store new tuple
    zhashx_update (tuple->container, key, tuple);
    zhashx_freefn (tuple->container, key, tuple_free);

    //  Deliver to calling application
    zstr_sendx (self->pipe, "DELIVER", key, value, NULL);

    //  Hold in server context so we can broadcast to all clients
    self->cur_tuple = tuple;
    engine_broadcast_event (self, NULL, forward_event);

    //  Copy new tuple announcement to all remotes
    zgossip_msg_t *gossip = zgossip_msg_new ();
    zgossip_msg_set_id (gossip, ZGOSSIP_MSG_PUBLISH);
    zsock_t *remote = (zsock_t *) zlistx_first (self->remotes);
    while (remote) {
        zgossip_msg_set_key (gossip, tuple->key);
        zgossip_msg_set_value (gossip, tuple->value);
        zgossip_msg_send (gossip, remote);
        remote = (zsock_t *) zlistx_next (self->remotes);
    }
    zgossip_msg_destroy (&gossip);
}
示例#5
0
文件: zgossip.c 项目: Cargo-Labs/czmq
void
zgossip_test (bool verbose)
{
    printf (" * zgossip: ");
    if (verbose)
        printf ("\n");

    //  @selftest
    //  Test basic client-to-server operation of the protocol
    zactor_t *server = zactor_new (zgossip, "server");
    assert (server);
    if (verbose)
        zstr_send (server, "VERBOSE");
    zstr_sendx (server, "BIND", "inproc://zgossip", NULL);

    zsock_t *client = zsock_new (ZMQ_DEALER);
    assert (client);
    zsock_set_rcvtimeo (client, 2000);
    int rc = zsock_connect (client, "inproc://zgossip");
    assert (rc == 0);
    
    //  Send HELLO, which gets no message
    zgossip_msg_t *message = zgossip_msg_new ();
    zgossip_msg_set_id (message, ZGOSSIP_MSG_HELLO);
    zgossip_msg_send (message, client);

    //  Send PING, expect PONG back
    zgossip_msg_set_id (message, ZGOSSIP_MSG_PING);
    zgossip_msg_send (message, client);
    zgossip_msg_recv (message, client);
    assert (zgossip_msg_id (message) == ZGOSSIP_MSG_PONG);
    zgossip_msg_destroy (&message);
    
    zactor_destroy (&server);
    zsock_destroy (&client);

    //  Test peer-to-peer operations
    zactor_t *base = zactor_new (zgossip, "base");
    assert (base);
    if (verbose)
        zstr_send (base, "VERBOSE");
    //  Set a 100msec timeout on clients so we can test expiry
    zstr_sendx (base, "SET", "server/timeout", "100", NULL);
    zstr_sendx (base, "BIND", "inproc://base", NULL);

    zactor_t *alpha = zactor_new (zgossip, "alpha");
    assert (alpha);
    zstr_sendx (alpha, "CONNECT", "inproc://base", NULL);
    zstr_sendx (alpha, "PUBLISH", "inproc://alpha-1", "service1", NULL);
    zstr_sendx (alpha, "PUBLISH", "inproc://alpha-2", "service2", NULL);

    zactor_t *beta = zactor_new (zgossip, "beta");
    assert (beta);
    zstr_sendx (beta, "CONNECT", "inproc://base", NULL);
    zstr_sendx (beta, "PUBLISH", "inproc://beta-1", "service1", NULL);
    zstr_sendx (beta, "PUBLISH", "inproc://beta-2", "service2", NULL);

    //  got nothing
    zclock_sleep (200);

    zactor_destroy (&base);
    zactor_destroy (&alpha);
    zactor_destroy (&beta);

    //  @end
    printf ("OK\n");
}
示例#6
0
void
zgossip_msg_test (bool verbose)
{
    printf (" * zgossip_msg:");

    if (verbose)
        printf ("\n");

    //  @selftest
    //  Simple create/destroy test
    zgossip_msg_t *self = zgossip_msg_new ();
    assert (self);
    zgossip_msg_destroy (&self);
    //  Create pair of sockets we can send through
    //  We must bind before connect if we wish to remain compatible with ZeroMQ < v4
    zsock_t *output = zsock_new (ZMQ_DEALER);
    assert (output);
    int rc = zsock_bind (output, "inproc://selftest-zgossip_msg");
    assert (rc == 0);

    zsock_t *input = zsock_new (ZMQ_ROUTER);
    assert (input);
    rc = zsock_connect (input, "inproc://selftest-zgossip_msg");
    assert (rc == 0);


    //  Encode/send/decode and verify each message type
    int instance;
    self = zgossip_msg_new ();
    zgossip_msg_set_id (self, ZGOSSIP_MSG_HELLO);

    //  Send twice
    zgossip_msg_send (self, output);
    zgossip_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        zgossip_msg_recv (self, input);
        assert (zgossip_msg_routing_id (self));
    }
    zgossip_msg_set_id (self, ZGOSSIP_MSG_PUBLISH);

    zgossip_msg_set_key (self, "Life is short but Now lasts for ever");
    zgossip_msg_set_value (self, "Life is short but Now lasts for ever");
    zgossip_msg_set_ttl (self, 123);
    //  Send twice
    zgossip_msg_send (self, output);
    zgossip_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        zgossip_msg_recv (self, input);
        assert (zgossip_msg_routing_id (self));
        assert (streq (zgossip_msg_key (self), "Life is short but Now lasts for ever"));
        assert (streq (zgossip_msg_value (self), "Life is short but Now lasts for ever"));
        assert (zgossip_msg_ttl (self) == 123);
    }
    zgossip_msg_set_id (self, ZGOSSIP_MSG_PING);

    //  Send twice
    zgossip_msg_send (self, output);
    zgossip_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        zgossip_msg_recv (self, input);
        assert (zgossip_msg_routing_id (self));
    }
    zgossip_msg_set_id (self, ZGOSSIP_MSG_PONG);

    //  Send twice
    zgossip_msg_send (self, output);
    zgossip_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        zgossip_msg_recv (self, input);
        assert (zgossip_msg_routing_id (self));
    }
    zgossip_msg_set_id (self, ZGOSSIP_MSG_INVALID);

    //  Send twice
    zgossip_msg_send (self, output);
    zgossip_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        zgossip_msg_recv (self, input);
        assert (zgossip_msg_routing_id (self));
    }

    zgossip_msg_destroy (&self);
    zsock_destroy (&input);
    zsock_destroy (&output);
    //  @end

    printf ("OK\n");
}
示例#7
0
文件: zgossip.c 项目: taotetek/czmq
void
zgossip_test (bool verbose)
{
    printf (" * zgossip: ");
    if (verbose)
        printf ("\n");

    //  @selftest
    //  Test basic client-to-server operation of the protocol
    zactor_t *server = zactor_new (zgossip, "server");
    assert (server);
    if (verbose)
        zstr_send (server, "VERBOSE");
    zstr_sendx (server, "BIND", "inproc://zgossip", NULL);

    zsock_t *client = zsock_new (ZMQ_DEALER);
    assert (client);
    zsock_set_rcvtimeo (client, 2000);
    int rc = zsock_connect (client, "inproc://zgossip");
    assert (rc == 0);

    //  Send HELLO, which gets no message
    zgossip_msg_t *message = zgossip_msg_new ();
    zgossip_msg_set_id (message, ZGOSSIP_MSG_HELLO);
    zgossip_msg_send (message, client);

    //  Send PING, expect PONG back
    zgossip_msg_set_id (message, ZGOSSIP_MSG_PING);
    zgossip_msg_send (message, client);
    zgossip_msg_recv (message, client);
    assert (zgossip_msg_id (message) == ZGOSSIP_MSG_PONG);
    zgossip_msg_destroy (&message);

    zactor_destroy (&server);
    zsock_destroy (&client);

    //  Test peer-to-peer operations
    zactor_t *base = zactor_new (zgossip, "base");
    assert (base);
    if (verbose)
        zstr_send (base, "VERBOSE");
    //  Set a 100msec timeout on clients so we can test expiry
    zstr_sendx (base, "SET", "server/timeout", "100", NULL);
    zstr_sendx (base, "BIND", "inproc://base", NULL);

    zactor_t *alpha = zactor_new (zgossip, "alpha");
    assert (alpha);
    zstr_sendx (alpha, "CONNECT", "inproc://base", NULL);
    zstr_sendx (alpha, "PUBLISH", "inproc://alpha-1", "service1", NULL);
    zstr_sendx (alpha, "PUBLISH", "inproc://alpha-2", "service2", NULL);

    zactor_t *beta = zactor_new (zgossip, "beta");
    assert (beta);
    zstr_sendx (beta, "CONNECT", "inproc://base", NULL);
    zstr_sendx (beta, "PUBLISH", "inproc://beta-1", "service1", NULL);
    zstr_sendx (beta, "PUBLISH", "inproc://beta-2", "service2", NULL);

    //  got nothing
    zclock_sleep (200);

    zstr_send (alpha, "STATUS");
    char *command, *status, *key, *value;

    zstr_recvx (alpha, &command, &key, &value, NULL);
    assert (streq (command, "DELIVER"));
    assert (streq (key, "inproc://alpha-1"));
    assert (streq (value, "service1"));
    zstr_free (&command);
    zstr_free (&key);
    zstr_free (&value);

    zstr_recvx (alpha, &command, &key, &value, NULL);
    assert (streq (command, "DELIVER"));
    assert (streq (key, "inproc://alpha-2"));
    assert (streq (value, "service2"));
    zstr_free (&command);
    zstr_free (&key);
    zstr_free (&value);

    zstr_recvx (alpha, &command, &key, &value, NULL);
    assert (streq (command, "DELIVER"));
    assert (streq (key, "inproc://beta-1"));
    assert (streq (value, "service1"));
    zstr_free (&command);
    zstr_free (&key);
    zstr_free (&value);

    zstr_recvx (alpha, &command, &key, &value, NULL);
    assert (streq (command, "DELIVER"));
    assert (streq (key, "inproc://beta-2"));
    assert (streq (value, "service2"));
    zstr_free (&command);
    zstr_free (&key);
    zstr_free (&value);

    zstr_recvx (alpha, &command, &status, NULL);
    assert (streq (command, "STATUS"));
    assert (atoi (status) == 4);
    zstr_free (&command);
    zstr_free (&status);

    zactor_destroy (&base);
    zactor_destroy (&alpha);
    zactor_destroy (&beta);

#ifdef CZMQ_BUILD_DRAFT_API
    //  DRAFT-API: Security
    // curve
    if (zsys_has_curve()) {
        if (verbose)
            printf("testing CURVE support");
        zclock_sleep (2000);
        zactor_t *auth = zactor_new(zauth, NULL);
        assert (auth);
        if (verbose) {
            zstr_sendx (auth, "VERBOSE", NULL);
            zsock_wait (auth);
        }
        zstr_sendx(auth,"ALLOW","127.0.0.1",NULL);
        zsock_wait(auth);
        zstr_sendx (auth, "CURVE", CURVE_ALLOW_ANY, NULL);
        zsock_wait (auth);

        server = zactor_new (zgossip, "server");
        if (verbose)
            zstr_send (server, "VERBOSE");
        assert (server);

        zcert_t *client1_cert = zcert_new ();
        zcert_t *server_cert = zcert_new ();

        zstr_sendx (server, "SET PUBLICKEY", zcert_public_txt (server_cert), NULL);
        zstr_sendx (server, "SET SECRETKEY", zcert_secret_txt (server_cert), NULL);
        zstr_sendx (server, "ZAP DOMAIN", "TEST", NULL);

        zstr_sendx (server, "BIND", "tcp://127.0.0.1:*", NULL);
        zstr_sendx (server, "PORT", NULL);
        zstr_recvx (server, &command, &value, NULL);
        assert (streq (command, "PORT"));
        int port = atoi (value);
        zstr_free (&command);
        zstr_free (&value);
        char endpoint [32];
        sprintf (endpoint, "tcp://127.0.0.1:%d", port);

        zactor_t *client1 = zactor_new (zgossip, "client");
        if (verbose)
            zstr_send (client1, "VERBOSE");
        assert (client1);

        zstr_sendx (client1, "SET PUBLICKEY", zcert_public_txt (client1_cert), NULL);
        zstr_sendx (client1, "SET SECRETKEY", zcert_secret_txt (client1_cert), NULL);
        zstr_sendx (client1, "ZAP DOMAIN", "TEST", NULL);

        const char *public_txt = zcert_public_txt (server_cert);
        zstr_sendx (client1, "CONNECT", endpoint, public_txt, NULL);
        zstr_sendx (client1, "PUBLISH", "tcp://127.0.0.1:9001", "service1", NULL);

        zclock_sleep (500);

        zstr_send (server, "STATUS");
        zclock_sleep (500);

        zstr_recvx (server, &command, &key, &value, NULL);
        assert (streq (command, "DELIVER"));
        assert (streq (value, "service1"));

        zstr_free (&command);
        zstr_free (&key);
        zstr_free (&value);

        zstr_sendx (client1, "$TERM", NULL);
        zstr_sendx (server, "$TERM", NULL);

        zclock_sleep(500);

        zcert_destroy (&client1_cert);
        zcert_destroy (&server_cert);

        zactor_destroy (&client1);
        zactor_destroy (&server);
        zactor_destroy (&auth);
    }
#endif

#if defined (__WINDOWS__)
    zsys_shutdown();
#endif

    //  @end
    printf ("OK\n");
}