static void server_terminate (server_t *self) { zactor_destroy (&self->mailbox); zhashx_destroy (&self->streams); zhashx_destroy (&self->services); zhashx_destroy (&self->clients); }
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); }
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; }
static void server_terminate (server_t *self) { zgossip_msg_destroy (&self->message); zlistx_destroy (&self->remotes); zhashx_destroy (&self->tuples); }
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 (©); break; } item = item->next; } } } return copy; }
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; } }
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; } }
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 }
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; } }
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; } }
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); }
static void server_terminate (server_t *self) { s_service_destroy (&self->xrap); zhashx_destroy (&self->clients); }
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 (¶meters); // 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"); }
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 (©); // 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 (©); // 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 (©); 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"); }
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; }
/// // Destroy a hash container and all items in it QZhashx::~QZhashx () { zhashx_destroy (&self); }