GNUnet 0.22.0
plugin_dhtu_ip.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet
3 Copyright (C) 2021, 2022 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
27#include "platform.h"
28#include "gnunet_dhtu_plugin.h"
29#include "plugin_dhtu_ip.h"
30
34#define SCAN_FREQ GNUNET_TIME_UNIT_MINUTES
35
39#define MAX_DESTS 256
40
41
47{
48
53
58
62 void *app_ctx;
63
67 char *address;
68
72 struct sockaddr_storage addr;
73
77 socklen_t addrlen;
78
82 unsigned int scan_generation;
83
84};
85
86
92{
93
98
103
107 void *app_ctx;
108
113
118
123
127 struct sockaddr_storage addr;
128
132 socklen_t addrlen;
133
137 unsigned int ph_count;
138
139};
140
146{
151
156
161};
162
163
167struct Plugin
168{
173
178
183
189
194
199
204
209
213 char *port;
214
219
224
228 unsigned int scan_generation;
229
233 uint16_t port16;
234};
235
236
246static struct GNUNET_DHTU_Target *
248 const struct GNUNET_PeerIdentity *pid,
249 const struct sockaddr *addr,
250 socklen_t addrlen)
251{
252 struct GNUNET_DHTU_Target *dst;
253
254 if (MAX_DESTS <=
256 {
257 struct GNUNET_HashCode key;
258
259 dst = NULL;
260 for (struct GNUNET_DHTU_Target *pos = plugin->dst_head;
261 NULL != pos;
262 pos = pos->next)
263 {
264 /* >= here assures we remove oldest entries first */
265 if ( (NULL == dst) ||
266 (dst->ph_count >= pos->ph_count) )
267 dst = pos;
268 }
269 GNUNET_assert (NULL != dst);
270 plugin->env->disconnect_cb (dst->app_ctx);
271 GNUNET_CRYPTO_hash (&dst->addr,
272 dst->addrlen,
273 &key);
276 &key,
277 dst));
279 plugin->dst_tail,
280 dst);
281 GNUNET_assert (NULL == dst->ph_head);
282 GNUNET_free (dst);
283 }
284 dst = GNUNET_new (struct GNUNET_DHTU_Target);
285 dst->addrlen = addrlen;
286 dst->pid = *pid;
287 memcpy (&dst->addr,
288 addr,
289 addrlen);
291 plugin->dst_tail,
292 dst);
293 plugin->env->connect_cb (plugin->env->cls,
294 dst,
295 &dst->pid,
296 &dst->app_ctx);
297 return dst;
298}
299
300
311static struct GNUNET_DHTU_Target *
313 const struct GNUNET_PeerIdentity *pid,
314 const void *addr,
315 size_t addrlen)
316{
317 struct GNUNET_HashCode key;
318 struct GNUNET_DHTU_Target *dst;
319
321 addrlen,
322 &key);
324 &key);
325 if (NULL == dst)
326 {
327 dst = create_target (plugin,
328 pid,
329 (const struct sockaddr *) addr,
330 addrlen);
333 plugin->dsts,
334 &key,
335 dst,
337 }
338 else
339 {
340 /* move to head of DLL */
342 plugin->dst_tail,
343 dst);
345 plugin->dst_tail,
346 dst);
347
348 }
349 return dst;
350}
351
352
360static void
361ip_try_connect (void *cls,
362 const struct GNUNET_PeerIdentity *pid,
363 const char *address)
364{
365 struct Plugin *plugin = cls;
366 char *colon;
367 const char *port;
368 char *addr;
369 struct addrinfo hints = {
370 .ai_flags = AI_NUMERICHOST | AI_NUMERICSERV
371 };
372 struct addrinfo *result = NULL;
373
374 if (0 !=
375 strncmp (address,
376 "ip+",
377 strlen ("ip+")))
378 return;
379 address += strlen ("ip+");
380 if (0 !=
381 strncmp (address,
382 "udp://",
383 strlen ("udp://")))
384 return;
385 address += strlen ("udp://");
386 addr = GNUNET_strdup (address);
387 colon = strchr (addr, ':');
388 if (NULL == colon)
389 {
390 port = plugin->port;
391 }
392 else
393 {
394 *colon = '\0';
395 port = colon + 1;
396 }
397 if (0 !=
398 getaddrinfo (addr,
399 port,
400 &hints,
401 &result))
402 {
403 GNUNET_break (0);
404 GNUNET_free (addr);
405 return;
406 }
407 GNUNET_free (addr);
408 (void) find_target (plugin,
409 pid,
410 result->ai_addr,
411 result->ai_addrlen);
412 freeaddrinfo (result);
413}
414
415
424static struct GNUNET_DHTU_PreferenceHandle *
425ip_hold (void *cls,
427{
429
431 ph->target = target;
434 ph);
435 target->ph_count++;
436 return ph;
437}
438
439
446static void
448{
449 struct GNUNET_DHTU_Target *target = ph->target;
450
452 target->ph_tail,
453 ph);
454 target->ph_count--;
455 GNUNET_free (ph);
456}
457
458
474static void
475ip_send (void *cls,
476 struct GNUNET_DHTU_Target *target,
477 const void *msg,
478 size_t msg_size,
480 void *finished_cb_cls)
481{
482 struct Plugin *plugin = cls;
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);
492 buf,
493 sizeof (buf),
494 (const struct sockaddr *) &target->addr,
495 target->addrlen);
496 finished_cb (finished_cb_cls);
497}
498
499
508static struct GNUNET_DHTU_Source *
510 const struct sockaddr *addr,
511 socklen_t addrlen)
512{
513 struct GNUNET_DHTU_Source *src;
514
515 src = GNUNET_new (struct GNUNET_DHTU_Source);
516 src->addrlen = addrlen;
517 memcpy (&src->addr,
518 addr,
519 addrlen);
520 src->scan_generation = plugin->scan_generation;
521 switch (addr->sa_family)
522 {
523 case AF_INET:
524 {
525 const struct sockaddr_in *s4 = (const struct sockaddr_in *) addr;
526 char buf[INET_ADDRSTRLEN];
527
528 GNUNET_assert (sizeof (struct sockaddr_in) == addrlen);
530 "ip+udp://%s:%u",
531 inet_ntop (AF_INET,
532 &s4->sin_addr,
533 buf,
534 sizeof (buf)),
535 ntohs (s4->sin_port));
536 }
537 break;
538 case AF_INET6:
539 {
540 const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *) addr;
541 char buf[INET6_ADDRSTRLEN];
542
543 GNUNET_assert (sizeof (struct sockaddr_in6) == addrlen);
545 "ip+udp://[%s]:%u",
546 inet_ntop (AF_INET6,
547 &s6->sin6_addr,
548 buf,
549 sizeof (buf)),
550 ntohs (s6->sin6_port));
551 }
552 break;
553 default:
554 GNUNET_break (0);
555 GNUNET_free (src);
556 return NULL;
557 }
559 plugin->src_tail,
560 src);
561 plugin->env->address_add_cb (plugin->env->cls,
562 src->address,
563 src,
564 &src->app_ctx);
565 return src;
566}
567
568
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
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
677process_ifcs (void *cls,
678 const char *name,
679 int isDefault,
680 const struct sockaddr *addr,
681 const struct sockaddr *broadcast_addr,
682 const struct sockaddr *netmask,
683 socklen_t addrlen)
684{
685 struct Plugin *plugin = cls;
686 struct GNUNET_DHTU_Source *src;
687
688 for (src = plugin->src_head;
689 NULL != src;
690 src = src->next)
691 {
692 if ( (addrlen == src->addrlen) &&
693 (0 == addrcmp_np (addr,
694 (const struct sockaddr *) &src->addr,
695 addrlen)) )
696 {
697 src->scan_generation = plugin->scan_generation;
698 return GNUNET_OK;
699 }
700 }
701 switch (addr->sa_family)
702 {
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 }
732 return GNUNET_OK;
733}
734
735
741static void
742scan (void *cls)
743{
744 struct Plugin *plugin = cls;
745 struct GNUNET_DHTU_Source *next;
746
747 plugin->scan_generation++;
749 plugin);
750 for (struct GNUNET_DHTU_Source *src = plugin->src_head;
751 NULL != src;
752 src = next)
753 {
754 next = src->next;
755 if (src->scan_generation >= plugin->scan_generation)
756 continue;
758 plugin->src_tail,
759 src);
760 plugin->env->address_del_cb (src->app_ctx);
761 GNUNET_free (src->address);
762 GNUNET_free (src);
763 }
765 &scan,
766 plugin);
767}
768
769
779static struct GNUNET_DHTU_Source *
781 const void *addr,
782 size_t addrlen)
783{
784 for (struct GNUNET_DHTU_Source *src = plugin->src_head;
785 NULL != src;
786 src = src->next)
787 {
788 if ( (addrlen == src->addrlen) &&
789 (0 == addrcmp (addr,
790 (const struct sockaddr *) &src->addr,
791 addrlen)) )
792 return src;
793 }
794
795 return create_source (plugin,
796 (const struct sockaddr *) addr,
797 addrlen);
798}
799
800
806static void
807read_cb (void *cls)
808{
809 struct Plugin *plugin = cls;
810 ssize_t ret;
811 const struct GNUNET_PeerIdentity *pid;
812 char buf[65536] GNUNET_ALIGN;
813 struct sockaddr_storage sa;
814 struct iovec iov = {
815 .iov_base = buf,
816 .iov_len = sizeof (buf)
817 };
818 char ctl[128];
819 struct msghdr mh = {
820 .msg_name = &sa,
821 .msg_namelen = sizeof (sa),
822 .msg_iov = &iov,
823 .msg_iovlen = 1,
824 .msg_control = ctl,
825 .msg_controllen = sizeof (ctl)
826 };
827 struct GNUNET_DHTU_Target *dst = NULL;
828 struct GNUNET_DHTU_Source *src = NULL;
829
830 ret = recvmsg (GNUNET_NETWORK_get_fd (plugin->sock),
831 &mh,
832 MSG_DONTWAIT);
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))
850 {
852 "Got CMSG level %u (%d/%d), type %u (%d/%d)\n",
853 cmsg->cmsg_level,
854 (cmsg->cmsg_level == IPPROTO_IP),
855 (cmsg->cmsg_level == IPPROTO_IPV6),
856 cmsg->cmsg_type,
857 (cmsg->cmsg_type == IP_PKTINFO),
858 (cmsg->cmsg_type == IPV6_PKTINFO));
859 if ( (cmsg->cmsg_level == IPPROTO_IP) &&
860 (cmsg->cmsg_type == IP_PKTINFO) )
861 {
862 if (CMSG_LEN (sizeof (struct in_pktinfo)) ==
863 cmsg->cmsg_len)
864 {
865 struct in_pktinfo pi;
866
867 memcpy (&pi,
868 CMSG_DATA (cmsg),
869 sizeof (pi));
870 {
871 struct sockaddr_in sa_tmp = {
872 .sin_family = AF_INET,
873 .sin_addr = pi.ipi_addr,
874 .sin_port = htons (plugin->port16)
875 };
876
877 src = find_source (plugin,
878 &sa_tmp,
879 sizeof (sa_tmp));
880 /* For sources we discovered by reading,
881 force the generation far into the future */
882 src->scan_generation = plugin->scan_generation + 60;
883 }
884 break;
885 }
886 else
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)
894 {
895 struct in6_pktinfo pi;
896
897 memcpy (&pi,
898 CMSG_DATA (cmsg),
899 sizeof (pi));
900 {
901 struct sockaddr_in6 sa_tmp = {
902 .sin6_family = AF_INET6,
903 .sin6_addr = pi.ipi6_addr,
904 .sin6_port = htons (plugin->port16),
905 .sin6_scope_id = pi.ipi6_ifindex
906 };
907
908 src = find_source (plugin,
909 &sa_tmp,
910 sizeof (sa_tmp));
911 /* For sources we discovered by reading,
912 force the generation far into the future */
913 src->scan_generation = plugin->scan_generation + 60;
914 break;
915 }
916 }
917 else
918 GNUNET_break (0);
919 }
920 }
921 if (NULL == src)
922 {
923 GNUNET_break (0);
924 return;
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));
941}
942
943
952{
953 struct GNUNET_DHTU_PluginFunctions *api;
954 struct Plugin *plugin;
955 char *port;
956 unsigned int nport;
957 int sock;
958 int af;
959 unsigned long long nse;
960
961 if (GNUNET_OK !=
963 "DHTU-IP",
964 "NSE",
965 &nse))
966 {
968 "DHTU-IP",
969 "NSE");
970 return NULL;
971 }
972 if (GNUNET_OK !=
974 "DHTU-IP",
975 "UDP_PORT",
976 &port))
977 {
979 "DHTU-IP",
980 "UDP_PORT");
981 return NULL;
982 }
983 {
984 char dummy;
985
986 if ( (1 != sscanf (port,
987 "%u%c",
988 &nport,
989 &dummy)) ||
990 (nport > UINT16_MAX) )
991 {
993 "DHTU-IP",
994 "UDP_PORT",
995 "must be number below 65536");
997 return NULL;
998 }
999 }
1000 plugin = GNUNET_new (struct Plugin);
1001 plugin->env = env;
1002 plugin->port = port;
1003 plugin->port16 = (uint16_t) nport;
1004 if (GNUNET_OK !=
1006 &plugin->my_id))
1007 {
1009 return NULL;
1010 }
1011 if (GNUNET_NETWORK_test_pf (PF_INET6))
1012 af = AF_INET6;
1013 else
1014 af = AF_INET;
1015 sock = socket (af,
1016 SOCK_DGRAM,
1017 IPPROTO_UDP);
1018 if (-1 == sock)
1019 {
1021 "socket");
1022 GNUNET_free (plugin->port);
1024 return NULL;
1025 }
1026 switch (af)
1027 {
1028 case AF_INET:
1029 {
1030 int on = 1;
1031
1032 if (0 !=
1033 setsockopt (sock,
1034 IPPROTO_IP,
1035 IP_PKTINFO,
1036 &on,
1037 sizeof (on)))
1038 {
1040 "setsockopt");
1041 }
1042 }
1043 {
1044 struct sockaddr_in sa = {
1045 .sin_family = AF_INET,
1046 .sin_port = htons ((uint16_t) nport)
1047 };
1048
1049 if (0 !=
1050 bind (sock,
1051 (const struct sockaddr *) &sa,
1052 sizeof (sa)))
1053 {
1055 "socket");
1056 GNUNET_break (0 ==
1057 close (sock));
1058 GNUNET_free (plugin->port);
1060 return NULL;
1061 }
1062 }
1063 break;
1064 case AF_INET6:
1065 {
1066 int on = 1;
1067
1068 if (0 !=
1069 setsockopt (sock,
1070 IPPROTO_IPV6,
1071 IPV6_RECVPKTINFO,
1072 &on,
1073 sizeof (on)))
1074 {
1076 "setsockopt");
1077 }
1078 }
1079 {
1080 struct sockaddr_in6 sa = {
1081 .sin6_family = AF_INET6,
1082 .sin6_port = htons ((uint16_t) nport)
1083 };
1084
1085 if (0 !=
1086 bind (sock,
1087 (const struct sockaddr *) &sa,
1088 sizeof (sa)))
1089 {
1091 "socket");
1092 GNUNET_break (0 ==
1093 close (sock));
1094 GNUNET_free (plugin->port);
1096 return NULL;
1097 }
1098 }
1099 break;
1100 }
1102 GNUNET_NO);
1106 plugin->sock,
1107 &read_cb,
1108 plugin);
1109 env->network_size_cb (env->cls,
1111 log (nse) / log (2),
1112 -1.0 /* stddev */);
1113 plugin->scan_task = GNUNET_SCHEDULER_add_now (&scan,
1114 plugin);
1116 api->cls = plugin;
1118 api->hold = &ip_hold;
1119 api->drop = &ip_drop;
1120 api->send = &ip_send;
1121 return api;
1122}
1123
1124
1131void *
1133{
1134 struct Plugin *plugin = api->cls;
1135 struct GNUNET_DHTU_Source *src;
1136 struct GNUNET_DHTU_Target *dst;
1137
1138 while (NULL != (dst = plugin->dst_head))
1139 {
1140 plugin->env->disconnect_cb (dst->app_ctx);
1141 GNUNET_assert (NULL == dst->ph_head);
1143 plugin->dst_tail,
1144 dst);
1145 GNUNET_free (dst);
1146 }
1147 while (NULL != (src = plugin->src_head))
1148 {
1149 plugin->env->address_del_cb (src->app_ctx);
1151 plugin->src_tail,
1152 src);
1153 GNUNET_free (src->address);
1154 GNUNET_free (src);
1155 }
1156 plugin->env->network_size_cb (plugin->env->cls,
1158 0.0,
1159 0.0);
1161 if (NULL != plugin->read_task)
1162 {
1163 GNUNET_SCHEDULER_cancel (plugin->read_task);
1164 plugin->read_task = NULL;
1165 }
1166 GNUNET_SCHEDULER_cancel (plugin->scan_task);
1169 GNUNET_free (plugin->port);
1171 GNUNET_free (api);
1172 return NULL;
1173}
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static int ret
Final status code.
Definition: gnunet-arm.c:93
static uint16_t port
Port number.
Definition: gnunet-bcd.c:146
static struct GNUNET_CADET_Handle * mh
Cadet handle.
Definition: gnunet-cadet.c:92
static struct GNUNET_TESTING_PluginFunctions * plugin
Plugin to dynamically load a test case.
static void finished_cb(void *cls, enum GNUNET_GenericReturnValue rv)
static char * address
GNS address for this phone.
struct GNUNET_HashCode key
The key used in the DHT.
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
static char * name
Name (label) of the records to list.
static struct GNUNET_NSE_Handle * nse
The handle to the NSE service.
Definition: gnunet-nse.c:34
static int result
Global testing status.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_get_peer_identity(const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_PeerIdentity *dst)
Retrieve the identity of the host's peer.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
#define GNUNET_log(kind,...)
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to 'struct's.
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
void GNUNET_log_config_invalid(enum GNUNET_ErrorType kind, const char *section, const char *option, const char *required)
Log error message about invalid configuration option value.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:508
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition: network.c:1001
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_box_native(int fd)
Box a native socket (and check that it is a socket).
Definition: network.c:580
enum GNUNET_GenericReturnValue GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition: network.c:79
ssize_t GNUNET_NETWORK_socket_sendto(const struct GNUNET_NETWORK_Handle *desc, const void *message, size_t length, const struct sockaddr *dest_addr, socklen_t dest_len)
Send data to a particular destination (always non-blocking).
Definition: network.c:772
void GNUNET_OS_network_interfaces_list(GNUNET_OS_NetworkInterfaceProcessor proc, void *proc_cls)
Enumerate all network interfaces.
Definition: os_network.c:397
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition: scheduler.c:1510
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:979
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1303
void(* GNUNET_SCHEDULER_TaskCallback)(void *cls)
Signature of the main function of a task.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1276
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
#define GNUNET_TIME_UNIT_ZERO_ABS
Absolute time zero.
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
#define AI_NUMERICSERV
AI_NUMERICSERV not defined in windows.
Definition: platform.h:219
static int addrcmp(const struct sockaddr *a1, const struct sockaddr *a2, size_t alen)
Compare two addresses for equality.
static enum GNUNET_GenericReturnValue process_ifcs(void *cls, const char *name, int isDefault, const struct sockaddr *addr, const struct sockaddr *broadcast_addr, const struct sockaddr *netmask, socklen_t addrlen)
Callback function invoked for each interface found.
struct GNUNET_DHTU_PluginFunctions * DHTU_ip_init(struct GNUNET_DHTU_PluginEnvironment *env)
Entry point for the plugin.
static void ip_send(void *cls, struct GNUNET_DHTU_Target *target, const void *msg, size_t msg_size, GNUNET_SCHEDULER_TaskCallback finished_cb, void *finished_cb_cls)
Send message to some other participant over the network.
static int addrcmp_np(const struct sockaddr *a1, const struct sockaddr *a2, size_t alen)
Compare two addresses excluding the ports for equality.
static struct GNUNET_DHTU_Source * find_source(struct Plugin *plugin, const void *addr, size_t addrlen)
Find our source matching addr.
static void read_cb(void *cls)
UDP socket is ready to receive.
static void scan(void *cls)
Scan network interfaces for IP address changes.
#define MAX_DESTS
Maximum number of concurrently active destinations to support.
static struct GNUNET_DHTU_PreferenceHandle * ip_hold(void *cls, struct GNUNET_DHTU_Target *target)
Request underlay to keep the connection to target alive if possible.
#define SCAN_FREQ
How frequently should we re-scan our local interfaces for IPs?
static struct GNUNET_DHTU_Target * find_target(struct Plugin *plugin, const struct GNUNET_PeerIdentity *pid, const void *addr, size_t addrlen)
Find target matching addr.
static void ip_try_connect(void *cls, const struct GNUNET_PeerIdentity *pid, const char *address)
Request creation of a session with a peer at the given address.
static struct GNUNET_DHTU_Source * create_source(struct Plugin *plugin, const struct sockaddr *addr, socklen_t addrlen)
Create a new source on which we may be receiving traffic.
void * DHTU_ip_done(struct GNUNET_DHTU_PluginFunctions *api)
Exit point from the plugin.
static void ip_drop(struct GNUNET_DHTU_PreferenceHandle *ph)
Do no long request underlay to keep the connection alive.
static struct GNUNET_DHTU_Target * create_target(struct Plugin *plugin, const struct GNUNET_PeerIdentity *pid, const struct sockaddr *addr, socklen_t addrlen)
Create a target to which we may send traffic.
void * cls
Closure for all of the callbacks.
Internal representation of the hash map.
The datastore service will pass a pointer to a struct of this type as the first and only argument to ...
struct returned by the initialization function of the plugin
void(* try_connect)(void *cls, const struct GNUNET_PeerIdentity *pid, const char *address)
Request creation of a session with a peer at the given address.
void * cls
Closure to pass to all plugin functions.
struct GNUNET_DHTU_PreferenceHandle *(* hold)(void *cls, struct GNUNET_DHTU_Target *target)
Request underlay to keep the connection to target alive if possible.
void(* drop)(struct GNUNET_DHTU_PreferenceHandle *ph)
Do no longer request underlay to keep the connection alive.
void(* send)(void *cls, struct GNUNET_DHTU_Target *target, const void *msg, size_t msg_size, GNUNET_SCHEDULER_TaskCallback finished_cb, void *finished_cb_cls)
Send message to some other participant over the network.
Opaque handle expressing a preference of the DHT to keep a particular target connected.
struct GNUNET_DHTU_PreferenceHandle * prev
Kept in a DLL.
struct GNUNET_DHTU_Target * target
Target a preference was expressed for.
struct GNUNET_DHTU_PreferenceHandle * next
Kept in a DLL.
Opaque handle that the underlay offers for our address to be used when sending messages to another pe...
struct GNUNET_DHTU_Source * prev
Kept in a DLL.
void * app_ctx
Application context for this source.
socklen_t addrlen
Number of bytes in addr.
struct GNUNET_DHTU_Source * next
Kept in a DLL.
char * address
Address in URL form ("ip+udp://$PID/$IP:$PORT")
struct sockaddr_storage addr
My actual address.
unsigned int scan_generation
Last generation this address was observed.
Opaque handle that the underlay offers for the target peer when sending messages to another peer.
struct GNUNET_DHTU_Target * prev
Kept in a DLL.
struct GNUNET_DHTU_PreferenceHandle * ph_head
Head of preferences expressed for this target.
unsigned int ph_count
Preference counter, length of the ph_head DLL.
socklen_t addrlen
Number of bytes in addr.
void * app_ctx
Application context for this target.
struct GNUNET_DHTU_PreferenceHandle * ph_tail
Tail of preferences expressed for this target.
struct GNUNET_DHTU_Target * next
Kept in a DLL.
struct sockaddr_storage addr
Target IP address.
struct GNUNET_PeerIdentity pid
Identity of this peer.
A 512-bit hashcode.
handle to a socket
Definition: network.c:53
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Definition: scheduler.c:135
void * cls
Closure to pass to start_testcase.
Handle for a plugin.
Definition: block.c:38
struct GNUNET_BLOCK_PluginFunctions * api
Plugin API.
Definition: block.c:47
struct GNUNET_PeerIdentity my_id
My identity.
struct GNUNET_SCHEDULER_Task * scan_task
Task that scans for IP address changes.
unsigned int scan_generation
How often have we scanned for IPs?
struct GNUNET_SCHEDULER_Task * read_task
Task that reads incoming UDP packets.
struct GNUNET_NETWORK_Handle * sock
My UDP socket.
uint16_t port16
Port as a 16-bit value.
char * port
Port we bind to.
struct GNUNET_DHTU_Source * src_tail
Tail of sources where we receive traffic.
struct GNUNET_CONTAINER_MultiHashMap * dsts
Map from hashes of sockaddrs to targets.
struct GNUNET_DATACACHE_PluginEnvironment * env
Our execution environment.
struct GNUNET_DHTU_Target * dst_tail
Tail of destinations that are active.
struct GNUNET_DHTU_Target * dst_head
Head of destinations that are active.
struct GNUNET_DHTU_Source * src_head
Head of sources where we receive traffic.