libgnunetchat

library for GNUnet Messenger
Log | Files | Refs | README | LICENSE

commit a3be90bc89ba9ab4968329f49013412b5f2e2af6
parent ecccdbe89ad906f5d995e45ec1ff40117d642b18
Author: TheJackiMonster <thejackimonster@gmail.com>
Date:   Thu, 29 Jul 2021 23:01:26 +0200

Implemented dynamic context creation for contacts

Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>

Diffstat:
Msrc/gnunet_chat_handle_intern.c | 29++++++++++++++++++-----------
Msrc/gnunet_chat_lib.c | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/gnunet_chat_lib_intern.c | 14++++++++++++++
3 files changed, 86 insertions(+), 11 deletions(-)

diff --git a/src/gnunet_chat_handle_intern.c b/src/gnunet_chat_handle_intern.c @@ -211,7 +211,7 @@ check_handle_room_members (void* cls, return GNUNET_YES; } -struct GNUNET_CHAT_Context* +int request_handle_context_by_room (struct GNUNET_CHAT_Handle *handle, struct GNUNET_MESSENGER_Room *room) { @@ -222,7 +222,7 @@ request_handle_context_by_room (struct GNUNET_CHAT_Handle *handle, ); if (context) - return context; + return GNUNET_OK; context = context_create_from_room(handle, room); context_load_config(context); @@ -232,14 +232,16 @@ request_handle_context_by_room (struct GNUNET_CHAT_Handle *handle, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) { context_destroy(context); - return NULL; + return GNUNET_SYSERR; } struct GNUNET_CHAT_CheckHandleRoomMembers check; check.ignore_key = GNUNET_MESSENGER_get_key(handle->messenger); check.contact = NULL; - GNUNET_MESSENGER_iterate_members(room, check_handle_room_members, &check); + const int checks = GNUNET_MESSENGER_iterate_members( + room, check_handle_room_members, &check + ); if (check.contact) { @@ -257,11 +259,11 @@ request_handle_context_by_room (struct GNUNET_CHAT_Handle *handle, if (GNUNET_OK == GNUNET_CONTAINER_multishortmap_put( handle->contacts, &shorthash, contact, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) - return context; + return GNUNET_OK; contact_destroy(contact); } - else + else if (checks >= 2) { context->type = GNUNET_CHAT_CONTEXT_TYPE_GROUP; @@ -277,14 +279,20 @@ request_handle_context_by_room (struct GNUNET_CHAT_Handle *handle, if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put( handle->groups, key, group, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) - return context; + return GNUNET_OK; group_destroy(group); } + else + { + context->type = GNUNET_CHAT_CONTEXT_TYPE_UNKNOWN; + + // TODO: handle chats which only contain yourself currently! + } GNUNET_CONTAINER_multihashmap_remove(handle->contexts, key, context); context_destroy(context); - return NULL; + return GNUNET_SYSERR; } int @@ -293,9 +301,8 @@ find_handle_rooms (void *cls, struct GNUNET_MESSENGER_Room *room, { struct GNUNET_CHAT_Handle *handle = cls; - request_handle_context_by_room( - handle, room - ); + if (GNUNET_OK != request_handle_context_by_room(handle, room)) + return GNUNET_NO; return GNUNET_YES; } diff --git a/src/gnunet_chat_lib.c b/src/gnunet_chat_lib.c @@ -171,6 +171,9 @@ GNUNET_CHAT_group_create (struct GNUNET_CHAT_Handle *handle, handle->messenger, &key ); + if (!room) + return NULL; + struct GNUNET_CHAT_Context *context = context_create_from_room(handle, room); context->type = GNUNET_CHAT_CONTEXT_TYPE_GROUP; @@ -290,6 +293,57 @@ GNUNET_CHAT_contact_get_context (struct GNUNET_CHAT_Contact *contact) if (!contact) return NULL; + if (contact->context) + return contact->context; + + struct GNUNET_CHAT_ContactFindRoom find; + find.room = NULL; + GNUNET_MESSENGER_find_rooms( + contact->handle->messenger, + contact->member, + it_contact_find_room, + &find + ); + + // TODO: Check if the found room is a group or not + + if (!(find.room)) + return NULL; + + struct GNUNET_HashCode key; + GNUNET_CRYPTO_random_block(GNUNET_CRYPTO_QUALITY_WEAK, &key, sizeof(key)); + + if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains( + contact->handle->contexts, &key)) + return NULL; + + struct GNUNET_MESSENGER_Room *room = GNUNET_MESSENGER_open_room( + contact->handle->messenger, &key + ); + + if (!room) + return NULL; + + struct GNUNET_CHAT_Context *context = context_create_from_room( + contact->handle, room + ); + + if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put( + contact->handle->contexts, &key, context, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) + { + context_destroy(context); + return NULL; + } + + struct GNUNET_MESSENGER_Message msg; + msg.header.kind = GNUNET_MESSENGER_KIND_INVITE; + GNUNET_CRYPTO_get_peer_identity(contact->handle->cfg, &(msg.body.invite.door)); + GNUNET_memcpy(&(msg.body.invite.key), &key, sizeof(msg.body.invite.key)); + + GNUNET_MESSENGER_send_message(find.room, &msg, contact->member); + + contact->context = context; return contact->context; } diff --git a/src/gnunet_chat_lib_intern.c b/src/gnunet_chat_lib_intern.c @@ -68,6 +68,20 @@ it_handle_iterate_groups (void *cls, return it->cb(it->cls, it->handle, group); } +struct GNUNET_CHAT_ContactFindRoom +{ + struct GNUNET_MESSENGER_Room *room; +}; + +int +it_contact_find_room (void *cls, struct GNUNET_MESSENGER_Room *room, + GNUNET_UNUSED const struct GNUNET_MESSENGER_Contact *member) +{ + struct GNUNET_CHAT_ContactFindRoom *find = cls; + find->room = room; + return GNUNET_NO; +} + struct GNUNET_CHAT_GroupIterateContacts { struct GNUNET_CHAT_Group *group;