GNUnet 0.21.2
gnunet-service-messenger_member.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2020--2024 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 */
26#include "platform.h"
28
30
31#include "messenger_api_util.h"
32
35 const struct GNUNET_ShortHashCode *id)
36{
38
39 struct GNUNET_MESSENGER_Member *member = GNUNET_new (struct
41
42 member->store = store;
43
44 if (id)
45 GNUNET_memcpy (&(member->id), id, sizeof(member->id));
46 else if (GNUNET_YES != generate_free_member_id (&(member->id),
47 store->members))
48 {
49 GNUNET_free (member);
50 return NULL;
51 }
52
55
56 return member;
57}
58
59
62 const struct GNUNET_HashCode *key,
63 void *value)
64{
65 struct GNUNET_MESSENGER_MemberSession *session = value;
66 destroy_member_session (session);
67 return GNUNET_YES;
68}
69
70
73 const struct GNUNET_ShortHashCode *key,
74 void *value)
75{
76 struct GNUNET_MESSENGER_Subscription *subscription = value;
77 destroy_subscription (subscription);
78 return GNUNET_YES;
79}
80
81
82void
84{
86
91
94
96}
97
98
99const struct GNUNET_ShortHashCode*
101{
102 GNUNET_assert (member);
103
104 return &(member->id);
105}
106
107
110 const char *filename)
111{
112 struct GNUNET_MESSENGER_Member *member = cls;
113
115 {
116 char *directory;
117
118 GNUNET_asprintf (&directory, "%s%c", filename, DIR_SEPARATOR);
119
120 load_member_session (member, directory);
121 GNUNET_free (directory);
122 }
123
124 return GNUNET_OK;
125}
126
127
128void
130 const char *directory)
131{
132 GNUNET_assert ((store) && (directory));
133
134 char *config_file;
135 GNUNET_asprintf (&config_file, "%s%s", directory, "member.cfg");
136
137 struct GNUNET_MESSENGER_Member *member = NULL;
138
140 goto free_config;
141
142 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Load member configuration: %s\n",
144
146
148 {
150
151 if (GNUNET_OK != GNUNET_CONFIGURATION_get_data (cfg, "member", "id", &id,
152 sizeof(id)))
153 goto destroy_config;
154
155 member = add_store_member (store, &id);
156 }
157
158destroy_config:
159
161
162free_config:
164
165 if (! member)
166 return;
167
168 char *scan_dir;
169 GNUNET_asprintf (&scan_dir, "%s%s%c", directory, "sessions", DIR_SEPARATOR);
170
173
175}
176
177
180 const struct GNUNET_HashCode *key,
181 void *value)
182{
183 const char *sessions_directory = cls;
184
185 char *load_dir;
186 GNUNET_asprintf (&load_dir, "%s%s%c", sessions_directory, GNUNET_h2s (key),
188
189 struct GNUNET_MESSENGER_MemberSession *session = value;
190
192 load_member_session_next (session, load_dir);
193
194 GNUNET_free (load_dir);
195 return GNUNET_YES;
196}
197
198
199void
201 const char *directory)
202{
203 GNUNET_assert ((member) && (directory));
204
205 char *load_dir;
206 GNUNET_asprintf (&load_dir, "%s%s%c", directory, "sessions", DIR_SEPARATOR);
207
209 iterate_load_next_session, load_dir);
210
211 GNUNET_free (load_dir);
212}
213
214
217 const struct GNUNET_HashCode *key,
218 void *value)
219{
220 const char *sessions_directory = cls;
221
222 char *save_dir;
223 GNUNET_asprintf (&save_dir, "%s%s%c", sessions_directory, GNUNET_h2s (key),
225
226 struct GNUNET_MESSENGER_MemberSession *session = value;
227
228 if ((GNUNET_YES == GNUNET_DISK_directory_test (save_dir, GNUNET_NO)) ||
230 save_member_session (session, save_dir);
231
232 GNUNET_free (save_dir);
233 return GNUNET_YES;
234}
235
236
237void
239 const char *directory)
240{
241 GNUNET_assert ((member) && (directory));
242
243 char *config_file;
244 GNUNET_asprintf (&config_file, "%s%s", directory, "member.cfg");
245
246 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Save member configuration: %s\n",
248
250
251 char *id_data = GNUNET_STRINGS_data_to_string_alloc (&(member->id),
252 sizeof(member->id));
253
254 if (id_data)
255 {
256 GNUNET_CONFIGURATION_set_value_string (cfg, "member", "id", id_data);
257
258 GNUNET_free (id_data);
259 }
260
263
265
266 char *save_dir;
267 GNUNET_asprintf (&save_dir, "%s%s%c", directory, "sessions", DIR_SEPARATOR);
268
269 if ((GNUNET_YES == GNUNET_DISK_directory_test (save_dir, GNUNET_NO)) ||
272 iterate_save_session, save_dir);
273
274 GNUNET_free (save_dir);
275}
276
277
278static void
281{
282 GNUNET_assert ((session) && (next));
283
284 if (session == next)
285 return;
286
287 if (next->next)
288 sync_session_contact_from_next (session, next->next);
289 else
290 session->contact = next->contact;
291}
292
293
296 const struct GNUNET_HashCode *key,
297 void *value)
298{
299 struct GNUNET_MESSENGER_MemberSession *session = value;
300
301 if (session->next)
302 sync_session_contact_from_next (session, session->next);
303
304 return GNUNET_YES;
305}
306
307
308void
310{
312
315}
316
317
321{
323
324 struct GNUNET_HashCode hash;
325 GNUNET_CRYPTO_hash (public_key, sizeof(*public_key), &hash);
326
327 return GNUNET_CONTAINER_multihashmap_get (member->sessions, &hash);
328}
329
330
332{
334 const struct GNUNET_HashCode *hash;
335
337};
338
341 const struct GNUNET_HashCode *key,
342 void *value)
343{
344 struct GNUNET_MESSENGER_ClosureSearchSession *search = cls;
345 struct GNUNET_MESSENGER_MemberSession *session = value;
346
347 if (GNUNET_OK != verify_member_session_as_sender (session, search->message,
348 search->hash))
349 return GNUNET_YES;
350
351 search->match = session;
352 return GNUNET_NO;
353}
354
355
359{
361 public_key);
362
363 if (session)
364 return session;
365
367
368 if (session)
369 add_member_session (member, session);
370
371 return session;
372}
373
374
377 const struct GNUNET_MESSENGER_Message *message,
378 const struct GNUNET_HashCode *hash)
379{
380 GNUNET_assert ((member) && (message) && (hash) &&
381 (0 == GNUNET_memcmp (&(member->id),
382 &(message->header.sender_id))));
383
384 if (GNUNET_MESSENGER_KIND_JOIN == message->header.kind)
385 return try_member_session (member, &(message->body.join.key));
386
388
389 search.message = message;
390 search.hash = hash;
391
392 search.match = NULL;
394 iterate_search_session, &search);
395
396 return search.match;
397}
398
399
400void
402 struct GNUNET_MESSENGER_MemberSession *session)
403{
404 if (! session)
405 return;
406
407 GNUNET_assert ((member) && (session->member == member));
408
409 const struct GNUNET_CRYPTO_PublicKey *public_key =
411
412 struct GNUNET_HashCode hash;
413 GNUNET_CRYPTO_hash (public_key, sizeof(*public_key), &hash);
414
416 member->sessions, &hash, session,
419 "Adding a member session failed: %s\n",
420 GNUNET_h2s (&hash));
421}
422
423
424void
426 struct GNUNET_MESSENGER_MemberSession *session)
427{
428 GNUNET_assert ((member) && (session) && (session->member == member));
429
430 const struct GNUNET_CRYPTO_PublicKey *public_key =
432
433 struct GNUNET_HashCode hash;
434 GNUNET_CRYPTO_hash (public_key, sizeof(*public_key), &hash);
435
437 &hash, session))
439 "Removing a member session failed: %s\n",
440 GNUNET_h2s (&hash));
441}
442
443
445{
447 void *cls;
448};
449
452 const struct GNUNET_HashCode *key,
453 void *value)
454{
456 struct GNUNET_MESSENGER_MemberSession *session = value;
457
458 return iterate->it (iterate->cls, get_member_session_public_key (session),
459 session);
460}
461
462
463int
466 void *cls)
467{
468 GNUNET_assert ((member) && (member->sessions) && (it));
469
471
472 iterate.it = it;
473 iterate.cls = cls;
474
477 &iterate);
478}
479
480
481void
483 struct GNUNET_MESSENGER_Subscription *subscription)
484{
485 GNUNET_assert ((member) && (member->subscriptions) && (subscription));
486
487 const struct GNUNET_ShortHashCode *discourse;
488 discourse = get_subscription_discourse(subscription);
489
491 member->subscriptions, discourse, subscription,
494 "Adding a member subscription failed: %s\n",
495 GNUNET_sh2s (discourse));
496}
497
498
499void
501 struct GNUNET_MESSENGER_Subscription *subscription)
502{
503 GNUNET_assert ((member) && (member->subscriptions) && (subscription));
504
505 const struct GNUNET_ShortHashCode *discourse;
506 discourse = get_subscription_discourse(subscription);
507
509 discourse,
510 subscription))
512 "Removing a member subscription failed: %s\n",
513 GNUNET_sh2s (discourse));
514}
515
516
519 const struct GNUNET_ShortHashCode *discourse)
520{
522
524}
525
526
527int
530 void *cls)
531{
532 GNUNET_assert ((member) && (member->subscriptions) && (it));
533
536 cls);
537}
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:109
static char * config_file
Set to the name of the config file used.
Definition: gnunet-arm.c:84
struct GNUNET_HashCode key
The key used in the DHT.
static char * filename
static struct GNUNET_IDENTITY_Handle * id
Handle to IDENTITY.
static char * value
Value of the record to add/remove.
static enum GNUNET_GenericReturnValue iterate_member_sessions_it(void *cls, const struct GNUNET_HashCode *key, void *value)
void add_member_subscription(struct GNUNET_MESSENGER_Member *member, struct GNUNET_MESSENGER_Subscription *subscription)
Adds a given subscription to a member.
const struct GNUNET_ShortHashCode * get_member_id(const struct GNUNET_MESSENGER_Member *member)
Returns the current id of a given member.
void remove_member_session(struct GNUNET_MESSENGER_Member *member, struct GNUNET_MESSENGER_MemberSession *session)
Removes a given member session from its member.
struct GNUNET_MESSENGER_MemberSession * get_member_session_of(struct GNUNET_MESSENGER_Member *member, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Returns the member session of a member using a public key which can verify the signature of a given m...
static void sync_session_contact_from_next(struct GNUNET_MESSENGER_MemberSession *session, struct GNUNET_MESSENGER_MemberSession *next)
static struct GNUNET_MESSENGER_MemberSession * try_member_session(struct GNUNET_MESSENGER_Member *member, const struct GNUNET_CRYPTO_PublicKey *public_key)
void save_member(struct GNUNET_MESSENGER_Member *member, const char *directory)
Saves data from a member into a directory which can be load to restore the member completely.
static enum GNUNET_GenericReturnValue iterate_sync_session_contact(void *cls, const struct GNUNET_HashCode *key, void *value)
void destroy_member(struct GNUNET_MESSENGER_Member *member)
Destroys a member and frees its memory fully.
struct GNUNET_MESSENGER_MemberSession * get_member_session(const struct GNUNET_MESSENGER_Member *member, const struct GNUNET_CRYPTO_PublicKey *public_key)
Returns the member session of a member identified by a given public key.
struct GNUNET_MESSENGER_Subscription * get_member_subscription(struct GNUNET_MESSENGER_Member *member, const struct GNUNET_ShortHashCode *discourse)
Returns the active subscription of a given member to a selected discourse.
static enum GNUNET_GenericReturnValue iterate_destroy_subscription(void *cls, const struct GNUNET_ShortHashCode *key, void *value)
static enum GNUNET_GenericReturnValue iterate_destroy_session(void *cls, const struct GNUNET_HashCode *key, void *value)
struct GNUNET_MESSENGER_Member * create_member(struct GNUNET_MESSENGER_MemberStore *store, const struct GNUNET_ShortHashCode *id)
Creates and allocates a new member of a room with an optionally defined or random id.
void remove_member_subscription(struct GNUNET_MESSENGER_Member *member, struct GNUNET_MESSENGER_Subscription *subscription)
Removes a given subscription from a member.
void load_member_next_sessions(const struct GNUNET_MESSENGER_Member *member, const char *directory)
Loads data about next sessions from a directory into an empty loaded member which does not contain a ...
static enum GNUNET_GenericReturnValue iterate_load_next_session(void *cls, const struct GNUNET_HashCode *key, void *value)
void add_member_session(struct GNUNET_MESSENGER_Member *member, struct GNUNET_MESSENGER_MemberSession *session)
Adds a given member session to its member.
void sync_member_contacts(struct GNUNET_MESSENGER_Member *member)
Synchronizes contacts between all sessions from a given member and other sessions which are linked to...
int iterate_member_subscriptions(struct GNUNET_MESSENGER_Member *member, GNUNET_MESSENGER_SubscriptionIteratorCallback it, void *cls)
Iterate through all subscriptions of a given member and call the provided iterator callback with a se...
int iterate_member_sessions(struct GNUNET_MESSENGER_Member *member, GNUNET_MESSENGER_MemberIteratorCallback it, void *cls)
Iterate through all member sessions currently connected to a given member and call the provided itera...
void load_member(struct GNUNET_MESSENGER_MemberStore *store, const char *directory)
Loads data from a directory into a new allocated and created member of a store if the required inform...
static enum GNUNET_GenericReturnValue callback_scan_for_sessions(void *cls, const char *filename)
static enum GNUNET_GenericReturnValue iterate_search_session(void *cls, const struct GNUNET_HashCode *key, void *value)
static enum GNUNET_GenericReturnValue iterate_save_session(void *cls, const struct GNUNET_HashCode *key, void *value)
enum GNUNET_GenericReturnValue(* GNUNET_MESSENGER_SubscriptionIteratorCallback)(void *cls, const struct GNUNET_ShortHashCode *discourse, struct GNUNET_MESSENGER_Subscription *subscribtion)
void destroy_member_session(struct GNUNET_MESSENGER_MemberSession *session)
Destroys a member session and frees its memory fully.
const struct GNUNET_CRYPTO_PublicKey * get_member_session_public_key(const struct GNUNET_MESSENGER_MemberSession *session)
Returns the public key of a given member session.
void load_member_session_next(struct GNUNET_MESSENGER_MemberSession *session, const char *directory)
Loads the connection from one session to another through the next attribute.
void load_member_session(struct GNUNET_MESSENGER_Member *member, const char *directory)
Loads data from a directory into a new allocated and created member session of a member if the requir...
void save_member_session(struct GNUNET_MESSENGER_MemberSession *session, const char *directory)
Saves data from a member session into a directory which can be load to restore the member session com...
struct GNUNET_MESSENGER_MemberSession * create_member_session(struct GNUNET_MESSENGER_Member *member, const struct GNUNET_CRYPTO_PublicKey *pubkey)
Creates and allocates a new member session of a member with a given public key.
enum GNUNET_GenericReturnValue verify_member_session_as_sender(const struct GNUNET_MESSENGER_MemberSession *session, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Verifies a given member session as sender of a selected message and its hash.
struct GNUNET_MESSENGER_Member * add_store_member(struct GNUNET_MESSENGER_MemberStore *store, const struct GNUNET_ShortHashCode *id)
Adds a member to a store under a specific id and returns it on success.
enum GNUNET_GenericReturnValue(* GNUNET_MESSENGER_MemberIteratorCallback)(void *cls, const struct GNUNET_CRYPTO_PublicKey *public_key, struct GNUNET_MESSENGER_MemberSession *session)
const struct GNUNET_ShortHashCode * get_subscription_discourse(const struct GNUNET_MESSENGER_Subscription *subscribtion)
void destroy_subscription(struct GNUNET_MESSENGER_Subscription *subscribtion)
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_data(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, void *buf, size_t buf_size)
Get Crockford32-encoded fixed-size binary data from a configuration.
void GNUNET_CONFIGURATION_set_value_string(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, const char *value)
Set a configuration value that should be a string.
void GNUNET_CONFIGURATION_destroy(struct GNUNET_CONFIGURATION_Handle *cfg)
Destroy configuration object.
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_create(void)
Create a new configuration object.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_parse(struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
Parse a configuration file, add all of the options in the file to the configuration environment.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_write(struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
Write configuration file.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory).
Definition: disk.c:482
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_test(const char *fil, int is_readable)
Test if fil is a directory and listable.
Definition: disk.c:403
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:496
int GNUNET_DISK_directory_scan(const char *dir_name, GNUNET_FileNameCallback callback, void *callback_cls)
Scan a directory for files.
Definition: disk.c:814
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
enum GNUNET_GenericReturnValue(* GNUNET_CONTAINER_ShortmapIterator)(void *cls, const struct GNUNET_ShortHashCode *key, void *value)
Iterator over hash map entries.
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.
enum GNUNET_GenericReturnValue 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_MultiShortmap * GNUNET_CONTAINER_multishortmap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multishortmap_put(struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
enum GNUNET_GenericReturnValue 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.
void * GNUNET_CONTAINER_multishortmap_get(const struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key)
Given a key find a value in the map matching the key.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
int GNUNET_CONTAINER_multishortmap_iterate(struct GNUNET_CONTAINER_MultiShortmap *map, GNUNET_CONTAINER_ShortmapIterator it, void *it_cls)
Iterate over all entries in the map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
void GNUNET_CONTAINER_multishortmap_destroy(struct GNUNET_CONTAINER_MultiShortmap *map)
Destroy a hash map.
int GNUNET_CONTAINER_multishortmap_remove(struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key, const void *value)
Remove the given key-value pair from the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST
, ' bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE...
#define GNUNET_log(kind,...)
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const char * GNUNET_sh2s(const struct GNUNET_ShortHashCode *shc)
Convert a short hash value to a string (for printing debug messages).
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_DEBUG
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
@ GNUNET_MESSENGER_KIND_JOIN
The join kind.
char * GNUNET_STRINGS_data_to_string_alloc(const void *buf, size_t size)
Return the base32crockford encoding of the given buffer.
Definition: strings.c:764
enum GNUNET_GenericReturnValue generate_free_member_id(struct GNUNET_ShortHashCode *id, const struct GNUNET_CONTAINER_MultiShortmap *members)
Tries to generate an unused member id and store it into the id parameter.
#define DIR_SEPARATOR
Definition: platform.h:165
An identity key as per LSD0001.
A 512-bit hashcode.
GNUNET_MESSENGER_MemberIteratorCallback it
const struct GNUNET_MESSENGER_Message * message
struct GNUNET_MESSENGER_MemberSession * match
struct GNUNET_MESSENGER_MemberSession * next
struct GNUNET_CONTAINER_MultiShortmap * members
struct GNUNET_CONTAINER_MultiHashMap * sessions
struct GNUNET_CONTAINER_MultiShortmap * subscriptions
struct GNUNET_MESSENGER_MemberStore * store
struct GNUNET_ShortHashCode id
struct GNUNET_MESSENGER_MessageJoin join
enum GNUNET_MESSENGER_MessageKind kind
The kind of the message.
struct GNUNET_ShortHashCode sender_id
The senders id inside of the room the message was sent in.
struct GNUNET_CRYPTO_PublicKey key
The senders public key to verify its signatures.
struct GNUNET_MESSENGER_MessageHeader header
Header.
struct GNUNET_MESSENGER_MessageBody body
Body.
A 256-bit hashcode.