GNUnet  0.20.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 
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 
310 static struct GNUNET_DHTU_Target *
312  const struct GNUNET_PeerIdentity *pid,
313  const void *addr,
314  size_t addrlen)
315 {
316  struct GNUNET_HashCode key;
317  struct GNUNET_DHTU_Target *dst;
318 
320  addrlen,
321  &key);
323  &key);
324  if (NULL == dst)
325  {
326  dst = create_target (plugin,
327  pid,
328  (const struct sockaddr *) addr,
329  addrlen);
332  plugin->dsts,
333  &key,
334  dst,
336  }
337  else
338  {
339  /* move to head of DLL */
341  plugin->dst_tail,
342  dst);
344  plugin->dst_tail,
345  dst);
346 
347  }
348  return dst;
349 }
350 
351 
359 static void
360 ip_try_connect (void *cls,
361  const struct GNUNET_PeerIdentity *pid,
362  const char *address)
363 {
364  struct Plugin *plugin = cls;
365  char *colon;
366  const char *port;
367  char *addr;
368  struct addrinfo hints = {
369  .ai_flags = AI_NUMERICHOST | AI_NUMERICSERV
370  };
371  struct addrinfo *result = NULL;
372 
373  if (0 !=
374  strncmp (address,
375  "ip+",
376  strlen ("ip+")))
377  return;
378  address += strlen ("ip+");
379  if (0 !=
380  strncmp (address,
381  "udp://",
382  strlen ("udp://")))
383  return;
384  address += strlen ("udp://");
385  addr = GNUNET_strdup (address);
386  colon = strchr (addr, ':');
387  if (NULL == colon)
388  {
389  port = plugin->port;
390  }
391  else
392  {
393  *colon = '\0';
394  port = colon + 1;
395  }
396  if (0 !=
397  getaddrinfo (addr,
398  port,
399  &hints,
400  &result))
401  {
402  GNUNET_break (0);
403  GNUNET_free (addr);
404  return;
405  }
406  GNUNET_free (addr);
407  (void) find_target (plugin,
408  pid,
409  result->ai_addr,
410  result->ai_addrlen);
411  freeaddrinfo (result);
412 }
413 
414 
423 static struct GNUNET_DHTU_PreferenceHandle *
424 ip_hold (void *cls,
425  struct GNUNET_DHTU_Target *target)
426 {
428 
430  ph->target = target;
432  target->ph_tail,
433  ph);
434  target->ph_count++;
435  return ph;
436 }
437 
438 
445 static void
447 {
448  struct GNUNET_DHTU_Target *target = ph->target;
449 
451  target->ph_tail,
452  ph);
453  target->ph_count--;
454  GNUNET_free (ph);
455 }
456 
457 
473 static void
474 ip_send (void *cls,
475  struct GNUNET_DHTU_Target *target,
476  const void *msg,
477  size_t msg_size,
479  void *finished_cb_cls)
480 {
481  struct Plugin *plugin = cls;
482  char buf[sizeof (plugin->my_id) + msg_size];
483 
484  memcpy (buf,
485  &plugin->my_id,
486  sizeof (plugin->my_id));
487  memcpy (&buf[sizeof (plugin->my_id)],
488  msg,
489  msg_size);
491  buf,
492  sizeof (buf),
493  (const struct sockaddr *) &target->addr,
494  target->addrlen);
495  finished_cb (finished_cb_cls);
496 }
497 
498 
507 static struct GNUNET_DHTU_Source *
509  const struct sockaddr *addr,
510  socklen_t addrlen)
511 {
512  struct GNUNET_DHTU_Source *src;
513 
514  src = GNUNET_new (struct GNUNET_DHTU_Source);
515  src->addrlen = addrlen;
516  memcpy (&src->addr,
517  addr,
518  addrlen);
519  src->scan_generation = plugin->scan_generation;
520  switch (addr->sa_family)
521  {
522  case AF_INET:
523  {
524  const struct sockaddr_in *s4 = (const struct sockaddr_in *) addr;
525  char buf[INET_ADDRSTRLEN];
526 
527  GNUNET_assert (sizeof (struct sockaddr_in) == addrlen);
528  GNUNET_asprintf (&src->address,
529  "ip+udp://%s:%u",
530  inet_ntop (AF_INET,
531  &s4->sin_addr,
532  buf,
533  sizeof (buf)),
534  ntohs (s4->sin_port));
535  }
536  break;
537  case AF_INET6:
538  {
539  const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *) addr;
540  char buf[INET6_ADDRSTRLEN];
541 
542  GNUNET_assert (sizeof (struct sockaddr_in6) == addrlen);
543  GNUNET_asprintf (&src->address,
544  "ip+udp://[%s]:%u",
545  inet_ntop (AF_INET6,
546  &s6->sin6_addr,
547  buf,
548  sizeof (buf)),
549  ntohs (s6->sin6_port));
550  }
551  break;
552  default:
553  GNUNET_break (0);
554  GNUNET_free (src);
555  return NULL;
556  }
558  plugin->src_tail,
559  src);
560  plugin->env->address_add_cb (plugin->env->cls,
561  src->address,
562  src,
563  &src->app_ctx);
564  return src;
565 }
566 
567 
577 static int
578 addrcmp_np (const struct sockaddr *a1,
579  const struct sockaddr *a2,
580  size_t alen)
581 {
582  GNUNET_assert (a1->sa_family == a2->sa_family);
583  switch (a1->sa_family)
584  {
585  case AF_INET:
586  GNUNET_assert (sizeof (struct sockaddr_in) == alen);
587  {
588  const struct sockaddr_in *s1 = (const struct sockaddr_in *) a1;
589  const struct sockaddr_in *s2 = (const struct sockaddr_in *) a2;
590 
591  if (s1->sin_addr.s_addr != s2->sin_addr.s_addr)
592  return 1;
593  break;
594  }
595  case AF_INET6:
596  GNUNET_assert (sizeof (struct sockaddr_in6) == alen);
597  {
598  const struct sockaddr_in6 *s1 = (const struct sockaddr_in6 *) a1;
599  const struct sockaddr_in6 *s2 = (const struct sockaddr_in6 *) a2;
600 
601  if (0 != GNUNET_memcmp (&s1->sin6_addr,
602  &s2->sin6_addr))
603  return 1;
604  break;
605  }
606  default:
607  GNUNET_assert (0);
608  }
609  return 0;
610 }
611 
612 
623 static int
624 addrcmp (const struct sockaddr *a1,
625  const struct sockaddr *a2,
626  size_t alen)
627 {
628  GNUNET_assert (a1->sa_family == a2->sa_family);
629  switch (a1->sa_family)
630  {
631  case AF_INET:
632  GNUNET_assert (sizeof (struct sockaddr_in) == alen);
633  {
634  const struct sockaddr_in *s1 = (const struct sockaddr_in *) a1;
635  const struct sockaddr_in *s2 = (const struct sockaddr_in *) a2;
636 
637  if (s1->sin_port != s2->sin_port)
638  return 1;
639  if (s1->sin_addr.s_addr != s2->sin_addr.s_addr)
640  return 1;
641  break;
642  }
643  case AF_INET6:
644  GNUNET_assert (sizeof (struct sockaddr_in6) == alen);
645  {
646  const struct sockaddr_in6 *s1 = (const struct sockaddr_in6 *) a1;
647  const struct sockaddr_in6 *s2 = (const struct sockaddr_in6 *) a2;
648 
649  if (s1->sin6_port != s2->sin6_port)
650  return 1;
651  if (0 != GNUNET_memcmp (&s1->sin6_addr,
652  &s2->sin6_addr))
653  return 1;
654  break;
655  }
656  default:
657  GNUNET_assert (0);
658  }
659  return 0;
660 }
661 
662 
675 static enum GNUNET_GenericReturnValue
676 process_ifcs (void *cls,
677  const char *name,
678  int isDefault,
679  const struct sockaddr *addr,
680  const struct sockaddr *broadcast_addr,
681  const struct sockaddr *netmask,
682  socklen_t addrlen)
683 {
684  struct Plugin *plugin = cls;
685  struct GNUNET_DHTU_Source *src;
686 
687  for (src = plugin->src_head;
688  NULL != src;
689  src = src->next)
690  {
691  if ( (addrlen == src->addrlen) &&
692  (0 == addrcmp_np (addr,
693  (const struct sockaddr *) &src->addr,
694  addrlen)) )
695  {
696  src->scan_generation = plugin->scan_generation;
697  return GNUNET_OK;
698  }
699  }
700  switch (addr->sa_family)
701  {
702  case AF_INET:
703  {
704  struct sockaddr_in v4;
705 
706  GNUNET_assert (sizeof(v4) == addrlen);
707  memcpy (&v4,
708  addr,
709  addrlen);
710  v4.sin_port = htons (plugin->port16);
711  (void) create_source (plugin,
712  (const struct sockaddr *) &v4,
713  sizeof (v4));
714  break;
715  }
716  case AF_INET6:
717  {
718  struct sockaddr_in6 v6;
719 
720  GNUNET_assert (sizeof(v6) == addrlen);
721  memcpy (&v6,
722  addr,
723  addrlen);
724  v6.sin6_port = htons (plugin->port16);
725  (void) create_source (plugin,
726  (const struct sockaddr *) &v6,
727  sizeof (v6));
728  break;
729  }
730  }
731  return GNUNET_OK;
732 }
733 
734 
740 static void
741 scan (void *cls)
742 {
743  struct Plugin *plugin = cls;
744  struct GNUNET_DHTU_Source *next;
745 
746  plugin->scan_generation++;
748  plugin);
749  for (struct GNUNET_DHTU_Source *src = plugin->src_head;
750  NULL != src;
751  src = next)
752  {
753  next = src->next;
754  if (src->scan_generation >= plugin->scan_generation)
755  continue;
757  plugin->src_tail,
758  src);
759  plugin->env->address_del_cb (src->app_ctx);
760  GNUNET_free (src->address);
761  GNUNET_free (src);
762  }
764  &scan,
765  plugin);
766 }
767 
768 
778 static struct GNUNET_DHTU_Source *
780  const void *addr,
781  size_t addrlen)
782 {
783  for (struct GNUNET_DHTU_Source *src = plugin->src_head;
784  NULL != src;
785  src = src->next)
786  {
787  if ( (addrlen == src->addrlen) &&
788  (0 == addrcmp (addr,
789  (const struct sockaddr *) &src->addr,
790  addrlen)) )
791  return src;
792  }
793 
794  return create_source (plugin,
795  (const struct sockaddr *) addr,
796  addrlen);
797 }
798 
799 
805 static void
806 read_cb (void *cls)
807 {
808  struct Plugin *plugin = cls;
809  ssize_t ret;
810  const struct GNUNET_PeerIdentity *pid;
811  char buf[65536] GNUNET_ALIGN;
812  struct sockaddr_storage sa;
813  struct iovec iov = {
814  .iov_base = buf,
815  .iov_len = sizeof (buf)
816  };
817  char ctl[128];
818  struct msghdr mh = {
819  .msg_name = &sa,
820  .msg_namelen = sizeof (sa),
821  .msg_iov = &iov,
822  .msg_iovlen = 1,
823  .msg_control = ctl,
824  .msg_controllen = sizeof (ctl)
825  };
826  struct GNUNET_DHTU_Target *dst = NULL;
827  struct GNUNET_DHTU_Source *src = NULL;
828 
829  ret = recvmsg (GNUNET_NETWORK_get_fd (plugin->sock),
830  &mh,
831  MSG_DONTWAIT);
834  plugin->sock,
835  &read_cb,
836  plugin);
837  if (ret < 0)
838  return; /* read failure, hopefully EAGAIN */
839  if (ret < sizeof (*pid))
840  {
841  GNUNET_break_op (0);
842  return;
843  }
844  /* find IP where we received message */
845  for (struct cmsghdr *cmsg = CMSG_FIRSTHDR (&mh);
846  NULL != cmsg;
847  cmsg = CMSG_NXTHDR (&mh,
848  cmsg))
849  {
851  "Got CMSG level %u (%d/%d), type %u (%d/%d)\n",
852  cmsg->cmsg_level,
853  (cmsg->cmsg_level == IPPROTO_IP),
854  (cmsg->cmsg_level == IPPROTO_IPV6),
855  cmsg->cmsg_type,
856  (cmsg->cmsg_type == IP_PKTINFO),
857  (cmsg->cmsg_type == IPV6_PKTINFO));
858  if ( (cmsg->cmsg_level == IPPROTO_IP) &&
859  (cmsg->cmsg_type == IP_PKTINFO) )
860  {
861  if (CMSG_LEN (sizeof (struct in_pktinfo)) ==
862  cmsg->cmsg_len)
863  {
864  struct in_pktinfo pi;
865 
866  memcpy (&pi,
867  CMSG_DATA (cmsg),
868  sizeof (pi));
869  {
870  struct sockaddr_in sa = {
871  .sin_family = AF_INET,
872  .sin_addr = pi.ipi_addr,
873  .sin_port = htons (plugin->port16)
874  };
875 
876  src = find_source (plugin,
877  &sa,
878  sizeof (sa));
879  /* For sources we discovered by reading,
880  force the generation far into the future */
881  src->scan_generation = plugin->scan_generation + 60;
882  }
883  break;
884  }
885  else
886  GNUNET_break (0);
887  }
888  if ( (cmsg->cmsg_level == IPPROTO_IPV6) &&
889  (cmsg->cmsg_type == IPV6_PKTINFO) )
890  {
891  if (CMSG_LEN (sizeof (struct in6_pktinfo)) ==
892  cmsg->cmsg_len)
893  {
894  struct in6_pktinfo pi;
895 
896  memcpy (&pi,
897  CMSG_DATA (cmsg),
898  sizeof (pi));
899  {
900  struct sockaddr_in6 sa = {
901  .sin6_family = AF_INET6,
902  .sin6_addr = pi.ipi6_addr,
903  .sin6_port = htons (plugin->port16),
904  .sin6_scope_id = pi.ipi6_ifindex
905  };
906 
907  src = find_source (plugin,
908  &sa,
909  sizeof (sa));
910  /* For sources we discovered by reading,
911  force the generation far into the future */
912  src->scan_generation = plugin->scan_generation + 60;
913  break;
914  }
915  }
916  else
917  GNUNET_break (0);
918  }
919  }
920  if (NULL == src)
921  {
922  GNUNET_break (0);
923  return;
924  }
925  pid = (const struct GNUNET_PeerIdentity *) buf;
926  dst = find_target (plugin,
927  pid,
928  &sa,
929  mh.msg_namelen);
930  if (NULL == dst)
931  {
932  GNUNET_break (0);
933  return;
934  }
935  plugin->env->receive_cb (plugin->env->cls,
936  &dst->app_ctx,
937  &src->app_ctx,
938  &buf[sizeof(*pid)],
939  ret - sizeof (*pid));
940 }
941 
942 
949 void *
951 {
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");
996  GNUNET_free (port);
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  {
1008  GNUNET_free (plugin);
1009  return NULL;
1010  }
1011  af = AF_INET6;
1012  sock = socket (af,
1013  SOCK_DGRAM,
1014  IPPROTO_UDP);
1015  if (-1 == sock)
1016  {
1018  "socket");
1019  GNUNET_free (plugin->port);
1020  GNUNET_free (plugin);
1021  return NULL;
1022  }
1023  switch (af)
1024  {
1025  case AF_INET:
1026  {
1027  int on = 1;
1028 
1029  if (0 !=
1030  setsockopt (sock,
1031  IPPROTO_IP,
1032  IP_PKTINFO,
1033  &on,
1034  sizeof (on)))
1035  {
1037  "setsockopt");
1038  }
1039  }
1040  {
1041  struct sockaddr_in sa = {
1042  .sin_family = AF_INET,
1043  .sin_port = htons ((uint16_t) nport)
1044  };
1045 
1046  if (0 !=
1047  bind (sock,
1048  (const struct sockaddr *) &sa,
1049  sizeof (sa)))
1050  {
1052  "socket");
1053  GNUNET_break (0 ==
1054  close (sock));
1055  GNUNET_free (plugin->port);
1056  GNUNET_free (plugin);
1057  return NULL;
1058  }
1059  }
1060  break;
1061  case AF_INET6:
1062  {
1063  int on = 1;
1064 
1065  if (0 !=
1066  setsockopt (sock,
1067  IPPROTO_IPV6,
1068  IPV6_RECVPKTINFO,
1069  &on,
1070  sizeof (on)))
1071  {
1073  "setsockopt");
1074  }
1075  }
1076  {
1077  struct sockaddr_in6 sa = {
1078  .sin6_family = AF_INET6,
1079  .sin6_port = htons ((uint16_t) nport)
1080  };
1081 
1082  if (0 !=
1083  bind (sock,
1084  (const struct sockaddr *) &sa,
1085  sizeof (sa)))
1086  {
1088  "socket");
1089  GNUNET_break (0 ==
1090  close (sock));
1091  GNUNET_free (plugin->port);
1092  GNUNET_free (plugin);
1093  return NULL;
1094  }
1095  }
1096  break;
1097  }
1099  GNUNET_NO);
1101  plugin->read_task = GNUNET_SCHEDULER_add_read_net (
1103  plugin->sock,
1104  &read_cb,
1105  plugin);
1106  env->network_size_cb (env->cls,
1108  log (nse) / log (2),
1109  -1.0 /* stddev */);
1110  plugin->scan_task = GNUNET_SCHEDULER_add_now (&scan,
1111  plugin);
1112  api = GNUNET_new (struct GNUNET_DHTU_PluginFunctions);
1113  api->cls = plugin;
1114  api->try_connect = &ip_try_connect;
1115  api->hold = &ip_hold;
1116  api->drop = &ip_drop;
1117  api->send = &ip_send;
1118  return api;
1119 }
1120 
1121 
1128 void *
1130 {
1131  struct GNUNET_DHTU_PluginFunctions *api = cls;
1132  struct Plugin *plugin = api->cls;
1133  struct GNUNET_DHTU_Source *src;
1134  struct GNUNET_DHTU_Target *dst;
1135 
1136  while (NULL != (dst = plugin->dst_head))
1137  {
1138  plugin->env->disconnect_cb (dst->app_ctx);
1139  GNUNET_assert (NULL == dst->ph_head);
1141  plugin->dst_tail,
1142  dst);
1143  GNUNET_free (dst);
1144  }
1145  while (NULL != (src = plugin->src_head))
1146  {
1147  plugin->env->address_del_cb (src->app_ctx);
1149  plugin->src_tail,
1150  src);
1151  GNUNET_free (src->address);
1152  GNUNET_free (src);
1153  }
1154  plugin->env->network_size_cb (plugin->env->cls,
1156  0.0,
1157  0.0);
1159  if (NULL != plugin->read_task)
1160  {
1161  GNUNET_SCHEDULER_cancel (plugin->read_task);
1162  plugin->read_task = NULL;
1163  }
1164  GNUNET_SCHEDULER_cancel (plugin->scan_task);
1167  GNUNET_free (plugin->port);
1168  GNUNET_free (plugin);
1169  GNUNET_free (api);
1170  return NULL;
1171 }
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
static void finished_cb(enum GNUNET_GenericReturnValue rv)
struct TestcasePlugin * 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.
@ 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:509
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition: network.c:1001
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
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
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_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1299
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:1506
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:975
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:1272
#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.
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.
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:54
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Definition: scheduler.c:136
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.