aboutsummaryrefslogtreecommitdiff
path: root/src/service/messenger/messenger_api_list_tunnels.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/service/messenger/messenger_api_list_tunnels.c')
-rw-r--r--src/service/messenger/messenger_api_list_tunnels.c298
1 files changed, 298 insertions, 0 deletions
diff --git a/src/service/messenger/messenger_api_list_tunnels.c b/src/service/messenger/messenger_api_list_tunnels.c
new file mode 100644
index 000000000..bb500233b
--- /dev/null
+++ b/src/service/messenger/messenger_api_list_tunnels.c
@@ -0,0 +1,298 @@
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 */
20/**
21 * @author Tobias Frisch
22 * @file src/messenger/messenger_api_list_tunnels.c
23 * @brief messenger api: client and service implementation of GNUnet MESSENGER service
24 */
25
26#include "messenger_api_list_tunnels.h"
27
28void
29init_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels)
30{
31 GNUNET_assert (tunnels);
32
33 tunnels->head = NULL;
34 tunnels->tail = NULL;
35}
36
37
38void
39clear_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels)
40{
41 GNUNET_assert (tunnels);
42
43 struct GNUNET_MESSENGER_ListTunnel *element;
44 for (element = tunnels->head; element;
45 element = remove_from_list_tunnels (tunnels, element))
46
47 tunnels->head = NULL;
48 tunnels->tail = NULL;
49}
50
51
52static int
53compare_list_tunnels (void *cls,
54 struct GNUNET_MESSENGER_ListTunnel *element0,
55 struct GNUNET_MESSENGER_ListTunnel *element1)
56{
57 struct GNUNET_PeerIdentity peer0, peer1;
58
59 GNUNET_PEER_resolve (element0->peer, &peer0);
60 GNUNET_PEER_resolve (element1->peer, &peer1);
61
62 return GNUNET_memcmp (&peer0, &peer1);
63}
64
65
66void
67add_to_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels,
68 const struct GNUNET_PeerIdentity *peer,
69 const struct GNUNET_HashCode *hash)
70{
71 GNUNET_assert ((tunnels) && (peer));
72
73 struct GNUNET_MESSENGER_ListTunnel *element = GNUNET_new (struct
74 GNUNET_MESSENGER_ListTunnel);
75
76 element->peer = GNUNET_PEER_intern (peer);
77 element->hash = hash ? GNUNET_memdup (hash, sizeof (struct GNUNET_HashCode)) :
78 NULL;
79
80 memset (&(element->connection), 0, sizeof (element->connection));
81
82 GNUNET_CONTAINER_DLL_insert_sorted (struct GNUNET_MESSENGER_ListTunnel,
83 compare_list_tunnels, NULL, tunnels->head,
84 tunnels->tail, element);
85}
86
87
88struct GNUNET_MESSENGER_ListTunnel*
89find_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels,
90 const struct GNUNET_PeerIdentity *peer,
91 size_t *index)
92{
93 GNUNET_assert ((tunnels) && (peer));
94
95 struct GNUNET_MESSENGER_ListTunnel *element;
96 struct GNUNET_PeerIdentity pid;
97
98 if (index)
99 *index = 0;
100
101 for (element = tunnels->head; element; element = element->next)
102 {
103 GNUNET_PEER_resolve (element->peer, &pid);
104
105 if (0 == GNUNET_memcmp (&pid, peer))
106 return element;
107
108 if (index)
109 (*index) = (*index) + 1;
110 }
111
112 return NULL;
113}
114
115
116struct GNUNET_MESSENGER_ListTunnel*
117find_list_tunnels_alternate (struct GNUNET_MESSENGER_ListTunnels *tunnels,
118 const struct GNUNET_PeerIdentity *peer)
119{
120 GNUNET_assert ((tunnels) && (peer));
121
122 struct GNUNET_MESSENGER_ListTunnel *element;
123 struct GNUNET_PeerIdentity pid;
124
125 for (element = tunnels->head; element; element = element->next)
126 {
127 GNUNET_PEER_resolve (element->peer, &pid);
128
129 if (0 != GNUNET_memcmp (&pid, peer))
130 return element;
131 }
132
133 return NULL;
134}
135
136
137enum GNUNET_GenericReturnValue
138verify_list_tunnels_flag_token (const struct
139 GNUNET_MESSENGER_ListTunnels *tunnels,
140 const struct GNUNET_PeerIdentity *peer,
141 enum GNUNET_MESSENGER_ConnectionFlags flag)
142{
143 GNUNET_assert ((tunnels) && (peer) && (flag));
144
145 struct GNUNET_MESSENGER_ListTunnel *element;
146 struct GNUNET_PeerIdentity pid;
147
148 for (element = tunnels->head; element; element = element->next)
149 {
150 if ((element->connection.flags & flag) != flag)
151 continue;
152
153 GNUNET_PEER_resolve (element->peer, &pid);
154
155 if (0 == GNUNET_memcmp (&pid, peer))
156 return GNUNET_OK;
157 }
158
159 return GNUNET_SYSERR;
160}
161
162
163void
164update_to_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels,
165 const struct GNUNET_PeerIdentity *peer,
166 const struct GNUNET_HashCode *hash)
167{
168 GNUNET_assert ((tunnels) && (peer));
169
170 struct GNUNET_MESSENGER_ListTunnel *element = find_list_tunnels (tunnels,
171 peer,
172 NULL);
173 if (! element)
174 return;
175
176 if (element->hash)
177 {
178 if (hash)
179 GNUNET_memcpy (element->hash, hash, sizeof(struct GNUNET_HashCode));
180 else
181 {
182 GNUNET_free (element->hash);
183 element->hash = NULL;
184 }
185 }
186 else if (hash)
187 element->hash = GNUNET_memdup (hash, sizeof(struct GNUNET_HashCode));
188}
189
190
191enum GNUNET_GenericReturnValue
192contains_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels,
193 const struct GNUNET_PeerIdentity *peer)
194{
195 GNUNET_assert ((tunnels) && (peer));
196
197 return find_list_tunnels (tunnels, peer, NULL) != NULL ? GNUNET_YES :
198 GNUNET_NO;
199}
200
201
202struct GNUNET_MESSENGER_ListTunnel*
203remove_from_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels,
204 struct GNUNET_MESSENGER_ListTunnel *element)
205{
206 GNUNET_assert ((tunnels) && (element));
207
208 struct GNUNET_MESSENGER_ListTunnel *next = element->next;
209
210 if ((tunnels->head) && (tunnels->tail))
211 GNUNET_CONTAINER_DLL_remove (tunnels->head, tunnels->tail, element);
212
213 if (element->hash)
214 GNUNET_free (element->hash);
215
216 GNUNET_PEER_change_rc (element->peer, -1);
217 GNUNET_free (element);
218
219 return next;
220}
221
222
223void
224load_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels,
225 const char *path)
226{
227 GNUNET_assert ((tunnels) && (path));
228
229 if (GNUNET_YES != GNUNET_DISK_file_test (path))
230 return;
231
232 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Load list of tunnels from path: %s\n",
233 path);
234
235 enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ
236 | GNUNET_DISK_PERM_USER_WRITE
237 );
238
239 struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open (
240 path, GNUNET_DISK_OPEN_READ, permission
241 );
242
243 if (! handle)
244 return;
245
246 GNUNET_DISK_file_seek (handle, 0, GNUNET_DISK_SEEK_SET);
247
248 struct GNUNET_PeerIdentity peer;
249 ssize_t len;
250
251 do {
252 len = GNUNET_DISK_file_read (handle, &peer, sizeof(peer));
253
254 if (len != sizeof(peer))
255 break;
256
257 add_to_list_tunnels (tunnels, &peer, NULL);
258 } while (len == sizeof(peer));
259
260 GNUNET_DISK_file_close (handle);
261}
262
263
264void
265save_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels,
266 const char *path)
267{
268 GNUNET_assert ((tunnels) && (path));
269
270 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Save list of tunnels to path: %s\n",
271 path);
272
273 enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ
274 | GNUNET_DISK_PERM_USER_WRITE
275 );
276
277 struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open (
278 path, GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_WRITE, permission
279 );
280
281 if (! handle)
282 return;
283
284 GNUNET_DISK_file_seek (handle, 0, GNUNET_DISK_SEEK_SET);
285
286 struct GNUNET_MESSENGER_ListTunnel *element;
287 struct GNUNET_PeerIdentity pid;
288
289 for (element = tunnels->head; element; element = element->next)
290 {
291 GNUNET_PEER_resolve (element->peer, &pid);
292
293 GNUNET_DISK_file_write (handle, &pid, sizeof(pid));
294 }
295
296 GNUNET_DISK_file_sync (handle);
297 GNUNET_DISK_file_close (handle);
298}