gnunet_chat_lobby.c (4182B)
1 /* 2 This file is part of GNUnet. 3 Copyright (C) 2022--2025 GNUnet e.V. 4 5 GNUnet is free software: you can redistribute it and/or modify it 6 under the terms of the GNU Affero General Public License as published 7 by the Free Software Foundation, either version 3 of the License, 8 or (at your option) any later version. 9 10 GNUnet is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Affero General Public License for more details. 14 15 You should have received a copy of the GNU Affero General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 SPDX-License-Identifier: AGPL3.0-or-later 19 */ 20 /* 21 * @author Tobias Frisch 22 * @file gnunet_chat_lobby.c 23 */ 24 25 #include "gnunet_chat_lobby.h" 26 27 #include "gnunet_chat_group.h" 28 #include "gnunet_chat_handle.h" 29 #include "gnunet_chat_lib.h" 30 #include "gnunet_chat_lobby_intern.c" 31 #include "gnunet_chat_util.h" 32 #include <gnunet/gnunet_messenger_service.h> 33 #include <gnunet/gnunet_util_lib.h> 34 35 struct GNUNET_CHAT_Lobby* 36 lobby_create (struct GNUNET_CHAT_Handle *handle) 37 { 38 GNUNET_assert(handle); 39 40 struct GNUNET_CHAT_Lobby *lobby = GNUNET_new(struct GNUNET_CHAT_Lobby); 41 42 lobby->handle = handle; 43 lobby->destruction = NULL; 44 lobby->context = NULL; 45 lobby->uri = NULL; 46 47 lobby->op = NULL; 48 lobby->query = NULL; 49 50 lobby->expiration = GNUNET_TIME_absolute_get_forever_(); 51 lobby->callback = NULL; 52 lobby->cls = NULL; 53 54 return lobby; 55 } 56 57 void 58 lobby_destroy (struct GNUNET_CHAT_Lobby *lobby) 59 { 60 GNUNET_assert(lobby); 61 62 if (lobby->destruction) 63 GNUNET_SCHEDULER_cancel(lobby->destruction); 64 65 if ((!(lobby->op)) && (!(lobby->query))) 66 goto skip_deletion; 67 68 handle_delete_lobby(lobby->handle, lobby); 69 70 skip_deletion: 71 if (lobby->op) 72 GNUNET_IDENTITY_cancel(lobby->op); 73 74 if (lobby->query) 75 GNUNET_NAMESTORE_cancel(lobby->query); 76 77 if (lobby->uri) 78 uri_destroy(lobby->uri); 79 80 GNUNET_free(lobby); 81 } 82 83 void 84 lobby_open (struct GNUNET_CHAT_Lobby *lobby, 85 enum GNUNET_CHAT_LobbyType type, 86 struct GNUNET_TIME_Relative delay, 87 GNUNET_CHAT_LobbyCallback callback, 88 void *cls) 89 { 90 GNUNET_assert(lobby); 91 92 char *name; 93 94 lobby->expiration = GNUNET_TIME_relative_to_absolute(delay); 95 lobby->callback = callback; 96 lobby->cls = cls; 97 98 if (lobby->op) 99 { 100 GNUNET_IDENTITY_cancel(lobby->op); 101 goto open_zone; 102 } 103 104 union GNUNET_MESSENGER_RoomKey key; 105 GNUNET_MESSENGER_create_room_key( 106 &key, 107 NULL, 108 GNUNET_NO, 109 GNUNET_CHAT_LOBBY_TYPE_GROUP == type? GNUNET_YES : GNUNET_NO, 110 GNUNET_CHAT_LOBBY_TYPE_FEED == type? GNUNET_YES : GNUNET_NO 111 ); 112 113 struct GNUNET_MESSENGER_Room *room = GNUNET_MESSENGER_open_room( 114 lobby->handle->messenger, 115 &key 116 ); 117 118 if (!room) 119 return; 120 121 lobby->context = context_create_from_room(lobby->handle, room); 122 123 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put( 124 lobby->handle->contexts, &(key.hash), lobby->context, 125 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) 126 { 127 context_destroy(lobby->context); 128 lobby->context = NULL; 129 130 GNUNET_MESSENGER_close_room(room); 131 return; 132 } 133 134 if (GNUNET_CHAT_CONTEXT_TYPE_GROUP == lobby->context->type) 135 { 136 struct GNUNET_CHAT_Group *group; 137 group = group_create_from_context(lobby->handle, lobby->context); 138 139 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put( 140 lobby->handle->groups, &(key.hash), group, 141 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) 142 { 143 group_destroy(group); 144 145 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove( 146 lobby->handle->contexts, &(key.hash), lobby->context)) 147 { 148 context_destroy(lobby->context); 149 lobby->context = NULL; 150 } 151 152 GNUNET_MESSENGER_close_room(room); 153 return; 154 } 155 } 156 157 context_write_records(lobby->context); 158 159 open_zone: 160 util_lobby_name(&(key.hash), &name); 161 162 lobby->op = GNUNET_IDENTITY_create( 163 lobby->handle->identity, 164 name, 165 NULL, 166 GNUNET_PUBLIC_KEY_TYPE_EDDSA, 167 cont_lobby_identity_create, 168 lobby 169 ); 170 171 GNUNET_free(name); 172 }