From ca912f85dae6b61dd80ab02d0e3f0b20a556da7c Mon Sep 17 00:00:00 2001 From: TheJackiMonster Date: Thu, 12 Nov 2020 20:58:07 +0100 Subject: -remerge branch 'jacki/messenger' This reverts commit e11d1e59e4ae5f7d89c33df3ae9ca8f1ece990cf. --- src/messenger/messenger_api_handle.c | 213 +++++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 src/messenger/messenger_api_handle.c (limited to 'src/messenger/messenger_api_handle.c') diff --git a/src/messenger/messenger_api_handle.c b/src/messenger/messenger_api_handle.c new file mode 100644 index 000000000..20ef77254 --- /dev/null +++ b/src/messenger/messenger_api_handle.c @@ -0,0 +1,213 @@ +/* + This file is part of GNUnet. + Copyright (C) 2020 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 + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/** + * @author Tobias Frisch + * @file src/messenger/messenger_api_handle.c + * @brief messenger api: client implementation of GNUnet MESSENGER service + */ + +#include "messenger_api_handle.h" + +struct GNUNET_MESSENGER_Handle* +create_handle (const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_MESSENGER_IdentityCallback identity_callback, + void *identity_cls, GNUNET_MESSENGER_MessageCallback msg_callback, void *msg_cls) +{ + struct GNUNET_MESSENGER_Handle *handle = GNUNET_new(struct GNUNET_MESSENGER_Handle); + + handle->cfg = cfg; + handle->mq = NULL; + + handle->identity_callback = identity_callback; + handle->identity_cls = identity_cls; + + handle->msg_callback = msg_callback; + handle->msg_cls = msg_cls; + + handle->name = NULL; + handle->pubkey = NULL; + + handle->reconnect_time = GNUNET_TIME_relative_get_zero_ (); + handle->reconnect_task = NULL; + + handle->rooms = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); + handle->contacts = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); + + return handle; +} + +static int +iterate_destroy_room (void *cls, const struct GNUNET_HashCode *key, void *value) +{ + struct GNUNET_MESSENGER_Room *room = value; + + destroy_room (room); + + return GNUNET_YES; +} + +static int +iterate_destroy_contact (void *cls, const struct GNUNET_HashCode *key, void *value) +{ + struct GNUNET_MESSENGER_Contact *contact = value; + + destroy_contact (contact); + + return GNUNET_YES; +} + +void +destroy_handle (struct GNUNET_MESSENGER_Handle *handle) +{ + if (handle->reconnect_task) + GNUNET_SCHEDULER_cancel (handle->reconnect_task); + + if (handle->mq) + GNUNET_MQ_destroy (handle->mq); + + if (handle->name) + GNUNET_free(handle->name); + + if (handle->pubkey) + GNUNET_free(handle->pubkey); + + if (handle->rooms) + { + GNUNET_CONTAINER_multihashmap_iterate (handle->rooms, iterate_destroy_room, NULL); + + GNUNET_CONTAINER_multihashmap_destroy (handle->rooms); + } + + if (handle->contacts) + { + GNUNET_CONTAINER_multihashmap_iterate (handle->contacts, iterate_destroy_contact, NULL); + + GNUNET_CONTAINER_multihashmap_destroy (handle->contacts); + } + + GNUNET_free(handle->name); +} + +void +set_handle_name (struct GNUNET_MESSENGER_Handle *handle, const char *name) +{ + if (handle->name) + GNUNET_free(handle->name); + + handle->name = name? GNUNET_strdup(name) : NULL; +} + +const char* +get_handle_name (const struct GNUNET_MESSENGER_Handle *handle) +{ + return handle->name; +} + +void +set_handle_key (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_IDENTITY_PublicKey *pubkey) +{ + if (!handle->pubkey) + handle->pubkey = GNUNET_new(struct GNUNET_IDENTITY_PublicKey); + + GNUNET_memcpy(handle->pubkey, pubkey, sizeof(*pubkey)); +} + +const struct GNUNET_IDENTITY_PublicKey* +get_handle_key (const struct GNUNET_MESSENGER_Handle *handle) +{ + if (!handle->pubkey) + { + struct GNUNET_IDENTITY_Ego *anonymous = GNUNET_IDENTITY_ego_get_anonymous (); + static struct GNUNET_IDENTITY_PublicKey pubkey; + + GNUNET_IDENTITY_ego_get_public_key (anonymous, &pubkey); + + return &pubkey; + } + + return handle->pubkey; +} + +struct GNUNET_MESSENGER_Contact* +get_handle_contact_by_pubkey (const struct GNUNET_MESSENGER_Handle *handle, + const struct GNUNET_IDENTITY_PublicKey *pubkey) +{ + struct GNUNET_HashCode hash; + + GNUNET_CRYPTO_hash (pubkey, sizeof(*pubkey), &hash); + + struct GNUNET_MESSENGER_Contact *contact = GNUNET_CONTAINER_multihashmap_get (handle->contacts, &hash); + + if (contact) + return contact; + + contact = create_contact (pubkey); + + if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (handle->contacts, &hash, contact, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) + return contact; + + destroy_contact (contact); + return NULL; +} + +void +swap_handle_contact_by_pubkey (struct GNUNET_MESSENGER_Handle *handle, struct GNUNET_MESSENGER_Contact *contact, + const struct GNUNET_IDENTITY_PublicKey *pubkey) +{ + const struct GNUNET_HashCode *hash = get_contact_id_from_key (contact); + + if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (handle->contacts, hash, contact)) + { + GNUNET_memcpy(&(contact->public_key), pubkey, sizeof(*pubkey)); + + hash = get_contact_id_from_key (contact); + + GNUNET_CONTAINER_multihashmap_put (handle->contacts, hash, contact, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); + } +} + +void +open_handle_room (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_HashCode *key) +{ + struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key); + + if (room) + room->opened = GNUNET_YES; +} + +void +entry_handle_room_at (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_PeerIdentity *door, + const struct GNUNET_HashCode *key) +{ + struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key); + + if (room) + add_to_list_tunnels (&(room->entries), door); +} + +void +close_handle_room (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_HashCode *key) +{ + struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key); + + if ((room) && (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (handle->rooms, key, room))) + destroy_room (room); +} -- cgit v1.2.3