Exemplo n.º 1
0
static int
s_agent_handle_control (agent_t *self)
{
    //  Get the whole message off the control socket in one go
    zmsg_t *request = zmsg_recv (self->control);
    char *command = zmsg_popstr (request);
    if (!command)
        return -1;                  //  Interrupted

    if (streq (command, "SET")) {
        char *name = zmsg_popstr (request);
        char *value = zmsg_popstr (request);
        curve_codec_set_metadata (self->codec, name, value);
        free (name);
        free (value);
    }
    else
    if (streq (command, "CONNECT")) {
        assert (!self->endpoint);
        self->endpoint = zmsg_popstr (request);
        int rc = zsocket_connect (self->dealer, "%s", self->endpoint);
        assert (rc != -1);
        zframe_t *server_key = zmsg_pop (request);
        zframe_t *output = curve_codec_execute (self->codec, &server_key);
        zframe_send (&output, self->dealer, 0);
        self->state = connecting;
    }
    else
    if (streq (command, "DISCONNECT")) {
        if (self->endpoint) {
            int rc = zsocket_disconnect (self->dealer, "%s", self->endpoint);
            assert (rc != -1);
            free (self->endpoint);
        }
    }
    else
    if (streq (command, "VERBOSE")) {
        char *verbose = zmsg_popstr (request);
        curve_codec_set_verbose (self->codec, *verbose == '1');
        free (verbose);
    }
    else
    if (streq (command, "TERMINATE")) {
        self->state = terminated;
        zstr_send (self->control, "OK");
    }
    else {
        puts ("E: invalid command from API");
        assert (false);
    }
    free (command);
    zmsg_destroy (&request);
    return 0;
}
Exemplo n.º 2
0
static int
s_agent_handle_router (agent_t *self)
{
    zframe_t *address = zframe_recv (self->router);
    char *hashkey = zframe_strhex (address);
    client_t *client = (client_t *) zhash_lookup (self->clients, hashkey);
    if (client == NULL
    && self->nbr_pending < self->max_pending) {
        client = client_new (self, address);
        client_set_pending (client);
        curve_codec_set_verbose (client->codec, self->verbose);
        zhash_foreach (self->metadata, client_set_metadata, client);
        zhash_insert (self->clients, hashkey, client);
        zhash_freefn (self->clients, hashkey, client_free);
    }
    free (hashkey);
    zframe_destroy (&address);

    //  If we're overloaded, discard client request without any further
    //  ado. The client will have to detect this and retry later.
    //  TODO: retry in client side to handle overloaded servers.
    if (client == NULL)
        return 0;

    //  If not yet connected, process one command frame
    //  We always read one request, and send one reply
    if (client->state == pending) {
        zframe_t *input = zframe_recv (self->router);
        zframe_t *output = curve_codec_execute (client->codec, &input);
        if (output) {
            zframe_send (&client->address, self->router, ZFRAME_MORE + ZFRAME_REUSE);
            zframe_send (&output, self->router, 0);
            if (curve_codec_connected (client->codec))
                client_set_connected (client);
        }
        else
            client_set_exception (client);
    }
    else
    //  If connected, process one message frame
    //  We will queue message frames in the client until we get a
    //  whole message ready to deliver up the data socket -- frames
    //  from different clients will be randomly intermixed.
    if (client->state == connected) {
        zframe_t *encrypted = zframe_recv (self->router);
        zframe_t *cleartext = curve_codec_decode (client->codec, &encrypted);
        if (cleartext) {
            if (client->incoming == NULL)
                client->incoming = zmsg_new ();
            zmsg_add (client->incoming, cleartext);
            if (!zframe_more (cleartext)) {
                zmsg_pushstr (client->incoming, client->hashkey);
                zmsg_send (&client->incoming, self->data);
            }
        }
        else
            client_set_exception (client);
    }
    //  If client is misbehaving, remove it
    if (client->state == exception)
        zhash_delete (self->clients, client->hashkey);

    return 0;
}
Exemplo n.º 3
0
static void *
server_task (void *args)
{
    bool verbose = *((bool *) args);

    //  Install the authenticator
    zctx_t *ctx = zctx_new ();
    zauth_t *auth = zauth_new (ctx);
    assert (auth);
    zauth_set_verbose (auth, verbose);
    zauth_configure_curve (auth, "*", TESTDIR);

    void *router = zsocket_new (ctx, ZMQ_ROUTER);
    int rc = zsocket_bind (router, "tcp://127.0.0.1:9005");
    assert (rc != -1);

    zcert_t *server_cert = zcert_load (TESTDIR "/server.cert");
    assert (server_cert);
    curve_codec_t *server = curve_codec_new_server (server_cert, ctx);
    assert (server);
    zcert_destroy (&server_cert);
    curve_codec_set_verbose (server, verbose);

    //  Set some metadata properties
    curve_codec_set_metadata (server, "Server", "CURVEZMQ/curve_codec");

    //  Execute incoming frames until ready or exception
    //  In practice we'd want a server instance per unique client
    while (!curve_codec_connected (server)) {
        zframe_t *sender = zframe_recv (router);
        zframe_t *input = zframe_recv (router);
        assert (input);
        zframe_t *output = curve_codec_execute (server, &input);
        assert (output);
        zframe_send (&sender, router, ZFRAME_MORE);
        zframe_send (&output, router, 0);
    }
    //  Check client metadata
    char *client_name = (char *) zhash_lookup (curve_codec_metadata (server), "client");
    assert (client_name);
    assert (streq (client_name, "CURVEZMQ/curve_client"));

    bool finished = false;
    while (!finished) {
        //  Now act as echo service doing a full decode and encode
        zframe_t *sender = zframe_recv (router);
        zframe_t *encrypted = zframe_recv (router);
        assert (encrypted);
        zframe_t *cleartext = curve_codec_decode (server, &encrypted);
        assert (cleartext);
        if (memcmp (cleartext, "END", 3) == 0)
            finished = true;
        //  Echo message back
        encrypted = curve_codec_encode (server, &cleartext);
        assert (encrypted);
        zframe_send (&sender, router, ZFRAME_MORE);
        zframe_send (&encrypted, router, 0);
    }
    curve_codec_destroy (&server);
    zauth_destroy (&auth);
    zctx_destroy (&ctx);
    return NULL;
}