Beispiel #1
0
static void
server_terminate (server_t *self)
{
    zactor_destroy (&self->mailbox);
    zhashx_destroy (&self->streams);
    zhashx_destroy (&self->services);
    zhashx_destroy (&self->clients);
}
Beispiel #2
0
static void
server_terminate (server_t *self)
{
    zactor_destroy (&self->mailbox);
    zhashx_destroy (&self->streams);
    zhashx_destroy (&self->services);
    zhashx_destroy (&self->clients);
    mlm_msgq_cfg_destroy (&self->service_queue_cfg);
}
Beispiel #3
0
zhashx_t *
zhashx_unpack (zframe_t *frame)
{
    zhashx_t *self = zhashx_new ();
    if (!self)
        return NULL;
    assert (frame);
    if (zframe_size (frame) < 4)
        return self;            //  Arguable...

    byte *needle = zframe_data (frame);
    byte *ceiling = needle + zframe_size (frame);
    size_t nbr_items = ntohl (*(uint32_t *) needle);
    needle += 4;
    while (nbr_items && needle < ceiling) {
        //  Get key as string
        size_t key_size = *needle++;
        if (needle + key_size <= ceiling) {
            char key [256];
            memcpy (key, needle, key_size);
            key [key_size] = 0;
            needle += key_size;

            //  Get value as longstr
            if (needle + 4 <= ceiling) {
                size_t value_size = ntohl (*(uint32_t *) needle);
                needle += 4;
                //  Be wary of malformed frames
                if (needle + value_size <= ceiling) {
                    char *value = (char *) zmalloc (value_size + 1);
                    if (!value) {
                        zhashx_destroy (&self);
                        return NULL;
                    }
                    memcpy (value, needle, value_size);
                    value [value_size] = 0;
                    needle += value_size;

                    //  Hash takes ownership of value
                    if (zhashx_insert (self, key, value)) {
                        zhashx_destroy (&self);
                        break;
                    }
                }
            }
        }
    }
    //  Hash will free values in destructor
    if (self)
        zhashx_autofree (self);
    return self;
}
Beispiel #4
0
static void
server_terminate (server_t *self)
{
    zgossip_msg_destroy (&self->message);
    zlistx_destroy (&self->remotes);
    zhashx_destroy (&self->tuples);
}
Beispiel #5
0
zhashx_t *
zhashx_dup (zhashx_t *self)
{
    if (!self)
        return NULL;

    zhashx_t *copy = zhashx_new ();
    if (copy) {
        copy->destructor = self->destructor;
        copy->duplicator = self->duplicator;
        uint index;
        size_t limit = primes [self->prime_index];
        for (index = 0; index < limit; index++) {
            item_t *item = self->items [index];
            while (item) {
                if (zhashx_insert (copy, item->key, item->value)) {
                    zhashx_destroy (&copy);
                    break;
                }
                item = item->next;
            }
        }
    }
    return copy;
}
Beispiel #6
0
static void
s_self_destroy (self_t **self_p)
{
    assert (self_p);
    if (*self_p) {
        self_t *self = *self_p;
        zhashx_destroy (&self->passwords);
        zhashx_destroy (&self->whitelist);
        zhashx_destroy (&self->blacklist);
        zcertstore_destroy (&self->certstore);
        zpoller_destroy (&self->poller);
        if (self->handler) {
            zsock_unbind (self->handler, ZAP_ENDPOINT);
            zsock_destroy (&self->handler);
        }
        free (self);
        *self_p = NULL;
    }
}
Beispiel #7
0
void
zcertstore_destroy (zcertstore_t **self_p)
{
    assert (self_p);
    if (*self_p) {
        zcertstore_t *self = *self_p;
        zhashx_destroy (&self->certs);
        free (self->location);
        free (self);
        *self_p = NULL;
    }
}
Beispiel #8
0
static void
server_terminate (server_t *self)
{
    zgossip_msg_destroy (&self->message);
    zlistx_destroy (&self->remotes);
    zhashx_destroy (&self->tuples);
    zstr_free (&self->public_key);
    zstr_free (&self->secret_key);
#ifdef CZMQ_BUILD_DRAFT_API
    //  DRAFT-API: Security
    zstr_free (&self->zap_domain);
#endif
}
Beispiel #9
0
void
zcertstore_destroy (zcertstore_t **self_p)
{
    assert (self_p);
    if (*self_p) {
        zcertstore_t *self = *self_p;
        zhashx_destroy (&self->certs);

        if (self->destructor)
            self->destructor (&self->state);

        freen (self);
        *self_p = NULL;
    }
}
Beispiel #10
0
void
zgtask_tree_destroy (zgtask_tree_t **self_p)
{
    assert (self_p);
    if (*self_p) {
        zgtask_tree_t *self = *self_p;

        // Free class properties
        free (self->name);

        zgtask_tree_destroy (&self->child);
        zgtask_tree_destroy (&self->brother);

        // Cleaning net
        zgtask_net_t *net = zgtask_tree_get_net (self);
        if (net) {
            zgtask_net_destroy (&net);
            zhashx_delete (self->data, "net");
        }

        // Cleaning task
        zgtask_task_t *task = zgtask_tree_get_task (self);
        if (task) {
            zgtask_task_destroy (&task);
            zhashx_delete (self->data, "task");
        }

        // Cleaning packet
        zgtask_packet_t *packet = zgtask_tree_get_packet (self);
        if (packet) {
            zgtask_packet_destroy (&packet);
            zhashx_delete (self->data, "packet");
        }

        //  Destroying data table
        zhashx_destroy (&self->data);

        //  Free object itself
        free (self);
        *self_p = NULL;
    }
}
Beispiel #11
0
zhashx_t *
zhashx_new (void)
{
    zhashx_t *self = (zhashx_t *) zmalloc (sizeof (zhashx_t));
    if (self) {
        self->prime_index = INITIAL_PRIME;
        self->chain_limit = INITIAL_CHAIN;
        size_t limit = primes [self->prime_index];
        self->items = (item_t **) zmalloc (sizeof (item_t *) * limit);
        if (self->items) {
            self->hasher = s_bernstein_hash;
            self->key_destructor = (czmq_destructor *) zstr_free;
            self->key_duplicator = (czmq_duplicator *) strdup;
            self->key_comparator = (czmq_comparator *) strcmp;
        }
        else
            zhashx_destroy (&self);
    }
    return self;
}
JNIEXPORT void JNICALL
Java_org_zeromq_czmq_Zhashx__1_1destroy (JNIEnv *env, jclass c, jlong self)
{
    zhashx_destroy ((zhashx_t **) &self);
}
Beispiel #13
0
static void
server_terminate (server_t *self)
{
    s_service_destroy (&self->xrap);
    zhashx_destroy (&self->clients);
}
Beispiel #14
0
void
ztrie_test (bool verbose)
{
    printf (" * ztrie: ");
    //  @selftest
    //  Create a new trie for matching strings that can be tokenized by a slash
    //  (e.g. URLs minus the protocol, address and port).
    ztrie_t *self = ztrie_new ('/');
    assert (self);

    int ret = 0;

    //  Let's start by inserting a couple of routes into the trie.
    //  This one is for the route '/foo/bar' the slash at the beginning of the
    //  route is important because everything before the first delimiter will be
    //  discarded. A slash at the end of a route is optional though. The data
    //  associated with this node is passed without destroy function which means
    //  it must be destroyed by the caller.
    int foo_bar_data = 10;
    ret = ztrie_insert_route (self, "/foo/bar", &foo_bar_data, NULL);
    assert (ret == 0);

    //  Now suppose we like to match all routes with two tokens that start with
    //  '/foo/' but aren't '/foo/bar'. This is possible by using regular
    //  expressions which are enclosed in an opening and closing curly bracket.
    //  Tokens that contain regular  expressions are always match after string
    //  based tokens.
    //  Note: There is no order in which regular expressions are sorted thus
    //  if you enter multiple expressions for a route you will have to make
    //  sure they don't have overlapping results. For example '/foo/{[^/]+}'
    //  and '/foo/{\d+} having could turn out badly.
    int foo_other_data = 100;
    ret = ztrie_insert_route (self, "/foo/{[^/]+}", &foo_other_data, NULL);
    assert (ret == 0);

    //  Regular expression are only matched against tokens of the same level.
    //  This allows us to append to are route with a regular expression as if
    //  it were a string.
    ret = ztrie_insert_route (self, "/foo/{[^/]+}/gulp", NULL, NULL);
    assert (ret == 0);

    //  Routes are identified by their endpoint, which is the last token of the route.
    //  It is possible to insert routes for a node that already exists but isn't an
    //  endpoint yet. The delimiter at the end of a route is optional and has no effect.
    ret = ztrie_insert_route (self, "/foo/", NULL, NULL);
    assert (ret == 0);

    //  If you try to insert a route which already exists the method will return -1.
    ret = ztrie_insert_route (self, "/foo", NULL, NULL);
    assert (ret == -1);

    //  It is not allowed to insert routes with empty tokens.
    ret = ztrie_insert_route (self, "//foo", NULL, NULL);
    assert (ret == -1);

    //  Everything before the first delimiter is ignored so 'foo/bar/baz' is equivalent
    //  to '/bar/baz'.
    ret = ztrie_insert_route (self, "foo/bar/baz", NULL, NULL);
    assert (ret == 0);
    ret = ztrie_insert_route (self, "/bar/baz", NULL, NULL);
    assert (ret == -1);

    //  Of course you are allowed to remove routes, in case there is data associated with a
    //  route and a destroy data function has been supplied that data will be destroyed.
    ret = ztrie_remove_route (self, "/foo");
    assert (ret == 0);

    //  Removing a non existent route will  as well return -1.
    ret = ztrie_remove_route (self, "/foo");
    assert (ret == -1);

    //  Removing a route with a regular expression must exactly match the entered one.
    ret = ztrie_remove_route (self, "/foo/{[^/]+}");
    assert (ret == 0);

    //  Next we like to match a path by regular expressions and also extract matched
    //  parts of a route. This can be done by naming the regular expression. The name of a
    //  regular expression is entered at the beginning of the curly brackets and separated
    //  by a colon from the regular expression. The first one in this examples is named
    //  'name' and names the expression '[^/]'. If there is no capturing group defined in
    //  the expression the whole matched string will be associated with this parameter. In
    //  case you don't like the get the whole matched string use a capturing group, like
    //  it has been done for the 'id' parameter. This is nice but you can even match as
    //  many parameter for a token as you like. Therefore simply put the parameter names
    //  separated by colons in front of the regular expression and make sure to add a
    //  capturing group for each parameter. The first parameter will be associated with
    //  the first capturing and so on.
    char *data = (char *) malloc (80);
    sprintf (data, "%s", "Hello World!");
    ret = ztrie_insert_route (self, "/baz/{name:[^/]+}/{id:--(\\d+)}/{street:nr:(\\a+)(\\d+)}", data, NULL);
    assert (ret == 0);

    //  There is a lot you can do with regular expression but matching routes
    //  of arbitrary length wont work. Therefore we make use of the asterisk
    //  operator. Just place it at the end of your route, e.g. '/config/bar/*'.
    ret = ztrie_insert_route (self, "/config/bar/*", NULL, NULL);
    assert (ret == 0);

    //  Appending to an asterisk as you would to with a regular expression
    //  isn't valid.
    ret = ztrie_insert_route (self, "/config/bar/*/bar", NULL, NULL);
    assert (ret == -1);

    //  The asterisk operator will only work as a leaf in the tree. If you
    //  enter an asterisk in the middle of your route it will simply be
    //  interpreted as a string.
    ret = ztrie_insert_route (self, "/test/*/bar", NULL, NULL);
    assert (ret == 0);

    //  If a parent has an asterisk as child it is not allowed to have
    //  other siblings.
    ret = ztrie_insert_route (self, "/config/bar/foo/glup", NULL, NULL);
    assert (ret != 0);

    //  Test matches
    bool hasMatch = false;

    //  The route '/bar/foo' will fail to match as this route has never been inserted.
    hasMatch = ztrie_matches (self, "/bar/foo");
    assert (!hasMatch);

    //  The route '/foo/bar' will match and we can obtain the data associated with it.
    hasMatch = ztrie_matches (self, "/foo/bar");
    assert (hasMatch);
    int foo_bar_hit_data = *((int *) ztrie_hit_data (self));
    assert (foo_bar_data == foo_bar_hit_data);

    //  This route is part of another but is no endpoint itself thus the matches will fail.
    hasMatch = ztrie_matches (self, "/baz/blub");
    assert (!hasMatch);

    //  This route will match our named regular expressions route. Thus we can extract data
    //  from the route by their names.
    hasMatch = ztrie_matches (self, "/baz/blub/--11/abc23");
    assert (hasMatch);
    char *match_data = (char *) ztrie_hit_data (self);
    assert (streq ("Hello World!", match_data));
    zhashx_t *parameters = ztrie_hit_parameters (self);
    assert (zhashx_size (parameters) == 4);
    assert (streq ("blub", (char *) zhashx_lookup (parameters, "name")));
    assert (streq ("11", (char *) zhashx_lookup (parameters, "id")));
    assert (streq ("abc", (char *) zhashx_lookup (parameters, "street")));
    assert (streq ("23", (char *) zhashx_lookup (parameters, "nr")));
    zhashx_destroy (&parameters);

    //  This will match our asterisk route '/config/bar/*'. As the result we
    //  can obtain the asterisk matched part of the route.
    hasMatch = ztrie_matches (self, "/config/bar/foo/bar");
    assert (hasMatch);
    assert (streq (ztrie_hit_asterisk_match (self), "foo/bar"));

    zstr_free (&data);
    ztrie_destroy (&self);
    //  @end

    printf ("OK\n");
}
Beispiel #15
0
void
zhashx_test (int verbose)
{
    printf (" * zhashx: ");

    //  @selftest
    zhashx_t *hash = zhashx_new ();
    assert (hash);
    assert (zhashx_size (hash) == 0);
    assert (zhashx_first (hash) == NULL);
    assert (zhashx_cursor (hash) == NULL);

    //  Insert some items
    int rc;
    rc = zhashx_insert (hash, "DEADBEEF", "dead beef");
    char *item = (char *) zhashx_first (hash);
    assert (streq ((char *) zhashx_cursor (hash), "DEADBEEF"));
    assert (streq (item, "dead beef"));
    assert (rc == 0);
    rc = zhashx_insert (hash, "ABADCAFE", "a bad cafe");
    assert (rc == 0);
    rc = zhashx_insert (hash, "C0DEDBAD", "coded bad");
    assert (rc == 0);
    rc = zhashx_insert (hash, "DEADF00D", "dead food");
    assert (rc == 0);
    assert (zhashx_size (hash) == 4);

    //  Look for existing items
    item = (char *) zhashx_lookup (hash, "DEADBEEF");
    assert (streq (item, "dead beef"));
    item = (char *) zhashx_lookup (hash, "ABADCAFE");
    assert (streq (item, "a bad cafe"));
    item = (char *) zhashx_lookup (hash, "C0DEDBAD");
    assert (streq (item, "coded bad"));
    item = (char *) zhashx_lookup (hash, "DEADF00D");
    assert (streq (item, "dead food"));

    //  Look for non-existent items
    item = (char *) zhashx_lookup (hash, "foo");
    assert (item == NULL);

    //  Try to insert duplicate items
    rc = zhashx_insert (hash, "DEADBEEF", "foo");
    assert (rc == -1);
    item = (char *) zhashx_lookup (hash, "DEADBEEF");
    assert (streq (item, "dead beef"));

    //  Some rename tests

    //  Valid rename, key is now LIVEBEEF
    rc = zhashx_rename (hash, "DEADBEEF", "LIVEBEEF");
    assert (rc == 0);
    item = (char *) zhashx_lookup (hash, "LIVEBEEF");
    assert (streq (item, "dead beef"));

    //  Trying to rename an unknown item to a non-existent key
    rc = zhashx_rename (hash, "WHATBEEF", "NONESUCH");
    assert (rc == -1);

    //  Trying to rename an unknown item to an existing key
    rc = zhashx_rename (hash, "WHATBEEF", "LIVEBEEF");
    assert (rc == -1);
    item = (char *) zhashx_lookup (hash, "LIVEBEEF");
    assert (streq (item, "dead beef"));

    //  Trying to rename an existing item to another existing item
    rc = zhashx_rename (hash, "LIVEBEEF", "ABADCAFE");
    assert (rc == -1);
    item = (char *) zhashx_lookup (hash, "LIVEBEEF");
    assert (streq (item, "dead beef"));
    item = (char *) zhashx_lookup (hash, "ABADCAFE");
    assert (streq (item, "a bad cafe"));

    //  Test keys method
    zlistx_t *keys = zhashx_keys (hash);
    assert (zlistx_size (keys) == 4);
    zlistx_destroy (&keys);

    zlistx_t *values = zhashx_values(hash);
    assert (zlistx_size (values) == 4);
    zlistx_destroy (&values);

    //  Test dup method
    zhashx_t *copy = zhashx_dup (hash);
    assert (zhashx_size (copy) == 4);
    item = (char *) zhashx_lookup (copy, "LIVEBEEF");
    assert (item);
    assert (streq (item, "dead beef"));
    zhashx_destroy (&copy);

    //  Test pack/unpack methods
    zframe_t *frame = zhashx_pack (hash);
    copy = zhashx_unpack (frame);
    zframe_destroy (&frame);
    assert (zhashx_size (copy) == 4);
    item = (char *) zhashx_lookup (copy, "LIVEBEEF");
    assert (item);
    assert (streq (item, "dead beef"));
    zhashx_destroy (&copy);

    //  Test save and load
    zhashx_comment (hash, "This is a test file");
    zhashx_comment (hash, "Created by %s", "czmq_selftest");
    zhashx_save (hash, ".cache");
    copy = zhashx_new ();
    assert (copy);
    zhashx_load (copy, ".cache");
    item = (char *) zhashx_lookup (copy, "LIVEBEEF");
    assert (item);
    assert (streq (item, "dead beef"));
    zhashx_destroy (&copy);
    zsys_file_delete (".cache");

    //  Delete a item
    zhashx_delete (hash, "LIVEBEEF");
    item = (char *) zhashx_lookup (hash, "LIVEBEEF");
    assert (item == NULL);
    assert (zhashx_size (hash) == 3);

    //  Check that the queue is robust against random usage
    struct {
        char name [100];
        bool exists;
    } testset [200];
    memset (testset, 0, sizeof (testset));
    int testmax = 200, testnbr, iteration;

    srandom ((unsigned) time (NULL));
    for (iteration = 0; iteration < 25000; iteration++) {
        testnbr = randof (testmax);
        if (testset [testnbr].exists) {
            item = (char *) zhashx_lookup (hash, testset [testnbr].name);
            assert (item);
            zhashx_delete (hash, testset [testnbr].name);
            testset [testnbr].exists = false;
        }
        else {
            sprintf (testset [testnbr].name, "%x-%x", rand (), rand ());
            if (zhashx_insert (hash, testset [testnbr].name, "") == 0)
                testset [testnbr].exists = true;
        }
    }
    //  Test 10K lookups
    for (iteration = 0; iteration < 10000; iteration++)
        item = (char *) zhashx_lookup (hash, "DEADBEEFABADCAFE");

    //  Destructor should be safe to call twice
    zhashx_destroy (&hash);
    zhashx_destroy (&hash);
    assert (hash == NULL);

    //  Test autofree; automatically copies and frees string values
    hash = zhashx_new ();
    assert (hash);
    zhashx_autofree (hash);
    char value [255];
    strcpy (value, "This is a string");
    rc = zhashx_insert (hash, "key1", value);
    assert (rc == 0);
    strcpy (value, "Ring a ding ding");
    rc = zhashx_insert (hash, "key2", value);
    assert (rc == 0);
    assert (streq ((char *) zhashx_lookup (hash, "key1"), "This is a string"));
    assert (streq ((char *) zhashx_lookup (hash, "key2"), "Ring a ding ding"));
    zhashx_destroy (&hash);
    //  @end

    printf ("OK\n");
}
Beispiel #16
0
static int
s_self_handle_pipe (self_t *self)
{
    //  Get the whole message off the pipe in one go
    zmsg_t *request = zmsg_recv (self->pipe);
    if (!request)
        return -1;                  //  Interrupted

    char *command = zmsg_popstr (request);
    if (self->verbose)
        zsys_info ("zauth: API command=%s", command);

    if (streq (command, "ALLOW")) {
        char *address = zmsg_popstr (request);
        while (address) {
            if (self->verbose)
                zsys_info ("zauth: - whitelisting ipaddress=%s", address);
            zhashx_insert (self->whitelist, address, "OK");
            zstr_free (&address);
            address = zmsg_popstr (request);
        }
        zsock_signal (self->pipe, 0);
    }
    else
    if (streq (command, "DENY")) {
        char *address = zmsg_popstr (request);
        while (address) {
            if (self->verbose)
                zsys_info ("zauth: - blacklisting ipaddress=%s", address);
            zhashx_insert (self->blacklist, address, "OK");
            zstr_free (&address);
            address = zmsg_popstr (request);
        }
        zsock_signal (self->pipe, 0);
    }
    else
    if (streq (command, "PLAIN")) {
        //  Get password file and load into zhash table
        //  If the file doesn't exist we'll get an empty table
        char *filename = zmsg_popstr (request);
        zhashx_destroy (&self->passwords);
        self->passwords = zhashx_new ();
        if (zhashx_load (self->passwords, filename) && self->verbose)
            zsys_info ("zauth: could not load file=%s", filename);
        zstr_free (&filename);
        zsock_signal (self->pipe, 0);
    }
    else
    if (streq (command, "CURVE")) {
        //  If location is CURVE_ALLOW_ANY, allow all clients. Otherwise
        //  treat location as a directory that holds the certificates.
        char *location = zmsg_popstr (request);
        if (streq (location, CURVE_ALLOW_ANY))
            self->allow_any = true;
        else {
            zcertstore_destroy (&self->certstore);
            // FIXME: what if this fails?
            self->certstore = zcertstore_new (location);
            self->allow_any = false;
        }
        zstr_free (&location);
        zsock_signal (self->pipe, 0);
    }
    else
    if (streq (command, "GSSAPI"))
        //  GSSAPI authentication is not yet implemented here
        zsock_signal (self->pipe, 0);
    else
    if (streq (command, "VERBOSE")) {
        self->verbose = true;
        zsock_signal (self->pipe, 0);
    }
    else
    if (streq (command, "$TERM"))
        self->terminated = true;
    else {
        zsys_error ("zauth: - invalid command: %s", command);
        assert (false);
    }
    zstr_free (&command);
    zmsg_destroy (&request);
    return 0;
}
Beispiel #17
0
///
//  Destroy a hash container and all items in it
QZhashx::~QZhashx ()
{
    zhashx_destroy (&self);
}