GNUnet 0.21.2
gnunet-service-messenger_peer_store.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2023--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 */
27
29#include "gnunet_common.h"
31#include "messenger_api_util.h"
32
34{
37};
38
39void
42{
43 GNUNET_assert ((store) && (service));
44
45 store->service = service;
47}
48
49
51iterate_destroy_peers (void *cls, const struct GNUNET_ShortHashCode *id,
52 void *value)
53{
55 GNUNET_free (entry);
56 return GNUNET_YES;
57}
58
59
60void
62{
63 GNUNET_assert ((store) && (store->peers));
64
65 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Clear peer store\n");
66
68 NULL);
70
71 store->peers = NULL;
72}
73
74
75void
77 const char *path)
78{
79 GNUNET_assert ((store) && (path));
80
82 return;
83
84 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Load peer store from path: %s\n",
85 path);
86
89 );
90
92 path, GNUNET_DISK_OPEN_READ, permission
93 );
94
95 if (! handle)
96 return;
97
99
102 struct GNUNET_PeerIdentity peer;
103 ssize_t len;
104
105 do {
106 len = GNUNET_DISK_file_read (handle, &peer, sizeof(peer));
107
108 if (len != sizeof(peer))
109 break;
110
111
113
114 if (! entry)
115 continue;
116
117 GNUNET_memcpy (&(entry->peer), &peer, sizeof(entry->peer));
118 entry->active = GNUNET_YES;
119
121
123 store->peers, &peer_id, entry,
125 continue;
126
127 GNUNET_free (entry);
128 } while (len == sizeof(peer));
129
131}
132
133
135iterate_save_peers (void *cls, const struct GNUNET_ShortHashCode *id,
136 void *value)
137{
138 struct GNUNET_DISK_FileHandle *handle = cls;
140
141 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Save peer store entry: %s\n",
142 GNUNET_sh2s (id));
143
144 if ((! entry) || (GNUNET_YES != entry->active))
145 return GNUNET_YES;
146
147 GNUNET_DISK_file_write (handle, &(entry->peer), sizeof(entry->peer));
148 return GNUNET_YES;
149}
150
151
152void
154 const char *path)
155{
156 GNUNET_assert ((store) && (path));
157
158 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Save peer store to path: %s\n",
159 path);
160
163 );
164
167 );
168
169 if (! handle)
170 return;
171
174 handle);
175
178}
179
180
182{
184 const struct GNUNET_HashCode *hash;
186};
187
189verify_store_peer (void *cls, const struct GNUNET_ShortHashCode *id,
190 void *value)
191{
194
195 if (! entry)
196 return GNUNET_YES;
197
198 if (GNUNET_OK == verify_message_by_peer (verify->message,
199 verify->hash, &(entry->peer)))
200 {
201 verify->sender = &(entry->peer);
202 return GNUNET_NO;
203 }
204
205 return GNUNET_YES;
206}
207
208
211 const struct GNUNET_PeerIdentity *peer,
212 const struct GNUNET_ShortHashCode *id,
214{
215 GNUNET_assert ((store) && (peer));
216
219
220 if (! entry)
221 return NULL;
222
223 GNUNET_memcpy (&(entry->peer), peer, sizeof(entry->peer));
224 entry->active = active;
225
227 store->peers, id, entry,
229 {
230 GNUNET_free (entry);
231 return NULL;
232 }
233
234 return entry;
235}
236
237
238static const struct GNUNET_PeerIdentity*
240{
241 static struct GNUNET_PeerIdentity peer;
242
243 if (GNUNET_OK != get_service_peer_identity (store->service, &peer))
244 return NULL;
245
246 return &peer;
247}
248
249
252 const struct GNUNET_MESSENGER_Message *message,
253 const struct GNUNET_HashCode *hash)
254{
255 GNUNET_assert ((store) && (store->peers) && (message) && (hash));
256
257 if (GNUNET_YES != is_peer_message (message))
258 return NULL;
259
261 verify.message = message;
262 verify.hash = hash;
263 verify.sender = NULL;
264
268
269 if (verify.sender)
270 return verify.sender;
271
272 const struct GNUNET_PeerIdentity *peer;
273 enum GNUNET_GenericReturnValue active;
274
275 if (GNUNET_MESSENGER_KIND_PEER == message->header.kind)
276 {
277 peer = &(message->body.peer.peer);
278 active = GNUNET_YES;
279 }
280 else if (GNUNET_MESSENGER_KIND_MISS == message->header.kind)
281 {
282 peer = &(message->body.miss.peer);
283 active = GNUNET_NO;
284 }
285 else
286 {
288 "Peer message does not contain a peer identity\n");
289
290 peer = get_store_service_peer_identity (store);
291 active = GNUNET_NO;
292
293 if (! peer)
294 return NULL;
295 }
296
299
300 if (0 != GNUNET_memcmp (&peer_id, &(message->header.sender_id)))
301 {
303 "Sender id does not match peer identity\n");
304 return NULL;
305 }
306
307 if (GNUNET_OK != verify_message_by_peer (message, hash, peer))
308 {
310 "Verification of message with peer identity failed!\n");
311 }
312
314 entry = add_peer_store_entry (store, peer, &peer_id, active);
315
316 if (! entry)
317 {
319 "Initialization of entry in peer store failed: %s\n",
321
322 return NULL;
323 }
324
325 return &(entry->peer);
326}
327
328
330{
333};
334
336find_store_peer (void *cls, const struct GNUNET_ShortHashCode *id, void *value)
337{
338 struct GNUNET_MESSENGER_ClosureFindPeer *find = cls;
340
341 if (! entry)
342 return GNUNET_YES;
343
344 if (0 == GNUNET_memcmp (find->requested, &(entry->peer)))
345 {
346 find->match = entry;
347 return GNUNET_NO;
348 }
349
350 return GNUNET_YES;
351}
352
353
354void
356 const struct GNUNET_PeerIdentity *peer,
358{
359 GNUNET_assert ((store) && (store->peers) && (peer));
360
363
364 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Update peer store entry: %s\n",
366
368 find.requested = peer;
369 find.match = NULL;
370
372 find_store_peer, &find);
373
374 if (find.match)
375 {
376 find.match->active = active;
377 return;
378 }
379
380 if (! add_peer_store_entry (store, peer, &peer_id, active))
382 "Initial update of entry in peer store failed: %s\n",
384}
static int verify
Verify mode.
Definition: gnunet-abd.c:128
static char * peer_id
Option –peer.
Definition: gnunet-cadet.c:42
static char * value
Value of the record to add/remove.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
void update_store_peer(struct GNUNET_MESSENGER_PeerStore *store, const struct GNUNET_PeerIdentity *peer, enum GNUNET_GenericReturnValue active)
Adds a peer identity to the store if necessary.
static enum GNUNET_GenericReturnValue find_store_peer(void *cls, const struct GNUNET_ShortHashCode *id, void *value)
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.
void load_peer_store(struct GNUNET_MESSENGER_PeerStore *store, const char *path)
Loads peer identities from a file into a peer store.
void clear_peer_store(struct GNUNET_MESSENGER_PeerStore *store)
Clears a peer store, wipes its content and deallocates its memory.
static const struct GNUNET_PeerIdentity * get_store_service_peer_identity(struct GNUNET_MESSENGER_PeerStore *store)
static enum GNUNET_GenericReturnValue iterate_destroy_peers(void *cls, const struct GNUNET_ShortHashCode *id, void *value)
static struct GNUNET_MESSENGER_PeerStoreEntry * add_peer_store_entry(struct GNUNET_MESSENGER_PeerStore *store, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_ShortHashCode *id, enum GNUNET_GenericReturnValue active)
static enum GNUNET_GenericReturnValue verify_store_peer(void *cls, const struct GNUNET_ShortHashCode *id, void *value)
static enum GNUNET_GenericReturnValue iterate_save_peers(void *cls, const struct GNUNET_ShortHashCode *id, void *value)
void save_peer_store(const struct GNUNET_MESSENGER_PeerStore *store, const char *path)
Saves peer identities from a peer store into a file.
void init_peer_store(struct GNUNET_MESSENGER_PeerStore *store, struct GNUNET_MESSENGER_Service *service)
Initializes a peer store as fully empty.
enum GNUNET_GenericReturnValue get_service_peer_identity(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.
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...
struct GNUNET_DISK_FileHandle * GNUNET_DISK_file_open(const char *fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm)
Open a file.
Definition: disk.c:1237
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
ssize_t GNUNET_DISK_file_write(const struct GNUNET_DISK_FileHandle *h, const void *buffer, size_t n)
Write a buffer to a file.
Definition: disk.c:686
off_t GNUNET_DISK_file_seek(const struct GNUNET_DISK_FileHandle *h, off_t offset, enum GNUNET_DISK_Seek whence)
Move the read/write pointer in a file.
Definition: disk.c:205
GNUNET_DISK_AccessPermissions
File access permissions, UNIX-style.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_sync(const struct GNUNET_DISK_FileHandle *h)
Write file changes to disk.
Definition: disk.c:1427
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1308
ssize_t GNUNET_DISK_file_read(const struct GNUNET_DISK_FileHandle *h, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: disk.c:622
@ GNUNET_DISK_OPEN_READ
Open the file for reading.
@ GNUNET_DISK_OPEN_WRITE
Open the file for writing.
@ GNUNET_DISK_OPEN_CREATE
Create file if it doesn't exist.
@ GNUNET_DISK_PERM_USER_READ
Owner can read.
@ GNUNET_DISK_PERM_USER_WRITE
Owner can write.
@ GNUNET_DISK_SEEK_SET
Seek an absolute position (from the start of the file).
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.
int GNUNET_CONTAINER_multishortmap_iterate(struct GNUNET_CONTAINER_MultiShortmap *map, GNUNET_CONTAINER_ShortmapIterator it, void *it_cls)
Iterate over all entries in the map.
void GNUNET_CONTAINER_multishortmap_destroy(struct GNUNET_CONTAINER_MultiShortmap *map)
Destroy a hash map.
int GNUNET_CONTAINER_multishortmap_get_multiple(struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key, GNUNET_CONTAINER_ShortmapIterator it, void *it_cls)
Iterate over all entries in the map that match a particular key.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
#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).
@ 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.
#define GNUNET_free(ptr)
Wrapper around free.
@ GNUNET_MESSENGER_KIND_MISS
The miss kind.
@ GNUNET_MESSENGER_KIND_PEER
The peer 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...
enum GNUNET_GenericReturnValue verify_message_by_peer(const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash, const struct GNUNET_PeerIdentity *identity)
Verifies the signature of a given message and its hash with a specific peer's identity.
void convert_peer_identity_to_id(const struct GNUNET_PeerIdentity *identity, struct GNUNET_ShortHashCode *id)
Converts a peers identity to a short hash code which can be used as id to refer to a peer via sender ...
Handle used to access files (and pipes).
A 512-bit hashcode.
struct GNUNET_MESSENGER_PeerStoreEntry * match
const struct GNUNET_PeerIdentity * requested
const struct GNUNET_MESSENGER_Message * message
struct GNUNET_MESSENGER_MessageMiss miss
struct GNUNET_MESSENGER_MessagePeer peer
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_PeerIdentity peer
The peer identity of a disconnected door to a room.
struct GNUNET_PeerIdentity peer
The peer identity of the sender opening a room.
struct GNUNET_MESSENGER_MessageHeader header
Header.
struct GNUNET_MESSENGER_MessageBody body
Body.
struct GNUNET_MESSENGER_Service * service
struct GNUNET_CONTAINER_MultiShortmap * peers
The identity of the host (wraps the signing key of the peer).
A 256-bit hashcode.