libgnunetchat

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

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 }