aboutsummaryrefslogtreecommitdiff
path: root/src/messenger/messenger_api_peer_store.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/messenger/messenger_api_peer_store.c')
-rw-r--r--src/messenger/messenger_api_peer_store.c180
1 files changed, 180 insertions, 0 deletions
diff --git a/src/messenger/messenger_api_peer_store.c b/src/messenger/messenger_api_peer_store.c
new file mode 100644
index 000000000..f0b9eb0bb
--- /dev/null
+++ b/src/messenger/messenger_api_peer_store.c
@@ -0,0 +1,180 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2023 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/messenger_api_peer_store.c
23 * @brief messenger api: client implementation of GNUnet MESSENGER service
24 */
25
26#include "platform.h"
27#include "messenger_api_peer_store.h"
28
29#include "messenger_api_message.h"
30#include "messenger_api_util.h"
31
32void
33init_peer_store (struct GNUNET_MESSENGER_PeerStore *store)
34{
35 GNUNET_assert (store);
36
37 store->peers = GNUNET_CONTAINER_multishortmap_create (4, GNUNET_NO);
38}
39
40static enum GNUNET_GenericReturnValue
41iterate_destroy_peers (void *cls, const struct GNUNET_ShortHashCode *id, void *value)
42{
43 struct GNUNET_PeerIdentity* peer = value;
44 GNUNET_free (peer);
45 return GNUNET_YES;
46}
47
48void
49clear_peer_store (struct GNUNET_MESSENGER_PeerStore *store)
50{
51 GNUNET_assert ((store) && (store->peers));
52
53 GNUNET_CONTAINER_multishortmap_iterate (store->peers, iterate_destroy_peers, NULL);
54 GNUNET_CONTAINER_multishortmap_destroy (store->peers);
55
56 store->peers = NULL;
57}
58
59struct GNUNET_MESSENGER_ClosureVerifyPeer
60{
61 const struct GNUNET_MESSENGER_Message *message;
62 const struct GNUNET_HashCode *hash;
63 struct GNUNET_PeerIdentity *sender;
64};
65
66static enum GNUNET_GenericReturnValue
67verify_store_peer(void *cls, const struct GNUNET_ShortHashCode *id, void *value)
68{
69 struct GNUNET_MESSENGER_ClosureVerifyPeer *verify = cls;
70 struct GNUNET_PeerIdentity* peer = value;
71
72 if ((peer) && (GNUNET_OK == verify_message_by_peer (verify->message, verify->hash, peer)))
73 {
74 verify->sender = peer;
75 return GNUNET_NO;
76 }
77
78 return GNUNET_YES;
79}
80
81struct GNUNET_PeerIdentity*
82get_store_peer_of (struct GNUNET_MESSENGER_PeerStore *store,
83 const struct GNUNET_MESSENGER_Message *message,
84 const struct GNUNET_HashCode *hash)
85{
86 GNUNET_assert ((store) && (store->peers) && (message) && (hash));
87
88 if (GNUNET_YES != is_peer_message (message))
89 return NULL;
90
91 if ((GNUNET_MESSENGER_KIND_PEER == message->header.kind) &&
92 (GNUNET_OK == verify_message_by_peer (message, hash, &(message->body.peer.peer))))
93 {
94 struct GNUNET_ShortHashCode peer_id;
95 convert_peer_identity_to_id (&(message->body.peer.peer), &peer_id);
96
97 if (0 == GNUNET_memcmp (&peer_id, &(message->header.sender_id)))
98 update_store_peer (store, &(message->body.peer.peer));
99 else
100 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Sender id does not match peer identity\n");
101 }
102
103 struct GNUNET_MESSENGER_ClosureVerifyPeer verify;
104 verify.message = message;
105 verify.hash = hash;
106 verify.sender = NULL;
107
108 GNUNET_CONTAINER_multishortmap_get_multiple (store->peers, &(message->header.sender_id),
109 verify_store_peer, &verify);
110
111 return verify.sender;
112}
113
114struct GNUNET_MESSENGER_ClosureFindPeer
115{
116 const struct GNUNET_PeerIdentity *requested;
117 struct GNUNET_PeerIdentity *match;
118};
119
120static enum GNUNET_GenericReturnValue
121find_store_peer(void *cls, const struct GNUNET_ShortHashCode *id, void *value)
122{
123 struct GNUNET_MESSENGER_ClosureFindPeer *find = cls;
124 struct GNUNET_PeerIdentity* peer = value;
125
126 if ((peer) && (0 == GNUNET_memcmp (find->requested, peer)))
127 {
128 find->match = peer;
129 return GNUNET_NO;
130 }
131
132 return GNUNET_YES;
133}
134
135void
136update_store_peer (struct GNUNET_MESSENGER_PeerStore *store,
137 const struct GNUNET_PeerIdentity* peer)
138{
139 GNUNET_assert ((store) && (store->peers) && (peer));
140
141 struct GNUNET_ShortHashCode peer_id;
142 convert_peer_identity_to_id (peer, &peer_id);
143
144 struct GNUNET_MESSENGER_ClosureFindPeer find;
145 find.requested = peer;
146 find.match = NULL;
147
148 GNUNET_CONTAINER_multishortmap_get_multiple (store->peers, &peer_id,
149 find_store_peer, &find);
150
151 if (find.match)
152 return;
153
154 struct GNUNET_PeerIdentity* copy = GNUNET_memdup (peer, sizeof (struct GNUNET_PeerIdentity));
155 GNUNET_CONTAINER_multishortmap_put (store->peers, &peer_id, copy,
156 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
157}
158
159void
160remove_store_peer (struct GNUNET_MESSENGER_PeerStore *store,
161 const struct GNUNET_PeerIdentity *peer)
162{
163 GNUNET_assert ((store) && (store->peers) && (peer));
164
165 struct GNUNET_ShortHashCode peer_id;
166 convert_peer_identity_to_id (peer, &peer_id);
167
168 struct GNUNET_MESSENGER_ClosureFindPeer find;
169 find.requested = peer;
170 find.match = NULL;
171
172 GNUNET_CONTAINER_multishortmap_get_multiple (store->peers, &peer_id,
173 find_store_peer, &find);
174
175 if (!find.match)
176 return;
177
178 if (GNUNET_YES == GNUNET_CONTAINER_multishortmap_remove (store->peers, &peer_id, find.match))
179 GNUNET_free(find.match);
180}