GNUnet 0.27.0
 
Loading...
Searching...
No Matches
gnunet-service-messenger_message_send.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2020--2026 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 */
27
34#include "gnunet_common.h"
35
44
45static void
48 enum GNUNET_GenericReturnValue check_permission)
49{
50 struct GNUNET_MESSENGER_MessageStore *message_store;
51 struct GNUNET_MESSENGER_ListMessage *element;
52
53 GNUNET_assert ((notify) && (session));
54
55 if (session->prev)
56 notify_about_members (notify, session->prev, GNUNET_YES);
57
58 message_store = get_srv_room_message_store (notify->room);
59
61 "Notify through all of member session: %s\n",
63
64 for (element = session->messages.head; element; element = element->next)
65 {
66 const struct GNUNET_MESSENGER_Message *message;
67
68 if ((notify->map) &&
70 &(element->hash))
71 ))
72 continue;
73
74 if ((GNUNET_YES == check_permission) &&
76 &(element->hash),
77 GNUNET_NO)))
78 {
80 "Permission for notification of session message denied!\n");
81 continue;
82 }
83
84 if ((notify->map) &&
85 (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (notify->map, &(element
86 ->hash),
87 NULL,
89
90
91
93 "Notification of session message could be duplicated!\n");
94
95 message = get_store_message (message_store, &(element->hash));
96
97 if ((! message) || (GNUNET_YES == is_peer_message (message)))
98 {
100 "Session message for notification is invalid!\n");
101 continue;
102 }
103
104 {
105 struct GNUNET_MESSENGER_SenderSession sender;
106 const struct GNUNET_HashCode *epoch;
107
108 sender.member = session;
109 epoch = get_store_message_epoch (message_store, &(element->hash));
110
111 notify_srv_handle_message (notify->handle, notify->room, &sender, message,
112 &(element->hash), epoch, GNUNET_NO);
113 }
114 }
115}
116
117
120 const struct
122 struct GNUNET_MESSENGER_SrvMemberSession *session)
123{
124 struct GNUNET_MESSENGER_MemberNotify *notify;
125
126 GNUNET_assert ((cls) && (session));
127
128 notify = cls;
129
130 if ((notify->session == session) ||
132 return GNUNET_YES;
133
134 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Notify about member session: %s\n",
136
138 return GNUNET_YES;
139}
140
141
144 const struct
147 )
148{
149 struct GNUNET_MESSENGER_MemberNotify *notify;
150 struct GNUNET_MESSENGER_MessageStore *message_store;
151 struct GNUNET_MESSENGER_ListMessage *element;
152
153 GNUNET_assert ((cls) && (session));
154
155 notify = cls;
156
157 if ((notify->session == session) ||
159 return GNUNET_YES;
160
161 message_store = get_srv_room_message_store (notify->room);
162
163 for (element = session->messages.head; element; element = element->next)
164 {
165 const struct GNUNET_MESSENGER_Message *message;
166
168 &(element->hash)))
169 continue;
170
171 message = get_store_message (message_store, &(element->hash));
172
173 if ((! message) ||
174 ((GNUNET_MESSENGER_KIND_JOIN != message->header.kind) &&
176 continue;
177
179 "Mark member session being labeled as important: %s\n",
181
182 GNUNET_CONTAINER_multihashmap_put (notify->map, &(element->hash), session,
184 }
185
186 return GNUNET_YES;
187}
188
189
192 const struct GNUNET_HashCode *hash);
193
194
197 const struct GNUNET_HashCode *hash,
198 const struct GNUNET_MESSENGER_Message *message)
199{
200 struct GNUNET_MESSENGER_SrvMemberSession *session;
201 enum GNUNET_GenericReturnValue notification;
202 struct GNUNET_PeerIdentity *peer_identity;
203
204 GNUNET_assert ((notify) && (message) && (hash));
205
206 session = GNUNET_CONTAINER_multihashmap_get (notify->map, hash);
207
208 if (session)
209 {
211 "Unmark member session from labeled as important: %s\n",
213
214 GNUNET_CONTAINER_multihashmap_put (notify->map, hash, NULL,
216 notify->epoch_counter++;
217
218 notification = GNUNET_YES;
219 }
221 hash))
222 return GNUNET_YES;
223 else
224 notification = GNUNET_NO;
225
226 peer_identity = NULL;
227
228 switch (message->header.kind)
229 {
231 if (GNUNET_YES == traverse_epoch_message (notify, &(message->body.join.epoch
232 )))
233 notification = GNUNET_YES;
234 break;
236 if (GNUNET_YES == traverse_epoch_message (notify, &(message->body.leave.
237 epoch)))
238 notification = GNUNET_YES;
239 break;
241 {
242 struct GNUNET_MESSENGER_PeerStore *peer_store;
243
244 peer_store = get_srv_room_peer_store (notify->room);
245
246 if (peer_store)
247 peer_identity = get_store_peer_of (peer_store, message, hash);
248
249 if (GNUNET_YES == traverse_epoch_message (notify, &(message->body.merge.
250 epochs[0])))
251 notification = GNUNET_YES;
252 if (GNUNET_YES == traverse_epoch_message (notify, &(message->body.merge.
253 epochs[1])))
254 notification = GNUNET_YES;
255 break;
256 }
257 default:
258 break;
259 }
260
261 if (GNUNET_YES != notification)
262 return notification;
263
264 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Notify about past epoch: %s\n",
265 GNUNET_h2s (hash));
266
267 if (! session)
268 {
269 struct GNUNET_MESSENGER_MemberStore *member_store;
270 struct GNUNET_MESSENGER_Member *member = NULL;
271
273 goto skip_session;
274
275 member_store = get_srv_room_member_store (notify->room);
276
277 if (member_store)
278 member = get_store_member_of (member_store, message);
279
280 if (member)
281 session = get_member_session_of (member, message, hash);
282
283skip_session:
284 GNUNET_CONTAINER_multihashmap_put (notify->map, hash, NULL,
286 }
287
288 {
289 struct GNUNET_MESSENGER_SenderSession sender;
290
291 if (session)
292 sender.member = session;
293 else if (peer_identity)
294 sender.peer = peer_identity;
295 else
296 {
298 "No valid sender session for message: %s\n",
299 GNUNET_h2s (hash));
300 return notification;
301 }
302
303 notify_srv_handle_message (notify->handle, notify->room, &sender, message,
304 hash, hash, GNUNET_NO);
305 }
306
307 return notification;
308}
309
310
313 const struct GNUNET_HashCode *hash)
314{
315 struct GNUNET_MESSENGER_MessageStore *message_store;
316 const struct GNUNET_MESSENGER_Message *message;
317
318 GNUNET_assert ((notify) && (hash));
319
320 if (GNUNET_is_zero (hash))
321 return GNUNET_NO;
322
324 return GNUNET_NO;
325
326 message_store = get_srv_room_message_store (notify->room);
327
328 if (! message_store)
329 return GNUNET_NO;
330
331 message = get_store_message (message_store, hash);
332
333 if (! message)
334 return GNUNET_NO;
335
336 return traverse_epoch_session_message (notify, hash, message);
337}
338
339
340void
343 const struct GNUNET_MESSENGER_Message *message,
344 const struct GNUNET_HashCode *hash)
345{
346 struct GNUNET_MESSENGER_MemberStore *member_store;
347 struct GNUNET_MESSENGER_Member *member;
348 struct GNUNET_MESSENGER_SrvMemberSession *session;
349
350 set_srv_handle_key (handle, &(message->body.join.key));
351
352 member_store = get_srv_room_member_store (room);
353 member = add_store_member (member_store,
354 &(message->header.sender_id));
355
356 if (! member)
357 {
359 "A member could not join with ID: %s\n",
360 GNUNET_sh2s (&(message->header.sender_id)));
361 goto skip_member_notification;
362 }
363
364 session = get_member_session_of (member, message, hash);
365
366 if (! session)
367 {
369 "A valid session is required to join a room!\n");
370 goto skip_member_notification;
371 }
372
373 {
374 struct GNUNET_MESSENGER_MemberNotify notify;
375
376 notify.room = room;
377 notify.handle = handle;
378 notify.session = session;
380 notify.epoch_counter = 0;
381
382 if (notify.map)
383 {
384 uint32_t epoch_count;
385
387 notify);
388
389 epoch_count = GNUNET_CONTAINER_multihashmap_size (notify.map);
390
392 "Notify about all (%u) related epochs for current membership verification!\n",
393 epoch_count);
394
395 traverse_epoch_message (&notify, &(message->body.join.epoch));
396
397 if (epoch_count > notify.epoch_counter)
398 {
399 uint32_t missing;
400
401 missing = epoch_count - notify.epoch_counter;
402
404 "Missing at least %u epoch%s for current membership verification!\n",
405 missing, missing > 1? "s" : "");
406 }
407 }
408
410 "Notify about all member sessions except: %s\n",
412
414
415 if (notify.map)
417 }
418
419skip_member_notification:
421}
422
423
424void
427 const struct GNUNET_MESSENGER_Message *message,
428 const struct GNUNET_HashCode *hash)
429{
430 set_srv_handle_key (handle, &(message->body.key.key));
431}
432
433
434void
437 const struct GNUNET_MESSENGER_Message *message,
438 const struct GNUNET_HashCode *hash)
439{
441
442 if (! room->peer_message)
443 room->peer_message = GNUNET_new (struct GNUNET_HashCode);
444
445 GNUNET_memcpy (room->peer_message, hash, sizeof(struct GNUNET_HashCode));
446
448
449 if (! msg)
451 "Sending connection message failed: %s\n",
452 GNUNET_h2s (&(room->key)));
453 else
454 send_srv_room_message (room, room->host, msg);
455}
456
457
458void
461 const struct GNUNET_MESSENGER_Message *message,
462 const struct GNUNET_HashCode *hash)
463{
465 &(message->body.id.id));
466}
467
468
469void
472 const struct GNUNET_MESSENGER_Message *message,
473 const struct GNUNET_HashCode *hash)
474{
475 struct GNUNET_MESSENGER_OperationStore *operation_store;
476
477 operation_store = get_srv_room_operation_store (room);
478
480 operation_store,
481 &(message->body.request.hash),
484}
struct GNUNET_MessageHeader * msg
Definition 005.c:2
static unsigned int epochs
-e option.
void notify_srv_handle_message(struct GNUNET_MESSENGER_SrvHandle *handle, struct GNUNET_MESSENGER_SrvRoom *room, const struct GNUNET_MESSENGER_SenderSession *session, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash, const struct GNUNET_HashCode *epoch, enum GNUNET_GenericReturnValue recent)
Notifies the handle that a new message was received or sent.
enum GNUNET_GenericReturnValue change_srv_handle_member_id(struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_HashCode *key, const struct GNUNET_ShortHashCode *unique_id)
Changes the member id of a given handle in a specific room to match a unique_id and returns GNUNET_OK...
void set_srv_handle_key(struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_CRYPTO_BlindablePublicKey *key)
Sets the public key of a given handle.
struct GNUNET_MESSENGER_SrvMemberSession * 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...
enum GNUNET_GenericReturnValue is_member_session_completed(const struct GNUNET_MESSENGER_SrvMemberSession *session)
Returns if the given member session has been completed.
const struct GNUNET_ShortHashCode * get_member_session_id(const struct GNUNET_MESSENGER_SrvMemberSession *session)
Returns the member id of a given member session.
enum GNUNET_GenericReturnValue check_member_session_history(const struct GNUNET_MESSENGER_SrvMemberSession *session, const struct GNUNET_HashCode *hash, enum GNUNET_GenericReturnValue ownership)
Checks the history of a session for a specific message which is identified by its hash and if the own...
struct GNUNET_MESSENGER_Member * get_store_member_of(struct GNUNET_MESSENGER_MemberStore *store, const struct GNUNET_MESSENGER_Message *message)
Returns the member of a store using a sender id of a given message.
int iterate_store_members(struct GNUNET_MESSENGER_MemberStore *store, GNUNET_MESSENGER_MemberIteratorCallback it, void *cls)
Iterate through all member sessions currently connected to the members of the given member store and ...
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.
struct GNUNET_MESSENGER_Message * create_message_connection(const struct GNUNET_MESSENGER_SrvRoom *room)
Creates and allocates a new connection message containing the amount of the peer's connections in a g...
static enum GNUNET_GenericReturnValue traverse_epoch_message(struct GNUNET_MESSENGER_MemberNotify *notify, const struct GNUNET_HashCode *hash)
static enum GNUNET_GenericReturnValue traverse_epoch_session_message(struct GNUNET_MESSENGER_MemberNotify *notify, const struct GNUNET_HashCode *hash, const struct GNUNET_MESSENGER_Message *message)
static enum GNUNET_GenericReturnValue iterate_epoch_session_members(void *cls, const struct GNUNET_CRYPTO_BlindablePublicKey *public_key, struct GNUNET_MESSENGER_SrvMemberSession *session)
void send_message_id(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a sent id message to update the handles member id in the room.
static void notify_about_members(struct GNUNET_MESSENGER_MemberNotify *notify, struct GNUNET_MESSENGER_SrvMemberSession *session, enum GNUNET_GenericReturnValue check_permission)
static enum GNUNET_GenericReturnValue iterate_notify_about_members(void *cls, const struct GNUNET_CRYPTO_BlindablePublicKey *public_key, struct GNUNET_MESSENGER_SrvMemberSession *session)
void send_message_request(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a sent request message to trigger the request operation for this service.
void send_message_join(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a sent join message to ensure growth of the decentralized room structure.
void send_message_key(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a sent key message to ensure changes to the public key of the sending handle.
void send_message_peer(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles a sent peer message to update the rooms peer message of this service.
const struct GNUNET_HashCode * get_store_message_epoch(const struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash)
Returns the epoch hash of a message from a message store matching a given hash.
const struct GNUNET_MESSENGER_Message * get_store_message(struct GNUNET_MESSENGER_MessageStore *store, const struct GNUNET_HashCode *hash)
Returns the message from a message store matching a given hash.
enum GNUNET_GenericReturnValue use_store_operation(struct GNUNET_MESSENGER_OperationStore *store, const struct GNUNET_HashCode *hash, enum GNUNET_MESSENGER_OperationType type, struct GNUNET_TIME_Relative delay)
Tries to use an operation under a given hash in a specific operation store.
struct GNUNET_PeerIdentity * get_store_peer_of(struct GNUNET_MESSENGER_PeerStore *store, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Returns the peer identity inside the store which verifies the signature of a given message as valid.
struct GNUNET_MESSENGER_MessageStore * get_srv_room_message_store(struct GNUNET_MESSENGER_SrvRoom *room)
Returns the used message store of a given room.
struct GNUNET_MESSENGER_PeerStore * get_srv_room_peer_store(struct GNUNET_MESSENGER_SrvRoom *room)
Returns the used peer store of a given room.
void check_srv_room_peer_status(struct GNUNET_MESSENGER_SrvRoom *room, struct GNUNET_MESSENGER_SrvTunnel *tunnel)
Checks the current state of opening a given room from this peer and re-publishes it if necessary to a...
enum GNUNET_GenericReturnValue send_srv_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.
struct GNUNET_MESSENGER_OperationStore * get_srv_room_operation_store(struct GNUNET_MESSENGER_SrvRoom *room)
Returns the used operation store of a given room.
const struct GNUNET_HashCode * get_srv_room_key(const struct GNUNET_MESSENGER_SrvRoom *room)
Returns the shared secret you need to access a room.
struct GNUNET_MESSENGER_MemberStore * get_srv_room_member_store(struct GNUNET_MESSENGER_SrvRoom *room)
Returns the used member store of a given room.
#define GNUNET_MESSENGER_REQUEST_DELAY
static struct GNUNET_VPN_Handle * handle
Handle to vpn service.
Definition gnunet-vpn.c:35
commonly used definitions; globals in this file are exempt from the rule that the module name ("commo...
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL).
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_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.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST
, ' bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE...
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE
If a value with the given key exists, replace it.
#define GNUNET_is_zero(a)
Check that memory in a is all zeros.
#define GNUNET_log(kind,...)
#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_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_new(type)
Allocate a struct or union of the given type.
@ GNUNET_MESSENGER_KIND_LEAVE
The leave kind.
@ GNUNET_MESSENGER_KIND_JOIN
The join kind.
@ GNUNET_MESSENGER_KIND_MERGE
The merge kind.
enum GNUNET_GenericReturnValue is_peer_message(const struct GNUNET_MESSENGER_Message *message)
Returns whether a specific kind of message can be sent by the service without usage of a clients priv...
Internal representation of the hash map.
An identity key as per LSD0001.
A 512-bit hashcode.
struct GNUNET_MESSENGER_ListMessage * next
struct GNUNET_MESSENGER_ListMessage * head
struct GNUNET_CONTAINER_MultiHashMap * map
struct GNUNET_MESSENGER_SrvMemberSession * session
struct GNUNET_MESSENGER_SrvHandle * handle
struct GNUNET_MESSENGER_MessageRequest request
struct GNUNET_MESSENGER_MessageMerge merge
struct GNUNET_MESSENGER_MessageId id
struct GNUNET_MESSENGER_MessageLeave leave
struct GNUNET_MESSENGER_MessageKey key
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_ShortHashCode id
The new id which will replace the senders id in a room.
struct GNUNET_CRYPTO_BlindablePublicKey key
The senders blindable public key to verify its signatures.
struct GNUNET_HashCode epoch
The previous epoch the message was sent from.
struct GNUNET_CRYPTO_BlindablePublicKey key
The new blindable public key which replaces the current senders public key.
struct GNUNET_HashCode hash
The hash of the requested message.
struct GNUNET_MESSENGER_MessageHeader header
Header.
struct GNUNET_MESSENGER_MessageBody body
Body.
struct GNUNET_MESSENGER_SrvMemberSession * member
struct GNUNET_MESSENGER_SrvMemberSession * prev
struct GNUNET_MESSENGER_SrvHandle * host
The identity of the host (wraps the signing key of the peer).