diff options
Diffstat (limited to 'src/messenger/gnunet-service-messenger_ego_store.c')
-rw-r--r-- | src/messenger/gnunet-service-messenger_ego_store.c | 274 |
1 files changed, 223 insertions, 51 deletions
diff --git a/src/messenger/gnunet-service-messenger_ego_store.c b/src/messenger/gnunet-service-messenger_ego_store.c index c460ac1c7..3eb313b08 100644 --- a/src/messenger/gnunet-service-messenger_ego_store.c +++ b/src/messenger/gnunet-service-messenger_ego_store.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2020--2021 GNUnet e.V. + Copyright (C) 2020--2022 GNUnet e.V. GNUnet is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published @@ -23,6 +23,7 @@ * @brief GNUnet MESSENGER service */ +#include "platform.h" #include "gnunet-service-messenger_ego_store.h" #include "gnunet-service-messenger_handle.h" @@ -33,14 +34,21 @@ callback_update_ego (void *cls, void **ctx, const char *identifier) { - if ((!ego) || (!identifier)) + if ((!ctx) || (!identifier)) return; struct GNUNET_MESSENGER_EgoStore *store = cls; - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "New ego in use: '%s'\n", identifier); - - update_store_ego (store, identifier, GNUNET_IDENTITY_ego_get_private_key (ego)); + if (ego) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New ego in use: '%s'\n", identifier); + update_store_ego (store, identifier, GNUNET_IDENTITY_ego_get_private_key (ego)); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego got deleted: '%s'\n", identifier); + delete_store_ego (store, identifier); + } } void @@ -52,6 +60,7 @@ init_ego_store(struct GNUNET_MESSENGER_EgoStore *store, store->cfg = config; store->identity = GNUNET_IDENTITY_connect (config, &callback_update_ego, store); store->egos = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); + store->handles = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); store->lu_start = NULL; store->lu_end = NULL; @@ -60,7 +69,6 @@ init_ego_store(struct GNUNET_MESSENGER_EgoStore *store, store->op_end = NULL; } - static int iterate_destroy_egos (void *cls, const struct GNUNET_HashCode *key, @@ -109,6 +117,8 @@ clear_ego_store(struct GNUNET_MESSENGER_EgoStore *store) GNUNET_CONTAINER_multihashmap_iterate (store->egos, iterate_destroy_egos, NULL); GNUNET_CONTAINER_multihashmap_destroy (store->egos); + GNUNET_CONTAINER_multihashmap_destroy (store->handles); + if (store->identity) { GNUNET_IDENTITY_disconnect (store->identity); @@ -117,29 +127,44 @@ clear_ego_store(struct GNUNET_MESSENGER_EgoStore *store) } } +static int +iterate_create_ego (void *cls, + const struct GNUNET_HashCode *key, + void *value) +{ + struct GNUNET_MESSENGER_SrvHandle *handle = value; + set_srv_handle_ego (handle, (struct GNUNET_MESSENGER_Ego*) cls); + return GNUNET_YES; +} + static void callback_ego_create (void *cls, const struct GNUNET_IDENTITY_PrivateKey *key, - const char *emsg) + enum GNUNET_ErrorCode ec) { struct GNUNET_MESSENGER_EgoOperation *element = cls; struct GNUNET_MESSENGER_EgoStore *store = element->store; - GNUNET_assert(element->identifier); + GNUNET_assert (element->identifier); - if (emsg) - GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s\n", emsg); + /** + * FIXME: This is dangerous, please handle errors + */ + if (GNUNET_EC_NONE != ec) + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%s\n", + GNUNET_ErrorCode_get_hint (ec)); if (key) { - struct GNUNET_MESSENGER_SrvHandle *handle = element->handle; - struct GNUNET_MESSENGER_Ego *msg_ego = update_store_ego (store, element->identifier, key); - set_handle_ego (handle, msg_ego); + struct GNUNET_HashCode hash; + GNUNET_CRYPTO_hash (element->identifier, strlen (element->identifier), &hash); + + GNUNET_CONTAINER_multihashmap_get_multiple (store->handles, &hash, iterate_create_ego, msg_ego); } else - GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Creating ego failed!\n"); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Creating ego failed!\n"); GNUNET_CONTAINER_DLL_remove (store->op_start, store->op_end, element); GNUNET_free (element->identifier); @@ -148,24 +173,70 @@ callback_ego_create (void *cls, void create_store_ego (struct GNUNET_MESSENGER_EgoStore *store, - const char *identifier, - void *handle) + const char *identifier) { GNUNET_assert ((store) && (identifier)); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Store create ego: %s\n", identifier); + struct GNUNET_MESSENGER_EgoOperation *element = GNUNET_new (struct GNUNET_MESSENGER_EgoOperation); element->store = store; - element->handle = handle; + element->cls = NULL; element->identifier = GNUNET_strdup (identifier); - element->operation = GNUNET_IDENTITY_create (store->identity, identifier, NULL, - GNUNET_IDENTITY_TYPE_ECDSA, callback_ego_create, element); + element->operation = GNUNET_IDENTITY_create ( + store->identity, + identifier, + NULL, + GNUNET_IDENTITY_TYPE_ECDSA, + callback_ego_create, + element + ); GNUNET_CONTAINER_DLL_insert (store->op_start, store->op_end, element); } +void +bind_store_ego (struct GNUNET_MESSENGER_EgoStore *store, + const char *identifier, + void *handle) +{ + GNUNET_assert ((store) && (identifier) && (handle)); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Store bind ego: %s\n", identifier); + + struct GNUNET_HashCode hash; + GNUNET_CRYPTO_hash (identifier, strlen (identifier), &hash); + + if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains_value(store->handles, &hash, handle)) + return; + + if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(store->handles, &hash, handle, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)) + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Putting handle binding to ego store failed!\n"); +} + +void +unbind_store_ego (struct GNUNET_MESSENGER_EgoStore *store, + const char *identifier, + void *handle) +{ + GNUNET_assert ((store) && (identifier) && (handle)); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Store unbind ego: %s\n", identifier); + + struct GNUNET_HashCode hash; + GNUNET_CRYPTO_hash (identifier, strlen (identifier), &hash); + + if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains_value(store->handles, &hash, handle)) + return; + + if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove(store->handles, &hash, handle)) + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Removing handle binding from ego store failed!\n"); +} + static void callback_ego_lookup (void *cls, struct GNUNET_IDENTITY_Ego *ego) @@ -173,16 +244,30 @@ callback_ego_lookup (void *cls, struct GNUNET_MESSENGER_EgoLookup *element = cls; struct GNUNET_MESSENGER_EgoStore *store = element->store; - GNUNET_assert(element->identifier); + GNUNET_assert (element->identifier); - struct GNUNET_MESSENGER_Ego *msg_ego; + struct GNUNET_MESSENGER_Ego *msg_ego = NULL; if (ego) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New ego looked up: '%s'\n", element->identifier); msg_ego = update_store_ego ( - store, element->identifier, GNUNET_IDENTITY_ego_get_private_key(ego) + store, + element->identifier, + GNUNET_IDENTITY_ego_get_private_key(ego) ); + } else - msg_ego = NULL; + { + struct GNUNET_HashCode hash; + GNUNET_CRYPTO_hash (element->identifier, strlen (element->identifier), &hash); + + if (GNUNET_CONTAINER_multihashmap_get (store->egos, &hash)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looked up ego got deleted: '%s'\n", element->identifier); + delete_store_ego(store, element->identifier); + } + } if (element->cb) element->cb(element->cls, element->identifier, msg_ego); @@ -200,43 +285,37 @@ lookup_store_ego(struct GNUNET_MESSENGER_EgoStore *store, { GNUNET_assert (store); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Store lookup ego: %s\n", identifier); + if (!identifier) { lookup(cls, identifier, NULL); return; } - struct GNUNET_HashCode hash; - GNUNET_CRYPTO_hash (identifier, strlen (identifier), &hash); - - struct GNUNET_MESSENGER_Ego *ego = GNUNET_CONTAINER_multihashmap_get (store->egos, &hash); + struct GNUNET_MESSENGER_EgoLookup *element = GNUNET_new (struct GNUNET_MESSENGER_EgoLookup); - if (ego) - lookup(cls, identifier, ego); - else - { - struct GNUNET_MESSENGER_EgoLookup *element = GNUNET_new (struct GNUNET_MESSENGER_EgoLookup); - - element->store = store; + element->store = store; - element->cb = lookup; - element->cls = cls; + element->cb = lookup; + element->cls = cls; - element->identifier = GNUNET_strdup (identifier); + element->identifier = GNUNET_strdup (identifier); - element->lookup = GNUNET_IDENTITY_ego_lookup(store->cfg, identifier, callback_ego_lookup, element); + element->lookup = GNUNET_IDENTITY_ego_lookup(store->cfg, identifier, callback_ego_lookup, element); - GNUNET_CONTAINER_DLL_insert (store->lu_start, store->lu_end, element); - } + GNUNET_CONTAINER_DLL_insert (store->lu_start, store->lu_end, element); } struct GNUNET_MESSENGER_Ego* -update_store_ego(struct GNUNET_MESSENGER_EgoStore *store, - const char *identifier, - const struct GNUNET_IDENTITY_PrivateKey *key) +update_store_ego (struct GNUNET_MESSENGER_EgoStore *store, + const char *identifier, + const struct GNUNET_IDENTITY_PrivateKey *key) { GNUNET_assert ((store) && (identifier) && (key)); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Store update ego: %s\n", identifier); + struct GNUNET_HashCode hash; GNUNET_CRYPTO_hash (identifier, strlen (identifier), &hash); @@ -256,26 +335,63 @@ update_store_ego(struct GNUNET_MESSENGER_EgoStore *store, return ego; } +void +delete_store_ego (struct GNUNET_MESSENGER_EgoStore *store, + const char *identifier) +{ + GNUNET_assert ((store) && (identifier)); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Store delete ego: %s\n", identifier); + + struct GNUNET_HashCode hash; + GNUNET_CRYPTO_hash (identifier, strlen (identifier), &hash); + + struct GNUNET_MESSENGER_Ego *ego = GNUNET_CONTAINER_multihashmap_get (store->egos, &hash); + + if (ego) + { + GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Ego is not stored!\n"); + return; + } + + if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (store->egos, &hash, ego)) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Removing ego from store failed!\n"); + return; + } + + GNUNET_free(ego); +} + static void callback_ego_rename (void *cls, - const char *emsg) + enum GNUNET_ErrorCode ec) { struct GNUNET_MESSENGER_EgoOperation *element = cls; struct GNUNET_MESSENGER_EgoStore *store = element->store; - GNUNET_assert(element->identifier); + GNUNET_assert (element->identifier); - if (emsg) - GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s\n", emsg); + /** + * FIXME: Dangerous, handle error + */ + if (GNUNET_EC_NONE != ec) + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%s\n", + GNUNET_ErrorCode_get_hint (ec)); struct GNUNET_HashCode hash; GNUNET_CRYPTO_hash (element->identifier, strlen (element->identifier), &hash); struct GNUNET_MESSENGER_Ego *ego = GNUNET_CONTAINER_multihashmap_get (store->egos, &hash); + if (!ego) + GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Ego is not stored!\n"); + + char *identifier = (char*) element->cls; + if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (store->egos, &hash, ego)) { - GNUNET_CRYPTO_hash ((char*) element->handle, strlen ((char*) element->handle), &hash); + GNUNET_CRYPTO_hash (identifier, strlen (identifier), &hash); GNUNET_CONTAINER_multihashmap_put (store->egos, &hash, ego, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); @@ -283,7 +399,7 @@ callback_ego_rename (void *cls, else GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Renaming ego failed!\n"); - GNUNET_free (element->handle); + GNUNET_free (identifier); GNUNET_CONTAINER_DLL_remove (store->op_start, store->op_end, element); GNUNET_free (element->identifier); @@ -297,14 +413,70 @@ rename_store_ego (struct GNUNET_MESSENGER_EgoStore *store, { GNUNET_assert ((store) && (old_identifier) && (new_identifier)); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Store rename ego: %s -> %s\n", old_identifier, new_identifier); + struct GNUNET_MESSENGER_EgoOperation *element = GNUNET_new (struct GNUNET_MESSENGER_EgoOperation); element->store = store; - element->handle = GNUNET_strdup (new_identifier); + element->cls = GNUNET_strdup (new_identifier); element->identifier = GNUNET_strdup (old_identifier); - element->operation = GNUNET_IDENTITY_rename (store->identity, old_identifier, new_identifier, callback_ego_rename, element); + element->operation = GNUNET_IDENTITY_rename ( + store->identity, + old_identifier, + new_identifier, + callback_ego_rename, + element + ); + + GNUNET_CONTAINER_DLL_insert (store->op_start, store->op_end, element); +} + +static void +callback_ego_delete (void *cls, + enum GNUNET_ErrorCode ec) +{ + struct GNUNET_MESSENGER_EgoOperation *element = cls; + struct GNUNET_MESSENGER_EgoStore *store = element->store; + + GNUNET_assert (element->identifier); + + /** + * FIXME: Dangerous, handle error + */ + if (GNUNET_EC_NONE != ec) + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%s\n", + GNUNET_ErrorCode_get_hint (ec)); + + create_store_ego (store, element->identifier); + + GNUNET_CONTAINER_DLL_remove (store->op_start, store->op_end, element); + GNUNET_free (element->identifier); + GNUNET_free (element); +} + +void +renew_store_ego (struct GNUNET_MESSENGER_EgoStore *store, + const char *identifier) +{ + GNUNET_assert ((store) && (identifier)); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Store renew ego: %s\n", identifier); + + struct GNUNET_MESSENGER_EgoOperation *element = GNUNET_new (struct GNUNET_MESSENGER_EgoOperation); + + element->store = store; + element->cls = NULL; + + element->identifier = GNUNET_strdup (identifier); + + element->operation = GNUNET_IDENTITY_delete( + store->identity, + identifier, + callback_ego_delete, + element + ); GNUNET_CONTAINER_DLL_insert (store->op_start, store->op_end, element); } |