diff options
Diffstat (limited to 'src/dhtu')
-rw-r--r-- | src/dhtu/Makefile.am | 7 | ||||
-rw-r--r-- | src/dhtu/dhtu.conf | 7 | ||||
-rw-r--r-- | src/dhtu/plugin_dhtu_gnunet.c | 63 | ||||
-rw-r--r-- | src/dhtu/plugin_dhtu_ip.c | 434 |
4 files changed, 328 insertions, 183 deletions
diff --git a/src/dhtu/Makefile.am b/src/dhtu/Makefile.am index 0e10721cd..ebffa9ecf 100644 --- a/src/dhtu/Makefile.am +++ b/src/dhtu/Makefile.am | |||
@@ -10,6 +10,10 @@ if USE_COVERAGE | |||
10 | XLIBS = -lgcov | 10 | XLIBS = -lgcov |
11 | endif | 11 | endif |
12 | 12 | ||
13 | pkgcfg_DATA = \ | ||
14 | dhtu.conf | ||
15 | |||
16 | |||
13 | plugin_LTLIBRARIES = \ | 17 | plugin_LTLIBRARIES = \ |
14 | libgnunet_plugin_dhtu_gnunet.la \ | 18 | libgnunet_plugin_dhtu_gnunet.la \ |
15 | libgnunet_plugin_dhtu_ip.la | 19 | libgnunet_plugin_dhtu_ip.la |
@@ -67,6 +71,9 @@ test_dhtu_ip_LDADD = \ | |||
67 | check_PROGRAMS = \ | 71 | check_PROGRAMS = \ |
68 | test_dhtu_ip | 72 | test_dhtu_ip |
69 | 73 | ||
74 | EXTRA_DIST = \ | ||
75 | dhtu.conf | ||
76 | |||
70 | if ENABLE_TEST_RUN | 77 | if ENABLE_TEST_RUN |
71 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; | 78 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; |
72 | TESTS = \ | 79 | TESTS = \ |
diff --git a/src/dhtu/dhtu.conf b/src/dhtu/dhtu.conf new file mode 100644 index 000000000..ea5ade752 --- /dev/null +++ b/src/dhtu/dhtu.conf | |||
@@ -0,0 +1,7 @@ | |||
1 | [dhtu-gnunet] | ||
2 | ENABLED = YES | ||
3 | |||
4 | [dhtu-ip] | ||
5 | ENABLED = NO | ||
6 | NSE = 4 | ||
7 | UDP_PORT = 6666 | ||
diff --git a/src/dhtu/plugin_dhtu_gnunet.c b/src/dhtu/plugin_dhtu_gnunet.c index 2163af941..b072be2be 100644 --- a/src/dhtu/plugin_dhtu_gnunet.c +++ b/src/dhtu/plugin_dhtu_gnunet.c | |||
@@ -70,11 +70,6 @@ struct GNUNET_DHTU_Source | |||
70 | { | 70 | { |
71 | 71 | ||
72 | /** | 72 | /** |
73 | * Hash of @e pid, position of this peer in the DHT overlay. | ||
74 | */ | ||
75 | struct GNUNET_DHTU_HashKey id; | ||
76 | |||
77 | /** | ||
78 | * Application context for this source. | 73 | * Application context for this source. |
79 | */ | 74 | */ |
80 | void *app_ctx; | 75 | void *app_ctx; |
@@ -125,11 +120,6 @@ struct GNUNET_DHTU_Target | |||
125 | struct GNUNET_PeerIdentity pid; | 120 | struct GNUNET_PeerIdentity pid; |
126 | 121 | ||
127 | /** | 122 | /** |
128 | * Hash of @e pid, position of this peer in the DHT overlay. | ||
129 | */ | ||
130 | struct GNUNET_DHTU_HashKey id; | ||
131 | |||
132 | /** | ||
133 | * Preference counter, length of the @a ph_head DLL. | 123 | * Preference counter, length of the @a ph_head DLL. |
134 | */ | 124 | */ |
135 | unsigned int ph_count; | 125 | unsigned int ph_count; |
@@ -240,27 +230,26 @@ hello_offered_cb (void *cls) | |||
240 | * Request creation of a session with a peer at the given @a address. | 230 | * Request creation of a session with a peer at the given @a address. |
241 | * | 231 | * |
242 | * @param cls closure (internal context for the plugin) | 232 | * @param cls closure (internal context for the plugin) |
233 | * @param pid target identity of the peer to connect to | ||
243 | * @param address target address to connect to | 234 | * @param address target address to connect to |
244 | */ | 235 | */ |
245 | static void | 236 | static void |
246 | ip_try_connect (void *cls, | 237 | gnunet_try_connect (void *cls, |
247 | const char *address) | 238 | const struct GNUNET_PeerIdentity *pid, |
239 | const char *address) | ||
248 | { | 240 | { |
249 | struct Plugin *plugin = cls; | 241 | struct Plugin *plugin = cls; |
250 | struct GNUNET_HELLO_Message *hello = NULL; | 242 | struct GNUNET_HELLO_Message *hello = NULL; |
251 | struct HelloHandle *hh; | 243 | struct HelloHandle *hh; |
252 | struct GNUNET_CRYPTO_EddsaPublicKey pubkey; | 244 | struct GNUNET_CRYPTO_EddsaPublicKey pubkey; |
253 | 245 | ||
246 | (void) pid; /* will be needed with future address URIs */ | ||
254 | if (GNUNET_OK != | 247 | if (GNUNET_OK != |
255 | GNUNET_HELLO_parse_uri (address, | 248 | GNUNET_HELLO_parse_uri (address, |
256 | &pubkey, | 249 | &pubkey, |
257 | &hello, | 250 | &hello, |
258 | &GPI_plugins_find)) | 251 | &GPI_plugins_find)) |
259 | { | ||
260 | GNUNET_break (0); | ||
261 | return; | 252 | return; |
262 | } | ||
263 | |||
264 | hh = GNUNET_new (struct HelloHandle); | 253 | hh = GNUNET_new (struct HelloHandle); |
265 | hh->plugin = plugin; | 254 | hh->plugin = plugin; |
266 | GNUNET_CONTAINER_DLL_insert (plugin->hh_head, | 255 | GNUNET_CONTAINER_DLL_insert (plugin->hh_head, |
@@ -283,8 +272,8 @@ ip_try_connect (void *cls, | |||
283 | * @param target connection to keep alive | 272 | * @param target connection to keep alive |
284 | */ | 273 | */ |
285 | static struct GNUNET_DHTU_PreferenceHandle * | 274 | static struct GNUNET_DHTU_PreferenceHandle * |
286 | ip_hold (void *cls, | 275 | gnunet_hold (void *cls, |
287 | struct GNUNET_DHTU_Target *target) | 276 | struct GNUNET_DHTU_Target *target) |
288 | { | 277 | { |
289 | struct Plugin *plugin = cls; | 278 | struct Plugin *plugin = cls; |
290 | struct GNUNET_DHTU_PreferenceHandle *ph; | 279 | struct GNUNET_DHTU_PreferenceHandle *ph; |
@@ -312,7 +301,7 @@ ip_hold (void *cls, | |||
312 | * @param target connection to keep alive | 301 | * @param target connection to keep alive |
313 | */ | 302 | */ |
314 | static void | 303 | static void |
315 | ip_drop (struct GNUNET_DHTU_PreferenceHandle *ph) | 304 | gnunet_drop (struct GNUNET_DHTU_PreferenceHandle *ph) |
316 | { | 305 | { |
317 | struct GNUNET_DHTU_Target *target = ph->target; | 306 | struct GNUNET_DHTU_Target *target = ph->target; |
318 | struct Plugin *plugin = target->plugin; | 307 | struct Plugin *plugin = target->plugin; |
@@ -350,12 +339,12 @@ ip_drop (struct GNUNET_DHTU_PreferenceHandle *ph) | |||
350 | * @param finished_cb_cls closure for @a finished_cb | 339 | * @param finished_cb_cls closure for @a finished_cb |
351 | */ | 340 | */ |
352 | static void | 341 | static void |
353 | ip_send (void *cls, | 342 | gnunet_send (void *cls, |
354 | struct GNUNET_DHTU_Target *target, | 343 | struct GNUNET_DHTU_Target *target, |
355 | const void *msg, | 344 | const void *msg, |
356 | size_t msg_size, | 345 | size_t msg_size, |
357 | GNUNET_SCHEDULER_TaskCallback finished_cb, | 346 | GNUNET_SCHEDULER_TaskCallback finished_cb, |
358 | void *finished_cb_cls) | 347 | void *finished_cb_cls) |
359 | { | 348 | { |
360 | struct GNUNET_MQ_Envelope *env; | 349 | struct GNUNET_MQ_Envelope *env; |
361 | struct GNUNET_MessageHeader *cmsg; | 350 | struct GNUNET_MessageHeader *cmsg; |
@@ -394,12 +383,9 @@ core_connect_cb (void *cls, | |||
394 | target->plugin = plugin; | 383 | target->plugin = plugin; |
395 | target->mq = mq; | 384 | target->mq = mq; |
396 | target->pid = *peer; | 385 | target->pid = *peer; |
397 | GNUNET_CRYPTO_hash (peer, | ||
398 | sizeof (*peer), | ||
399 | &target->id.sha512); | ||
400 | plugin->env->connect_cb (plugin->env->cls, | 386 | plugin->env->connect_cb (plugin->env->cls, |
401 | target, | 387 | target, |
402 | &target->id, | 388 | &target->pid, |
403 | &target->app_ctx); | 389 | &target->app_ctx); |
404 | return target; | 390 | return target; |
405 | } | 391 | } |
@@ -461,11 +447,7 @@ peerinfo_cb (void *cls, | |||
461 | &GPI_plugins_find); | 447 | &GPI_plugins_find); |
462 | if (NULL == addr) | 448 | if (NULL == addr) |
463 | return; | 449 | return; |
464 | GNUNET_CRYPTO_hash (peer, | ||
465 | sizeof (*peer), | ||
466 | &plugin->src.id.sha512); | ||
467 | plugin->env->address_add_cb (plugin->env->cls, | 450 | plugin->env->address_add_cb (plugin->env->cls, |
468 | &plugin->src.id, | ||
469 | addr, | 451 | addr, |
470 | &plugin->src, | 452 | &plugin->src, |
471 | &plugin->src.app_ctx); | 453 | &plugin->src.app_ctx); |
@@ -584,6 +566,10 @@ libgnunet_plugin_dhtu_gnunet_done (void *cls) | |||
584 | } | 566 | } |
585 | if (NULL != plugin->nse) | 567 | if (NULL != plugin->nse) |
586 | GNUNET_NSE_disconnect (plugin->nse); | 568 | GNUNET_NSE_disconnect (plugin->nse); |
569 | plugin->env->network_size_cb (plugin->env->cls, | ||
570 | GNUNET_TIME_UNIT_FOREVER_ABS, | ||
571 | 0.0, | ||
572 | 0.0); | ||
587 | if (NULL != plugin->core) | 573 | if (NULL != plugin->core) |
588 | GNUNET_CORE_disconnect (plugin->core); | 574 | GNUNET_CORE_disconnect (plugin->core); |
589 | if (NULL != plugin->ats) | 575 | if (NULL != plugin->ats) |
@@ -604,7 +590,7 @@ libgnunet_plugin_dhtu_gnunet_done (void *cls) | |||
604 | * @return the plugin's API | 590 | * @return the plugin's API |
605 | */ | 591 | */ |
606 | void * | 592 | void * |
607 | libgnunet_plugin_dhtu_ip_init (void *cls) | 593 | libgnunet_plugin_dhtu_gnunet_init (void *cls) |
608 | { | 594 | { |
609 | struct GNUNET_DHTU_PluginEnvironment *env = cls; | 595 | struct GNUNET_DHTU_PluginEnvironment *env = cls; |
610 | struct GNUNET_DHTU_PluginFunctions *api; | 596 | struct GNUNET_DHTU_PluginFunctions *api; |
@@ -621,10 +607,10 @@ libgnunet_plugin_dhtu_ip_init (void *cls) | |||
621 | plugin->env = env; | 607 | plugin->env = env; |
622 | api = GNUNET_new (struct GNUNET_DHTU_PluginFunctions); | 608 | api = GNUNET_new (struct GNUNET_DHTU_PluginFunctions); |
623 | api->cls = plugin; | 609 | api->cls = plugin; |
624 | api->try_connect = &ip_try_connect; | 610 | api->try_connect = &gnunet_try_connect; |
625 | api->hold = &ip_hold; | 611 | api->hold = &gnunet_hold; |
626 | api->drop = &ip_drop; | 612 | api->drop = &gnunet_drop; |
627 | api->send = &ip_send; | 613 | api->send = &gnunet_send; |
628 | plugin->ats = GNUNET_ATS_connectivity_init (env->cfg); | 614 | plugin->ats = GNUNET_ATS_connectivity_init (env->cfg); |
629 | plugin->core = GNUNET_CORE_connect (env->cfg, | 615 | plugin->core = GNUNET_CORE_connect (env->cfg, |
630 | plugin, | 616 | plugin, |
@@ -640,6 +626,7 @@ libgnunet_plugin_dhtu_ip_init (void *cls) | |||
640 | (NULL == plugin->nse) ) | 626 | (NULL == plugin->nse) ) |
641 | { | 627 | { |
642 | GNUNET_break (0); | 628 | GNUNET_break (0); |
629 | GNUNET_free (api); | ||
643 | libgnunet_plugin_dhtu_gnunet_done (plugin); | 630 | libgnunet_plugin_dhtu_gnunet_done (plugin); |
644 | return NULL; | 631 | return NULL; |
645 | } | 632 | } |
diff --git a/src/dhtu/plugin_dhtu_ip.c b/src/dhtu/plugin_dhtu_ip.c index 8eec6294b..612d2c119 100644 --- a/src/dhtu/plugin_dhtu_ip.c +++ b/src/dhtu/plugin_dhtu_ip.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | Copyright (C) 2021 GNUnet e.V. | 3 | Copyright (C) 2021, 2022 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 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 | 6 | under the terms of the GNU Affero General Public License as published |
@@ -56,17 +56,12 @@ struct GNUNET_DHTU_Source | |||
56 | struct GNUNET_DHTU_Source *prev; | 56 | struct GNUNET_DHTU_Source *prev; |
57 | 57 | ||
58 | /** | 58 | /** |
59 | * Position of this peer in the DHT. | ||
60 | */ | ||
61 | struct GNUNET_DHTU_HashKey id; | ||
62 | |||
63 | /** | ||
64 | * Application context for this source. | 59 | * Application context for this source. |
65 | */ | 60 | */ |
66 | void *app_ctx; | 61 | void *app_ctx; |
67 | 62 | ||
68 | /** | 63 | /** |
69 | * Address in URL form ("ip+udp://$IP:$PORT") | 64 | * Address in URL form ("ip+udp://$PID/$IP:$PORT") |
70 | */ | 65 | */ |
71 | char *address; | 66 | char *address; |
72 | 67 | ||
@@ -121,9 +116,9 @@ struct GNUNET_DHTU_Target | |||
121 | struct GNUNET_DHTU_PreferenceHandle *ph_tail; | 116 | struct GNUNET_DHTU_PreferenceHandle *ph_tail; |
122 | 117 | ||
123 | /** | 118 | /** |
124 | * Position of this peer in the DHT. | 119 | * Peer's identity. |
125 | */ | 120 | */ |
126 | struct GNUNET_DHTU_HashKey id; | 121 | struct GNUNET_PeerIdentity pid; |
127 | 122 | ||
128 | /** | 123 | /** |
129 | * Target IP address. | 124 | * Target IP address. |
@@ -217,14 +212,24 @@ struct Plugin | |||
217 | char *port; | 212 | char *port; |
218 | 213 | ||
219 | /** | 214 | /** |
215 | * My UDP socket. | ||
216 | */ | ||
217 | struct GNUNET_NETWORK_Handle *sock; | ||
218 | |||
219 | /** | ||
220 | * My identity. | ||
221 | */ | ||
222 | struct GNUNET_PeerIdentity my_id; | ||
223 | |||
224 | /** | ||
220 | * How often have we scanned for IPs? | 225 | * How often have we scanned for IPs? |
221 | */ | 226 | */ |
222 | unsigned int scan_generation; | 227 | unsigned int scan_generation; |
223 | 228 | ||
224 | /** | 229 | /** |
225 | * My UDP socket. | 230 | * Port as a 16-bit value. |
226 | */ | 231 | */ |
227 | struct GNUNET_NETWORK_Handle *sock; | 232 | uint16_t port16; |
228 | }; | 233 | }; |
229 | 234 | ||
230 | 235 | ||
@@ -232,18 +237,20 @@ struct Plugin | |||
232 | * Create a target to which we may send traffic. | 237 | * Create a target to which we may send traffic. |
233 | * | 238 | * |
234 | * @param plugin our plugin | 239 | * @param plugin our plugin |
240 | * @param pid presumed identity of the target | ||
235 | * @param addr target address | 241 | * @param addr target address |
236 | * @param addrlen number of bytes in @a addr | 242 | * @param addrlen number of bytes in @a addr |
237 | * @return new target object | 243 | * @return new target object |
238 | */ | 244 | */ |
239 | static struct GNUNET_DHTU_Target * | 245 | static struct GNUNET_DHTU_Target * |
240 | create_target (struct Plugin *plugin, | 246 | create_target (struct Plugin *plugin, |
247 | const struct GNUNET_PeerIdentity *pid, | ||
241 | const struct sockaddr *addr, | 248 | const struct sockaddr *addr, |
242 | socklen_t addrlen) | 249 | socklen_t addrlen) |
243 | { | 250 | { |
244 | struct GNUNET_DHTU_Target *dst; | 251 | struct GNUNET_DHTU_Target *dst; |
245 | 252 | ||
246 | if (MAX_DESTS > | 253 | if (MAX_DESTS <= |
247 | GNUNET_CONTAINER_multihashmap_size (plugin->dsts)) | 254 | GNUNET_CONTAINER_multihashmap_size (plugin->dsts)) |
248 | { | 255 | { |
249 | struct GNUNET_HashCode key; | 256 | struct GNUNET_HashCode key; |
@@ -275,42 +282,16 @@ create_target (struct Plugin *plugin, | |||
275 | } | 282 | } |
276 | dst = GNUNET_new (struct GNUNET_DHTU_Target); | 283 | dst = GNUNET_new (struct GNUNET_DHTU_Target); |
277 | dst->addrlen = addrlen; | 284 | dst->addrlen = addrlen; |
285 | dst->pid = *pid; | ||
278 | memcpy (&dst->addr, | 286 | memcpy (&dst->addr, |
279 | addr, | 287 | addr, |
280 | addrlen); | 288 | addrlen); |
281 | switch (addr->sa_family) | ||
282 | { | ||
283 | case AF_INET: | ||
284 | { | ||
285 | const struct sockaddr_in *s4 = (const struct sockaddr_in *) addr; | ||
286 | |||
287 | GNUNET_assert (sizeof (struct sockaddr_in) == addrlen); | ||
288 | GNUNET_CRYPTO_hash (&s4->sin_addr, | ||
289 | sizeof (struct in_addr), | ||
290 | &dst->id.sha512); | ||
291 | } | ||
292 | break; | ||
293 | case AF_INET6: | ||
294 | { | ||
295 | const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *) addr; | ||
296 | |||
297 | GNUNET_assert (sizeof (struct sockaddr_in6) == addrlen); | ||
298 | GNUNET_CRYPTO_hash (&s6->sin6_addr, | ||
299 | sizeof (struct in6_addr), | ||
300 | &dst->id.sha512); | ||
301 | } | ||
302 | break; | ||
303 | default: | ||
304 | GNUNET_break (0); | ||
305 | GNUNET_free (dst); | ||
306 | return NULL; | ||
307 | } | ||
308 | GNUNET_CONTAINER_DLL_insert (plugin->dst_head, | 289 | GNUNET_CONTAINER_DLL_insert (plugin->dst_head, |
309 | plugin->dst_tail, | 290 | plugin->dst_tail, |
310 | dst); | 291 | dst); |
311 | plugin->env->connect_cb (plugin->env->cls, | 292 | plugin->env->connect_cb (plugin->env->cls, |
312 | dst, | 293 | dst, |
313 | &dst->id, | 294 | &dst->pid, |
314 | &dst->app_ctx); | 295 | &dst->app_ctx); |
315 | return dst; | 296 | return dst; |
316 | } | 297 | } |
@@ -321,6 +302,7 @@ create_target (struct Plugin *plugin, | |||
321 | * create one! | 302 | * create one! |
322 | * | 303 | * |
323 | * @param plugin the plugin handle | 304 | * @param plugin the plugin handle |
305 | * @param pid presumed identity of the target | ||
324 | * @param src source target is from, or NULL if unknown | 306 | * @param src source target is from, or NULL if unknown |
325 | * @param addr socket address to find | 307 | * @param addr socket address to find |
326 | * @param addrlen number of bytes in @a addr | 308 | * @param addrlen number of bytes in @a addr |
@@ -328,6 +310,7 @@ create_target (struct Plugin *plugin, | |||
328 | */ | 310 | */ |
329 | static struct GNUNET_DHTU_Target * | 311 | static struct GNUNET_DHTU_Target * |
330 | find_target (struct Plugin *plugin, | 312 | find_target (struct Plugin *plugin, |
313 | const struct GNUNET_PeerIdentity *pid, | ||
331 | const void *addr, | 314 | const void *addr, |
332 | size_t addrlen) | 315 | size_t addrlen) |
333 | { | 316 | { |
@@ -342,6 +325,7 @@ find_target (struct Plugin *plugin, | |||
342 | if (NULL == dst) | 325 | if (NULL == dst) |
343 | { | 326 | { |
344 | dst = create_target (plugin, | 327 | dst = create_target (plugin, |
328 | pid, | ||
345 | (const struct sockaddr *) addr, | 329 | (const struct sockaddr *) addr, |
346 | addrlen); | 330 | addrlen); |
347 | GNUNET_assert (GNUNET_YES == | 331 | GNUNET_assert (GNUNET_YES == |
@@ -370,10 +354,12 @@ find_target (struct Plugin *plugin, | |||
370 | * Request creation of a session with a peer at the given @a address. | 354 | * Request creation of a session with a peer at the given @a address. |
371 | * | 355 | * |
372 | * @param cls closure (internal context for the plugin) | 356 | * @param cls closure (internal context for the plugin) |
357 | * @param pid identity of the target peer | ||
373 | * @param address target address to connect to | 358 | * @param address target address to connect to |
374 | */ | 359 | */ |
375 | static void | 360 | static void |
376 | ip_try_connect (void *cls, | 361 | ip_try_connect (void *cls, |
362 | const struct GNUNET_PeerIdentity *pid, | ||
377 | const char *address) | 363 | const char *address) |
378 | { | 364 | { |
379 | struct Plugin *plugin = cls; | 365 | struct Plugin *plugin = cls; |
@@ -389,19 +375,13 @@ ip_try_connect (void *cls, | |||
389 | strncmp (address, | 375 | strncmp (address, |
390 | "ip+", | 376 | "ip+", |
391 | strlen ("ip+"))) | 377 | strlen ("ip+"))) |
392 | { | ||
393 | GNUNET_break (0); | ||
394 | return; | 378 | return; |
395 | } | ||
396 | address += strlen ("ip+"); | 379 | address += strlen ("ip+"); |
397 | if (0 != | 380 | if (0 != |
398 | strncmp (address, | 381 | strncmp (address, |
399 | "udp://", | 382 | "udp://", |
400 | strlen ("udp://"))) | 383 | strlen ("udp://"))) |
401 | { | ||
402 | GNUNET_break (0); | ||
403 | return; | 384 | return; |
404 | } | ||
405 | address += strlen ("udp://"); | 385 | address += strlen ("udp://"); |
406 | addr = GNUNET_strdup (address); | 386 | addr = GNUNET_strdup (address); |
407 | colon = strchr (addr, ':'); | 387 | colon = strchr (addr, ':'); |
@@ -426,6 +406,7 @@ ip_try_connect (void *cls, | |||
426 | } | 406 | } |
427 | GNUNET_free (addr); | 407 | GNUNET_free (addr); |
428 | (void) find_target (plugin, | 408 | (void) find_target (plugin, |
409 | pid, | ||
429 | result->ai_addr, | 410 | result->ai_addr, |
430 | result->ai_addrlen); | 411 | result->ai_addrlen); |
431 | freeaddrinfo (result); | 412 | freeaddrinfo (result); |
@@ -499,10 +480,17 @@ ip_send (void *cls, | |||
499 | void *finished_cb_cls) | 480 | void *finished_cb_cls) |
500 | { | 481 | { |
501 | struct Plugin *plugin = cls; | 482 | struct Plugin *plugin = cls; |
502 | 483 | char buf[sizeof (plugin->my_id) + msg_size]; | |
484 | |||
485 | memcpy (buf, | ||
486 | &plugin->my_id, | ||
487 | sizeof (plugin->my_id)); | ||
488 | memcpy (&buf[sizeof (plugin->my_id)], | ||
489 | msg, | ||
490 | msg_size); | ||
503 | GNUNET_NETWORK_socket_sendto (plugin->sock, | 491 | GNUNET_NETWORK_socket_sendto (plugin->sock, |
504 | msg, | 492 | buf, |
505 | msg_size, | 493 | sizeof (buf), |
506 | (const struct sockaddr *) &target->addr, | 494 | (const struct sockaddr *) &target->addr, |
507 | target->addrlen); | 495 | target->addrlen); |
508 | finished_cb (finished_cb_cls); | 496 | finished_cb (finished_cb_cls); |
@@ -538,9 +526,6 @@ create_source (struct Plugin *plugin, | |||
538 | char buf[INET_ADDRSTRLEN]; | 526 | char buf[INET_ADDRSTRLEN]; |
539 | 527 | ||
540 | GNUNET_assert (sizeof (struct sockaddr_in) == addrlen); | 528 | GNUNET_assert (sizeof (struct sockaddr_in) == addrlen); |
541 | GNUNET_CRYPTO_hash (&s4->sin_addr, | ||
542 | sizeof (struct in_addr), | ||
543 | &src->id.sha512); | ||
544 | GNUNET_asprintf (&src->address, | 529 | GNUNET_asprintf (&src->address, |
545 | "ip+udp://%s:%u", | 530 | "ip+udp://%s:%u", |
546 | inet_ntop (AF_INET, | 531 | inet_ntop (AF_INET, |
@@ -556,9 +541,6 @@ create_source (struct Plugin *plugin, | |||
556 | char buf[INET6_ADDRSTRLEN]; | 541 | char buf[INET6_ADDRSTRLEN]; |
557 | 542 | ||
558 | GNUNET_assert (sizeof (struct sockaddr_in6) == addrlen); | 543 | GNUNET_assert (sizeof (struct sockaddr_in6) == addrlen); |
559 | GNUNET_CRYPTO_hash (&s6->sin6_addr, | ||
560 | sizeof (struct in6_addr), | ||
561 | &src->id.sha512); | ||
562 | GNUNET_asprintf (&src->address, | 544 | GNUNET_asprintf (&src->address, |
563 | "ip+udp://[%s]:%u", | 545 | "ip+udp://[%s]:%u", |
564 | inet_ntop (AF_INET6, | 546 | inet_ntop (AF_INET6, |
@@ -577,7 +559,6 @@ create_source (struct Plugin *plugin, | |||
577 | plugin->src_tail, | 559 | plugin->src_tail, |
578 | src); | 560 | src); |
579 | plugin->env->address_add_cb (plugin->env->cls, | 561 | plugin->env->address_add_cb (plugin->env->cls, |
580 | &src->id, | ||
581 | src->address, | 562 | src->address, |
582 | src, | 563 | src, |
583 | &src->app_ctx); | 564 | &src->app_ctx); |
@@ -586,6 +567,101 @@ create_source (struct Plugin *plugin, | |||
586 | 567 | ||
587 | 568 | ||
588 | /** | 569 | /** |
570 | * Compare two addresses excluding the ports for equality. Only compares IP | ||
571 | * address. Must only be called on AF_INET or AF_INET6 addresses. | ||
572 | * | ||
573 | * @param a1 address to compare | ||
574 | * @param a2 address to compare | ||
575 | * @param alen number of bytes in @a a1 and @a a2 | ||
576 | * @return 0 if @a a1 == @a a2. | ||
577 | */ | ||
578 | static int | ||
579 | addrcmp_np (const struct sockaddr *a1, | ||
580 | const struct sockaddr *a2, | ||
581 | size_t alen) | ||
582 | { | ||
583 | GNUNET_assert (a1->sa_family == a2->sa_family); | ||
584 | switch (a1->sa_family) | ||
585 | { | ||
586 | case AF_INET: | ||
587 | GNUNET_assert (sizeof (struct sockaddr_in) == alen); | ||
588 | { | ||
589 | const struct sockaddr_in *s1 = (const struct sockaddr_in *) a1; | ||
590 | const struct sockaddr_in *s2 = (const struct sockaddr_in *) a2; | ||
591 | |||
592 | if (s1->sin_addr.s_addr != s2->sin_addr.s_addr) | ||
593 | return 1; | ||
594 | break; | ||
595 | } | ||
596 | case AF_INET6: | ||
597 | GNUNET_assert (sizeof (struct sockaddr_in6) == alen); | ||
598 | { | ||
599 | const struct sockaddr_in6 *s1 = (const struct sockaddr_in6 *) a1; | ||
600 | const struct sockaddr_in6 *s2 = (const struct sockaddr_in6 *) a2; | ||
601 | |||
602 | if (0 != GNUNET_memcmp (&s1->sin6_addr, | ||
603 | &s2->sin6_addr)) | ||
604 | return 1; | ||
605 | break; | ||
606 | } | ||
607 | default: | ||
608 | GNUNET_assert (0); | ||
609 | } | ||
610 | return 0; | ||
611 | } | ||
612 | |||
613 | |||
614 | /** | ||
615 | * Compare two addresses for equality. Only | ||
616 | * compares IP address and port. Must only be | ||
617 | * called on AF_INET or AF_INET6 addresses. | ||
618 | * | ||
619 | * @param a1 address to compare | ||
620 | * @param a2 address to compare | ||
621 | * @param alen number of bytes in @a a1 and @a a2 | ||
622 | * @return 0 if @a a1 == @a a2. | ||
623 | */ | ||
624 | static int | ||
625 | addrcmp (const struct sockaddr *a1, | ||
626 | const struct sockaddr *a2, | ||
627 | size_t alen) | ||
628 | { | ||
629 | GNUNET_assert (a1->sa_family == a2->sa_family); | ||
630 | switch (a1->sa_family) | ||
631 | { | ||
632 | case AF_INET: | ||
633 | GNUNET_assert (sizeof (struct sockaddr_in) == alen); | ||
634 | { | ||
635 | const struct sockaddr_in *s1 = (const struct sockaddr_in *) a1; | ||
636 | const struct sockaddr_in *s2 = (const struct sockaddr_in *) a2; | ||
637 | |||
638 | if (s1->sin_port != s2->sin_port) | ||
639 | return 1; | ||
640 | if (s1->sin_addr.s_addr != s2->sin_addr.s_addr) | ||
641 | return 1; | ||
642 | break; | ||
643 | } | ||
644 | case AF_INET6: | ||
645 | GNUNET_assert (sizeof (struct sockaddr_in6) == alen); | ||
646 | { | ||
647 | const struct sockaddr_in6 *s1 = (const struct sockaddr_in6 *) a1; | ||
648 | const struct sockaddr_in6 *s2 = (const struct sockaddr_in6 *) a2; | ||
649 | |||
650 | if (s1->sin6_port != s2->sin6_port) | ||
651 | return 1; | ||
652 | if (0 != GNUNET_memcmp (&s1->sin6_addr, | ||
653 | &s2->sin6_addr)) | ||
654 | return 1; | ||
655 | break; | ||
656 | } | ||
657 | default: | ||
658 | GNUNET_assert (0); | ||
659 | } | ||
660 | return 0; | ||
661 | } | ||
662 | |||
663 | |||
664 | /** | ||
589 | * Callback function invoked for each interface found. | 665 | * Callback function invoked for each interface found. |
590 | * | 666 | * |
591 | * @param cls closure | 667 | * @param cls closure |
@@ -597,7 +673,7 @@ create_source (struct Plugin *plugin, | |||
597 | * @param addrlen length of the address | 673 | * @param addrlen length of the address |
598 | * @return #GNUNET_OK to continue iteration, #GNUNET_SYSERR to abort | 674 | * @return #GNUNET_OK to continue iteration, #GNUNET_SYSERR to abort |
599 | */ | 675 | */ |
600 | static int | 676 | static enum GNUNET_GenericReturnValue |
601 | process_ifcs (void *cls, | 677 | process_ifcs (void *cls, |
602 | const char *name, | 678 | const char *name, |
603 | int isDefault, | 679 | int isDefault, |
@@ -614,17 +690,45 @@ process_ifcs (void *cls, | |||
614 | src = src->next) | 690 | src = src->next) |
615 | { | 691 | { |
616 | if ( (addrlen == src->addrlen) && | 692 | if ( (addrlen == src->addrlen) && |
617 | (0 == memcmp (addr, | 693 | (0 == addrcmp_np (addr, |
618 | &src->addr, | 694 | (const struct sockaddr *) &src->addr, |
619 | addrlen)) ) | 695 | addrlen)) ) |
620 | { | 696 | { |
621 | src->scan_generation = plugin->scan_generation; | 697 | src->scan_generation = plugin->scan_generation; |
622 | return GNUNET_OK; | 698 | return GNUNET_OK; |
623 | } | 699 | } |
624 | } | 700 | } |
625 | (void) create_source (plugin, | 701 | switch (addr->sa_family) |
626 | addr, | 702 | { |
627 | addrlen); | 703 | case AF_INET: |
704 | { | ||
705 | struct sockaddr_in v4; | ||
706 | |||
707 | GNUNET_assert (sizeof(v4) == addrlen); | ||
708 | memcpy (&v4, | ||
709 | addr, | ||
710 | addrlen); | ||
711 | v4.sin_port = htons (plugin->port16); | ||
712 | (void) create_source (plugin, | ||
713 | (const struct sockaddr *) &v4, | ||
714 | sizeof (v4)); | ||
715 | break; | ||
716 | } | ||
717 | case AF_INET6: | ||
718 | { | ||
719 | struct sockaddr_in6 v6; | ||
720 | |||
721 | GNUNET_assert (sizeof(v6) == addrlen); | ||
722 | memcpy (&v6, | ||
723 | addr, | ||
724 | addrlen); | ||
725 | v6.sin6_port = htons (plugin->port16); | ||
726 | (void) create_source (plugin, | ||
727 | (const struct sockaddr *) &v6, | ||
728 | sizeof (v6)); | ||
729 | break; | ||
730 | } | ||
731 | } | ||
628 | return GNUNET_OK; | 732 | return GNUNET_OK; |
629 | } | 733 | } |
630 | 734 | ||
@@ -648,7 +752,7 @@ scan (void *cls) | |||
648 | src = next) | 752 | src = next) |
649 | { | 753 | { |
650 | next = src->next; | 754 | next = src->next; |
651 | if (src->scan_generation == plugin->scan_generation) | 755 | if (src->scan_generation >= plugin->scan_generation) |
652 | continue; | 756 | continue; |
653 | GNUNET_CONTAINER_DLL_remove (plugin->src_head, | 757 | GNUNET_CONTAINER_DLL_remove (plugin->src_head, |
654 | plugin->src_tail, | 758 | plugin->src_tail, |
@@ -682,9 +786,9 @@ find_source (struct Plugin *plugin, | |||
682 | src = src->next) | 786 | src = src->next) |
683 | { | 787 | { |
684 | if ( (addrlen == src->addrlen) && | 788 | if ( (addrlen == src->addrlen) && |
685 | (0 == memcmp (addr, | 789 | (0 == addrcmp (addr, |
686 | &src->addr, | 790 | (const struct sockaddr *) &src->addr, |
687 | addrlen)) ) | 791 | addrlen)) ) |
688 | return src; | 792 | return src; |
689 | } | 793 | } |
690 | 794 | ||
@@ -704,7 +808,8 @@ read_cb (void *cls) | |||
704 | { | 808 | { |
705 | struct Plugin *plugin = cls; | 809 | struct Plugin *plugin = cls; |
706 | ssize_t ret; | 810 | ssize_t ret; |
707 | char buf[65536]; | 811 | const struct GNUNET_PeerIdentity *pid; |
812 | char buf[65536] GNUNET_ALIGN; | ||
708 | struct sockaddr_storage sa; | 813 | struct sockaddr_storage sa; |
709 | struct iovec iov = { | 814 | struct iovec iov = { |
710 | .iov_base = buf, | 815 | .iov_base = buf, |
@@ -719,98 +824,120 @@ read_cb (void *cls) | |||
719 | .msg_control = ctl, | 824 | .msg_control = ctl, |
720 | .msg_controllen = sizeof (ctl) | 825 | .msg_controllen = sizeof (ctl) |
721 | }; | 826 | }; |
827 | struct GNUNET_DHTU_Target *dst = NULL; | ||
828 | struct GNUNET_DHTU_Source *src = NULL; | ||
722 | 829 | ||
723 | ret = recvmsg (GNUNET_NETWORK_get_fd (plugin->sock), | 830 | ret = recvmsg (GNUNET_NETWORK_get_fd (plugin->sock), |
724 | &mh, | 831 | &mh, |
725 | MSG_DONTWAIT); | 832 | MSG_DONTWAIT); |
726 | if (ret >= 0) | 833 | plugin->read_task = GNUNET_SCHEDULER_add_read_net ( |
834 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
835 | plugin->sock, | ||
836 | &read_cb, | ||
837 | plugin); | ||
838 | if (ret < 0) | ||
839 | return; /* read failure, hopefully EAGAIN */ | ||
840 | if (ret < sizeof (*pid)) | ||
841 | { | ||
842 | GNUNET_break_op (0); | ||
843 | return; | ||
844 | } | ||
845 | /* find IP where we received message */ | ||
846 | for (struct cmsghdr *cmsg = CMSG_FIRSTHDR (&mh); | ||
847 | NULL != cmsg; | ||
848 | cmsg = CMSG_NXTHDR (&mh, | ||
849 | cmsg)) | ||
727 | { | 850 | { |
728 | struct GNUNET_DHTU_Target *dst = NULL; | 851 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
729 | struct GNUNET_DHTU_Source *src = NULL; | 852 | "Got CMSG level %u (%d/%d), type %u (%d/%d)\n", |
730 | struct cmsghdr *cmsg; | 853 | cmsg->cmsg_level, |
731 | 854 | (cmsg->cmsg_level == IPPROTO_IP), | |
732 | /* find IP where we received message */ | 855 | (cmsg->cmsg_level == IPPROTO_IPV6), |
733 | for (cmsg = CMSG_FIRSTHDR (&mh); | 856 | cmsg->cmsg_type, |
734 | NULL != cmsg; | 857 | (cmsg->cmsg_type == IP_PKTINFO), |
735 | cmsg = CMSG_NXTHDR (&mh, | 858 | (cmsg->cmsg_type == IPV6_PKTINFO)); |
736 | cmsg)) | 859 | if ( (cmsg->cmsg_level == IPPROTO_IP) && |
860 | (cmsg->cmsg_type == IP_PKTINFO) ) | ||
737 | { | 861 | { |
738 | if ( (cmsg->cmsg_level == IPPROTO_IP) && | 862 | if (CMSG_LEN (sizeof (struct in_pktinfo)) == |
739 | (cmsg->cmsg_type == IP_PKTINFO) ) | 863 | cmsg->cmsg_len) |
740 | { | 864 | { |
741 | if (CMSG_LEN (sizeof (struct in_pktinfo)) == | 865 | struct in_pktinfo pi; |
742 | cmsg->cmsg_len) | 866 | |
867 | memcpy (&pi, | ||
868 | CMSG_DATA (cmsg), | ||
869 | sizeof (pi)); | ||
743 | { | 870 | { |
744 | struct in_pktinfo pi; | 871 | struct sockaddr_in sa = { |
745 | 872 | .sin_family = AF_INET, | |
746 | memcpy (&pi, | 873 | .sin_addr = pi.ipi_addr, |
747 | CMSG_DATA (cmsg), | 874 | .sin_port = htons (plugin->port16) |
748 | sizeof (pi)); | 875 | }; |
749 | { | 876 | |
750 | struct sockaddr_in sa = { | 877 | src = find_source (plugin, |
751 | .sin_family = AF_INET, | 878 | &sa, |
752 | .sin_addr = pi.ipi_addr | 879 | sizeof (sa)); |
753 | }; | 880 | /* For sources we discovered by reading, |
754 | 881 | force the generation far into the future */ | |
755 | src = find_source (plugin, | 882 | src->scan_generation = plugin->scan_generation + 60; |
756 | &sa, | ||
757 | sizeof (sa)); | ||
758 | } | ||
759 | break; | ||
760 | } | 883 | } |
761 | else | 884 | break; |
762 | GNUNET_break (0); | ||
763 | } | 885 | } |
764 | if ( (cmsg->cmsg_level == IPPROTO_IPV6) && | 886 | else |
765 | (cmsg->cmsg_type == IPV6_RECVPKTINFO) ) | 887 | GNUNET_break (0); |
888 | } | ||
889 | if ( (cmsg->cmsg_level == IPPROTO_IPV6) && | ||
890 | (cmsg->cmsg_type == IPV6_PKTINFO) ) | ||
891 | { | ||
892 | if (CMSG_LEN (sizeof (struct in6_pktinfo)) == | ||
893 | cmsg->cmsg_len) | ||
766 | { | 894 | { |
767 | if (CMSG_LEN (sizeof (struct in6_pktinfo)) == | 895 | struct in6_pktinfo pi; |
768 | cmsg->cmsg_len) | 896 | |
897 | memcpy (&pi, | ||
898 | CMSG_DATA (cmsg), | ||
899 | sizeof (pi)); | ||
769 | { | 900 | { |
770 | struct in6_pktinfo pi; | 901 | struct sockaddr_in6 sa = { |
771 | 902 | .sin6_family = AF_INET6, | |
772 | memcpy (&pi, | 903 | .sin6_addr = pi.ipi6_addr, |
773 | CMSG_DATA (cmsg), | 904 | .sin6_port = htons (plugin->port16), |
774 | sizeof (pi)); | 905 | .sin6_scope_id = pi.ipi6_ifindex |
775 | { | 906 | }; |
776 | struct sockaddr_in6 sa = { | 907 | |
777 | .sin6_family = AF_INET6, | 908 | src = find_source (plugin, |
778 | .sin6_addr = pi.ipi6_addr, | 909 | &sa, |
779 | .sin6_scope_id = pi.ipi6_ifindex | 910 | sizeof (sa)); |
780 | }; | 911 | /* For sources we discovered by reading, |
781 | 912 | force the generation far into the future */ | |
782 | src = find_source (plugin, | 913 | src->scan_generation = plugin->scan_generation + 60; |
783 | &sa, | 914 | break; |
784 | sizeof (sa)); | ||
785 | break; | ||
786 | } | ||
787 | } | 915 | } |
788 | else | ||
789 | GNUNET_break (0); | ||
790 | } | 916 | } |
791 | } | 917 | else |
792 | dst = find_target (plugin, | 918 | GNUNET_break (0); |
793 | &sa, | ||
794 | mh.msg_namelen); | ||
795 | if ( (NULL == src) || | ||
796 | (NULL == dst) ) | ||
797 | { | ||
798 | GNUNET_break (0); | ||
799 | } | ||
800 | else | ||
801 | { | ||
802 | plugin->env->receive_cb (plugin->env->cls, | ||
803 | dst->app_ctx, | ||
804 | src->app_ctx, | ||
805 | buf, | ||
806 | ret); | ||
807 | } | 919 | } |
808 | } | 920 | } |
809 | plugin->read_task = GNUNET_SCHEDULER_add_read_net ( | 921 | if (NULL == src) |
810 | GNUNET_TIME_UNIT_FOREVER_REL, | 922 | { |
811 | plugin->sock, | 923 | GNUNET_break (0); |
812 | &read_cb, | 924 | return; |
813 | plugin); | 925 | } |
926 | pid = (const struct GNUNET_PeerIdentity *) buf; | ||
927 | dst = find_target (plugin, | ||
928 | pid, | ||
929 | &sa, | ||
930 | mh.msg_namelen); | ||
931 | if (NULL == dst) | ||
932 | { | ||
933 | GNUNET_break (0); | ||
934 | return; | ||
935 | } | ||
936 | plugin->env->receive_cb (plugin->env->cls, | ||
937 | &dst->app_ctx, | ||
938 | &src->app_ctx, | ||
939 | &buf[sizeof(*pid)], | ||
940 | ret - sizeof (*pid)); | ||
814 | } | 941 | } |
815 | 942 | ||
816 | 943 | ||
@@ -874,6 +1001,14 @@ libgnunet_plugin_dhtu_ip_init (void *cls) | |||
874 | plugin = GNUNET_new (struct Plugin); | 1001 | plugin = GNUNET_new (struct Plugin); |
875 | plugin->env = env; | 1002 | plugin->env = env; |
876 | plugin->port = port; | 1003 | plugin->port = port; |
1004 | plugin->port16 = (uint16_t) nport; | ||
1005 | if (GNUNET_OK != | ||
1006 | GNUNET_CRYPTO_get_peer_identity (env->cfg, | ||
1007 | &plugin->my_id)) | ||
1008 | { | ||
1009 | GNUNET_free (plugin); | ||
1010 | return NULL; | ||
1011 | } | ||
877 | af = AF_INET6; | 1012 | af = AF_INET6; |
878 | sock = socket (af, | 1013 | sock = socket (af, |
879 | SOCK_DGRAM, | 1014 | SOCK_DGRAM, |
@@ -1017,9 +1152,18 @@ libgnunet_plugin_dhtu_ip_done (void *cls) | |||
1017 | GNUNET_free (src->address); | 1152 | GNUNET_free (src->address); |
1018 | GNUNET_free (src); | 1153 | GNUNET_free (src); |
1019 | } | 1154 | } |
1155 | plugin->env->network_size_cb (plugin->env->cls, | ||
1156 | GNUNET_TIME_UNIT_FOREVER_ABS, | ||
1157 | 0.0, | ||
1158 | 0.0); | ||
1020 | GNUNET_CONTAINER_multihashmap_destroy (plugin->dsts); | 1159 | GNUNET_CONTAINER_multihashmap_destroy (plugin->dsts); |
1160 | if (NULL != plugin->read_task) | ||
1161 | { | ||
1162 | GNUNET_SCHEDULER_cancel (plugin->read_task); | ||
1163 | plugin->read_task = NULL; | ||
1164 | } | ||
1021 | GNUNET_SCHEDULER_cancel (plugin->scan_task); | 1165 | GNUNET_SCHEDULER_cancel (plugin->scan_task); |
1022 | GNUNET_break (0 == | 1166 | GNUNET_break (GNUNET_OK == |
1023 | GNUNET_NETWORK_socket_close (plugin->sock)); | 1167 | GNUNET_NETWORK_socket_close (plugin->sock)); |
1024 | GNUNET_free (plugin->port); | 1168 | GNUNET_free (plugin->port); |
1025 | GNUNET_free (plugin); | 1169 | GNUNET_free (plugin); |