aboutsummaryrefslogtreecommitdiff
path: root/src/dhtu
diff options
context:
space:
mode:
Diffstat (limited to 'src/dhtu')
-rw-r--r--src/dhtu/Makefile.am7
-rw-r--r--src/dhtu/dhtu.conf7
-rw-r--r--src/dhtu/plugin_dhtu_gnunet.c63
-rw-r--r--src/dhtu/plugin_dhtu_ip.c434
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
11endif 11endif
12 12
13pkgcfg_DATA = \
14 dhtu.conf
15
16
13plugin_LTLIBRARIES = \ 17plugin_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 = \
67check_PROGRAMS = \ 71check_PROGRAMS = \
68 test_dhtu_ip 72 test_dhtu_ip
69 73
74EXTRA_DIST = \
75 dhtu.conf
76
70if ENABLE_TEST_RUN 77if ENABLE_TEST_RUN
71AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; 78AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME;
72TESTS = \ 79TESTS = \
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]
2ENABLED = YES
3
4[dhtu-ip]
5ENABLED = NO
6NSE = 4
7UDP_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 */
245static void 236static void
246ip_try_connect (void *cls, 237gnunet_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 */
285static struct GNUNET_DHTU_PreferenceHandle * 274static struct GNUNET_DHTU_PreferenceHandle *
286ip_hold (void *cls, 275gnunet_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 */
314static void 303static void
315ip_drop (struct GNUNET_DHTU_PreferenceHandle *ph) 304gnunet_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 */
352static void 341static void
353ip_send (void *cls, 342gnunet_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 */
606void * 592void *
607libgnunet_plugin_dhtu_ip_init (void *cls) 593libgnunet_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 */
239static struct GNUNET_DHTU_Target * 245static struct GNUNET_DHTU_Target *
240create_target (struct Plugin *plugin, 246create_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 */
329static struct GNUNET_DHTU_Target * 311static struct GNUNET_DHTU_Target *
330find_target (struct Plugin *plugin, 312find_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 */
375static void 360static void
376ip_try_connect (void *cls, 361ip_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 */
578static int
579addrcmp_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 */
624static int
625addrcmp (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 */
600static int 676static enum GNUNET_GenericReturnValue
601process_ifcs (void *cls, 677process_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);