GNUnet  0.11.x
gnunet-service-messenger_service.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2020--2021 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  */
29 
30 static void
32 {
33  struct GNUNET_MESSENGER_Service *service = cls;
34 
35  if (service)
36  {
37  service->shutdown = NULL;
38 
40  }
41 }
42 
45  struct GNUNET_SERVICE_Handle *service_handle)
46 {
47  GNUNET_assert((config) && (service_handle));
48 
50 
51  service->config = config;
52  service->service = service_handle;
53 
55 
56  service->dir = NULL;
57 
60  "MESSENGER_DIR", &(service->dir)))
61  {
62  if (service->dir)
63  GNUNET_free(service->dir);
64 
65  service->dir = NULL;
66  }
67  else
68  {
71  {
72  GNUNET_free(service->dir);
73 
74  service->dir = NULL;
75  }
76  }
77 
78  service->cadet = GNUNET_CADET_connect (service->config);
79 
81 
82  init_list_handles (&(service->handles));
83 
85 
87 
88  return service;
89 }
90 
91 static int
93  const struct GNUNET_HashCode *key,
94  void *value)
95 {
96  struct GNUNET_MESSENGER_SrvRoom *room = value;
97  destroy_room (room);
98  return GNUNET_YES;
99 }
100 
101 void
103 {
105 
106  if (service->shutdown)
107  {
108  GNUNET_SCHEDULER_cancel (service->shutdown);
109 
110  service->shutdown = NULL;
111  }
112 
114  clear_list_handles (&(service->handles));
115 
118 
120 
121  if (service->cadet)
122  {
124 
125  service->cadet = NULL;
126  }
127 
128  if (service->dir)
129  {
130  GNUNET_free(service->dir);
131 
132  service->dir = NULL;
133  }
134 
135  GNUNET_SERVICE_shutdown (service->service);
136 
138 }
139 
142 {
144 
145  return &(service->ego_store);
146 }
147 
150 {
152 
153  return &(service->contact_store);
154 }
155 
158  struct GNUNET_MQ_Handle *mq)
159 {
160  GNUNET_assert((service) && (mq));
161 
163 
164  if (handle)
165  {
166  add_list_handle (&(service->handles), handle);
167  }
168 
169  return handle;
170 }
171 
172 void
175 {
176  GNUNET_assert((service) && (handle));
177 
178  if (!handle)
179  return;
180 
181  if (GNUNET_YES == remove_list_handle (&(service->handles), handle))
183 }
184 
185 int
187  struct GNUNET_PeerIdentity *peer)
188 {
189  GNUNET_assert((service) && (peer));
190 
191  return GNUNET_CRYPTO_get_peer_identity (service->config, peer);
192 }
193 
196  const struct GNUNET_HashCode *key)
197 {
198  GNUNET_assert((service) && (key));
199 
201 }
202 
203 int
206  const struct GNUNET_HashCode *key)
207 {
208  GNUNET_assert((service) && (handle) && (key));
209 
211 
212  if (room)
213  return open_room (room, handle);
214 
215  room = create_room (handle, key);
216 
217  if ((GNUNET_YES == open_room (room, handle)) &&
219  key, room,
221  return GNUNET_YES;
222 
223  destroy_room (room);
224  return GNUNET_NO;
225 }
226 
227 int
230  const struct GNUNET_PeerIdentity *door,
231  const struct GNUNET_HashCode *key)
232 {
233  GNUNET_assert((service) && (handle) && (door) && (key));
234 
236 
237  if (room)
238  {
239  if (GNUNET_YES == enter_room_at (room, handle, door))
240  return GNUNET_YES;
241  else
242  return GNUNET_NO;
243  }
244 
245  room = create_room (handle, key);
246 
247  if ((GNUNET_YES == enter_room_at (room, handle, door)) &&
249  key, room,
251  {
252  return GNUNET_YES;
253  }
254  else
255  {
256  destroy_room (room);
257  return GNUNET_NO;
258  }
259 
260 }
261 
262 int
265  const struct GNUNET_HashCode *key)
266 {
267  GNUNET_assert((service) && (handle) && (key));
268 
270 
271  if (!room)
272  return GNUNET_NO;
273 
275 
276  const struct GNUNET_ShortHashCode *id = get_handle_member_id (handle, key);
277 
278  GNUNET_assert(id);
279 
280  if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (handle->member_ids, key, id))
281  return GNUNET_NO;
282 
284  &(service->handles), key);
285 
286  if (!member_handle)
287  {
289  {
290  destroy_room (room);
291  return GNUNET_YES;
292  }
293  else
294  return GNUNET_NO;
295  }
296 
297  if (room->host == handle)
298  room->host = member_handle;
299 
300  return GNUNET_YES;
301 }
302 
303 void
305  struct GNUNET_MESSENGER_SrvRoom *room,
306  const struct GNUNET_MESSENGER_MemberSession *session,
307  const struct GNUNET_MESSENGER_Message *message,
308  const struct GNUNET_HashCode *hash)
309 {
310  GNUNET_assert((service) && (room) && (session) && (message) && (hash));
311 
312  struct GNUNET_MESSENGER_ListHandle *element = service->handles.head;
313 
314  while (element)
315  {
316  notify_handle_message (element->handle, get_room_key(room), session, message, hash);
317  element = element->next;
318  }
319 }
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static char * value
Value of the record to add/remove.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
GNUnet MESSENGER service.
void clear_ego_store(struct GNUNET_MESSENGER_EgoStore *store)
Clears an EGO-store, wipes its content and deallocates its memory.
void init_ego_store(struct GNUNET_MESSENGER_EgoStore *store, const struct GNUNET_CONFIGURATION_Handle *config)
Initializes an EGO-store as fully empty.
void notify_handle_message(struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key, const struct GNUNET_MESSENGER_MemberSession *session, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Notifies the handle that a new message was received or sent.
struct GNUNET_MESSENGER_SrvHandle * create_handle(struct GNUNET_MESSENGER_Service *service, struct GNUNET_MQ_Handle *mq)
Creates and allocates a new handle related to a service and using a given mq (message queue).
const struct GNUNET_ShortHashCode * get_handle_member_id(const struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key)
Returns the member id of a given handle in a specific room.
void destroy_handle(struct GNUNET_MESSENGER_SrvHandle *handle)
Destroys a handle and frees its memory fully.
void add_list_handle(struct GNUNET_MESSENGER_ListHandles *handles, struct GNUNET_MESSENGER_SrvHandle *handle)
Adds a specific handle to the end of the list.
void init_list_handles(struct GNUNET_MESSENGER_ListHandles *handles)
Initializes list of handles as empty list.
struct GNUNET_MESSENGER_SrvHandle * find_list_handle_by_member(const struct GNUNET_MESSENGER_ListHandles *handles, const struct GNUNET_HashCode *key)
Searches linearly through the list of handles for members of a specific room which is identified by a...
int remove_list_handle(struct GNUNET_MESSENGER_ListHandles *handles, struct GNUNET_MESSENGER_SrvHandle *handle)
Removes the first entry matching with a specific handle from the list of handles and returns GNUNET_Y...
void clear_list_handles(struct GNUNET_MESSENGER_ListHandles *handles)
Destroys remaining handles and clears the list.
struct GNUNET_MESSENGER_Message * create_message_leave()
Creates and allocates a new leave message.
int send_room_message(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, struct GNUNET_MESSENGER_Message *message)
Sends a message from a given handle into a room.
const struct GNUNET_HashCode * get_room_key(const struct GNUNET_MESSENGER_SrvRoom *room)
Returns the shared secret you need to access a room.
int open_room(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle)
Tries to open a room for a given handle.
int enter_room_at(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_PeerIdentity *door)
Connects a tunnel to a hosting peer of a room through a so called door which is represented by a peer...
struct GNUNET_MESSENGER_SrvRoom * create_room(struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key)
Creates and allocates a new room for a handle with a given key.
void destroy_room(struct GNUNET_MESSENGER_SrvRoom *room)
Destroys a room and frees its memory fully.
void remove_service_handle(struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvHandle *handle)
Removes a handle from a service and destroys it.
struct GNUNET_MESSENGER_SrvHandle * add_service_handle(struct GNUNET_MESSENGER_Service *service, struct GNUNET_MQ_Handle *mq)
Creates and adds a new handle to a service using a given message queue.
void destroy_service(struct GNUNET_MESSENGER_Service *service)
Destroys a service and frees its memory fully.
int entry_service_room(struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_PeerIdentity *door, const struct GNUNET_HashCode *key)
Tries to enter a room using a given key for a service by a specific handle.
struct GNUNET_MESSENGER_SrvRoom * get_service_room(const struct GNUNET_MESSENGER_Service *service, const struct GNUNET_HashCode *key)
Returns the room identified by a given key for a service.
void handle_service_message(struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_MESSENGER_MemberSession *session, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Sends a received or sent message with a given hash to each handle of a service which is currently mem...
struct GNUNET_MESSENGER_EgoStore * get_service_ego_store(struct GNUNET_MESSENGER_Service *service)
Returns the used EGO-store of a given service.
static void callback_shutdown_service(void *cls)
struct GNUNET_MESSENGER_Service * create_service(const struct GNUNET_CONFIGURATION_Handle *config, struct GNUNET_SERVICE_Handle *service_handle)
Creates and allocates a new service using a given config and a GNUnet service handle.
int open_service_room(struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key)
Tries to open a room using a given key for a service by a specific handle.
int close_service_room(struct GNUNET_MESSENGER_Service *service, struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key)
Tries to close a room using a given key for a service by a specific handle.
int get_service_peer_identity(const struct GNUNET_MESSENGER_Service *service, struct GNUNET_PeerIdentity *peer)
Tries to write the peer identity of the peer running a service on to the peer parameter.
struct GNUNET_MESSENGER_ContactStore * get_service_contact_store(struct GNUNET_MESSENGER_Service *service)
Returns the used contact store of a given service.
static int iterate_destroy_rooms(void *cls, const struct GNUNET_HashCode *key, void *value)
GNUnet MESSENGER service.
static const struct GNUNET_CONFIGURATION_Handle * config
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:775
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition: cadet_api.c:910
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
int GNUNET_CRYPTO_get_peer_identity(const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_PeerIdentity *dst)
Retrieve the identity of the host's peer.
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_test(const char *fil, int is_readable)
Test if fil is a directory and listable.
Definition: disk.c:404
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:496
int GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST
, ' bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE...
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_MESSENGER_SERVICE_NAME
Identifier of GNUnet MESSENGER Service.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition: scheduler.c:1331
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972
void GNUNET_SERVICE_shutdown(struct GNUNET_SERVICE_Handle *sh)
Explicitly stops the service.
Definition: service.c:2384
void clear_contact_store(struct GNUNET_MESSENGER_ContactStore *store)
Clears a contact store, wipes its content and deallocates its memory.
void init_contact_store(struct GNUNET_MESSENGER_ContactStore *store)
Initializes a contact store as fully empty.
A 512-bit hashcode.
struct GNUNET_MESSENGER_ListHandle * next
struct GNUNET_MESSENGER_SrvHandle * handle
struct GNUNET_MESSENGER_SrvHandle * host
Handle to a message queue.
Definition: mq.c:86
The identity of the host (wraps the signing key of the peer).
Handle to a service.
Definition: service.c:117
A 256-bit hashcode.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.