diff options
Diffstat (limited to 'src/transport/gnunet-service-transport_hello.c')
-rw-r--r-- | src/transport/gnunet-service-transport_hello.c | 368 |
1 files changed, 0 insertions, 368 deletions
diff --git a/src/transport/gnunet-service-transport_hello.c b/src/transport/gnunet-service-transport_hello.c deleted file mode 100644 index 472c77c27..000000000 --- a/src/transport/gnunet-service-transport_hello.c +++ /dev/null | |||
@@ -1,368 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2010,2011 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 | /** | ||
22 | * @file transport/gnunet-service-transport_hello.c | ||
23 | * @brief hello management implementation | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_constants.h" | ||
28 | #include "gnunet_hello_lib.h" | ||
29 | #include "gnunet_peerinfo_service.h" | ||
30 | #include "gnunet_statistics_service.h" | ||
31 | #include "gnunet-service-transport_hello.h" | ||
32 | #include "gnunet-service-transport.h" | ||
33 | #include "gnunet-service-transport_plugins.h" | ||
34 | |||
35 | |||
36 | /** | ||
37 | * How often do we refresh our HELLO (due to expiration concerns)? | ||
38 | */ | ||
39 | #define HELLO_REFRESH_PERIOD GNUNET_TIME_relative_multiply ( \ | ||
40 | GNUNET_TIME_UNIT_HOURS, 6) | ||
41 | |||
42 | /** | ||
43 | * Hello address expiration | ||
44 | */ | ||
45 | extern struct GNUNET_TIME_Relative hello_expiration; | ||
46 | |||
47 | |||
48 | /** | ||
49 | * Entry in linked list of network addresses for ourselves. Also | ||
50 | * includes a cached signature for 'struct TransportPongMessage's. | ||
51 | */ | ||
52 | struct OwnAddressList | ||
53 | { | ||
54 | /** | ||
55 | * This is a doubly-linked list. | ||
56 | */ | ||
57 | struct OwnAddressList *next; | ||
58 | |||
59 | /** | ||
60 | * This is a doubly-linked list. | ||
61 | */ | ||
62 | struct OwnAddressList *prev; | ||
63 | |||
64 | /** | ||
65 | * The address. | ||
66 | */ | ||
67 | struct GNUNET_HELLO_Address *address; | ||
68 | |||
69 | /** | ||
70 | * How long until the current signature expires? (ZERO if the | ||
71 | * signature was never created). | ||
72 | */ | ||
73 | struct GNUNET_TIME_Absolute pong_sig_expires; | ||
74 | |||
75 | /** | ||
76 | * Signature for a 'struct TransportPongMessage' for this address. | ||
77 | */ | ||
78 | struct GNUNET_CRYPTO_EddsaSignature pong_signature; | ||
79 | |||
80 | /** | ||
81 | * How often has this address been added/removed? Used as | ||
82 | * some plugins may learn the same external address from | ||
83 | * multiple origins. | ||
84 | */ | ||
85 | unsigned int rc; | ||
86 | }; | ||
87 | |||
88 | |||
89 | /** | ||
90 | * Our HELLO message. | ||
91 | */ | ||
92 | static struct GNUNET_HELLO_Message *our_hello; | ||
93 | |||
94 | /** | ||
95 | * Function to call on HELLO changes. | ||
96 | */ | ||
97 | static GST_HelloCallback hello_cb; | ||
98 | |||
99 | /** | ||
100 | * Closure for #hello_cb. | ||
101 | */ | ||
102 | static void *hello_cb_cls; | ||
103 | |||
104 | /** | ||
105 | * Head of my addresses. | ||
106 | */ | ||
107 | static struct OwnAddressList *oal_head; | ||
108 | |||
109 | /** | ||
110 | * Tail of my addresses. | ||
111 | */ | ||
112 | static struct OwnAddressList *oal_tail; | ||
113 | |||
114 | /** | ||
115 | * Should we use a friend-only HELLO? | ||
116 | */ | ||
117 | static int friend_option; | ||
118 | |||
119 | /** | ||
120 | * Identifier of #refresh_hello_task(). | ||
121 | */ | ||
122 | static struct GNUNET_SCHEDULER_Task *hello_task; | ||
123 | |||
124 | |||
125 | /** | ||
126 | * Closure for #address_generator(). | ||
127 | */ | ||
128 | struct GeneratorContext | ||
129 | { | ||
130 | /** | ||
131 | * Where are we in the DLL? | ||
132 | */ | ||
133 | struct OwnAddressList *addr_pos; | ||
134 | |||
135 | /** | ||
136 | * When do addresses expire? | ||
137 | */ | ||
138 | struct GNUNET_TIME_Absolute expiration; | ||
139 | }; | ||
140 | |||
141 | |||
142 | /** | ||
143 | * Add an address from the `struct OwnAddressList` to the buffer. | ||
144 | * | ||
145 | * @param cls the `struct GeneratorContext` | ||
146 | * @param max maximum number of bytes left | ||
147 | * @param buf where to write the address | ||
148 | * @return bytes written or #GNUNET_SYSERR to signal the | ||
149 | * end of the iteration. | ||
150 | */ | ||
151 | static ssize_t | ||
152 | address_generator (void *cls, | ||
153 | size_t max, | ||
154 | void *buf) | ||
155 | { | ||
156 | struct GeneratorContext *gc = cls; | ||
157 | ssize_t ret; | ||
158 | |||
159 | if (NULL == gc->addr_pos) | ||
160 | return GNUNET_SYSERR; /* Done */ | ||
161 | ret = GNUNET_HELLO_add_address (gc->addr_pos->address, | ||
162 | gc->expiration, | ||
163 | buf, | ||
164 | max); | ||
165 | gc->addr_pos = gc->addr_pos->next; | ||
166 | return ret; | ||
167 | } | ||
168 | |||
169 | |||
170 | /** | ||
171 | * Construct our HELLO message from all of the addresses of | ||
172 | * all of the transports. | ||
173 | * | ||
174 | * @param cls unused | ||
175 | */ | ||
176 | static void | ||
177 | refresh_hello_task (void *cls) | ||
178 | { | ||
179 | struct GeneratorContext gc; | ||
180 | |||
181 | hello_task = NULL; | ||
182 | gc.addr_pos = oal_head; | ||
183 | gc.expiration = GNUNET_TIME_relative_to_absolute (hello_expiration); | ||
184 | |||
185 | GNUNET_free (our_hello); | ||
186 | our_hello = GNUNET_HELLO_create (&GST_my_identity.public_key, | ||
187 | &address_generator, | ||
188 | &gc, | ||
189 | friend_option); | ||
190 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
191 | "Refreshed my %s HELLO, new size is %d\n", | ||
192 | (GNUNET_YES == friend_option) ? "friend-only" : "public", | ||
193 | GNUNET_HELLO_size (our_hello)); | ||
194 | GNUNET_STATISTICS_update (GST_stats, | ||
195 | gettext_noop ("# refreshed my HELLO"), | ||
196 | 1, | ||
197 | GNUNET_NO); | ||
198 | if (NULL != hello_cb) | ||
199 | hello_cb (hello_cb_cls, | ||
200 | GST_hello_get ()); | ||
201 | GNUNET_PEERINFO_add_peer (GST_peerinfo, | ||
202 | our_hello, | ||
203 | NULL, | ||
204 | NULL); | ||
205 | hello_task = | ||
206 | GNUNET_SCHEDULER_add_delayed (HELLO_REFRESH_PERIOD, | ||
207 | &refresh_hello_task, | ||
208 | NULL); | ||
209 | } | ||
210 | |||
211 | |||
212 | /** | ||
213 | * Schedule task to refresh hello (but only if such a | ||
214 | * task exists already, as otherwise the module might | ||
215 | * have been shutdown). | ||
216 | */ | ||
217 | static void | ||
218 | refresh_hello () | ||
219 | { | ||
220 | if (NULL != hello_task) | ||
221 | { | ||
222 | GNUNET_SCHEDULER_cancel (hello_task); | ||
223 | hello_task = GNUNET_SCHEDULER_add_now (&refresh_hello_task, | ||
224 | NULL); | ||
225 | } | ||
226 | } | ||
227 | |||
228 | |||
229 | /** | ||
230 | * Initialize the HELLO module. | ||
231 | * | ||
232 | * @param friend_only use a friend only hello | ||
233 | * @param cb function to call whenever our HELLO changes | ||
234 | * @param cb_cls closure for @a cb | ||
235 | */ | ||
236 | void | ||
237 | GST_hello_start (int friend_only, | ||
238 | GST_HelloCallback cb, | ||
239 | void *cb_cls) | ||
240 | { | ||
241 | hello_cb = cb; | ||
242 | hello_cb_cls = cb_cls; | ||
243 | friend_option = friend_only; | ||
244 | refresh_hello_task (NULL); | ||
245 | } | ||
246 | |||
247 | |||
248 | /** | ||
249 | * Shutdown the HELLO module. | ||
250 | */ | ||
251 | void | ||
252 | GST_hello_stop () | ||
253 | { | ||
254 | hello_cb = NULL; | ||
255 | hello_cb_cls = NULL; | ||
256 | if (NULL != hello_task) | ||
257 | { | ||
258 | GNUNET_SCHEDULER_cancel (hello_task); | ||
259 | hello_task = NULL; | ||
260 | } | ||
261 | if (NULL != our_hello) | ||
262 | { | ||
263 | GNUNET_free (our_hello); | ||
264 | our_hello = NULL; | ||
265 | } | ||
266 | } | ||
267 | |||
268 | |||
269 | /** | ||
270 | * Obtain this peers HELLO message. | ||
271 | * | ||
272 | * @return our HELLO message | ||
273 | */ | ||
274 | const struct GNUNET_MessageHeader * | ||
275 | GST_hello_get () | ||
276 | { | ||
277 | return (const struct GNUNET_MessageHeader *) our_hello; | ||
278 | } | ||
279 | |||
280 | |||
281 | /** | ||
282 | * Add or remove an address from this peer's HELLO message. | ||
283 | * | ||
284 | * @param addremove #GNUNET_YES to add, #GNUNET_NO to remove | ||
285 | * @param address address to add or remove | ||
286 | */ | ||
287 | void | ||
288 | GST_hello_modify_addresses (int addremove, | ||
289 | const struct GNUNET_HELLO_Address *address) | ||
290 | { | ||
291 | struct OwnAddressList *al; | ||
292 | |||
293 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
294 | (GNUNET_YES == addremove) | ||
295 | ? "Adding `%s' to the set of our addresses\n" | ||
296 | : "Removing `%s' from the set of our addresses\n", | ||
297 | GST_plugins_a2s (address)); | ||
298 | GNUNET_assert (NULL != address); | ||
299 | for (al = oal_head; al != NULL; al = al->next) | ||
300 | if (0 == GNUNET_HELLO_address_cmp (address, al->address)) | ||
301 | break; | ||
302 | if (GNUNET_NO == addremove) | ||
303 | { | ||
304 | if (NULL == al) | ||
305 | { | ||
306 | /* address to be removed not found!? */ | ||
307 | GNUNET_break (0); | ||
308 | return; | ||
309 | } | ||
310 | al->rc--; | ||
311 | if (0 != al->rc) | ||
312 | return; /* RC not yet zero */ | ||
313 | GNUNET_CONTAINER_DLL_remove (oal_head, | ||
314 | oal_tail, | ||
315 | al); | ||
316 | GNUNET_HELLO_address_free (al->address); | ||
317 | GNUNET_free (al); | ||
318 | refresh_hello (); | ||
319 | return; | ||
320 | } | ||
321 | if (NULL != al) | ||
322 | { | ||
323 | /* address added twice or more */ | ||
324 | al->rc++; | ||
325 | return; | ||
326 | } | ||
327 | al = GNUNET_new (struct OwnAddressList); | ||
328 | al->rc = 1; | ||
329 | GNUNET_CONTAINER_DLL_insert (oal_head, | ||
330 | oal_tail, | ||
331 | al); | ||
332 | al->address = GNUNET_HELLO_address_copy (address); | ||
333 | refresh_hello (); | ||
334 | } | ||
335 | |||
336 | |||
337 | /** | ||
338 | * Test if a particular address is one of ours. | ||
339 | * | ||
340 | * @param address address to test | ||
341 | * @param sig location where to cache PONG signatures for this address [set] | ||
342 | * @param sig_expiration how long until the current 'sig' expires? | ||
343 | * (ZERO if sig was never created) [set] | ||
344 | * @return #GNUNET_YES if this is one of our addresses, | ||
345 | * #GNUNET_NO if not | ||
346 | */ | ||
347 | int | ||
348 | GST_hello_test_address (const struct GNUNET_HELLO_Address *address, | ||
349 | struct GNUNET_CRYPTO_EddsaSignature **sig, | ||
350 | struct GNUNET_TIME_Absolute **sig_expiration) | ||
351 | { | ||
352 | struct OwnAddressList *al; | ||
353 | |||
354 | for (al = oal_head; al != NULL; al = al->next) | ||
355 | if (0 == GNUNET_HELLO_address_cmp (address, | ||
356 | al->address)) | ||
357 | { | ||
358 | *sig = &al->pong_signature; | ||
359 | *sig_expiration = &al->pong_sig_expires; | ||
360 | return GNUNET_YES; | ||
361 | } | ||
362 | *sig = NULL; | ||
363 | *sig_expiration = NULL; | ||
364 | return GNUNET_NO; | ||
365 | } | ||
366 | |||
367 | |||
368 | /* end of file gnunet-service-transport_hello.c */ | ||