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.c237
1 files changed, 237 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..b2513370c
--- /dev/null
+++ b/src/service/messenger/messenger_api_list_tunnels.c
@@ -0,0 +1,237 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2020--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_list_tunnels.c
23 * @brief messenger api: client and service implementation of GNUnet MESSENGER service
24 */
25
26#include "platform.h"
27#include "messenger_api_list_tunnels.h"
28
29void
30init_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels)
31{
32 GNUNET_assert (tunnels);
33
34 tunnels->head = NULL;
35 tunnels->tail = NULL;
36}
37
38
39void
40clear_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels)
41{
42 GNUNET_assert (tunnels);
43
44 struct GNUNET_MESSENGER_ListTunnel *element;
45 for (element = tunnels->head; element; element = remove_from_list_tunnels (
46 tunnels, element))
47
48 tunnels->head = NULL;
49 tunnels->tail = NULL;
50}
51
52
53static int
54compare_list_tunnels (void *cls,
55 struct GNUNET_MESSENGER_ListTunnel *element0,
56 struct GNUNET_MESSENGER_ListTunnel *element1)
57{
58 return ((int) element0->peer) - ((int) element1->peer);
59}
60
61
62void
63add_to_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels,
64 const struct GNUNET_PeerIdentity *peer,
65 const struct GNUNET_HashCode *hash)
66{
67 GNUNET_assert ((tunnels) && (peer));
68
69 struct GNUNET_MESSENGER_ListTunnel *element = GNUNET_new (struct
70 GNUNET_MESSENGER_ListTunnel);
71
72 element->peer = GNUNET_PEER_intern (peer);
73 element->hash = hash ? GNUNET_memdup (hash, sizeof(struct GNUNET_HashCode)) :
74 NULL;
75
76 GNUNET_CONTAINER_DLL_insert_sorted (struct GNUNET_MESSENGER_ListTunnel,
77 compare_list_tunnels, NULL, tunnels->head,
78 tunnels->tail, element);
79}
80
81
82struct GNUNET_MESSENGER_ListTunnel*
83find_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels,
84 const struct GNUNET_PeerIdentity *peer,
85 size_t *index)
86{
87 GNUNET_assert ((tunnels) && (peer));
88
89 struct GNUNET_MESSENGER_ListTunnel *element;
90 struct GNUNET_PeerIdentity pid;
91
92 if (index)
93 *index = 0;
94
95 for (element = tunnels->head; element; element = element->next)
96 {
97 GNUNET_PEER_resolve (element->peer, &pid);
98
99 if (0 == GNUNET_memcmp (&pid, peer))
100 return element;
101
102 if (index)
103 (*index) = (*index) + 1;
104 }
105
106 return NULL;
107}
108
109
110void
111update_to_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels,
112 const struct GNUNET_PeerIdentity *peer,
113 const struct GNUNET_HashCode *hash)
114{
115 GNUNET_assert ((tunnels) && (peer));
116
117 struct GNUNET_MESSENGER_ListTunnel *element = find_list_tunnels (tunnels,
118 peer,
119 NULL);
120 if (! element)
121 return;
122
123 if (element->hash)
124 {
125 if (hash)
126 GNUNET_memcpy (element->hash, hash, sizeof(struct GNUNET_HashCode));
127 else
128 {
129 GNUNET_free (element->hash);
130 element->hash = NULL;
131 }
132 }
133 else if (hash)
134 element->hash = GNUNET_memdup (hash, sizeof(struct GNUNET_HashCode));
135}
136
137
138int
139contains_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels,
140 const struct GNUNET_PeerIdentity *peer)
141{
142 GNUNET_assert ((tunnels) && (peer));
143
144 return find_list_tunnels (tunnels, peer, NULL) != NULL ? GNUNET_YES :
145 GNUNET_NO;
146}
147
148
149struct GNUNET_MESSENGER_ListTunnel*
150remove_from_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels,
151 struct GNUNET_MESSENGER_ListTunnel *element)
152{
153 GNUNET_assert ((tunnels) && (element));
154
155 struct GNUNET_MESSENGER_ListTunnel *next = element->next;
156
157 if ((tunnels->head) && (tunnels->tail))
158 GNUNET_CONTAINER_DLL_remove (tunnels->head, tunnels->tail, element);
159
160 if (element->hash)
161 GNUNET_free (element->hash);
162
163 GNUNET_PEER_change_rc (element->peer, -1);
164 GNUNET_free (element);
165
166 return next;
167}
168
169
170void
171load_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels,
172 const char *path)
173{
174 GNUNET_assert ((tunnels) && (path));
175
176 if (GNUNET_YES != GNUNET_DISK_file_test (path))
177 return;
178
179 enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ
180 | GNUNET_DISK_PERM_USER_WRITE);
181
182 struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open (
183 path, GNUNET_DISK_OPEN_READ, permission
184 );
185
186 if (! handle)
187 return;
188
189 GNUNET_DISK_file_seek (handle, 0, GNUNET_DISK_SEEK_SET);
190
191 struct GNUNET_PeerIdentity peer;
192 ssize_t len;
193
194 do {
195 len = GNUNET_DISK_file_read (handle, &peer, sizeof(peer));
196
197 if (len != sizeof(peer))
198 break;
199
200 add_to_list_tunnels (tunnels, &peer, NULL);
201 } while (len == sizeof(peer));
202
203 GNUNET_DISK_file_close (handle);
204}
205
206
207void
208save_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels,
209 const char *path)
210{
211 GNUNET_assert ((tunnels) && (path));
212
213 enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ
214 | GNUNET_DISK_PERM_USER_WRITE);
215
216 struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open (
217 path, GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_WRITE, permission
218 );
219
220 if (! handle)
221 return;
222
223 GNUNET_DISK_file_seek (handle, 0, GNUNET_DISK_SEEK_SET);
224
225 struct GNUNET_MESSENGER_ListTunnel *element;
226 struct GNUNET_PeerIdentity pid;
227
228 for (element = tunnels->head; element; element = element->next)
229 {
230 GNUNET_PEER_resolve (element->peer, &pid);
231
232 GNUNET_DISK_file_write (handle, &pid, sizeof(pid));
233 }
234
235 GNUNET_DISK_file_sync (handle);
236 GNUNET_DISK_file_close (handle);
237}