aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <grothoff@gnunet.org>2021-07-06 23:16:53 +0200
committerChristian Grothoff <grothoff@gnunet.org>2021-07-06 23:16:53 +0200
commitd0d24c62f4b4a1872c8b52ad902b11aa4962d2c2 (patch)
tree3c7b51b2d16d9478d9c2efbbeaf04bb18f3d41b7 /src
parent7d384a118326f5ce8237281c5b5ffa36c32662fe (diff)
downloadgnunet-d0d24c62f4b4a1872c8b52ad902b11aa4962d2c2.tar.gz
gnunet-d0d24c62f4b4a1872c8b52ad902b11aa4962d2c2.zip
-rudimentary untested IP DHTU plugin
Diffstat (limited to 'src')
-rw-r--r--src/dhtu/plugin_dhtu_ip.c366
-rw-r--r--src/include/gnunet_dhtu_plugin.h4
2 files changed, 269 insertions, 101 deletions
diff --git a/src/dhtu/plugin_dhtu_ip.c b/src/dhtu/plugin_dhtu_ip.c
index 19fe19192..a0da9d680 100644
--- a/src/dhtu/plugin_dhtu_ip.c
+++ b/src/dhtu/plugin_dhtu_ip.c
@@ -23,6 +23,11 @@
23 * 23 *
24 * @file plugin_dhtu_ip.c 24 * @file plugin_dhtu_ip.c
25 * @brief plain IP based DHT network underlay 25 * @brief plain IP based DHT network underlay
26 *
27 * TODO:
28 * - call NSE callback
29 * - expire destination addresses
30 * - faster lookup of destinations
26 */ 31 */
27#include "platform.h" 32#include "platform.h"
28#include "gnunet_dhtu_plugin.h" 33#include "gnunet_dhtu_plugin.h"
@@ -85,11 +90,26 @@ struct GNUNET_DHTU_Source
85 */ 90 */
86struct GNUNET_DHTU_Target 91struct GNUNET_DHTU_Target
87{ 92{
93 // FIXME: add mechanism for targets to expire
94 /**
95 * Kept in a DLL.
96 */
97 struct GNUNET_DHTU_Target *next;
98
99 /**
100 * Kept in a DLL.
101 */
102 struct GNUNET_DHTU_Target *prev;
88 103
89 /** 104 /**
90 * Application context for this target. 105 * Application context for this target.
91 */ 106 */
92 void *app_ctx; 107 void *app_ctx;
108
109 /**
110 * Hash of the IP address.
111 */
112 struct GNUNET_DHTU_Hash id;
93 113
94 /** 114 /**
95 * Head of preferences expressed for this target. 115 * Head of preferences expressed for this target.
@@ -162,6 +182,16 @@ struct Plugin
162 struct GNUNET_DHTU_Source *src_tail; 182 struct GNUNET_DHTU_Source *src_tail;
163 183
164 /** 184 /**
185 * Head of destinations that are active.
186 */
187 struct GNUNET_DHTU_Target *dst_head;
188
189 /**
190 * Tail of destinations that are active.
191 */
192 struct GNUNET_DHTU_Target *dst_tail;
193
194 /**
165 * Task that scans for IP address changes. 195 * Task that scans for IP address changes.
166 */ 196 */
167 struct GNUNET_SCHEDULER_Task *scan_task; 197 struct GNUNET_SCHEDULER_Task *scan_task;
@@ -231,6 +261,99 @@ ip_verify (void *cls,
231 261
232 262
233/** 263/**
264 * Create a target to which we may send traffic.
265 *
266 * @param plugin our plugin
267 * @param addr target address
268 * @param addrlen number of bytes in @a addr
269 * @return new target object
270 */
271static struct GNUNET_DHTU_Target *
272create_target (struct Plugin *plugin,
273 const struct sockaddr *addr,
274 socklen_t addrlen)
275{
276 static struct GNUNET_DHTU_PublicKey pk;
277 struct GNUNET_DHTU_Target *dst;
278
279 pk.size = htons (sizeof (pk));
280 dst = GNUNET_new (struct GNUNET_DHTU_Target);
281 dst->addrlen = addrlen;
282 memcpy (&dst->addr,
283 addr,
284 addrlen);
285 switch (addr->sa_family)
286 {
287 case AF_INET:
288 {
289 const struct sockaddr_in *s4 = (const struct sockaddr_in *) addr;
290
291 GNUNET_assert (sizeof (struct sockaddr_in) == addrlen);
292 GNUNET_CRYPTO_hash (&s4->sin_addr,
293 sizeof (struct in_addr),
294 &dst->id.hc);
295 }
296 break;
297 case AF_INET6:
298 {
299 const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *) addr;
300
301 GNUNET_assert (sizeof (struct sockaddr_in6) == addrlen);
302 GNUNET_CRYPTO_hash (&s6->sin6_addr,
303 sizeof (struct in6_addr),
304 &dst->id.hc);
305 }
306 break;
307 default:
308 GNUNET_break (0);
309 GNUNET_free (dst);
310 return NULL;
311 }
312 GNUNET_CONTAINER_DLL_insert (plugin->dst_head,
313 plugin->dst_tail,
314 dst);
315 plugin->env->connect_cb (plugin->env->cls,
316 &pk,
317 &dst->id,
318 dst,
319 &dst->app_ctx);
320 return dst;
321}
322
323
324/**
325 * Find target matching @a addr. If none exists,
326 * create one!
327 *
328 * @param plugin the plugin handle
329 * @param src source target is from, or NULL if unknown
330 * @param addr socket address to find
331 * @param addrlen number of bytes in @a addr
332 * @return matching target object
333 */
334static struct GNUNET_DHTU_Target *
335find_target (struct Plugin *plugin,
336 const void *addr,
337 size_t addrlen)
338{
339 // FIXME-OPTIMIZE: use hash map instead of linear search
340 for (struct GNUNET_DHTU_Target *dst = plugin->dst_head;
341 NULL != dst;
342 dst = dst->next)
343 {
344 if ( (addrlen == dst->addrlen) &&
345 (0 == memcmp (addr,
346 &dst->addr,
347 addrlen)) )
348 return dst;
349 }
350 return create_target (plugin,
351 (const struct sockaddr *) addr,
352 addrlen);
353}
354
355
356/**
234 * Request creation of a session with a peer at the given @a address. 357 * Request creation of a session with a peer at the given @a address.
235 * 358 *
236 * @param cls closure (internal context for the plugin) 359 * @param cls closure (internal context for the plugin)
@@ -289,9 +412,9 @@ ip_try_connect (void *cls,
289 return; 412 return;
290 } 413 }
291 GNUNET_free (addr); 414 GNUNET_free (addr);
292 (void) result->ai_addr; // FIXME: use! 415 (void) find_target (plugin,
293 416 result->ai_addr,
294 // FIXME: create target, etc. 417 result->ai_addrlen);
295 freeaddrinfo (result); 418 freeaddrinfo (result);
296} 419}
297 420
@@ -533,7 +656,7 @@ scan (void *cls)
533 * create one! 656 * create one!
534 * 657 *
535 * @param plugin the plugin handle 658 * @param plugin the plugin handle
536 * @param addr IP address to find 659 * @param addr socket address to find
537 * @param addrlen number of bytes in @a addr 660 * @param addrlen number of bytes in @a addr
538 * @return matching source object 661 * @return matching source object
539 */ 662 */
@@ -546,61 +669,16 @@ find_source (struct Plugin *plugin,
546 NULL != src; 669 NULL != src;
547 src = src->next) 670 src = src->next)
548 { 671 {
549 if ( (addrlen == sizeof (struct in_addr)) && 672 if ( (addrlen == src->addrlen) &&
550 (src->addrlen == sizeof (struct sockaddr_in)) ) 673 (0 == memcmp (addr,
551 { 674 &src->addr,
552 const struct sockaddr_in *sa = 675 addrlen)) )
553 (const struct sockaddr_in *) &src->addr;
554 if (0 == memcmp (addr,
555 &sa->sin_addr,
556 addrlen))
557 return src;
558 }
559 if ( (addrlen == sizeof (struct in6_addr)) &&
560 (src->addrlen == sizeof (struct sockaddr_in6)) )
561 {
562 const struct sockaddr_in6 *sa =
563 (const struct sockaddr_in6 *) &src->addr;
564 if (0 == memcmp (addr,
565 &sa->sin6_addr,
566 addrlen))
567 return src; 676 return src;
568 }
569 } 677 }
570 678
571 { 679 return create_source (plugin,
572 struct sockaddr_storage sa; 680 (const struct sockaddr *) addr,
573 socklen_t salen; 681 addrlen);
574
575 memset (&sa,
576 0,
577 sizeof (sa));
578 if (addrlen == sizeof (struct in_addr))
579 {
580 struct sockaddr_in *s4 =
581 (struct sockaddr_in *) &sa;
582
583 s4->sin_family = AF_INET;
584 memcpy (&s4->sin_addr,
585 addr,
586 addrlen);
587 salen = sizeof (*s4);
588 }
589 if (addrlen == sizeof (struct in6_addr))
590 {
591 struct sockaddr_in6 *s6 =
592 (struct sockaddr_in6 *) &sa;
593
594 s6->sin6_family = AF_INET6;
595 memcpy (&s6->sin6_addr,
596 addr,
597 addrlen);
598 salen = sizeof (*s6);
599 }
600 return create_source (plugin,
601 (const struct sockaddr *) &sa,
602 salen);
603 }
604} 682}
605 683
606 684
@@ -620,7 +698,7 @@ read_cb (void *cls)
620 .iov_base = buf, 698 .iov_base = buf,
621 .iov_len = sizeof (buf) 699 .iov_len = sizeof (buf)
622 }; 700 };
623 char ctl[1024]; 701 char ctl[128];
624 struct msghdr mh = { 702 struct msghdr mh = {
625 .msg_name = &sa, 703 .msg_name = &sa,
626 .msg_namelen = sizeof (sa), 704 .msg_namelen = sizeof (sa),
@@ -629,7 +707,7 @@ read_cb (void *cls)
629 .msg_control = ctl, 707 .msg_control = ctl,
630 .msg_controllen = sizeof (ctl) 708 .msg_controllen = sizeof (ctl)
631 }; 709 };
632 710
633 ret = recvmsg (GNUNET_NETWORK_get_fd (plugin->sock), 711 ret = recvmsg (GNUNET_NETWORK_get_fd (plugin->sock),
634 &mh, 712 &mh,
635 MSG_DONTWAIT); 713 MSG_DONTWAIT);
@@ -638,54 +716,70 @@ read_cb (void *cls)
638 struct GNUNET_DHTU_Target *dst = NULL; 716 struct GNUNET_DHTU_Target *dst = NULL;
639 struct GNUNET_DHTU_Source *src = NULL; 717 struct GNUNET_DHTU_Source *src = NULL;
640 struct cmsghdr *cmsg; 718 struct cmsghdr *cmsg;
641 struct msghdr *msh = mh.msg_control;
642 719
643 /* find IP where we received message */ 720 /* find IP where we received message */
644 for (cmsg = CMSG_FIRSTHDR (msh); 721 for (cmsg = CMSG_FIRSTHDR (&mh);
645 NULL != cmsg; 722 NULL != cmsg;
646 cmsg = CMSG_NXTHDR (msh, 723 cmsg = CMSG_NXTHDR (&mh,
647 cmsg)) 724 cmsg))
648 { 725 {
649 if ( (cmsg->cmsg_level == IPPROTO_IP) && 726 if ( (cmsg->cmsg_level == IPPROTO_IP) &&
650 (cmsg->cmsg_type == IP_ORIGDSTADDR) ) 727 (cmsg->cmsg_type == IP_PKTINFO) )
651 { 728 {
652 if (CMSG_LEN (sizeof (struct in_addr)) == 729 if (CMSG_LEN (sizeof (struct in_pktinfo)) ==
653 cmsg->cmsg_len) 730 cmsg->cmsg_len)
654 { 731 {
655 struct in6_addr ia; 732 struct in_pktinfo pi;
656 733
657 memcpy (&ia, 734 memcpy (&pi,
658 CMSG_DATA (cmsg), 735 CMSG_DATA (cmsg),
659 sizeof (ia)); 736 sizeof (pi));
660 src = find_source (plugin, 737 {
661 &ia, 738 struct sockaddr_in sa = {
662 sizeof (ia)); 739 .sin_family = AF_INET,
740 .sin_addr = pi.ipi_addr
741 };
742
743 src = find_source (plugin,
744 &sa,
745 sizeof (sa));
746 }
663 break; 747 break;
664 } 748 }
665 else 749 else
666 GNUNET_break (0); 750 GNUNET_break (0);
667 } 751 }
668 if ( (cmsg->cmsg_level == IPPROTO_IPV6) && 752 if ( (cmsg->cmsg_level == IPPROTO_IPV6) &&
669 (cmsg->cmsg_type == IP_ORIGDSTADDR) ) 753 (cmsg->cmsg_type == IPV6_RECVPKTINFO) )
670 { 754 {
671 if (CMSG_LEN (sizeof (struct in6_addr)) == 755 if (CMSG_LEN (sizeof (struct in6_pktinfo)) ==
672 cmsg->cmsg_len) 756 cmsg->cmsg_len)
673 { 757 {
674 struct in6_addr ia; 758 struct in6_pktinfo pi;
675 759
676 memcpy (&ia, 760 memcpy (&pi,
677 CMSG_DATA (cmsg), 761 CMSG_DATA (cmsg),
678 sizeof (ia)); 762 sizeof (pi));
679 src = find_source (plugin, 763 {
680 &ia, 764 struct sockaddr_in6 sa = {
681 sizeof (ia)); 765 .sin6_family = AF_INET6,
682 break; 766 .sin6_addr = pi.ipi6_addr,
767 .sin6_scope_id = pi.ipi6_ifindex
768 };
769
770 src = find_source (plugin,
771 &sa,
772 sizeof (sa));
773 break;
774 }
683 } 775 }
684 else 776 else
685 GNUNET_break (0); 777 GNUNET_break (0);
686 } 778 }
687 } 779 }
688 // FIXME: find or create 'dst'! 780 dst = find_target (plugin,
781 &sa,
782 mh.msg_namelen);
689 if ( (NULL == src) || 783 if ( (NULL == src) ||
690 (NULL == dst) ) 784 (NULL == dst) )
691 { 785 {
@@ -723,6 +817,7 @@ libgnunet_plugin_dhtu_ip_init (void *cls)
723 char *port; 817 char *port;
724 unsigned int nport; 818 unsigned int nport;
725 int sock; 819 int sock;
820 int af;
726 821
727 if (GNUNET_OK != 822 if (GNUNET_OK !=
728 GNUNET_CONFIGURATION_get_value_string (env->cfg, 823 GNUNET_CONFIGURATION_get_value_string (env->cfg,
@@ -755,7 +850,8 @@ libgnunet_plugin_dhtu_ip_init (void *cls)
755 plugin = GNUNET_new (struct Plugin); 850 plugin = GNUNET_new (struct Plugin);
756 plugin->env = env; 851 plugin->env = env;
757 plugin->port = port; 852 plugin->port = port;
758 sock = socket (AF_INET6, 853 af = AF_INET6;
854 sock = socket (af,
759 SOCK_DGRAM, 855 SOCK_DGRAM,
760 IPPROTO_UDP); 856 IPPROTO_UDP);
761 if (-1 == sock) 857 if (-1 == sock)
@@ -766,25 +862,79 @@ libgnunet_plugin_dhtu_ip_init (void *cls)
766 GNUNET_free (plugin); 862 GNUNET_free (plugin);
767 return NULL; 863 return NULL;
768 } 864 }
769 { 865 switch (af) {
770 struct sockaddr_in6 sa = { 866 case AF_INET:
771 .sin6_family = AF_INET6,
772 .sin6_port = htons ((uint16_t) nport)
773 };
774
775 if (0 !=
776 bind (sock,
777 &sa,
778 sizeof (sa)))
779 { 867 {
780 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, 868 int on = 1;
781 "socket"); 869
782 GNUNET_break (0 == 870 if (0 !=
783 close (sock)); 871 setsockopt (sock,
784 GNUNET_free (plugin->port); 872 IPPROTO_IP,
785 GNUNET_free (plugin); 873 IP_PKTINFO,
786 return NULL; 874 &on,
875 sizeof (on)))
876 {
877 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
878 "setsockopt");
879 }
880 }
881 {
882 struct sockaddr_in sa = {
883 .sin_family = AF_INET,
884 .sin_port = htons ((uint16_t) nport)
885 };
886
887 if (0 !=
888 bind (sock,
889 &sa,
890 sizeof (sa)))
891 {
892 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
893 "socket");
894 GNUNET_break (0 ==
895 close (sock));
896 GNUNET_free (plugin->port);
897 GNUNET_free (plugin);
898 return NULL;
899 }
787 } 900 }
901 break;
902 case AF_INET6:
903 {
904 int on = 1;
905
906 if (0 !=
907 setsockopt (sock,
908 IPPROTO_IPV6,
909 IPV6_RECVPKTINFO,
910 &on,
911 sizeof (on)))
912 {
913 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
914 "setsockopt");
915 }
916 }
917 {
918 struct sockaddr_in6 sa = {
919 .sin6_family = AF_INET6,
920 .sin6_port = htons ((uint16_t) nport)
921 };
922
923 if (0 !=
924 bind (sock,
925 &sa,
926 sizeof (sa)))
927 {
928 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
929 "socket");
930 GNUNET_break (0 ==
931 close (sock));
932 GNUNET_free (plugin->port);
933 GNUNET_free (plugin);
934 return NULL;
935 }
936 }
937 break;
788 } 938 }
789 plugin->sock = GNUNET_NETWORK_socket_box_native (sock); 939 plugin->sock = GNUNET_NETWORK_socket_box_native (sock);
790 plugin->read_task = GNUNET_SCHEDULER_add_read_net ( 940 plugin->read_task = GNUNET_SCHEDULER_add_read_net (
@@ -818,6 +968,26 @@ libgnunet_plugin_dhtu_ip_done (void *cls)
818{ 968{
819 struct GNUNET_DHTU_PluginFunctions *api = cls; 969 struct GNUNET_DHTU_PluginFunctions *api = cls;
820 struct Plugin *plugin = api->cls; 970 struct Plugin *plugin = api->cls;
971 struct GNUNET_DHTU_Source *src;
972 struct GNUNET_DHTU_Target *dst;
973
974 while (NULL != (dst = plugin->dst_head))
975 {
976 plugin->env->disconnect_cb (dst->app_ctx);
977 GNUNET_CONTAINER_DLL_remove (plugin->dst_head,
978 plugin->dst_tail,
979 dst);
980 GNUNET_free (dst);
981 }
982 while (NULL != (src = plugin->src_head))
983 {
984 plugin->env->address_del_cb (src->app_ctx);
985 GNUNET_CONTAINER_DLL_remove (plugin->src_head,
986 plugin->src_tail,
987 src);
988 GNUNET_free (src->address);
989 GNUNET_free (src);
990 }
821 991
822 GNUNET_SCHEDULER_cancel (plugin->scan_task); 992 GNUNET_SCHEDULER_cancel (plugin->scan_task);
823 GNUNET_break (0 == 993 GNUNET_break (0 ==
diff --git a/src/include/gnunet_dhtu_plugin.h b/src/include/gnunet_dhtu_plugin.h
index bcf61eaa2..4e5abf476 100644
--- a/src/include/gnunet_dhtu_plugin.h
+++ b/src/include/gnunet_dhtu_plugin.h
@@ -168,7 +168,7 @@ struct GNUNET_DHTU_PluginEnvironment
168 * @param std_dev standard deviation for the estimate 168 * @param std_dev standard deviation for the estimate
169 */ 169 */
170 void 170 void
171 (*network_size_cb)(void *ctx, 171 (*network_size_cb)(void *cls,
172 struct GNUNET_TIME_Absolute timestamp, 172 struct GNUNET_TIME_Absolute timestamp,
173 double logestimate, 173 double logestimate,
174 double std_dev); 174 double std_dev);
@@ -184,7 +184,6 @@ struct GNUNET_DHTU_PluginEnvironment
184 * pointer will remain valid until @e disconnect_cb is called 184 * pointer will remain valid until @e disconnect_cb is called
185 * @param target handle to the target, 185 * @param target handle to the target,
186 * pointer will remain valid until @e disconnect_cb is called 186 * pointer will remain valid until @e disconnect_cb is called
187 * @param sctx context of the source address on which the connection happened
188 * @param[out] ctx storage space for DHT to use in association with this target 187 * @param[out] ctx storage space for DHT to use in association with this target
189 */ 188 */
190 void 189 void
@@ -192,7 +191,6 @@ struct GNUNET_DHTU_PluginEnvironment
192 const struct GNUNET_DHTU_PublicKey *pk, 191 const struct GNUNET_DHTU_PublicKey *pk,
193 const struct GNUNET_DHTU_Hash *peer_id, 192 const struct GNUNET_DHTU_Hash *peer_id,
194 struct GNUNET_DHTU_Target *target, 193 struct GNUNET_DHTU_Target *target,
195 void *sctx,
196 void **ctx); 194 void **ctx);
197 195
198 /** 196 /**