GNUnet  0.17.5
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 
33 #define SCAN_FREQ GNUNET_TIME_UNIT_MINUTES
34 
38 #define MAX_DESTS 256
39 
40 
45 struct GNUNET_DHTU_Source
46 {
47 
52 
57 
61  void *app_ctx;
62 
66  char *address;
67 
71  struct sockaddr_storage addr;
72 
76  socklen_t addrlen;
77 
81  unsigned int scan_generation;
82 
83 };
84 
85 
90 struct GNUNET_DHTU_Target
91 {
92 
97 
102 
106  void *app_ctx;
107 
112 
117 
121  struct GNUNET_PeerIdentity pid;
122 
126  struct sockaddr_storage addr;
127 
131  socklen_t addrlen;
132 
136  unsigned int ph_count;
137 
138 };
139 
145 {
150 
155 
159  struct GNUNET_DHTU_Target *target;
160 };
161 
162 
166 struct Plugin
167 {
172 
177 
182 
188 
193 
198 
203 
208 
212  char *port;
213 
218 
222  struct GNUNET_PeerIdentity my_id;
223 
227  unsigned int scan_generation;
228 
232  uint16_t port16;
233 };
234 
235 
245 static struct GNUNET_DHTU_Target *
247  const struct GNUNET_PeerIdentity *pid,
248  const struct sockaddr *addr,
249  socklen_t addrlen)
250 {
251  struct GNUNET_DHTU_Target *dst;
252 
253  if (MAX_DESTS <=
255  {
256  struct GNUNET_HashCode key;
257 
258  dst = NULL;
259  for (struct GNUNET_DHTU_Target *pos = plugin->dst_head;
260  NULL != pos;
261  pos = pos->next)
262  {
263  /* >= here assures we remove oldest entries first */
264  if ( (NULL == dst) ||
265  (dst->ph_count >= pos->ph_count) )
266  dst = pos;
267  }
268  GNUNET_assert (NULL != dst);
269  plugin->env->disconnect_cb (dst->app_ctx);
270  GNUNET_CRYPTO_hash (&dst->addr,
271  dst->addrlen,
272  &key);
275  &key,
276  dst));
278  plugin->dst_tail,
279  dst);
280  GNUNET_assert (NULL == dst->ph_head);
281  GNUNET_free (dst);
282  }
283  dst = GNUNET_new (struct GNUNET_DHTU_Target);
284  dst->addrlen = addrlen;
285  dst->pid = *pid;
286  memcpy (&dst->addr,
287  addr,
288  addrlen);
290  plugin->dst_tail,
291  dst);
292  plugin->env->connect_cb (plugin->env->cls,
293  dst,
294  &dst->pid,
295  &dst->app_ctx);
296  return dst;
297 }
298 
299 
311 static 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 
360 static void
361 ip_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 
424 static struct GNUNET_DHTU_PreferenceHandle *
425 ip_hold (void *cls,
426  struct GNUNET_DHTU_Target *target)
427 {
429 
431  ph->target = target;
433  target->ph_tail,
434  ph);
435  target->ph_count++;
436  return ph;
437 }
438 
439 
446 static 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 
474 static void
475 ip_send (void *cls,
476  struct GNUNET_DHTU_Target *target,
477  const void *msg,
478  size_t msg_size,
479  GNUNET_SCHEDULER_TaskCallback finished_cb,
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 
508 static 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);
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);
529  GNUNET_asprintf (&src->address,
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);
544  GNUNET_asprintf (&src->address,
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 
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 
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 
676 static enum GNUNET_GenericReturnValue
677 process_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  {
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 
741 static void
742 scan (void *cls)
743 {
744  struct Plugin *plugin = cls;
745  struct GNUNET_DHTU_Source *next;
746 
749  plugin);
750  for (struct GNUNET_DHTU_Source *src = plugin->src_head;
751  NULL != src;
752  src = next)
753  {
754  next = src->next;
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 
779 static 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 
806 static void
807 read_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 = {
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,
879  sizeof (sa));
880  /* For sources we discovered by reading,
881  force the generation far into the future */
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 = {
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,
910  sizeof (sa));
911  /* For sources we discovered by reading,
912  force the generation far into the future */
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 
950 void *
952 {
954  struct GNUNET_DHTU_PluginFunctions *api;
955  struct Plugin *plugin;
956  char *port;
957  unsigned int nport;
958  int sock;
959  int af;
960  unsigned long long nse;
961 
962  if (GNUNET_OK !=
964  "DHTU-IP",
965  "NSE",
966  &nse))
967  {
969  "DHTU-IP",
970  "NSE");
971  return NULL;
972  }
973  if (GNUNET_OK !=
975  "DHTU-IP",
976  "UDP_PORT",
977  &port))
978  {
980  "DHTU-IP",
981  "UDP_PORT");
982  return NULL;
983  }
984  {
985  char dummy;
986 
987  if ( (1 != sscanf (port,
988  "%u%c",
989  &nport,
990  &dummy)) ||
991  (nport > UINT16_MAX) )
992  {
994  "DHTU-IP",
995  "UDP_PORT",
996  "must be number below 65536");
997  GNUNET_free (port);
998  return NULL;
999  }
1000  }
1001  plugin = GNUNET_new (struct Plugin);
1002  plugin->env = env;
1003  plugin->port = port;
1004  plugin->port16 = (uint16_t) nport;
1005  if (GNUNET_OK !=
1007  &plugin->my_id))
1008  {
1009  GNUNET_free (plugin);
1010  return NULL;
1011  }
1012  af = AF_INET6;
1013  sock = socket (af,
1014  SOCK_DGRAM,
1015  IPPROTO_UDP);
1016  if (-1 == sock)
1017  {
1019  "socket");
1020  GNUNET_free (plugin->port);
1021  GNUNET_free (plugin);
1022  return NULL;
1023  }
1024  switch (af)
1025  {
1026  case AF_INET:
1027  {
1028  int on = 1;
1029 
1030  if (0 !=
1031  setsockopt (sock,
1032  IPPROTO_IP,
1033  IP_PKTINFO,
1034  &on,
1035  sizeof (on)))
1036  {
1038  "setsockopt");
1039  }
1040  }
1041  {
1042  struct sockaddr_in sa = {
1043  .sin_family = AF_INET,
1044  .sin_port = htons ((uint16_t) nport)
1045  };
1046 
1047  if (0 !=
1048  bind (sock,
1049  (const struct sockaddr *) &sa,
1050  sizeof (sa)))
1051  {
1053  "socket");
1054  GNUNET_break (0 ==
1055  close (sock));
1056  GNUNET_free (plugin->port);
1057  GNUNET_free (plugin);
1058  return NULL;
1059  }
1060  }
1061  break;
1062  case AF_INET6:
1063  {
1064  int on = 1;
1065 
1066  if (0 !=
1067  setsockopt (sock,
1068  IPPROTO_IPV6,
1069  IPV6_RECVPKTINFO,
1070  &on,
1071  sizeof (on)))
1072  {
1074  "setsockopt");
1075  }
1076  }
1077  {
1078  struct sockaddr_in6 sa = {
1079  .sin6_family = AF_INET6,
1080  .sin6_port = htons ((uint16_t) nport)
1081  };
1082 
1083  if (0 !=
1084  bind (sock,
1085  (const struct sockaddr *) &sa,
1086  sizeof (sa)))
1087  {
1089  "socket");
1090  GNUNET_break (0 ==
1091  close (sock));
1092  GNUNET_free (plugin->port);
1093  GNUNET_free (plugin);
1094  return NULL;
1095  }
1096  }
1097  break;
1098  }
1100  GNUNET_NO);
1104  plugin->sock,
1105  &read_cb,
1106  plugin);
1107  env->network_size_cb (env->cls,
1109  log (nse) / log (2),
1110  -1.0 /* stddev */);
1112  plugin);
1113  api = GNUNET_new (struct GNUNET_DHTU_PluginFunctions);
1114  api->cls = plugin;
1115  api->try_connect = &ip_try_connect;
1116  api->hold = &ip_hold;
1117  api->drop = &ip_drop;
1118  api->send = &ip_send;
1119  return api;
1120 }
1121 
1122 
1129 void *
1131 {
1132  struct GNUNET_DHTU_PluginFunctions *api = cls;
1133  struct Plugin *plugin = api->cls;
1134  struct GNUNET_DHTU_Source *src;
1135  struct GNUNET_DHTU_Target *dst;
1136 
1137  while (NULL != (dst = plugin->dst_head))
1138  {
1139  plugin->env->disconnect_cb (dst->app_ctx);
1140  GNUNET_assert (NULL == dst->ph_head);
1142  plugin->dst_tail,
1143  dst);
1144  GNUNET_free (dst);
1145  }
1146  while (NULL != (src = plugin->src_head))
1147  {
1148  plugin->env->address_del_cb (src->app_ctx);
1150  plugin->src_tail,
1151  src);
1152  GNUNET_free (src->address);
1153  GNUNET_free (src);
1154  }
1155  plugin->env->network_size_cb (plugin->env->cls,
1157  0.0,
1158  0.0);
1160  if (NULL != plugin->read_task)
1161  {
1163  plugin->read_task = NULL;
1164  }
1168  GNUNET_free (plugin->port);
1169  GNUNET_free (plugin);
1170  GNUNET_free (api);
1171  return NULL;
1172 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static struct GNUNET_ATS_PerformanceHandle * ph
ATS performance handle used.
Definition: gnunet-ats.c:116
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
static struct GNUNET_CADET_Handle * mh
Cadet handle.
Definition: gnunet-cadet.c:92
struct Plugin * plugin
The process handle to the testbed service.
static char * address
GNS address for this phone.
static struct GNUNET_PEERINFO_Handle * pi
Handle to peerinfo service.
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 struct GNUNET_NSE_Handle * nse
The handle to the NSE service.
Definition: gnunet-nse.c:33
static int result
Global testing status.
static char buf[2048]
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
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.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash 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.
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.
@ 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.
Definition: gnunet_common.h:96
@ GNUNET_OK
Definition: gnunet_common.h:99
@ GNUNET_YES
@ GNUNET_NO
Definition: gnunet_common.h:98
#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:1023
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:794
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:584
void GNUNET_OS_network_interfaces_list(GNUNET_OS_NetworkInterfaceProcessor proc, void *proc_cls)
Enumerate all network interfaces.
Definition: os_network.c:396
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:1281
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:1502
void(* GNUNET_SCHEDULER_TaskCallback)(void *cls)
Signature of the main function of a task.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:957
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:1254
#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:218
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.
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 void read_cb(void *cls)
UDP socket is ready to receive.
void * libgnunet_plugin_dhtu_ip_done(void *cls)
Exit point from the plugin.
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.
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_Target * find_target(struct Plugin *plugin, const struct GNUNET_PeerIdentity *pid, const void *addr, size_t addrlen)
Find target matching addr.
static struct GNUNET_DHTU_Source * find_source(struct Plugin *plugin, const void *addr, size_t addrlen)
Find our source matching addr.
#define SCAN_FREQ
How frequently should we re-scan our local interfaces for IPs?
void * libgnunet_plugin_dhtu_ip_init(void *cls)
Entry point for the plugin.
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.
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 void ip_drop(struct GNUNET_DHTU_PreferenceHandle *ph)
Do no long request underlay to keep the connection alive.
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.
const char * name
void * cls
Closure for all of the callbacks.
Internal representation of the hash map.
void * cls
Closure to use for callbacks.
The datastore service will pass a pointer to a struct of this type as the first and only argument to ...
void * cls
Closure to use for callbacks.
struct returned by the initialization function of the plugin
struct GNUNET_DHTU_PreferenceHandle *(* hold)(void *cls, struct GNUNET_DHTU_Target *target)
Request underlay to keep the connection to target alive if possible.
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.
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
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_NETWORK_Handle * sock
My UDP socket.
uint16_t port16
Port as a 16-bit value.
struct GNUNET_SCHEDULER_Task * read_task
Task that reads incoming UDP packets.
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_DHTU_Target * dst_tail
Tail of destinations that are active.
struct GNUNET_DATACACHE_PluginEnvironment * env
Our execution environment.
struct GNUNET_DHTU_Target * dst_head
Head of destinations that are active.
char * port
Port we bind to.
struct GNUNET_DHTU_Source * src_head
Head of sources where we receive traffic.