Exemple #1
0
//  Execute state machine as long as we have events
static void
server_client_execute (server_t *self, client_t *client, int event)
{
    client->next_event = event;
    while (client->next_event) {
        client->event = client->next_event;
        client->next_event = 0;
        switch (client->state) {
            case start_state:
                if (client->event == ohai_event) {
                    try_anonymous_access (self, client);
                    client->state = checking_client_state;
                }
                else
                if (client->event == heartbeat_event) {
                }
                else
                if (client->event == expired_event) {
                    terminate_the_client (self, client);
                }
                else {
                    //  Process all other events
                    fmq_msg_set_id (client->reply, FMQ_MSG_RTFM);
                    fmq_msg_send (&client->reply, client->router);
                    client->reply = fmq_msg_new (0);
                    fmq_msg_set_address (client->reply, client->address);
                    terminate_the_client (self, client);
                }
                break;

            case checking_client_state:
                if (client->event == friend_event) {
                    fmq_msg_set_id (client->reply, FMQ_MSG_OHAI_OK);
                    fmq_msg_send (&client->reply, client->router);
                    client->reply = fmq_msg_new (0);
                    fmq_msg_set_address (client->reply, client->address);
                    client->state = ready_state;
                }
                else
                if (client->event == foe_event) {
                    fmq_msg_set_id (client->reply, FMQ_MSG_SRSLY);
                    fmq_msg_send (&client->reply, client->router);
                    client->reply = fmq_msg_new (0);
                    fmq_msg_set_address (client->reply, client->address);
                    terminate_the_client (self, client);
                }
                else
                if (client->event == maybe_event) {
                    list_security_mechanisms (self, client);
                    fmq_msg_set_id (client->reply, FMQ_MSG_ORLY);
                    fmq_msg_send (&client->reply, client->router);
                    client->reply = fmq_msg_new (0);
                    fmq_msg_set_address (client->reply, client->address);
                    client->state = challenging_client_state;
                }
                else
                if (client->event == heartbeat_event) {
                }
                else
                if (client->event == expired_event) {
                    terminate_the_client (self, client);
                }
                else
                if (client->event == ohai_event) {
                    try_anonymous_access (self, client);
                    client->state = checking_client_state;
                }
                else {
                    //  Process all other events
                    fmq_msg_set_id (client->reply, FMQ_MSG_RTFM);
                    fmq_msg_send (&client->reply, client->router);
                    client->reply = fmq_msg_new (0);
                    fmq_msg_set_address (client->reply, client->address);
                    terminate_the_client (self, client);
                }
                break;

            case challenging_client_state:
                if (client->event == yarly_event) {
                    try_security_mechanism (self, client);
                    client->state = checking_client_state;
                }
                else
                if (client->event == heartbeat_event) {
                }
                else
                if (client->event == expired_event) {
                    terminate_the_client (self, client);
                }
                else
                if (client->event == ohai_event) {
                    try_anonymous_access (self, client);
                    client->state = checking_client_state;
                }
                else {
                    //  Process all other events
                    fmq_msg_set_id (client->reply, FMQ_MSG_RTFM);
                    fmq_msg_send (&client->reply, client->router);
                    client->reply = fmq_msg_new (0);
                    fmq_msg_set_address (client->reply, client->address);
                    terminate_the_client (self, client);
                }
                break;

            case ready_state:
                if (client->event == icanhaz_event) {
                    store_client_subscription (self, client);
                    fmq_msg_set_id (client->reply, FMQ_MSG_ICANHAZ_OK);
                    fmq_msg_send (&client->reply, client->router);
                    client->reply = fmq_msg_new (0);
                    fmq_msg_set_address (client->reply, client->address);
                }
                else
                if (client->event == nom_event) {
                    store_client_credit (self, client);
                    get_next_patch_for_client (self, client);
                    client->state = dispatching_state;
                }
                else
                if (client->event == hugz_event) {
                    fmq_msg_set_id (client->reply, FMQ_MSG_HUGZ_OK);
                    fmq_msg_send (&client->reply, client->router);
                    client->reply = fmq_msg_new (0);
                    fmq_msg_set_address (client->reply, client->address);
                }
                else
                if (client->event == kthxbai_event) {
                    terminate_the_client (self, client);
                }
                else
                if (client->event == dispatch_event) {
                    get_next_patch_for_client (self, client);
                    client->state = dispatching_state;
                }
                else
                if (client->event == heartbeat_event) {
                    fmq_msg_set_id (client->reply, FMQ_MSG_HUGZ);
                    fmq_msg_send (&client->reply, client->router);
                    client->reply = fmq_msg_new (0);
                    fmq_msg_set_address (client->reply, client->address);
                }
                else
                if (client->event == expired_event) {
                    terminate_the_client (self, client);
                }
                else
                if (client->event == ohai_event) {
                    try_anonymous_access (self, client);
                    client->state = checking_client_state;
                }
                else {
                    //  Process all other events
                    fmq_msg_set_id (client->reply, FMQ_MSG_RTFM);
                    fmq_msg_send (&client->reply, client->router);
                    client->reply = fmq_msg_new (0);
                    fmq_msg_set_address (client->reply, client->address);
                    terminate_the_client (self, client);
                }
                break;

            case dispatching_state:
                if (client->event == send_chunk_event) {
                    fmq_msg_set_id (client->reply, FMQ_MSG_CHEEZBURGER);
                    fmq_msg_send (&client->reply, client->router);
                    client->reply = fmq_msg_new (0);
                    fmq_msg_set_address (client->reply, client->address);
                    get_next_patch_for_client (self, client);
                }
                else
                if (client->event == send_delete_event) {
                    fmq_msg_set_id (client->reply, FMQ_MSG_CHEEZBURGER);
                    fmq_msg_send (&client->reply, client->router);
                    client->reply = fmq_msg_new (0);
                    fmq_msg_set_address (client->reply, client->address);
                    get_next_patch_for_client (self, client);
                }
                else
                if (client->event == next_patch_event) {
                    get_next_patch_for_client (self, client);
                }
                else
                if (client->event == no_credit_event) {
                    client->state = ready_state;
                }
                else
                if (client->event == finished_event) {
                    client->state = ready_state;
                }
                else
                if (client->event == heartbeat_event) {
                }
                else
                if (client->event == expired_event) {
                    terminate_the_client (self, client);
                }
                else
                if (client->event == ohai_event) {
                    try_anonymous_access (self, client);
                    client->state = checking_client_state;
                }
                else {
                    //  Process all other events
                    fmq_msg_set_id (client->reply, FMQ_MSG_RTFM);
                    fmq_msg_send (&client->reply, client->router);
                    client->reply = fmq_msg_new (0);
                    fmq_msg_set_address (client->reply, client->address);
                    terminate_the_client (self, client);
                }
                break;

        }
        if (client->next_event == terminate_event) {
            //  Automatically calls client_destroy
            zhash_delete (self->clients, client->hashkey);
            break;
        }
    }
}
Exemple #2
0
void
fmq_msg_test (bool verbose)
{
    printf (" * fmq_msg:");

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

    //  @selftest
    //  Simple create/destroy test
    fmq_msg_t *self = fmq_msg_new ();
    assert (self);
    fmq_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-fmq_msg");
    assert (rc == 0);

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


    //  Encode/send/decode and verify each message type
    int instance;
    self = fmq_msg_new ();
    fmq_msg_set_id (self, FMQ_MSG_OHAI);

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

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
    }
    fmq_msg_set_id (self, FMQ_MSG_OHAI_OK);

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

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
    }
    fmq_msg_set_id (self, FMQ_MSG_ICANHAZ);

    fmq_msg_set_path (self, "Life is short but Now lasts for ever");
    zhash_t *icanhaz_options = zhash_new ();
    zhash_insert (icanhaz_options, "Name", "Brutus");
    fmq_msg_set_options (self, &icanhaz_options);
    zhash_t *icanhaz_cache = zhash_new ();
    zhash_insert (icanhaz_cache, "Name", "Brutus");
    fmq_msg_set_cache (self, &icanhaz_cache);
    //  Send twice
    fmq_msg_send (self, output);
    fmq_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
        assert (streq (fmq_msg_path (self), "Life is short but Now lasts for ever"));
        zhash_t *options = fmq_msg_get_options (self);
        assert (zhash_size (options) == 2);
        assert (streq ((char *) zhash_first (options), "Brutus"));
        assert (streq ((char *) zhash_cursor (options), "Name"));
        zhash_destroy (&options);
        if (instance == 1)
            zhash_destroy (&icanhaz_options);
        zhash_t *cache = fmq_msg_get_cache (self);
        assert (zhash_size (cache) == 2);
        assert (streq ((char *) zhash_first (cache), "Brutus"));
        assert (streq ((char *) zhash_cursor (cache), "Name"));
        zhash_destroy (&cache);
        if (instance == 1)
            zhash_destroy (&icanhaz_cache);
    }
    fmq_msg_set_id (self, FMQ_MSG_ICANHAZ_OK);

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

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
    }
    fmq_msg_set_id (self, FMQ_MSG_NOM);

    fmq_msg_set_credit (self, 123);
    fmq_msg_set_sequence (self, 123);
    //  Send twice
    fmq_msg_send (self, output);
    fmq_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
        assert (fmq_msg_credit (self) == 123);
        assert (fmq_msg_sequence (self) == 123);
    }
    fmq_msg_set_id (self, FMQ_MSG_CHEEZBURGER);

    fmq_msg_set_sequence (self, 123);
    fmq_msg_set_operation (self, 123);
    fmq_msg_set_filename (self, "Life is short but Now lasts for ever");
    fmq_msg_set_offset (self, 123);
    fmq_msg_set_eof (self, 123);
    zhash_t *cheezburger_headers = zhash_new ();
    zhash_insert (cheezburger_headers, "Name", "Brutus");
    fmq_msg_set_headers (self, &cheezburger_headers);
    zchunk_t *cheezburger_chunk = zchunk_new ("Captcha Diem", 12);
    fmq_msg_set_chunk (self, &cheezburger_chunk);
    //  Send twice
    fmq_msg_send (self, output);
    fmq_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
        assert (fmq_msg_sequence (self) == 123);
        assert (fmq_msg_operation (self) == 123);
        assert (streq (fmq_msg_filename (self), "Life is short but Now lasts for ever"));
        assert (fmq_msg_offset (self) == 123);
        assert (fmq_msg_eof (self) == 123);
        zhash_t *headers = fmq_msg_get_headers (self);
        assert (zhash_size (headers) == 2);
        assert (streq ((char *) zhash_first (headers), "Brutus"));
        assert (streq ((char *) zhash_cursor (headers), "Name"));
        zhash_destroy (&headers);
        if (instance == 1)
            zhash_destroy (&cheezburger_headers);
        assert (memcmp (zchunk_data (fmq_msg_chunk (self)), "Captcha Diem", 12) == 0);
        if (instance == 1)
            zchunk_destroy (&cheezburger_chunk);
    }
    fmq_msg_set_id (self, FMQ_MSG_HUGZ);

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

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
    }
    fmq_msg_set_id (self, FMQ_MSG_HUGZ_OK);

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

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
    }
    fmq_msg_set_id (self, FMQ_MSG_KTHXBAI);

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

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
    }
    fmq_msg_set_id (self, FMQ_MSG_SRSLY);

    fmq_msg_set_reason (self, "Life is short but Now lasts for ever");
    //  Send twice
    fmq_msg_send (self, output);
    fmq_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
        assert (streq (fmq_msg_reason (self), "Life is short but Now lasts for ever"));
    }
    fmq_msg_set_id (self, FMQ_MSG_RTFM);

    fmq_msg_set_reason (self, "Life is short but Now lasts for ever");
    //  Send twice
    fmq_msg_send (self, output);
    fmq_msg_send (self, output);

    for (instance = 0; instance < 2; instance++) {
        fmq_msg_recv (self, input);
        assert (fmq_msg_routing_id (self));
        assert (streq (fmq_msg_reason (self), "Life is short but Now lasts for ever"));
    }

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

    printf ("OK\n");
}
Exemple #3
0
int
fmq_server_test (bool verbose)
{
    printf (" * fmq_server: ");
    fflush (stdout);
    zctx_t *ctx = zctx_new ();
    
    fmq_server_t *self;
    void *dealer = zsocket_new (ctx, ZMQ_DEALER);
    zsocket_set_rcvtimeo (dealer, 2000);
    zsocket_connect (dealer, "tcp://localhost:5670");
    
    fmq_msg_t *request, *reply;
    
    //  Run selftest using '' configuration
    self = fmq_server_new ();
    assert (self);
    int port = fmq_server_bind (self, "tcp://*:5670");
    assert (port == 5670);                            
    request = fmq_msg_new (FMQ_MSG_OHAI);
    fmq_msg_send (&request, dealer);
    reply = fmq_msg_recv (dealer);
    assert (reply);
    assert (fmq_msg_id (reply) == FMQ_MSG_SRSLY);
    fmq_msg_destroy (&reply);

    request = fmq_msg_new (FMQ_MSG_ICANHAZ);
    fmq_msg_send (&request, dealer);
    reply = fmq_msg_recv (dealer);
    assert (reply);
    assert (fmq_msg_id (reply) == FMQ_MSG_RTFM);
    fmq_msg_destroy (&reply);

    request = fmq_msg_new (FMQ_MSG_NOM);
    fmq_msg_send (&request, dealer);
    reply = fmq_msg_recv (dealer);
    assert (reply);
    assert (fmq_msg_id (reply) == FMQ_MSG_RTFM);
    fmq_msg_destroy (&reply);

    request = fmq_msg_new (FMQ_MSG_HUGZ);
    fmq_msg_send (&request, dealer);
    reply = fmq_msg_recv (dealer);
    assert (reply);
    assert (fmq_msg_id (reply) == FMQ_MSG_RTFM);
    fmq_msg_destroy (&reply);

    fmq_server_destroy (&self);
    //  Run selftest using 'anonymous.cfg' configuration
    self = fmq_server_new ();
    assert (self);
    fmq_server_configure (self, "anonymous.cfg");
    port = fmq_server_bind (self, "tcp://*:5670");
    assert (port == 5670);                        
    request = fmq_msg_new (FMQ_MSG_OHAI);
    fmq_msg_send (&request, dealer);
    reply = fmq_msg_recv (dealer);
    assert (reply);
    assert (fmq_msg_id (reply) == FMQ_MSG_OHAI_OK);
    fmq_msg_destroy (&reply);

    request = fmq_msg_new (FMQ_MSG_NOM);
    fmq_msg_send (&request, dealer);

    request = fmq_msg_new (FMQ_MSG_HUGZ);
    fmq_msg_send (&request, dealer);
    reply = fmq_msg_recv (dealer);
    assert (reply);
    assert (fmq_msg_id (reply) == FMQ_MSG_HUGZ_OK);
    fmq_msg_destroy (&reply);

    request = fmq_msg_new (FMQ_MSG_YARLY);
    fmq_msg_send (&request, dealer);
    reply = fmq_msg_recv (dealer);
    assert (reply);
    assert (fmq_msg_id (reply) == FMQ_MSG_RTFM);
    fmq_msg_destroy (&reply);

    fmq_server_destroy (&self);
    //  Run selftest using 'server_test.cfg' configuration
    self = fmq_server_new ();
    assert (self);
    fmq_server_configure (self, "server_test.cfg");
    port = fmq_server_bind (self, "tcp://*:5670");
    assert (port == 5670);                        
    request = fmq_msg_new (FMQ_MSG_OHAI);
    fmq_msg_send (&request, dealer);
    reply = fmq_msg_recv (dealer);
    assert (reply);
    assert (fmq_msg_id (reply) == FMQ_MSG_ORLY);
    fmq_msg_destroy (&reply);

    request = fmq_msg_new (FMQ_MSG_YARLY);
    fmq_msg_set_mechanism (request, "PLAIN");                                
    fmq_msg_set_response (request, fmq_sasl_plain_encode ("guest", "guest"));
    fmq_msg_send (&request, dealer);
    reply = fmq_msg_recv (dealer);
    assert (reply);
    assert (fmq_msg_id (reply) == FMQ_MSG_OHAI_OK);
    fmq_msg_destroy (&reply);

    request = fmq_msg_new (FMQ_MSG_NOM);
    fmq_msg_send (&request, dealer);

    request = fmq_msg_new (FMQ_MSG_HUGZ);
    fmq_msg_send (&request, dealer);
    reply = fmq_msg_recv (dealer);
    assert (reply);
    assert (fmq_msg_id (reply) == FMQ_MSG_HUGZ_OK);
    fmq_msg_destroy (&reply);

    reply = fmq_msg_recv (dealer);
    assert (reply);
    assert (fmq_msg_id (reply) == FMQ_MSG_HUGZ);
    fmq_msg_destroy (&reply);

    fmq_server_destroy (&self);

    zctx_destroy (&ctx);
    //  @end

    //  No clean way to wait for a background thread to exit
    //  Under valgrind this will randomly show as leakage
    //  Reduce this by giving server thread time to exit
    zclock_sleep (200);
    printf ("OK\n");
    return 0;
}
Exemple #4
0
static void
client_execute (client_t *self, int event)
{
    self->next_event = event;
    while (self->next_event) {
        self->event = self->next_event;
        self->next_event = 0;
        switch (self->state) {
            case start_state:
                if (self->event == ready_event) {
                    fmq_msg_id_set (self->request, FMQ_MSG_OHAI);
                    fmq_msg_send (&self->request, self->dealer);
                    self->request = fmq_msg_new (0);
                    self->state = requesting_access_state;
                }
                else
                if (self->event == srsly_event) {
                    log_access_denied (self);
                    terminate_the_client (self);
                    self->state = start_state;
                }
                else
                if (self->event == rtfm_event) {
                    log_invalid_message (self);
                    terminate_the_client (self);
                }
                else {
                    log_protocol_error (self);
                    terminate_the_client (self);
                }
                break;

            case requesting_access_state:
                if (self->event == orly_event) {
                    try_security_mechanism (self);
                    fmq_msg_id_set (self->request, FMQ_MSG_YARLY);
                    fmq_msg_send (&self->request, self->dealer);
                    self->request = fmq_msg_new (0);
                    self->state = requesting_access_state;
                }
                else
                if (self->event == ohai_ok_event) {
                    connected_to_server (self);
                    get_first_subscription (self);
                    self->state = subscribing_state;
                }
                else
                if (self->event == srsly_event) {
                    log_access_denied (self);
                    terminate_the_client (self);
                    self->state = start_state;
                }
                else
                if (self->event == rtfm_event) {
                    log_invalid_message (self);
                    terminate_the_client (self);
                }
                else {
                    log_protocol_error (self);
                    terminate_the_client (self);
                }
                break;

            case subscribing_state:
                if (self->event == ok_event) {
                    fmq_msg_id_set (self->request, FMQ_MSG_ICANHAZ);
                    fmq_msg_send (&self->request, self->dealer);
                    self->request = fmq_msg_new (0);
                    get_next_subscription (self);
                    self->state = subscribing_state;
                }
                else
                if (self->event == finished_event) {
                    refill_credit_as_needed (self);
                    self->state = ready_state;
                }
                else
                if (self->event == srsly_event) {
                    log_access_denied (self);
                    terminate_the_client (self);
                    self->state = start_state;
                }
                else
                if (self->event == rtfm_event) {
                    log_invalid_message (self);
                    terminate_the_client (self);
                }
                else {
                    log_protocol_error (self);
                    terminate_the_client (self);
                }
                break;

            case ready_state:
                if (self->event == cheezburger_event) {
                    process_the_patch (self);
                    refill_credit_as_needed (self);
                }
                else
                if (self->event == hugz_event) {
                    fmq_msg_id_set (self->request, FMQ_MSG_HUGZ_OK);
                    fmq_msg_send (&self->request, self->dealer);
                    self->request = fmq_msg_new (0);
                }
                else
                if (self->event == subscribe_event) {
                    fmq_msg_id_set (self->request, FMQ_MSG_ICANHAZ);
                    fmq_msg_send (&self->request, self->dealer);
                    self->request = fmq_msg_new (0);
                }
                else
                if (self->event == send_credit_event) {
                    fmq_msg_id_set (self->request, FMQ_MSG_NOM);
                    fmq_msg_send (&self->request, self->dealer);
                    self->request = fmq_msg_new (0);
                }
                else
                if (self->event == icanhaz_ok_event) {
                }
                else
                if (self->event == srsly_event) {
                    log_access_denied (self);
                    terminate_the_client (self);
                    self->state = start_state;
                }
                else
                if (self->event == rtfm_event) {
                    log_invalid_message (self);
                    terminate_the_client (self);
                }
                else {
                    log_protocol_error (self);
                    terminate_the_client (self);
                }
                break;

        }
        if (self->next_event == terminate_event) {
            self->stopped = true;
            break;
        }
    }
}