diff options
Diffstat (limited to 'src/dhtu/plugin_dhtu_ip.c')
-rw-r--r-- | src/dhtu/plugin_dhtu_ip.c | 434 |
1 files changed, 289 insertions, 145 deletions
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); |