aboutsummaryrefslogtreecommitdiff
path: root/src/messenger/gnunet-service-messenger_member.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/messenger/gnunet-service-messenger_member.c')
-rw-r--r--src/messenger/gnunet-service-messenger_member.c415
1 files changed, 0 insertions, 415 deletions
diff --git a/src/messenger/gnunet-service-messenger_member.c b/src/messenger/gnunet-service-messenger_member.c
deleted file mode 100644
index 976b68fe6..000000000
--- a/src/messenger/gnunet-service-messenger_member.c
+++ /dev/null
@@ -1,415 +0,0 @@
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 */
20/**
21 * @author Tobias Frisch
22 * @file src/messenger/gnunet-service-messenger_member.c
23 * @brief GNUnet MESSENGER service
24 */
25
26#include "gnunet-service-messenger_member.h"
27
28#include "gnunet-service-messenger_member_session.h"
29
30struct GNUNET_MESSENGER_Member*
31create_member (struct GNUNET_MESSENGER_MemberStore *store,
32 const struct GNUNET_ShortHashCode *id)
33{
34 GNUNET_assert (store);
35
36 struct GNUNET_MESSENGER_Member *member = GNUNET_new(struct GNUNET_MESSENGER_Member);
37
38 member->store = store;
39
40 if (id)
41 GNUNET_memcpy(&(member->id), id, sizeof(member->id));
42 else if (GNUNET_YES != generate_free_member_id(&(member->id), store->members))
43 {
44 GNUNET_free (member);
45 return NULL;
46 }
47
48 member->sessions = GNUNET_CONTAINER_multihashmap_create(2, GNUNET_NO);
49
50 return member;
51}
52
53static int
54iterate_destroy_session (void *cls,
55 const struct GNUNET_HashCode *key,
56 void *value)
57{
58 struct GNUNET_MESSENGER_MemberSession *session = value;
59 destroy_member_session(session);
60 return GNUNET_YES;
61}
62
63void
64destroy_member (struct GNUNET_MESSENGER_Member *member)
65{
66 GNUNET_assert((member) && (member->sessions));
67
68 GNUNET_CONTAINER_multihashmap_iterate (member->sessions, iterate_destroy_session, NULL);
69 GNUNET_CONTAINER_multihashmap_destroy (member->sessions);
70
71 GNUNET_free (member);
72}
73
74const struct GNUNET_ShortHashCode*
75get_member_id (const struct GNUNET_MESSENGER_Member *member)
76{
77 GNUNET_assert (member);
78
79 return &(member->id);
80}
81
82static int
83callback_scan_for_sessions (void *cls,
84 const char *filename)
85{
86 struct GNUNET_MESSENGER_Member *member = cls;
87
88 if (GNUNET_YES == GNUNET_DISK_directory_test (filename, GNUNET_YES))
89 {
90 char *directory;
91
92 GNUNET_asprintf (&directory, "%s%c", filename, DIR_SEPARATOR);
93
94 load_member_session(member, directory);
95 GNUNET_free (directory);
96 }
97
98 return GNUNET_OK;
99}
100
101void
102load_member (struct GNUNET_MESSENGER_MemberStore *store,
103 const char *directory)
104{
105 GNUNET_assert ((store) && (directory));
106
107 char *config_file;
108 GNUNET_asprintf (&config_file, "%s%s", directory, "member.cfg");
109
110 struct GNUNET_MESSENGER_Member *member = NULL;
111
112 if (GNUNET_YES != GNUNET_DISK_file_test (config_file))
113 goto free_config;
114
115 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Load member configuration: %s\n", config_file);
116
117 struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create ();
118
119 if (GNUNET_OK == GNUNET_CONFIGURATION_parse (cfg, config_file))
120 {
121 struct GNUNET_ShortHashCode id;
122
123 if (GNUNET_OK != GNUNET_CONFIGURATION_get_data (cfg, "member", "id", &id, sizeof(id)))
124 goto destroy_config;
125
126 member = add_store_member(store, &id);
127 }
128
129destroy_config:
130
131 GNUNET_CONFIGURATION_destroy (cfg);
132
133free_config:
134 GNUNET_free(config_file);
135
136 if (!member)
137 return;
138
139 char *scan_dir;
140 GNUNET_asprintf (&scan_dir, "%s%s%c", directory, "sessions", DIR_SEPARATOR);
141
142 if (GNUNET_OK == GNUNET_DISK_directory_test (scan_dir, GNUNET_YES))
143 GNUNET_DISK_directory_scan (scan_dir, callback_scan_for_sessions, member);
144
145 GNUNET_free(scan_dir);
146}
147
148static int
149iterate_load_next_session (void *cls,
150 const struct GNUNET_HashCode *key,
151 void *value)
152{
153 const char* sessions_directory = cls;
154
155 char* load_dir;
156 GNUNET_asprintf (&load_dir, "%s%s%c", sessions_directory, GNUNET_h2s(key), DIR_SEPARATOR);
157
158 struct GNUNET_MESSENGER_MemberSession *session = value;
159
160 if (GNUNET_YES == GNUNET_DISK_directory_test (load_dir, GNUNET_YES))
161 load_member_session_next (session, load_dir);
162
163 GNUNET_free (load_dir);
164 return GNUNET_YES;
165}
166
167void
168load_member_next_sessions (const struct GNUNET_MESSENGER_Member *member,
169 const char *directory)
170{
171 GNUNET_assert ((member) && (directory));
172
173 char* load_dir;
174 GNUNET_asprintf (&load_dir, "%s%s%c", directory, "sessions", DIR_SEPARATOR);
175
176 GNUNET_CONTAINER_multihashmap_iterate (member->sessions, iterate_load_next_session, load_dir);
177
178 GNUNET_free(load_dir);
179}
180
181static int
182iterate_save_session (void *cls,
183 const struct GNUNET_HashCode *key,
184 void *value)
185{
186 const char* sessions_directory = cls;
187
188 char* save_dir;
189 GNUNET_asprintf (&save_dir, "%s%s%c", sessions_directory, GNUNET_h2s(key), DIR_SEPARATOR);
190
191 struct GNUNET_MESSENGER_MemberSession *session = value;
192
193 if ((GNUNET_YES == GNUNET_DISK_directory_test (save_dir, GNUNET_NO)) ||
194 (GNUNET_OK == GNUNET_DISK_directory_create (save_dir)))
195 save_member_session (session, save_dir);
196
197 GNUNET_free (save_dir);
198 return GNUNET_YES;
199}
200
201void
202save_member (struct GNUNET_MESSENGER_Member *member,
203 const char *directory)
204{
205 GNUNET_assert ((member) && (directory));
206
207 char *config_file;
208 GNUNET_asprintf (&config_file, "%s%s", directory, "member.cfg");
209
210 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Save member configuration: %s\n", config_file);
211
212 struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create ();
213
214 char *id_data = GNUNET_STRINGS_data_to_string_alloc (&(member->id), sizeof(member->id));
215
216 if (id_data)
217 {
218 GNUNET_CONFIGURATION_set_value_string (cfg, "member", "id", id_data);
219
220 GNUNET_free(id_data);
221 }
222
223 GNUNET_CONFIGURATION_write (cfg, config_file);
224 GNUNET_CONFIGURATION_destroy (cfg);
225
226 GNUNET_free(config_file);
227
228 char* save_dir;
229 GNUNET_asprintf (&save_dir, "%s%s%c", directory, "sessions", DIR_SEPARATOR);
230
231 if ((GNUNET_YES == GNUNET_DISK_directory_test (save_dir, GNUNET_NO)) ||
232 (GNUNET_OK == GNUNET_DISK_directory_create (save_dir)))
233 GNUNET_CONTAINER_multihashmap_iterate (member->sessions, iterate_save_session, save_dir);
234
235 GNUNET_free(save_dir);
236}
237
238static void
239sync_session_contact_from_next (struct GNUNET_MESSENGER_MemberSession *session,
240 struct GNUNET_MESSENGER_MemberSession *next)
241{
242 GNUNET_assert((session) && (next));
243
244 if (session == next)
245 return;
246
247 if (next->next)
248 sync_session_contact_from_next (session, next->next);
249 else
250 session->contact = next->contact;
251}
252
253static int
254iterate_sync_session_contact (void *cls,
255 const struct GNUNET_HashCode *key,
256 void *value)
257{
258 struct GNUNET_MESSENGER_MemberSession *session = value;
259
260 if (session->next)
261 sync_session_contact_from_next (session, session->next);
262
263 return GNUNET_YES;
264}
265
266void
267sync_member_contacts (struct GNUNET_MESSENGER_Member *member)
268{
269 GNUNET_assert ((member) && (member->sessions));
270
271 GNUNET_CONTAINER_multihashmap_iterate (member->sessions, iterate_sync_session_contact, NULL);
272}
273
274struct GNUNET_MESSENGER_MemberSession*
275get_member_session (const struct GNUNET_MESSENGER_Member *member,
276 const struct GNUNET_IDENTITY_PublicKey *public_key)
277{
278 GNUNET_assert ((member) && (public_key));
279
280 struct GNUNET_HashCode hash;
281 GNUNET_CRYPTO_hash(public_key, sizeof(*public_key), &hash);
282
283 return GNUNET_CONTAINER_multihashmap_get(member->sessions, &hash);
284}
285
286struct GNUNET_MESSENGER_ClosureSearchSession {
287 const struct GNUNET_MESSENGER_Message *message;
288 const struct GNUNET_HashCode *hash;
289
290 struct GNUNET_MESSENGER_MemberSession *match;
291};
292
293static int
294iterate_search_session (void *cls,
295 const struct GNUNET_HashCode *key,
296 void *value)
297{
298 struct GNUNET_MESSENGER_ClosureSearchSession* search = cls;
299 struct GNUNET_MESSENGER_MemberSession *session = value;
300
301 if (GNUNET_OK != verify_member_session_as_sender(session, search->message, search->hash))
302 return GNUNET_YES;
303
304 search->match = session;
305 return GNUNET_NO;
306}
307
308static struct GNUNET_MESSENGER_MemberSession*
309try_member_session (struct GNUNET_MESSENGER_Member *member,
310 const struct GNUNET_IDENTITY_PublicKey *public_key)
311{
312 struct GNUNET_MESSENGER_MemberSession* session = get_member_session(member, public_key);
313
314 if (session)
315 return session;
316
317 session = create_member_session(member, public_key);
318
319 if (session)
320 add_member_session(member, session);
321
322 return session;
323}
324
325struct GNUNET_MESSENGER_MemberSession*
326get_member_session_of (struct GNUNET_MESSENGER_Member *member,
327 const struct GNUNET_MESSENGER_Message *message,
328 const struct GNUNET_HashCode *hash)
329{
330 GNUNET_assert ((member) && (message) && (hash) &&
331 (0 == GNUNET_memcmp(&(member->id), &(message->header.sender_id))));
332
333 if (GNUNET_MESSENGER_KIND_INFO == message->header.kind)
334 return try_member_session(member, &(message->body.info.host_key));
335 else if (GNUNET_MESSENGER_KIND_JOIN == message->header.kind)
336 return try_member_session(member, &(message->body.join.key));
337
338 struct GNUNET_MESSENGER_ClosureSearchSession search;
339
340 search.message = message;
341 search.hash = hash;
342
343 search.match = NULL;
344 GNUNET_CONTAINER_multihashmap_iterate(member->sessions, iterate_search_session, &search);
345
346 return search.match;
347}
348
349void
350add_member_session (struct GNUNET_MESSENGER_Member *member,
351 struct GNUNET_MESSENGER_MemberSession *session)
352{
353 if (!session)
354 return;
355
356 GNUNET_assert((member) && (session->member == member));
357
358 const struct GNUNET_IDENTITY_PublicKey *public_key = get_member_session_public_key(session);
359
360 struct GNUNET_HashCode hash;
361 GNUNET_CRYPTO_hash(public_key, sizeof(*public_key), &hash);
362
363 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(
364 member->sessions, &hash, session,
365 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
366 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Adding a member session failed: %s\n",
367 GNUNET_h2s(&hash));
368}
369
370void
371remove_member_session (struct GNUNET_MESSENGER_Member *member,
372 struct GNUNET_MESSENGER_MemberSession *session)
373{
374 GNUNET_assert ((member) && (session) && (session->member == member));
375
376 const struct GNUNET_IDENTITY_PublicKey *public_key = get_member_session_public_key(session);
377
378 struct GNUNET_HashCode hash;
379 GNUNET_CRYPTO_hash(public_key, sizeof(*public_key), &hash);
380
381 if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove(member->sessions, &hash, session))
382 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Removing a member session failed: %s\n",
383 GNUNET_h2s(&hash));
384}
385
386struct GNUNET_MESSENGER_ClosureIterateSessions {
387 GNUNET_MESSENGER_MemberIteratorCallback it;
388 void *cls;
389};
390
391static int
392iterate_member_sessions_it (void *cls,
393 const struct GNUNET_HashCode *key,
394 void *value)
395{
396 struct GNUNET_MESSENGER_ClosureIterateSessions *iterate = cls;
397 struct GNUNET_MESSENGER_MemberSession *session = value;
398
399 return iterate->it (iterate->cls, get_member_session_public_key(session), session);
400}
401
402int
403iterate_member_sessions (struct GNUNET_MESSENGER_Member *member,
404 GNUNET_MESSENGER_MemberIteratorCallback it,
405 void *cls)
406{
407 GNUNET_assert ((member) && (member->sessions) && (it));
408
409 struct GNUNET_MESSENGER_ClosureIterateSessions iterate;
410
411 iterate.it = it;
412 iterate.cls = cls;
413
414 return GNUNET_CONTAINER_multihashmap_iterate(member->sessions, iterate_member_sessions_it, &iterate);
415}