GNUnet  0.20.0
gnunet-service-vpn.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2010, 2011, 2012, 2016, 2017 Christian Grothoff
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 
33 #include "platform.h"
34 #include "gnunet_util_lib.h"
35 #include "gnunet_common.h"
36 #include "gnunet_protocols.h"
37 #include "gnunet_applications.h"
38 #include "gnunet_cadet_service.h"
40 #include "gnunet_constants.h"
41 #include "gnunet_regex_service.h"
42 #include "vpn.h"
43 #include "exit.h"
44 
45 
49 #define MAX_MESSAGE_QUEUE_SIZE 4
50 
51 
55 struct ChannelState;
56 
61 struct DestinationEntry;
62 
68 {
73 
78 
83 
87  uint16_t destination_port;
88 };
89 
90 
96 {
101  struct GNUNET_HashCode key;
102 
107 
112 
117 
123 
127  union
128  {
129  struct
130  {
135 
141 
142  struct
143  {
147  int af;
148 
152  union
153  {
157  struct in_addr v4;
158 
162  struct in6_addr v6;
163  } ip;
166 };
167 
168 
173 {
178 
183 
187  size_t len;
188 
192  const void *msg;
193 };
194 
195 
199 struct ChannelState
200 {
206 
211 
217 
222 
227 
235 
239  int af;
240 
246 
250  unsigned int tmq_length;
251 
255  uint8_t protocol;
256 
260  union
261  {
265  struct in_addr v4;
266 
270  struct in6_addr v6;
272 
277  union
278  {
282  struct in_addr v4;
283 
287  struct in6_addr v6;
289 
293  uint16_t source_port;
294 
299 };
300 
301 
305 static int global_ret;
306 
310 static const struct GNUNET_CONFIGURATION_Handle *cfg;
311 
316 
322 
327 
333 
339 
344 
349 
353 static char *vpn_argv[7];
354 
358 static unsigned long long ipv6prefix;
359 
364 static unsigned long long max_destination_mappings;
365 
370 static unsigned long long max_channel_mappings;
371 
372 
381 static void
383  const void *address,
384  struct GNUNET_HashCode *key)
385 {
386  switch (af)
387  {
388  case AF_INET:
389  GNUNET_CRYPTO_hash (address, sizeof(struct in_addr), key);
390  break;
391 
392  case AF_INET6:
393  GNUNET_CRYPTO_hash (address, sizeof(struct in6_addr), key);
394  break;
395 
396  default:
397  GNUNET_assert (0);
398  break;
399  }
400 }
401 
402 
415 static void
417  uint8_t protocol,
418  const void *source_ip,
419  uint16_t source_port,
420  const void *destination_ip,
421  uint16_t destination_port,
422  struct GNUNET_HashCode *key)
423 {
424  char *off;
425 
426  memset (key, 0, sizeof(struct GNUNET_HashCode));
427  /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
428  so we put the ports in there (and hope for few collisions) */
429  off = (char *) key;
430  GNUNET_memcpy (off, &source_port, sizeof(uint16_t));
431  off += sizeof(uint16_t);
432  GNUNET_memcpy (off, &destination_port, sizeof(uint16_t));
433  off += sizeof(uint16_t);
434  switch (af)
435  {
436  case AF_INET:
437  GNUNET_memcpy (off, source_ip, sizeof(struct in_addr));
438  off += sizeof(struct in_addr);
439  GNUNET_memcpy (off, destination_ip, sizeof(struct in_addr));
440  off += sizeof(struct in_addr);
441  break;
442 
443  case AF_INET6:
444  GNUNET_memcpy (off, source_ip, sizeof(struct in6_addr));
445  off += sizeof(struct in6_addr);
446  GNUNET_memcpy (off, destination_ip, sizeof(struct in6_addr));
447  off += sizeof(struct in6_addr);
448  break;
449 
450  default:
451  GNUNET_assert (0);
452  break;
453  }
454  GNUNET_memcpy (off, &protocol, sizeof(uint8_t));
455  /* off += sizeof (uint8_t); */
456 }
457 
458 
467 static void
469  uint64_t request_id,
470  int result_af,
471  const void *addr)
472 {
473  struct GNUNET_MQ_Envelope *env;
475  size_t rlen;
476 
477  switch (result_af)
478  {
479  case AF_INET:
480  rlen = sizeof(struct in_addr);
481  break;
482 
483  case AF_INET6:
484  rlen = sizeof(struct in6_addr);
485  break;
486 
487  case AF_UNSPEC:
488  rlen = 0;
489  break;
490 
491  default:
492  GNUNET_assert (0);
493  return;
494  }
496  res->result_af = htonl (result_af);
497  res->request_id = request_id;
498  GNUNET_memcpy (&res[1], addr, rlen);
500 }
501 
502 
508 static void
510 {
511  struct GNUNET_HashCode key;
512  struct ChannelMessageQueueEntry *tnq;
513  struct GNUNET_CADET_Channel *channel;
514 
515  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up channel state\n");
516  if (NULL != (channel = ts->channel))
517  {
518  ts->channel = NULL;
520  return;
521  }
523  gettext_noop ("# Active channels"),
524  -1,
525  GNUNET_NO);
526  while (NULL != (tnq = ts->tmq_head))
527  {
529  ts->tmq_length--;
530  GNUNET_free (tnq);
531  }
532  GNUNET_assert (0 == ts->tmq_length);
533  GNUNET_assert (NULL == ts->destination.heap_node);
534  if (NULL != ts->search)
535  {
537  ts->search = NULL;
538  }
539  if (NULL != ts->heap_node)
540  {
542  ts->heap_node = NULL;
544  ts->protocol,
545  &ts->source_ip,
546  ts->source_port,
547  &ts->destination_ip,
548  ts->destination_port,
549  &key);
550  GNUNET_assert (
551  GNUNET_YES ==
553  }
554  GNUNET_free (ts);
555 }
556 
557 
565 static void
567 {
568  struct GNUNET_MQ_Handle *mq;
569 
570  GNUNET_assert (NULL != ts->channel);
575  GNUNET_MQ_send (mq, env);
577  {
579  GNUNET_assert (NULL != env);
581  gettext_noop (
582  "# Messages dropped in cadet queue (overflow)"),
583  1,
584  GNUNET_NO);
586  }
587 }
588 
589 
596 static const char *
598 {
599  static char dest[256];
600 
601  if (de->is_service)
602  {
604  sizeof(dest),
605  "HS: %s-%s",
606  GNUNET_i2s (&de->details.service_destination.target),
607  GNUNET_h2s (
608  &de->details.service_destination.service_descriptor));
609  }
610  else
611  {
612  inet_ntop (de->details.exit_destination.af,
613  &de->details.exit_destination.ip,
614  dest,
615  sizeof(dest));
616  }
617  return dest;
618 }
619 
620 
628 static void
629 channel_cleaner (void *cls, const struct GNUNET_CADET_Channel *channel)
630 {
631  struct ChannelState *ts = cls;
632 
633  ts->channel =
634  NULL; /* we must not call GNUNET_CADET_channel_destroy() anymore */
636  "CADET notified us about death of channel to `%s'\n",
638  free_channel_state (ts);
639 }
640 
641 
651 static void
653  struct GNUNET_TUN_IPv4Header *ipp,
654  struct GNUNET_TUN_UdpHeader *udp)
655 {
657  ts->protocol,
658  sizeof(struct GNUNET_TUN_TcpHeader),
659  &ts->source_ip.v4,
660  &ts->destination_ip.v4);
661  udp->source_port = htons (ts->source_port);
662  udp->destination_port = htons (ts->destination_port);
663  udp->len = htons (0);
664  udp->crc = htons (0);
665 }
666 
667 
677 static void
679  struct GNUNET_TUN_IPv6Header *ipp,
680  struct GNUNET_TUN_UdpHeader *udp)
681 {
683  ts->protocol,
684  sizeof(struct GNUNET_TUN_TcpHeader),
685  &ts->source_ip.v6,
686  &ts->destination_ip.v6);
687  udp->source_port = htons (ts->source_port);
688  udp->destination_port = htons (ts->destination_port);
689  udp->len = htons (0);
690  udp->crc = htons (0);
691 }
692 
693 
702 static int
703 check_icmp_back (void *cls, const struct GNUNET_EXIT_IcmpToVPNMessage *i2v)
704 {
705  struct ChannelState *ts = cls;
706 
707  if (NULL == ts->heap_node)
708  {
709  GNUNET_break_op (0);
710  return GNUNET_SYSERR;
711  }
712  if (AF_UNSPEC == ts->af)
713  {
714  GNUNET_break_op (0);
715  return GNUNET_SYSERR;
716  }
717  return GNUNET_OK;
718 }
719 
720 
728 static void
729 handle_icmp_back (void *cls, const struct GNUNET_EXIT_IcmpToVPNMessage *i2v)
730 {
731  struct ChannelState *ts = cls;
732  size_t mlen;
733 
735  gettext_noop ("# ICMP packets received from cadet"),
736  1,
737  GNUNET_NO);
738  mlen =
739  ntohs (i2v->header.size) - sizeof(struct GNUNET_EXIT_IcmpToVPNMessage);
740  {
741  char sbuf[INET6_ADDRSTRLEN];
742  char dbuf[INET6_ADDRSTRLEN];
743 
744  GNUNET_log (
746  "Received ICMP packet from cadet, sending %u bytes from %s -> %s via TUN\n",
747  (unsigned int) mlen,
748  inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof(sbuf)),
749  inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof(dbuf)));
750  }
751  switch (ts->af)
752  {
753  case AF_INET: {
754  size_t size = sizeof(struct GNUNET_TUN_IPv4Header)
755  + sizeof(struct GNUNET_TUN_IcmpHeader)
756  + sizeof(struct GNUNET_MessageHeader)
757  + sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
758  {
759  /* reserve some extra space in case we have an ICMP type here where
760  we will need to make up the payload ourselves */
761  char buf[size + sizeof(struct GNUNET_TUN_IPv4Header) + 8] GNUNET_ALIGN;
762  struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
763  struct GNUNET_TUN_Layer2PacketHeader *tun =
764  (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1];
765  struct GNUNET_TUN_IPv4Header *ipv4 =
766  (struct GNUNET_TUN_IPv4Header *) &tun[1];
767  struct GNUNET_TUN_IcmpHeader *icmp =
768  (struct GNUNET_TUN_IcmpHeader *) &ipv4[1];
770  tun->flags = htons (0);
771  tun->proto = htons (ETH_P_IPV4);
773  IPPROTO_ICMP,
774  sizeof(struct GNUNET_TUN_IcmpHeader)
775  + mlen,
776  &ts->destination_ip.v4,
777  &ts->source_ip.v4);
778  *icmp = i2v->icmp_header;
779  GNUNET_memcpy (&icmp[1], &i2v[1], mlen);
780  /* For some ICMP types, we need to adjust (make up) the payload here.
781  Also, depending on the AF used on the other side, we have to
782  do ICMP PT (translate ICMP types) */
783  switch (ntohl (i2v->af))
784  {
785  case AF_INET:
786  switch (icmp->type)
787  {
790  break;
791 
795  struct GNUNET_TUN_IPv4Header *ipp =
796  (struct GNUNET_TUN_IPv4Header *) &icmp[1];
797  struct GNUNET_TUN_UdpHeader *udp =
798  (struct GNUNET_TUN_UdpHeader *) &ipp[1];
799 
800  if (mlen != 0)
801  {
802  /* sender did not strip ICMP payload? */
803  GNUNET_break_op (0);
804  return;
805  }
806  size += sizeof(struct GNUNET_TUN_IPv4Header) + 8;
807  GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
808  make_up_icmpv4_payload (ts, ipp, udp);
809  }
810  break;
811 
812  default:
813  GNUNET_break_op (0);
815  stats,
816  gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
817  1,
818  GNUNET_NO);
819  return;
820  }
821  /* end AF_INET */
822  break;
823 
824  case AF_INET6:
825  /* ICMP PT 6-to-4 and possibly making up payloads */
826  switch (icmp->type)
827  {
830  {
831  struct GNUNET_TUN_IPv4Header *ipp =
832  (struct GNUNET_TUN_IPv4Header *) &icmp[1];
833  struct GNUNET_TUN_UdpHeader *udp =
834  (struct GNUNET_TUN_UdpHeader *) &ipp[1];
835 
836  if (mlen != 0)
837  {
838  /* sender did not strip ICMP payload? */
839  GNUNET_break_op (0);
840  return;
841  }
842  size += sizeof(struct GNUNET_TUN_IPv4Header) + 8;
843  GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
844  make_up_icmpv4_payload (ts, ipp, udp);
845  }
846  break;
847 
850  {
851  struct GNUNET_TUN_IPv4Header *ipp =
852  (struct GNUNET_TUN_IPv4Header *) &icmp[1];
853  struct GNUNET_TUN_UdpHeader *udp =
854  (struct GNUNET_TUN_UdpHeader *) &ipp[1];
855 
856  if (mlen != 0)
857  {
858  /* sender did not strip ICMP payload? */
859  GNUNET_break_op (0);
860  return;
861  }
862  size += sizeof(struct GNUNET_TUN_IPv4Header) + 8;
863  GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
864  make_up_icmpv4_payload (ts, ipp, udp);
865  }
866  break;
867 
871  stats,
872  gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"),
873  1,
874  GNUNET_NO);
875  return;
876 
879  break;
880 
883  break;
884 
885  default:
886  GNUNET_break_op (0);
888  stats,
889  gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
890  1,
891  GNUNET_NO);
892  return;
893  }
894  /* end AF_INET6 */
895  break;
896 
897  default:
898  GNUNET_break_op (0);
899  return;
900  }
901  msg->size = htons (size);
902  GNUNET_TUN_calculate_icmp_checksum (icmp, &i2v[1], mlen);
903  (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL);
904  }
905  }
906  break;
907 
908  case AF_INET6: {
909  size_t size = sizeof(struct GNUNET_TUN_IPv6Header)
910  + sizeof(struct GNUNET_TUN_IcmpHeader)
911  + sizeof(struct GNUNET_MessageHeader)
912  + sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
913  {
914  char buf[size + sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
915  struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
916  struct GNUNET_TUN_Layer2PacketHeader *tun =
917  (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1];
918  struct GNUNET_TUN_IPv6Header *ipv6 =
919  (struct GNUNET_TUN_IPv6Header *) &tun[1];
920  struct GNUNET_TUN_IcmpHeader *icmp =
921  (struct GNUNET_TUN_IcmpHeader *) &ipv6[1];
923  tun->flags = htons (0);
924  tun->proto = htons (ETH_P_IPV6);
926  IPPROTO_ICMPV6,
927  sizeof(struct GNUNET_TUN_IcmpHeader)
928  + mlen,
929  &ts->destination_ip.v6,
930  &ts->source_ip.v6);
931  *icmp = i2v->icmp_header;
932  GNUNET_memcpy (&icmp[1], &i2v[1], mlen);
933 
934  /* For some ICMP types, we need to adjust (make up) the payload here.
935  Also, depending on the AF used on the other side, we have to
936  do ICMP PT (translate ICMP types) */
937  switch (ntohl (i2v->af))
938  {
939  case AF_INET:
940  /* ICMP PT 4-to-6 and possibly making up payloads */
941  switch (icmp->type)
942  {
945  break;
946 
949  break;
950 
953  {
954  struct GNUNET_TUN_IPv6Header *ipp =
955  (struct GNUNET_TUN_IPv6Header *) &icmp[1];
956  struct GNUNET_TUN_UdpHeader *udp =
957  (struct GNUNET_TUN_UdpHeader *) &ipp[1];
958 
959  if (mlen != 0)
960  {
961  /* sender did not strip ICMP payload? */
962  GNUNET_break_op (0);
963  return;
964  }
965  size += sizeof(struct GNUNET_TUN_IPv6Header) + 8;
966  GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
967  make_up_icmpv6_payload (ts, ipp, udp);
968  }
969  break;
970 
973  {
974  struct GNUNET_TUN_IPv6Header *ipp =
975  (struct GNUNET_TUN_IPv6Header *) &icmp[1];
976  struct GNUNET_TUN_UdpHeader *udp =
977  (struct GNUNET_TUN_UdpHeader *) &ipp[1];
978 
979  if (mlen != 0)
980  {
981  /* sender did not strip ICMP payload? */
982  GNUNET_break_op (0);
983  return;
984  }
985  size += sizeof(struct GNUNET_TUN_IPv6Header) + 8;
986  GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
987  make_up_icmpv6_payload (ts, ipp, udp);
988  }
989  break;
990 
993  stats,
994  gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"),
995  1,
996  GNUNET_NO);
997  return;
998 
999  default:
1000  GNUNET_break_op (0);
1002  stats,
1003  gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
1004  1,
1005  GNUNET_NO);
1006  return;
1007  }
1008  /* end AF_INET */
1009  break;
1010 
1011  case AF_INET6:
1012  switch (icmp->type)
1013  {
1018  struct GNUNET_TUN_IPv6Header *ipp =
1019  (struct GNUNET_TUN_IPv6Header *) &icmp[1];
1020  struct GNUNET_TUN_UdpHeader *udp =
1021  (struct GNUNET_TUN_UdpHeader *) &ipp[1];
1022 
1023  if (mlen != 0)
1024  {
1025  /* sender did not strip ICMP payload? */
1026  GNUNET_break_op (0);
1027  return;
1028  }
1029  size += sizeof(struct GNUNET_TUN_IPv6Header) + 8;
1030  GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
1031  make_up_icmpv6_payload (ts, ipp, udp);
1032  }
1033  break;
1034 
1036  break;
1037 
1038  default:
1039  GNUNET_break_op (0);
1041  stats,
1042  gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
1043  1,
1044  GNUNET_NO);
1045  return;
1046  }
1047  /* end AF_INET6 */
1048  break;
1049 
1050  default:
1051  GNUNET_break_op (0);
1052  return;
1053  }
1054  msg->size = htons (size);
1055  GNUNET_TUN_calculate_icmp_checksum (icmp, &i2v[1], mlen);
1056  (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL);
1057  }
1058  }
1059  break;
1060 
1061  default:
1062  GNUNET_assert (0);
1063  }
1065  GNUNET_TIME_absolute_get ().abs_value_us);
1067 }
1068 
1069 
1078 static int
1079 check_udp_back (void *cls, const struct GNUNET_EXIT_UdpReplyMessage *reply)
1080 {
1081  struct ChannelState *ts = cls;
1082 
1083  if (NULL == ts->heap_node)
1084  {
1085  GNUNET_break_op (0);
1086  return GNUNET_SYSERR;
1087  }
1088  if (AF_UNSPEC == ts->af)
1089  {
1090  GNUNET_break_op (0);
1091  return GNUNET_SYSERR;
1092  }
1093  return GNUNET_OK;
1094 }
1095 
1096 
1104 static void
1105 handle_udp_back (void *cls, const struct GNUNET_EXIT_UdpReplyMessage *reply)
1106 {
1107  struct ChannelState *ts = cls;
1108  size_t mlen;
1109 
1111  gettext_noop ("# UDP packets received from cadet"),
1112  1,
1113  GNUNET_NO);
1114  mlen =
1115  ntohs (reply->header.size) - sizeof(struct GNUNET_EXIT_UdpReplyMessage);
1116  {
1117  char sbuf[INET6_ADDRSTRLEN];
1118  char dbuf[INET6_ADDRSTRLEN];
1119 
1120  GNUNET_log (
1122  "Received UDP reply from cadet, sending %u bytes from [%s]:%u -> [%s]:%u via TUN\n",
1123  (unsigned int) mlen,
1124  inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof(sbuf)),
1125  ts->destination_port,
1126  inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof(dbuf)),
1127  ts->source_port);
1128  }
1129  switch (ts->af)
1130  {
1131  case AF_INET: {
1132  size_t size = sizeof(struct GNUNET_TUN_IPv4Header)
1133  + sizeof(struct GNUNET_TUN_UdpHeader)
1134  + sizeof(struct GNUNET_MessageHeader)
1135  + sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1136  {
1137  char buf[size] GNUNET_ALIGN;
1138  struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
1139  struct GNUNET_TUN_Layer2PacketHeader *tun =
1140  (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1];
1141  struct GNUNET_TUN_IPv4Header *ipv4 =
1142  (struct GNUNET_TUN_IPv4Header *) &tun[1];
1143  struct GNUNET_TUN_UdpHeader *udp =
1144  (struct GNUNET_TUN_UdpHeader *) &ipv4[1];
1146  msg->size = htons (size);
1147  tun->flags = htons (0);
1148  tun->proto = htons (ETH_P_IPV4);
1150  IPPROTO_UDP,
1151  sizeof(struct GNUNET_TUN_UdpHeader)
1152  + mlen,
1153  &ts->destination_ip.v4,
1154  &ts->source_ip.v4);
1155  if (0 == ntohs (reply->source_port))
1156  udp->source_port = htons (ts->destination_port);
1157  else
1158  udp->source_port = reply->source_port;
1159  if (0 == ntohs (reply->destination_port))
1160  udp->destination_port = htons (ts->source_port);
1161  else
1162  udp->destination_port = reply->destination_port;
1163  udp->len = htons (mlen + sizeof(struct GNUNET_TUN_UdpHeader));
1164  GNUNET_TUN_calculate_udp4_checksum (ipv4, udp, &reply[1], mlen);
1165  GNUNET_memcpy (&udp[1], &reply[1], mlen);
1166  (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL);
1167  }
1168  }
1169  break;
1170 
1171  case AF_INET6: {
1172  size_t size = sizeof(struct GNUNET_TUN_IPv6Header)
1173  + sizeof(struct GNUNET_TUN_UdpHeader)
1174  + sizeof(struct GNUNET_MessageHeader)
1175  + sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1176  {
1177  char buf[size] GNUNET_ALIGN;
1178  struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
1179  struct GNUNET_TUN_Layer2PacketHeader *tun =
1180  (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1];
1181  struct GNUNET_TUN_IPv6Header *ipv6 =
1182  (struct GNUNET_TUN_IPv6Header *) &tun[1];
1183  struct GNUNET_TUN_UdpHeader *udp =
1184  (struct GNUNET_TUN_UdpHeader *) &ipv6[1];
1186  msg->size = htons (size);
1187  tun->flags = htons (0);
1188  tun->proto = htons (ETH_P_IPV6);
1190  IPPROTO_UDP,
1191  sizeof(struct GNUNET_TUN_UdpHeader)
1192  + mlen,
1193  &ts->destination_ip.v6,
1194  &ts->source_ip.v6);
1195  if (0 == ntohs (reply->source_port))
1196  udp->source_port = htons (ts->destination_port);
1197  else
1198  udp->source_port = reply->source_port;
1199  if (0 == ntohs (reply->destination_port))
1200  udp->destination_port = htons (ts->source_port);
1201  else
1202  udp->destination_port = reply->destination_port;
1203  udp->len = htons (mlen + sizeof(struct GNUNET_TUN_UdpHeader));
1204  GNUNET_TUN_calculate_udp6_checksum (ipv6, udp, &reply[1], mlen);
1205  GNUNET_memcpy (&udp[1], &reply[1], mlen);
1206  (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL);
1207  }
1208  }
1209  break;
1210 
1211  default:
1212  GNUNET_assert (0);
1213  }
1215  GNUNET_TIME_absolute_get ().abs_value_us);
1217 }
1218 
1219 
1228 static int
1230 {
1231  struct ChannelState *ts = cls;
1232 
1233  if (NULL == ts->heap_node)
1234  {
1235  GNUNET_break_op (0);
1236  return GNUNET_SYSERR;
1237  }
1238  if (data->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1239  {
1240  GNUNET_break_op (0);
1241  return GNUNET_SYSERR;
1242  }
1243  return GNUNET_OK;
1244 }
1245 
1246 
1254 static void
1256 {
1257  struct ChannelState *ts = cls;
1258  size_t mlen;
1259 
1261  gettext_noop ("# TCP packets received from cadet"),
1262  1,
1263  GNUNET_NO);
1264  mlen = ntohs (data->header.size) - sizeof(struct GNUNET_EXIT_TcpDataMessage);
1265  {
1266  char sbuf[INET6_ADDRSTRLEN];
1267  char dbuf[INET6_ADDRSTRLEN];
1268 
1269  GNUNET_log (
1271  "Received TCP reply from cadet, sending %u bytes from [%s]:%u -> [%s]:%u via TUN\n",
1272  (unsigned int) mlen,
1273  inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof(sbuf)),
1274  ts->destination_port,
1275  inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof(dbuf)),
1276  ts->source_port);
1277  }
1278  switch (ts->af)
1279  {
1280  case AF_INET: {
1281  size_t size = sizeof(struct GNUNET_TUN_IPv4Header)
1282  + sizeof(struct GNUNET_TUN_TcpHeader)
1283  + sizeof(struct GNUNET_MessageHeader)
1284  + sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1285  {
1286  char buf[size] GNUNET_ALIGN;
1287  struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
1288  struct GNUNET_TUN_Layer2PacketHeader *tun =
1289  (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1];
1290  struct GNUNET_TUN_IPv4Header *ipv4 =
1291  (struct GNUNET_TUN_IPv4Header *) &tun[1];
1292  struct GNUNET_TUN_TcpHeader *tcp =
1293  (struct GNUNET_TUN_TcpHeader *) &ipv4[1];
1295  msg->size = htons (size);
1296  tun->flags = htons (0);
1297  tun->proto = htons (ETH_P_IPV4);
1299  IPPROTO_TCP,
1300  sizeof(struct GNUNET_TUN_TcpHeader)
1301  + mlen,
1302  &ts->destination_ip.v4,
1303  &ts->source_ip.v4);
1304  *tcp = data->tcp_header;
1305  tcp->source_port = htons (ts->destination_port);
1306  tcp->destination_port = htons (ts->source_port);
1308  GNUNET_memcpy (&tcp[1], &data[1], mlen);
1309  (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL);
1310  }
1311  }
1312  break;
1313 
1314  case AF_INET6: {
1315  size_t size = sizeof(struct GNUNET_TUN_IPv6Header)
1316  + sizeof(struct GNUNET_TUN_TcpHeader)
1317  + sizeof(struct GNUNET_MessageHeader)
1318  + sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1319  {
1320  char buf[size] GNUNET_ALIGN;
1321  struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
1322  struct GNUNET_TUN_Layer2PacketHeader *tun =
1323  (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1];
1324  struct GNUNET_TUN_IPv6Header *ipv6 =
1325  (struct GNUNET_TUN_IPv6Header *) &tun[1];
1326  struct GNUNET_TUN_TcpHeader *tcp =
1327  (struct GNUNET_TUN_TcpHeader *) &ipv6[1];
1329  msg->size = htons (size);
1330  tun->flags = htons (0);
1331  tun->proto = htons (ETH_P_IPV6);
1333  IPPROTO_TCP,
1334  sizeof(struct GNUNET_TUN_TcpHeader)
1335  + mlen,
1336  &ts->destination_ip.v6,
1337  &ts->source_ip.v6);
1338  *tcp = data->tcp_header;
1339  tcp->source_port = htons (ts->destination_port);
1340  tcp->destination_port = htons (ts->source_port);
1342  GNUNET_memcpy (&tcp[1], &data[1], mlen);
1343  (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL);
1344  }
1345  }
1346  break;
1347  }
1349  GNUNET_TIME_absolute_get ().abs_value_us);
1351 }
1352 
1353 
1362 static struct GNUNET_CADET_Channel *
1364  const struct GNUNET_PeerIdentity *target,
1365  const struct GNUNET_HashCode *port)
1366 {
1367  struct GNUNET_MQ_MessageHandler cadet_handlers[] =
1368  { GNUNET_MQ_hd_var_size (udp_back,
1371  ts),
1372  GNUNET_MQ_hd_var_size (tcp_back,
1375  ts),
1376  GNUNET_MQ_hd_var_size (icmp_back,
1379  ts),
1380  GNUNET_MQ_handler_end () };
1381 
1383  ts,
1384  target,
1385  port,
1386  NULL,
1387  &channel_cleaner,
1388  cadet_handlers);
1389 }
1390 
1391 
1402 static void
1404  const struct GNUNET_PeerIdentity *id,
1405  const struct GNUNET_PeerIdentity *get_path,
1406  unsigned int get_path_length,
1407  const struct GNUNET_PeerIdentity *put_path,
1408  unsigned int put_path_length)
1409 {
1410  struct ChannelState *ts = cls;
1411  struct GNUNET_HashCode port;
1412 
1414  "Exit %s found for destination %s!\n",
1415  GNUNET_i2s (id),
1418  ts->search = NULL;
1419  switch (ts->af)
1420  {
1421  case AF_INET:
1422  /* these must match the strings used in gnunet-daemon-exit */
1425  &port);
1426  break;
1427 
1428  case AF_INET6:
1429  /* these must match the strings used in gnunet-daemon-exit */
1432  &port);
1433  break;
1434 
1435  default:
1436  GNUNET_break (0);
1437  return;
1438  }
1440  "Creating tunnel to %s for destination %s!\n",
1441  GNUNET_i2s (id),
1443  ts->channel = create_channel (ts, id, &port);
1444 }
1445 
1446 
1454 static struct ChannelState *
1456 {
1457  struct ChannelState *ts;
1458 
1460  gettext_noop ("# Cadet channels created"),
1461  1,
1462  GNUNET_NO);
1463  ts = GNUNET_new (struct ChannelState);
1464  ts->af = client_af;
1465  ts->destination = *dt->destination;
1466  ts->destination.heap_node = NULL; /* copy is NOT in destination heap */
1468  if (dt->destination->is_service)
1469  {
1470  struct GNUNET_HashCode cadet_port;
1471 
1474  .service_descriptor,
1475  ts->destination_port,
1476  &cadet_port);
1477  ts->channel =
1478  create_channel (ts,
1480  &cadet_port);
1481 
1482  if (NULL == ts->channel)
1483  {
1484  GNUNET_break (0);
1485  GNUNET_free (ts);
1486  return NULL;
1487  }
1489  "Creating channel to peer %s offering service %s on port %u\n",
1490  GNUNET_i2s (
1491  &dt->destination->details.service_destination.target),
1493  .service_descriptor),
1494  (unsigned int) ts->destination_port);
1495  }
1496  else
1497  {
1498  char *policy;
1499 
1500  switch (dt->destination->details.exit_destination.af)
1501  {
1502  case AF_INET: {
1504 
1506  .ip.v4,
1507  dt->destination_port,
1508  address);
1509  GNUNET_asprintf (&policy,
1510  "%s%s",
1512  address);
1513  break;
1514  }
1515 
1516  case AF_INET6: {
1518 
1520  .ip.v6,
1521  dt->destination_port,
1522  address);
1523  GNUNET_asprintf (&policy,
1524  "%s%s",
1526  address);
1527  break;
1528  }
1529 
1530  default:
1531  GNUNET_assert (0);
1532  break;
1533  }
1534 
1536  "Requesting connect by string: %s\n",
1537  policy);
1538  ts->search = GNUNET_REGEX_search (cfg, policy, &handle_regex_result, ts);
1539  GNUNET_free (policy);
1540  }
1541  return ts;
1542 }
1543 
1544 
1550 static void
1552 {
1553  struct ChannelState *ts;
1554 
1556  GNUNET_assert (NULL != ts);
1557  if (except == ts)
1558  return; /* can't do this */
1560  "Tearing down expired channel to %s\n",
1562  free_channel_state (ts);
1563 }
1564 
1565 
1577 static void
1579  int af,
1580  uint8_t protocol,
1581  const void *source_ip,
1582  const void *destination_ip,
1583  const void *payload,
1584  size_t payload_length)
1585 {
1586  struct GNUNET_HashCode key;
1587  struct ChannelState *ts;
1588  size_t alen;
1589  size_t mlen;
1590  struct GNUNET_MQ_Envelope *env;
1591  const struct GNUNET_TUN_UdpHeader *udp;
1592  const struct GNUNET_TUN_TcpHeader *tcp;
1593  const struct GNUNET_TUN_IcmpHeader *icmp;
1594  struct DestinationChannel *dt;
1595  uint16_t source_port;
1596  uint16_t destination_port;
1597 
1598  switch (protocol)
1599  {
1600  case IPPROTO_UDP: {
1601  if (payload_length < sizeof(struct GNUNET_TUN_UdpHeader))
1602  {
1603  /* blame kernel? */
1604  GNUNET_break (0);
1605  return;
1606  }
1607  tcp = NULL; /* make compiler happy */
1608  icmp = NULL; /* make compiler happy */
1609  udp = payload;
1610  if (udp->len < sizeof(struct GNUNET_TUN_UdpHeader))
1611  {
1612  GNUNET_break_op (0);
1613  return;
1614  }
1615  source_port = ntohs (udp->source_port);
1616  destination_port = ntohs (udp->destination_port);
1618  IPPROTO_UDP,
1619  source_ip,
1620  source_port,
1621  destination_ip,
1623  &key);
1624  }
1625  break;
1626 
1627  case IPPROTO_TCP: {
1628  if (payload_length < sizeof(struct GNUNET_TUN_TcpHeader))
1629  {
1630  /* blame kernel? */
1631  GNUNET_break (0);
1632  return;
1633  }
1634  udp = NULL; /* make compiler happy */
1635  icmp = NULL; /* make compiler happy */
1636  tcp = payload;
1637  if (tcp->off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1638  {
1639  GNUNET_break_op (0);
1640  return;
1641  }
1642  source_port = ntohs (tcp->source_port);
1643  destination_port = ntohs (tcp->destination_port);
1645  IPPROTO_TCP,
1646  source_ip,
1647  source_port,
1648  destination_ip,
1650  &key);
1651  }
1652  break;
1653 
1654  case IPPROTO_ICMP:
1655  case IPPROTO_ICMPV6: {
1656  if ((AF_INET == af) ^ (protocol == IPPROTO_ICMP))
1657  {
1658  GNUNET_break (0);
1659  return;
1660  }
1661  if (payload_length < sizeof(struct GNUNET_TUN_IcmpHeader))
1662  {
1663  /* blame kernel? */
1664  GNUNET_break (0);
1665  return;
1666  }
1667  tcp = NULL; /* make compiler happy */
1668  udp = NULL; /* make compiler happy */
1669  icmp = payload;
1670  source_port = 0;
1671  destination_port = 0;
1673  protocol,
1674  source_ip,
1675  0,
1676  destination_ip,
1677  0,
1678  &key);
1679  }
1680  break;
1681 
1682  default:
1684  _ ("Protocol %u not supported, dropping\n"),
1685  (unsigned int) protocol);
1686  return;
1687  }
1688  alen = 0;
1689  if (! destination->is_service)
1690  {
1691  switch (destination->details.exit_destination.af)
1692  {
1693  case AF_INET:
1694  alen = sizeof(struct in_addr);
1695  break;
1696 
1697  case AF_INET6:
1698  alen = sizeof(struct in6_addr);
1699  break;
1700 
1701  default:
1702  GNUNET_assert (0);
1703  }
1704 
1705  {
1706  char sbuf[INET6_ADDRSTRLEN];
1707  char dbuf[INET6_ADDRSTRLEN];
1708  char xbuf[INET6_ADDRSTRLEN];
1709 
1710  GNUNET_log (
1712  "Routing %s packet from [%s]:%u -> [%s]:%u to destination [%s]:%u\n",
1713  (protocol == IPPROTO_TCP) ? "TCP" : "UDP",
1714  inet_ntop (af, source_ip, sbuf, sizeof(sbuf)),
1715  source_port,
1716  inet_ntop (af, destination_ip, dbuf, sizeof(dbuf)),
1717  destination_port,
1718  inet_ntop (destination->details.exit_destination.af,
1719  &destination->details.exit_destination.ip,
1720  xbuf,
1721  sizeof(xbuf)),
1722  destination_port);
1723  }
1724  for (dt = destination->dt_head; NULL != dt; dt = dt->next)
1725  if (dt->destination_port == destination_port)
1726  break;
1727  }
1728  else
1729  {
1730  {
1731  char sbuf[INET6_ADDRSTRLEN];
1732  char dbuf[INET6_ADDRSTRLEN];
1733 
1734  GNUNET_log (
1736  "Routing %s packet from [%s]:%u -> [%s]:%u to service %s at peer %s\n",
1737  (protocol == IPPROTO_TCP) ? "TCP" : "UDP",
1738  inet_ntop (af, source_ip, sbuf, sizeof(sbuf)),
1739  source_port,
1740  inet_ntop (af, destination_ip, dbuf, sizeof(dbuf)),
1741  destination_port,
1742  GNUNET_h2s (
1743  &destination->details.service_destination.service_descriptor),
1744  GNUNET_i2s (&destination->details.service_destination.target));
1745  }
1746  for (dt = destination->dt_head; NULL != dt; dt = dt->next)
1747  if (dt->destination_port == destination_port)
1748  break;
1749  }
1750  if (NULL == dt)
1751  {
1752  dt = GNUNET_new (struct DestinationChannel);
1753  dt->destination = destination;
1754  GNUNET_CONTAINER_DLL_insert (destination->dt_head,
1755  destination->dt_tail,
1756  dt);
1757  dt->destination_port = destination_port;
1758  }
1759 
1760  /* see if we have an existing channel for this destination */
1762  if (NULL == ts)
1763  {
1765  "Creating new channel for key %s\n",
1766  GNUNET_h2s (&key));
1767  /* need to either use the existing channel from the destination (if still
1768  available) or create a fresh one */
1769  ts = create_channel_to_destination (dt, af);
1770  if (NULL == ts)
1771  return;
1772  /* now bind existing "unbound" channel to our IP/port tuple */
1773  ts->protocol = protocol;
1774  ts->af = af;
1775  if (AF_INET == af)
1776  {
1777  ts->source_ip.v4 = *(const struct in_addr *) source_ip;
1778  ts->destination_ip.v4 = *(const struct in_addr *) destination_ip;
1779  }
1780  else
1781  {
1782  ts->source_ip.v6 = *(const struct in6_addr *) source_ip;
1783  ts->destination_ip.v6 = *(const struct in6_addr *) destination_ip;
1784  }
1785  ts->source_port = source_port;
1786  ts->destination_port = destination_port;
1787  ts->heap_node =
1789  ts,
1790  GNUNET_TIME_absolute_get ().abs_value_us);
1793  channel_map,
1794  &key,
1795  ts,
1798  gettext_noop ("# Active channels"),
1799  1,
1800  GNUNET_NO);
1803  expire_channel (ts);
1804  }
1805  else
1806  {
1809  .abs_value_us);
1810  }
1811  if (NULL == ts->channel)
1812  {
1814  "Packet dropped, channel to %s not yet ready (%s)\n",
1816  (NULL == ts->search) ? "EXIT search failed"
1817  : "EXIT search active");
1819  gettext_noop (
1820  "# Packets dropped (channel not yet online)"),
1821  1,
1822  GNUNET_NO);
1823  return;
1824  }
1825 
1826  /* send via channel */
1827  switch (protocol)
1828  {
1829  case IPPROTO_UDP:
1830  if (destination->is_service)
1831  {
1832  struct GNUNET_EXIT_UdpServiceMessage *usm;
1833 
1834  mlen = sizeof(struct GNUNET_EXIT_UdpServiceMessage) + payload_length
1835  - sizeof(struct GNUNET_TUN_UdpHeader);
1836  if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1837  {
1838  GNUNET_break (0);
1839  return;
1840  }
1841  env = GNUNET_MQ_msg_extra (usm,
1842  payload_length
1843  - sizeof(struct GNUNET_TUN_UdpHeader),
1845  /* if the source port is below 32000, we assume it has a special
1846  meaning; if not, we pick a random port (this is a heuristic) */
1847  usm->source_port =
1848  (ntohs (udp->source_port) < 32000) ? udp->source_port : 0;
1849  usm->destination_port = udp->destination_port;
1850  GNUNET_memcpy (&usm[1],
1851  &udp[1],
1852  payload_length - sizeof(struct GNUNET_TUN_UdpHeader));
1853  }
1854  else
1855  {
1856  struct GNUNET_EXIT_UdpInternetMessage *uim;
1857  struct in_addr *ip4dst;
1858  struct in6_addr *ip6dst;
1859  void *payload;
1860 
1861  mlen = sizeof(struct GNUNET_EXIT_UdpInternetMessage) + alen
1862  + payload_length - sizeof(struct GNUNET_TUN_UdpHeader);
1863  if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1864  {
1865  GNUNET_break (0);
1866  return;
1867  }
1868  env = GNUNET_MQ_msg_extra (uim,
1869  payload_length + alen
1870  - sizeof(struct GNUNET_TUN_UdpHeader),
1872  uim->af = htonl (destination->details.exit_destination.af);
1873  uim->source_port =
1874  (ntohs (udp->source_port) < 32000) ? udp->source_port : 0;
1875  uim->destination_port = udp->destination_port;
1876  switch (destination->details.exit_destination.af)
1877  {
1878  case AF_INET:
1879  ip4dst = (struct in_addr *) &uim[1];
1880  *ip4dst = destination->details.exit_destination.ip.v4;
1881  payload = &ip4dst[1];
1882  break;
1883 
1884  case AF_INET6:
1885  ip6dst = (struct in6_addr *) &uim[1];
1886  *ip6dst = destination->details.exit_destination.ip.v6;
1887  payload = &ip6dst[1];
1888  break;
1889 
1890  default:
1891  GNUNET_assert (0);
1892  }
1894  &udp[1],
1895  payload_length - sizeof(struct GNUNET_TUN_UdpHeader));
1896  }
1897  break;
1898 
1899  case IPPROTO_TCP:
1900  if (GNUNET_NO == ts->is_established)
1901  {
1902  if (destination->is_service)
1903  {
1905 
1906  mlen = sizeof(struct GNUNET_EXIT_TcpServiceStartMessage)
1907  + payload_length - sizeof(struct GNUNET_TUN_TcpHeader);
1908  if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1909  {
1910  GNUNET_break (0);
1911  return;
1912  }
1913  env =
1914  GNUNET_MQ_msg_extra (tsm,
1915  payload_length
1916  - sizeof(struct GNUNET_TUN_TcpHeader),
1918  tsm->reserved = htonl (0);
1919  tsm->tcp_header = *tcp;
1920  GNUNET_memcpy (&tsm[1],
1921  &tcp[1],
1922  payload_length - sizeof(struct GNUNET_TUN_TcpHeader));
1923  }
1924  else
1925  {
1927  struct in_addr *ip4dst;
1928  struct in6_addr *ip6dst;
1929  void *payload;
1930 
1931  mlen = sizeof(struct GNUNET_EXIT_TcpInternetStartMessage) + alen
1932  + payload_length - sizeof(struct GNUNET_TUN_TcpHeader);
1933  if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1934  {
1935  GNUNET_break (0);
1936  return;
1937  }
1938  env =
1939  GNUNET_MQ_msg_extra (tim,
1940  payload_length + alen
1941  - sizeof(struct GNUNET_TUN_TcpHeader),
1943  tim->af = htonl (destination->details.exit_destination.af);
1944  tim->tcp_header = *tcp;
1945  switch (destination->details.exit_destination.af)
1946  {
1947  case AF_INET:
1948  ip4dst = (struct in_addr *) &tim[1];
1949  *ip4dst = destination->details.exit_destination.ip.v4;
1950  payload = &ip4dst[1];
1951  break;
1952 
1953  case AF_INET6:
1954  ip6dst = (struct in6_addr *) &tim[1];
1955  *ip6dst = destination->details.exit_destination.ip.v6;
1956  payload = &ip6dst[1];
1957  break;
1958 
1959  default:
1960  GNUNET_assert (0);
1961  }
1963  &tcp[1],
1964  payload_length - sizeof(struct GNUNET_TUN_TcpHeader));
1965  }
1966  }
1967  else
1968  {
1969  struct GNUNET_EXIT_TcpDataMessage *tdm;
1970 
1971  mlen = sizeof(struct GNUNET_EXIT_TcpDataMessage) + payload_length
1972  - sizeof(struct GNUNET_TUN_TcpHeader);
1973  if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1974  {
1975  GNUNET_break (0);
1976  return;
1977  }
1978  env = GNUNET_MQ_msg_extra (tdm,
1979  payload_length
1980  - sizeof(struct GNUNET_TUN_TcpHeader),
1982  tdm->reserved = htonl (0);
1983  tdm->tcp_header = *tcp;
1984  GNUNET_memcpy (&tdm[1],
1985  &tcp[1],
1986  payload_length - sizeof(struct GNUNET_TUN_TcpHeader));
1987  }
1988  break;
1989 
1990  case IPPROTO_ICMP:
1991  case IPPROTO_ICMPV6:
1992  if (destination->is_service)
1993  {
1994  struct GNUNET_EXIT_IcmpServiceMessage *ism;
1995 
1996  /* ICMP protocol translation will be done by the receiver (as we don't know
1997  the target AF); however, we still need to possibly discard the payload
1998  depending on the ICMP type */
1999  switch (af)
2000  {
2001  case AF_INET:
2002  switch (icmp->type)
2003  {
2006  break;
2007 
2011  /* throw away ICMP payload, won't be useful for the other side anyway */
2012  payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2013  break;
2014 
2015  default:
2017  gettext_noop (
2018  "# ICMPv4 packets dropped (not allowed)"),
2019  1,
2020  GNUNET_NO);
2021  return;
2022  }
2023  /* end of AF_INET */
2024  break;
2025 
2026  case AF_INET6:
2027  switch (icmp->type)
2028  {
2033  /* throw away ICMP payload, won't be useful for the other side anyway */
2034  payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2035  break;
2036 
2039  break;
2040 
2041  default:
2043  gettext_noop (
2044  "# ICMPv6 packets dropped (not allowed)"),
2045  1,
2046  GNUNET_NO);
2047  return;
2048  }
2049  /* end of AF_INET6 */
2050  break;
2051 
2052  default:
2053  GNUNET_assert (0);
2054  break;
2055  }
2056 
2057  /* update length calculations, as payload_length may have changed */
2058  mlen = sizeof(struct GNUNET_EXIT_IcmpServiceMessage) + alen
2059  + payload_length - sizeof(struct GNUNET_TUN_IcmpHeader);
2060  if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
2061  {
2062  GNUNET_break (0);
2063  return;
2064  }
2065 
2066  env = GNUNET_MQ_msg_extra (ism,
2067  payload_length
2068  - sizeof(struct GNUNET_TUN_IcmpHeader),
2070  ism->af = htonl (af); /* need to tell destination ICMP protocol family! */
2071  ism->icmp_header = *icmp;
2072  GNUNET_memcpy (&ism[1],
2073  &icmp[1],
2074  payload_length - sizeof(struct GNUNET_TUN_IcmpHeader));
2075  }
2076  else
2077  {
2078  struct GNUNET_EXIT_IcmpInternetMessage *iim;
2079  struct in_addr *ip4dst;
2080  struct in6_addr *ip6dst;
2081  void *payload;
2082  uint8_t new_type;
2083 
2084  new_type = icmp->type;
2085  /* Perform ICMP protocol-translation (depending on destination AF and source AF)
2086  and throw away ICMP payload depending on ICMP message type */
2087  switch (af)
2088  {
2089  case AF_INET:
2090  switch (icmp->type)
2091  {
2093  if (destination->details.exit_destination.af == AF_INET6)
2095  break;
2096 
2098  if (destination->details.exit_destination.af == AF_INET6)
2100  break;
2101 
2103  if (destination->details.exit_destination.af == AF_INET6)
2105  /* throw away IP-payload, exit will have to make it up anyway */
2106  payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2107  break;
2108 
2110  if (destination->details.exit_destination.af == AF_INET6)
2112  /* throw away IP-payload, exit will have to make it up anyway */
2113  payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2114  break;
2115 
2117  if (destination->details.exit_destination.af == AF_INET6)
2118  {
2120  stats,
2121  gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"),
2122  1,
2123  GNUNET_NO);
2124  return;
2125  }
2126  /* throw away IP-payload, exit will have to make it up anyway */
2127  payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2128  break;
2129 
2130  default:
2132  stats,
2133  gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
2134  1,
2135  GNUNET_NO);
2136  return;
2137  }
2138  /* end of AF_INET */
2139  break;
2140 
2141  case AF_INET6:
2142  switch (icmp->type)
2143  {
2145  if (destination->details.exit_destination.af == AF_INET)
2147  /* throw away IP-payload, exit will have to make it up anyway */
2148  payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2149  break;
2150 
2152  if (destination->details.exit_destination.af == AF_INET)
2154  /* throw away IP-payload, exit will have to make it up anyway */
2155  payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2156  break;
2157 
2159  if (destination->details.exit_destination.af == AF_INET)
2160  {
2162  stats,
2163  gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"),
2164  1,
2165  GNUNET_NO);
2166  return;
2167  }
2168  /* throw away IP-payload, exit will have to make it up anyway */
2169  payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2170  break;
2171 
2173  if (destination->details.exit_destination.af == AF_INET)
2174  {
2176  stats,
2177  gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"),
2178  1,
2179  GNUNET_NO);
2180  return;
2181  }
2182  /* throw away IP-payload, exit will have to make it up anyway */
2183  payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2184  break;
2185 
2187  if (destination->details.exit_destination.af == AF_INET)
2189  break;
2190 
2192  if (destination->details.exit_destination.af == AF_INET)
2193  new_type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY;
2194  break;
2195 
2196  default:
2198  stats,
2199  gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
2200  1,
2201  GNUNET_NO);
2202  return;
2203  }
2204  /* end of AF_INET6 */
2205  break;
2206 
2207  default:
2208  GNUNET_assert (0);
2209  }
2210 
2211  /* update length calculations, as payload_length may have changed */
2212  mlen = sizeof(struct GNUNET_EXIT_IcmpInternetMessage) + alen
2213  + payload_length - sizeof(struct GNUNET_TUN_IcmpHeader);
2214  if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
2215  {
2216  GNUNET_break (0);
2217  return;
2218  }
2219  env = GNUNET_MQ_msg_extra (iim,
2220  alen + payload_length
2221  - sizeof(struct GNUNET_TUN_IcmpHeader),
2223  iim->icmp_header = *icmp;
2224  iim->icmp_header.type = new_type;
2225  iim->af = htonl (destination->details.exit_destination.af);
2226  switch (destination->details.exit_destination.af)
2227  {
2228  case AF_INET:
2229  ip4dst = (struct in_addr *) &iim[1];
2230  *ip4dst = destination->details.exit_destination.ip.v4;
2231  payload = &ip4dst[1];
2232  break;
2233 
2234  case AF_INET6:
2235  ip6dst = (struct in6_addr *) &iim[1];
2236  *ip6dst = destination->details.exit_destination.ip.v6;
2237  payload = &ip6dst[1];
2238  break;
2239 
2240  default:
2241  GNUNET_assert (0);
2242  }
2244  &icmp[1],
2245  payload_length - sizeof(struct GNUNET_TUN_IcmpHeader));
2246  }
2247  break;
2248 
2249  default:
2250  /* not supported above, how can we get here !? */
2251  GNUNET_assert (0);
2252  break;
2253  }
2254  ts->is_established = GNUNET_YES;
2255  send_to_channel (ts, env);
2256 }
2257 
2258 
2271 static int
2272 message_token (void *cls, const struct GNUNET_MessageHeader *message)
2273 {
2274  const struct GNUNET_TUN_Layer2PacketHeader *tun;
2275  size_t mlen;
2276  struct GNUNET_HashCode key;
2277  struct DestinationEntry *de;
2278 
2280  gettext_noop (
2281  "# Packets received from TUN interface"),
2282  1,
2283  GNUNET_NO);
2284  mlen = ntohs (message->size);
2285  if ((ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) ||
2286  (mlen < sizeof(struct GNUNET_MessageHeader)
2287  + sizeof(struct GNUNET_TUN_Layer2PacketHeader)))
2288  {
2289  GNUNET_break (0);
2290  return GNUNET_OK;
2291  }
2292  tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1];
2293  mlen -= (sizeof(struct GNUNET_MessageHeader)
2294  + sizeof(struct GNUNET_TUN_Layer2PacketHeader));
2295  switch (ntohs (tun->proto))
2296  {
2297  case ETH_P_IPV6: {
2298  const struct GNUNET_TUN_IPv6Header *pkt6;
2299 
2300  if (mlen < sizeof(struct GNUNET_TUN_IPv6Header))
2301  {
2302  /* blame kernel */
2303  GNUNET_break (0);
2304  return GNUNET_OK;
2305  }
2306  pkt6 = (const struct GNUNET_TUN_IPv6Header *) &tun[1];
2309  if (NULL == de)
2310  {
2311  char buf[INET6_ADDRSTRLEN];
2312 
2313  GNUNET_log (
2315  _ ("Packet received for unmapped destination `%s' (dropping it)\n"),
2316  inet_ntop (AF_INET6, &pkt6->destination_address, buf, sizeof(buf)));
2317  return GNUNET_OK;
2318  }
2319  route_packet (de,
2320  AF_INET6,
2321  pkt6->next_header,
2322  &pkt6->source_address,
2323  &pkt6->destination_address,
2324  &pkt6[1],
2325  mlen - sizeof(struct GNUNET_TUN_IPv6Header));
2326  }
2327  break;
2328 
2329  case ETH_P_IPV4: {
2330  struct GNUNET_TUN_IPv4Header *pkt4;
2331 
2332  if (mlen < sizeof(struct GNUNET_TUN_IPv4Header))
2333  {
2334  /* blame kernel */
2335  GNUNET_break (0);
2336  return GNUNET_OK;
2337  }
2338  pkt4 = (struct GNUNET_TUN_IPv4Header *) &tun[1];
2341  if (NULL == de)
2342  {
2343  char buf[INET_ADDRSTRLEN];
2344 
2345  GNUNET_log (
2347  _ ("Packet received for unmapped destination `%s' (dropping it)\n"),
2348  inet_ntop (AF_INET, &pkt4->destination_address, buf, sizeof(buf)));
2349  return GNUNET_OK;
2350  }
2351  if (pkt4->header_length * 4 != sizeof(struct GNUNET_TUN_IPv4Header))
2352  {
2354  _ ("Received IPv4 packet with options (dropping it)\n"));
2355  return GNUNET_OK;
2356  }
2357  route_packet (de,
2358  AF_INET,
2359  pkt4->protocol,
2360  &pkt4->source_address,
2361  &pkt4->destination_address,
2362  &pkt4[1],
2363  mlen - sizeof(struct GNUNET_TUN_IPv4Header));
2364  }
2365  break;
2366 
2367  default:
2368  GNUNET_log (
2370  _ ("Received packet of unknown protocol %d from TUN (dropping it)\n"),
2371  (unsigned int) ntohs (tun->proto));
2372  break;
2373  }
2374  return GNUNET_OK;
2375 }
2376 
2377 
2386 static int
2387 allocate_v4_address (struct in_addr *v4)
2388 {
2389  const char *ipv4addr = vpn_argv[4];
2390  const char *ipv4mask = vpn_argv[5];
2391  struct in_addr addr;
2392  struct in_addr mask;
2393  struct in_addr rnd;
2394  struct GNUNET_HashCode key;
2395  unsigned int tries;
2396 
2397  GNUNET_assert (1 == inet_pton (AF_INET, ipv4addr, &addr));
2398  GNUNET_assert (1 == inet_pton (AF_INET, ipv4mask, &mask));
2399  /* Given 192.168.0.1/255.255.0.0, we want a mask
2400  of '192.168.255.255', thus: */
2401  mask.s_addr = addr.s_addr | ~mask.s_addr;
2402  tries = 0;
2403  do
2404  {
2405  tries++;
2406  if (tries > 16)
2407  {
2409  _ (
2410  "Failed to find unallocated IPv4 address in VPN's range\n"));
2411  return GNUNET_SYSERR;
2412  }
2413  /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
2414  rnd.s_addr =
2416  v4->s_addr = (addr.s_addr | rnd.s_addr) & mask.s_addr;
2417  get_destination_key_from_ip (AF_INET, v4, &key);
2418  }
2419  while ((GNUNET_YES ==
2421  (v4->s_addr == addr.s_addr) || (v4->s_addr == mask.s_addr));
2422  return GNUNET_OK;
2423 }
2424 
2425 
2434 static int
2435 allocate_v6_address (struct in6_addr *v6)
2436 {
2437  const char *ipv6addr = vpn_argv[2];
2438  struct in6_addr addr;
2439  struct in6_addr mask;
2440  struct in6_addr rnd;
2441  int i;
2442  struct GNUNET_HashCode key;
2443  unsigned int tries;
2444 
2445  GNUNET_assert (1 == inet_pton (AF_INET6, ipv6addr, &addr));
2446  GNUNET_assert (ipv6prefix < 128);
2447  /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
2448  thus: */
2449  mask = addr;
2450  for (i = 127; i >= ipv6prefix; i--)
2451  mask.s6_addr[i / 8] |= (1 << (i % 8));
2452 
2453  /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */
2454  tries = 0;
2455  do
2456  {
2457  tries++;
2458  if (tries > 16)
2459  {
2461  _ (
2462  "Failed to find unallocated IPv6 address in VPN's range\n"));
2463  return GNUNET_SYSERR;
2464  }
2465  for (i = 0; i < 16; i++)
2466  {
2467  rnd.s6_addr[i] =
2469  256);
2470  v6->s6_addr[i] = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
2471  }
2472  get_destination_key_from_ip (AF_INET6, v6, &key);
2473  }
2474  while ((GNUNET_YES ==
2476  (0 == GNUNET_memcmp (v6, &addr)) ||
2477  (0 == GNUNET_memcmp (v6, &mask)));
2478  return GNUNET_OK;
2479 }
2480 
2481 
2487 static void
2489 {
2490  struct DestinationChannel *dt;
2491 
2493  "Cleaning up destination entry `%s'\n",
2496  gettext_noop ("# Active destinations"),
2497  -1,
2498  GNUNET_NO);
2499  while (NULL != (dt = de->dt_head))
2500  {
2502  GNUNET_free (dt);
2503  }
2504  if (NULL != de->heap_node)
2505  {
2507  de->heap_node = NULL;
2508  GNUNET_assert (
2509  GNUNET_YES ==
2511  }
2512  GNUNET_free (de);
2513 }
2514 
2515 
2521 static void
2523 {
2524  struct DestinationEntry *de;
2525 
2527  GNUNET_assert (NULL != de);
2528  if (except == de)
2529  return; /* can't do this */
2531 }
2532 
2533 
2548 static int
2549 allocate_response_ip (int *result_af,
2550  void **addr,
2551  struct in_addr *v4,
2552  struct in6_addr *v6)
2553 {
2554  *addr = NULL;
2555  switch (*result_af)
2556  {
2557  case AF_INET:
2558  if (GNUNET_OK != allocate_v4_address (v4))
2559  *result_af = AF_UNSPEC;
2560  else
2561  *addr = v4;
2562  break;
2563 
2564  case AF_INET6:
2565  if (GNUNET_OK != allocate_v6_address (v6))
2566  *result_af = AF_UNSPEC;
2567  else
2568  *addr = v6;
2569  break;
2570 
2571  case AF_UNSPEC:
2572  if (GNUNET_OK == allocate_v4_address (v4))
2573  {
2574  *addr = v4;
2575  *result_af = AF_INET;
2576  }
2577  else if (GNUNET_OK == allocate_v6_address (v6))
2578  {
2579  *addr = v6;
2580  *result_af = AF_INET6;
2581  }
2582  break;
2583 
2584  default:
2585  GNUNET_break (0);
2586  return GNUNET_SYSERR;
2587  }
2588  return GNUNET_OK;
2589 }
2590 
2591 
2601 static int
2603  const struct RedirectToIpRequestMessage *msg)
2604 {
2605  size_t alen;
2606  int addr_af;
2607 
2608  alen = ntohs (msg->header.size) - sizeof(struct RedirectToIpRequestMessage);
2609  addr_af = (int) htonl (msg->addr_af);
2610  switch (addr_af)
2611  {
2612  case AF_INET:
2613  if (alen != sizeof(struct in_addr))
2614  {
2615  GNUNET_break (0);
2616  return GNUNET_SYSERR;
2617  }
2618  break;
2619 
2620  case AF_INET6:
2621  if (alen != sizeof(struct in6_addr))
2622  {
2623  GNUNET_break (0);
2624  return GNUNET_SYSERR;
2625  }
2626  break;
2627 
2628  default:
2629  GNUNET_break (0);
2630  return GNUNET_SYSERR;
2631  }
2632  return GNUNET_OK;
2633 }
2634 
2635 
2644 static void
2646  const struct RedirectToIpRequestMessage *msg)
2647 {
2648  struct GNUNET_SERVICE_Client *client = cls;
2649  size_t alen;
2650  int addr_af;
2651  int result_af;
2652  struct in_addr v4;
2653  struct in6_addr v6;
2654  void *addr;
2655  struct DestinationEntry *de;
2656  struct GNUNET_HashCode key;
2657 
2658  alen = ntohs (msg->header.size) - sizeof(struct RedirectToIpRequestMessage);
2659  addr_af = (int) htonl (msg->addr_af);
2660  /* allocate response IP */
2661  result_af = (int) htonl (msg->result_af);
2662  if (GNUNET_OK != allocate_response_ip (&result_af, &addr, &v4, &v6))
2663  {
2664  GNUNET_SERVICE_client_drop (client);
2665  return;
2666  }
2667  /* send reply with our IP address */
2668  send_client_reply (client, msg->request_id, result_af, addr);
2669  if (result_af == AF_UNSPEC)
2670  {
2671  /* failure, we're done */
2673  return;
2674  }
2675 
2676  {
2677  char sbuf[INET6_ADDRSTRLEN];
2678  char dbuf[INET6_ADDRSTRLEN];
2679 
2681  "Allocated address %s for redirection via exit to %s\n",
2682  inet_ntop (result_af, addr, sbuf, sizeof(sbuf)),
2683  inet_ntop (addr_af, &msg[1], dbuf, sizeof(dbuf)));
2684  }
2685 
2686  /* setup destination record */
2687  de = GNUNET_new (struct DestinationEntry);
2688  de->is_service = GNUNET_NO;
2689  de->details.exit_destination.af = addr_af;
2690  GNUNET_memcpy (&de->details.exit_destination.ip, &msg[1], alen);
2692  de->key = key;
2695  &key,
2696  de,
2699  de,
2701  msg->expiration_time)
2702  .abs_value_us);
2704  gettext_noop ("# Active destinations"),
2705  1,
2706  GNUNET_NO);
2709  expire_destination (de);
2711 }
2712 
2713 
2722 static void
2724  void *cls,
2725  const struct RedirectToServiceRequestMessage *msg)
2726 {
2727  struct GNUNET_SERVICE_Client *client = cls;
2728  int result_af;
2729  struct in_addr v4;
2730  struct in6_addr v6;
2731  void *addr;
2732  struct DestinationEntry *de;
2733  struct GNUNET_HashCode key;
2734  struct DestinationChannel *dt;
2735 
2736  /* allocate response IP */
2737  result_af = (int) htonl (msg->result_af);
2738  if (GNUNET_OK != allocate_response_ip (&result_af, &addr, &v4, &v6))
2739  {
2740  GNUNET_break (0);
2741  GNUNET_SERVICE_client_drop (client);
2742  return;
2743  }
2744  send_client_reply (client, msg->request_id, result_af, addr);
2745  if (result_af == AF_UNSPEC)
2746  {
2747  /* failure, we're done */
2749  _ ("Failed to allocate IP address for new destination\n"));
2751  return;
2752  }
2753 
2754  {
2755  char sbuf[INET6_ADDRSTRLEN];
2756 
2758  "Allocated address %s for redirection to service %s on peer %s\n",
2759  inet_ntop (result_af, addr, sbuf, sizeof(sbuf)),
2760  GNUNET_h2s (&msg->service_descriptor),
2761  GNUNET_i2s (&msg->target));
2762  }
2763 
2764  /* setup destination record */
2765  de = GNUNET_new (struct DestinationEntry);
2766  de->is_service = GNUNET_YES;
2767  de->details.service_destination.target = msg->target;
2768  de->details.service_destination.service_descriptor = msg->service_descriptor;
2769  get_destination_key_from_ip (result_af, addr, &key);
2770  de->key = key;
2773  &key,
2774  de,
2777  de,
2779  msg->expiration_time)
2780  .abs_value_us);
2783  expire_destination (de);
2784 
2785  dt = GNUNET_new (struct DestinationChannel);
2786  dt->destination = de;
2788  /* we're done */
2790 }
2791 
2792 
2801 static int
2802 cleanup_destination (void *cls, const struct GNUNET_HashCode *key, void *value)
2803 {
2804  struct DestinationEntry *de = value;
2805 
2807  return GNUNET_OK;
2808 }
2809 
2810 
2819 static int
2820 cleanup_channel (void *cls, const struct GNUNET_HashCode *key, void *value)
2821 {
2822  struct ChannelState *ts = value;
2823 
2825  "Tearing down channel to `%s' during cleanup\n",
2827  free_channel_state (ts);
2828  return GNUNET_OK;
2829 }
2830 
2831 
2837 static void
2838 cleanup (void *cls)
2839 {
2840  unsigned int i;
2841 
2842  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "VPN is shutting down\n");
2843  if (NULL != destination_map)
2844  {
2847  NULL);
2849  destination_map = NULL;
2850  }
2851  if (NULL != destination_heap)
2852  {
2854  destination_heap = NULL;
2855  }
2856  if (NULL != channel_map)
2857  {
2860  channel_map = NULL;
2861  }
2862  if (NULL != channel_heap)
2863  {
2865  channel_heap = NULL;
2866  }
2867  if (NULL != cadet_handle)
2868  {
2870  cadet_handle = NULL;
2871  }
2872  if (NULL != helper_handle)
2873  {
2876  helper_handle = NULL;
2877  }
2878  if (NULL != stats)
2879  {
2881  stats = NULL;
2882  }
2883  for (i = 0; i < 5; i++)
2884  GNUNET_free (vpn_argv[i]);
2885 }
2886 
2887 
2896 static void *
2898  struct GNUNET_SERVICE_Client *c,
2899  struct GNUNET_MQ_Handle *mq)
2900 {
2901  return c;
2902 }
2903 
2904 
2912 static void
2914  struct GNUNET_SERVICE_Client *c,
2915  void *internal_cls)
2916 {
2917  GNUNET_assert (c == internal_cls);
2918 }
2919 
2920 
2928 static void
2929 run (void *cls,
2930  const struct GNUNET_CONFIGURATION_Handle *cfg_,
2932 {
2933  char *ifname;
2934  char *ipv6addr;
2935  char *ipv6prefix_s;
2936  char *ipv4addr;
2937  char *ipv4mask;
2938  struct in_addr v4;
2939  struct in6_addr v6;
2940  char *binary;
2941 
2942  cfg = cfg_;
2943  binary = GNUNET_OS_get_suid_binary_path (cfg, "gnunet-helper-vpn");
2944 
2945  if (GNUNET_YES !=
2947  binary,
2948  GNUNET_YES,
2949  "-d gnunet-vpn - - 169.1.3.3.7 255.255.255.0")) // ipv4 only please!
2950  {
2952  "`%s' is not SUID or the path is invalid, refusing to run.\n",
2953  binary);
2954  GNUNET_free (binary);
2955  global_ret = 1;
2956  /* we won't "really" exit here, as the 'service' is still running;
2957  however, as no handlers are registered, the service won't do
2958  anything either */
2959  return;
2960  }
2961  stats = GNUNET_STATISTICS_create ("vpn", cfg);
2962  if (GNUNET_OK !=
2964  "VPN",
2965  "MAX_MAPPING",
2968  if (GNUNET_OK !=
2970  "VPN",
2971  "MAX_TUNNELS",
2973  max_channel_mappings = 200;
2974 
2975  destination_map =
2977  GNUNET_NO);
2980  channel_map =
2983 
2984 
2985  vpn_argv[0] = GNUNET_strdup ("vpn-gnunet");
2986  if (GNUNET_SYSERR ==
2987  GNUNET_CONFIGURATION_get_value_string (cfg, "VPN", "IFNAME", &ifname))
2988  {
2990  GNUNET_free (binary);
2992  return;
2993  }
2994  vpn_argv[1] = ifname;
2995  ipv6addr = NULL;
2996  if (GNUNET_OK == GNUNET_NETWORK_test_pf (PF_INET6))
2997  {
2999  "VPN",
3000  "IPV6ADDR",
3001  &ipv6addr)) ||
3002  (1 != inet_pton (AF_INET6, ipv6addr, &v6))))
3003  {
3005  "VPN",
3006  "IPV6ADDR",
3007  _ ("Must specify valid IPv6 address"));
3008  GNUNET_free (binary);
3010  GNUNET_free (ipv6addr);
3011  return;
3012  }
3013  vpn_argv[2] = ipv6addr;
3014  ipv6prefix_s = NULL;
3016  "VPN",
3017  "IPV6PREFIX",
3018  &ipv6prefix_s))
3019  {
3020  GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "VPN", "IPV6PREFIX");
3022  GNUNET_free (ipv6prefix_s);
3023  return;
3024  }
3025  vpn_argv[3] = ipv6prefix_s;
3027  "VPN",
3028  "IPV6PREFIX",
3029  &ipv6prefix)) ||
3030  (ipv6prefix >= 127))
3031  {
3033  "VPN",
3034  "IPV4MASK",
3035  _ ("Must specify valid IPv6 mask"));
3036  GNUNET_free (binary);
3038  return;
3039  }
3040  }
3041  else
3042  {
3044  _ (
3045  "IPv6 support disabled as this system does not support IPv6\n"));
3046  vpn_argv[2] = GNUNET_strdup ("-");
3047  vpn_argv[3] = GNUNET_strdup ("-");
3048  }
3049  if (GNUNET_OK == GNUNET_NETWORK_test_pf (PF_INET))
3050  {
3051  ipv4addr = NULL;
3053  "vpn",
3054  "IPV4ADDR",
3055  &ipv4addr)) ||
3056  (1 != inet_pton (AF_INET, ipv4addr, &v4))))
3057  {
3059  "VPN",
3060  "IPV4ADDR",
3061  _ ("Must specify valid IPv4 address"));
3062  GNUNET_free (binary);
3064  GNUNET_free (ipv4addr);
3065  return;
3066  }
3067  vpn_argv[4] = ipv4addr;
3068  ipv4mask = NULL;
3070  "vpn",
3071  "IPV4MASK",
3072  &ipv4mask)) ||
3073  (1 != inet_pton (AF_INET, ipv4mask, &v4))))
3074  {
3076  "VPN",
3077  "IPV4MASK",
3078  _ ("Must specify valid IPv4 mask"));
3079  GNUNET_free (binary);
3081  GNUNET_free (ipv4mask);
3082  return;
3083  }
3084  vpn_argv[5] = ipv4mask;
3085  }
3086  else
3087  {
3089  _ (
3090  "IPv4 support disabled as this system does not support IPv4\n"));
3091  vpn_argv[4] = GNUNET_strdup ("-");
3092  vpn_argv[5] = GNUNET_strdup ("-");
3093  }
3094  vpn_argv[6] = NULL;
3095 
3097  // FIXME never opens ports???
3099  binary,
3100  vpn_argv,
3101  &message_token,
3102  NULL,
3103  NULL);
3104  GNUNET_free (binary);
3106 }
3107 
3108 
3113  "vpn",
3115  &run,
3118  NULL,
3119  GNUNET_MQ_hd_var_size (client_redirect_to_ip,
3122  NULL),
3123  GNUNET_MQ_hd_fixed_size (client_redirect_to_service,
3126  NULL),
3128 
3129 
3130 /* end of gnunet-service-vpn.c */
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
format for cadet messages exchanged between VPN service and exit daemon
#define gettext_noop(String)
Definition: gettext.h:70
static int res
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
static char * address
GNS address for this phone.
struct GNUNET_HashCode key
The key used in the DHT.
uint32_t data
The data value.
static char * value
Value of the record to add/remove.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static unsigned long long payload
How much data are we currently storing in the database?
static struct GNUNET_CADET_Port * cadet_port
Listen port for incoming requests.
static char buf[2048]
static int check_icmp_back(void *cls, const struct GNUNET_EXIT_IcmpToVPNMessage *i2v)
We got an ICMP packet back from the CADET channel.
static void send_to_channel(struct ChannelState *ts, struct GNUNET_MQ_Envelope *env)
Add the given message to the given channel and trigger the transmission process.
static void get_channel_key_from_ips(int af, uint8_t protocol, const void *source_ip, uint16_t source_port, const void *destination_ip, uint16_t destination_port, struct GNUNET_HashCode *key)
Compute the key under which we would store an entry in the channel_map for the given socket address p...
static struct GNUNET_CONTAINER_MultiHashMap * channel_map
Map from source and destination address (IP+port) to connection information (mostly with the respecti...
static int allocate_response_ip(int *result_af, void **addr, struct in_addr *v4, struct in6_addr *v6)
Allocate an IP address for the response.
static struct GNUNET_CONTAINER_MultiHashMap * destination_map
Map from IP address to destination information (possibly with a CADET channel handle for fast setup).
static void handle_icmp_back(void *cls, const struct GNUNET_EXIT_IcmpToVPNMessage *i2v)
We got an ICMP packet back from the CADET channel.
static void route_packet(struct DestinationEntry *destination, int af, uint8_t protocol, const void *source_ip, const void *destination_ip, const void *payload, size_t payload_length)
Route a packet via cadet to the given destination.
static int cleanup_destination(void *cls, const struct GNUNET_HashCode *key, void *value)
Free memory occupied by an entry in the destination map.
static unsigned long long ipv6prefix
Length of the prefix of the VPN's IPv6 network.
static int check_tcp_back(void *cls, const struct GNUNET_EXIT_TcpDataMessage *data)
We got a TCP packet back from the CADET channel.
static int global_ret
Return value from main().
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
#define MAX_MESSAGE_QUEUE_SIZE
Maximum number of messages we allow in the queue for cadet.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we use.
static void get_destination_key_from_ip(int af, const void *address, struct GNUNET_HashCode *key)
Compute the key under which we would store an entry in the destination_map for the given IP address.
GNUNET_SERVICE_MAIN("vpn", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_var_size(client_redirect_to_ip, GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP, struct RedirectToIpRequestMessage, NULL), GNUNET_MQ_hd_fixed_size(client_redirect_to_service, GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_SERVICE, struct RedirectToServiceRequestMessage, NULL), GNUNET_MQ_handler_end())
Define "main" method using service macro.
static void cleanup(void *cls)
Function scheduled as very last function, cleans up after us.
static void * client_connect_cb(void *cls, struct GNUNET_SERVICE_Client *c, struct GNUNET_MQ_Handle *mq)
Callback called when a client connects to the service.
static void send_client_reply(struct GNUNET_SERVICE_Client *client, uint64_t request_id, int result_af, const void *addr)
Notify the client about the result of its request.
static void handle_udp_back(void *cls, const struct GNUNET_EXIT_UdpReplyMessage *reply)
We got a UDP packet back from the CADET channel.
static struct GNUNET_CADET_Channel * create_channel(struct ChannelState *ts, const struct GNUNET_PeerIdentity *target, const struct GNUNET_HashCode *port)
Create a channel for ts to target at port.
static int check_udp_back(void *cls, const struct GNUNET_EXIT_UdpReplyMessage *reply)
We got a UDP packet back from the CADET channel.
static struct ChannelState * create_channel_to_destination(struct DestinationChannel *dt, int client_af)
Initialize the given destination entry's cadet channel.
static void handle_regex_result(void *cls, const struct GNUNET_PeerIdentity *id, const struct GNUNET_PeerIdentity *get_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *put_path, unsigned int put_path_length)
Regex has found a potential exit peer for us; consider using it.
static const char * print_channel_destination(const struct DestinationEntry *de)
Output destination of a channel for diagnostics.
static char * vpn_argv[7]
Arguments to the vpn helper.
static void free_destination_entry(struct DestinationEntry *de)
Free resources occupied by a destination entry.
static struct GNUNET_CONTAINER_Heap * channel_heap
Min-Heap sorted by activity time to expire old mappings; values are of type 'struct ChannelState'.
static unsigned long long max_destination_mappings
If there are more than this number of address-mappings, old ones will be removed.
static int allocate_v6_address(struct in6_addr *v6)
Allocate an IPv6 address from the range of the channel for a new redirection.
static int cleanup_channel(void *cls, const struct GNUNET_HashCode *key, void *value)
Free memory occupied by an entry in the channel map.
static struct GNUNET_CONTAINER_Heap * destination_heap
Min-Heap sorted by activity time to expire old mappings.
static void handle_client_redirect_to_service(void *cls, const struct RedirectToServiceRequestMessage *msg)
A client asks us to setup a redirection to a particular peer offering a service.
static struct GNUNET_CADET_Handle * cadet_handle
Handle to the cadet service.
static void handle_tcp_back(void *cls, const struct GNUNET_EXIT_TcpDataMessage *data)
We got a TCP packet back from the CADET channel.
static int message_token(void *cls, const struct GNUNET_MessageHeader *message)
Receive packets from the helper-process (someone send to the local virtual channel interface).
static unsigned long long max_channel_mappings
If there are more than this number of open channels, old ones will be removed.
static void handle_client_redirect_to_ip(void *cls, const struct RedirectToIpRequestMessage *msg)
A client asks us to setup a redirection via some exit node to a particular IP.
static void expire_destination(struct DestinationEntry *except)
We have too many active destinations.
static void channel_cleaner(void *cls, const struct GNUNET_CADET_Channel *channel)
Function called whenever a channel is destroyed.
static void expire_channel(struct ChannelState *except)
We have too many active channels.
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *c, void *internal_cls)
Callback called when a client disconnected from the service.
static void make_up_icmpv6_payload(struct ChannelState *ts, struct GNUNET_TUN_IPv6Header *ipp, struct GNUNET_TUN_UdpHeader *udp)
Synthesize a plausible ICMP payload for an ICMP error response on the given channel.
static void free_channel_state(struct ChannelState *ts)
Free resources associated with a channel state.
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg_, struct GNUNET_SERVICE_Handle *service)
Main function that will be run by the scheduler.
static void make_up_icmpv4_payload(struct ChannelState *ts, struct GNUNET_TUN_IPv4Header *ipp, struct GNUNET_TUN_UdpHeader *udp)
Synthesize a plausible ICMP payload for an ICMP error response on the given channel.
static struct GNUNET_HELPER_Handle * helper_handle
The handle to the VPN helper process "gnunet-helper-vpn".
static int allocate_v4_address(struct in_addr *v4)
Allocate an IPv4 address from the range of the channel for a new redirection.
static int check_client_redirect_to_ip(void *cls, const struct RedirectToIpRequestMessage *msg)
A client asks us to setup a redirection via some exit node to a particular IP.
static int ipv4
Option -4: IPv4 requested.
Definition: gnunet-vpn.c:60
static int udp
Option -u: UDP requested.
Definition: gnunet-vpn.c:75
static int ipv6
Option -6: IPv6 requested.
Definition: gnunet-vpn.c:65
static int tcp
Option -t: TCP requested.
Definition: gnunet-vpn.c:70
Constants for network applications operating on top of the CADET service.
CADET service; establish channels to distant peers.
commonly used definitions; globals in this file are exempt from the rule that the module name ("commo...
Constants for network protocols.
API to access regex service to advertise capabilities via regex and discover respective peers using m...
API to create, modify and access statistics.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
#define GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX
Internet exit regex prefix.
#define GNUNET_APPLICATION_PORT_IPV4_GATEWAY
Internet IPv4 gateway (any TCP/UDP/ICMP).
#define GNUNET_APPLICATION_PORT_IPV6_GATEWAY
Internet IPv6 gateway (any TCP/UDP/ICMP).
struct GNUNET_CADET_Channel * GNUNET_CADET_channel_create(struct GNUNET_CADET_Handle *h, void *channel_cls, const struct GNUNET_PeerIdentity *destination, const struct GNUNET_HashCode *port, GNUNET_CADET_WindowSizeEventHandler window_changes, GNUNET_CADET_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Create a new channel towards a remote peer.
Definition: cadet_api.c:1015
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:872
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:830
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:774
struct GNUNET_MQ_Handle * GNUNET_CADET_get_mq(const struct GNUNET_CADET_Channel *channel)
Obtain the message queue for a connected peer.
Definition: cadet_api.c:1066
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition: cadet_api.c:894
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.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
#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_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL).
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.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the 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_MULTIPLE
Allow multiple values with the same 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...
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
void GNUNET_CONTAINER_heap_update_cost(struct GNUNET_CONTAINER_HeapNode *node, GNUNET_CONTAINER_HeapCostType new_cost)
Updates the cost of any node in the tree.
struct GNUNET_CONTAINER_HeapNode * GNUNET_CONTAINER_heap_insert(struct GNUNET_CONTAINER_Heap *heap, void *element, GNUNET_CONTAINER_HeapCostType cost)
Inserts a new element into the heap.
void * GNUNET_CONTAINER_heap_peek(const struct GNUNET_CONTAINER_Heap *heap)
Get element stored at the root of heap.
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
void GNUNET_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.
@ GNUNET_CONTAINER_HEAP_ORDER_MIN
Heap with the minimum cost at the root.
struct GNUNET_HELPER_SendHandle * GNUNET_HELPER_send(struct GNUNET_HELPER_Handle *h, const struct GNUNET_MessageHeader *msg, int can_drop, GNUNET_HELPER_Continuation cont, void *cont_cls)
Send an message to the helper.
Definition: helper.c:615
struct GNUNET_HELPER_Handle * GNUNET_HELPER_start(int with_control_pipe, const char *binary_name, char *const binary_argv[], GNUNET_MessageTokenizerCallback cb, GNUNET_HELPER_ExceptionCallback exp_cb, void *cb_cls)
Starts a helper and begins reading from it.
Definition: helper.c:462
enum GNUNET_GenericReturnValue GNUNET_HELPER_wait(struct GNUNET_HELPER_Handle *h)
Reap the helper process.
Definition: helper.c:208
enum GNUNET_GenericReturnValue GNUNET_HELPER_kill(struct GNUNET_HELPER_Handle *h, int soft_kill)
Sends termination signal to the helper process.
Definition: helper.c:168
#define GNUNET_log(kind,...)
void * cls
Closure for mv and cb.
#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.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#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.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
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.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ 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_.
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_MQ_env_set_options(struct GNUNET_MQ_Envelope *env, enum GNUNET_MQ_PriorityPreferences pp)
Set application-specific options for this envelope.
Definition: mq.c:830
unsigned int GNUNET_MQ_get_length(struct GNUNET_MQ_Handle *mq)
Obtain the current length of the message queue.
Definition: mq.c:293
struct GNUNET_MQ_Envelope * GNUNET_MQ_unsent_head(struct GNUNET_MQ_Handle *mq)
Remove the first envelope that has not yet been sent from the message queue and return it.
Definition: mq.c:344
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:304
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:285
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
Definition: gnunet_mq_lib.h:63
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
@ GNUNET_MQ_PREF_OUT_OF_ORDER
Flag to indicate that out-of-order delivery is OK.
@ GNUNET_MQ_PRIO_BEST_EFFORT
Best-effort traffic (e.g.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition: network.c:80
char * GNUNET_OS_get_suid_binary_path(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *progname)
Given the name of a helper, service or daemon binary construct the full path to the binary using the ...
enum GNUNET_GenericReturnValue GNUNET_OS_check_helper_binary(const char *binary, bool check_suid, const char *params)
Check whether an executable exists and possibly if the suid bit is set on the file.
#define GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY
Type of messages containing an UDP packet from a remote host.
#define GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP
VPN service responds to client with an IP to use for the requested redirection.
#define GNUNET_MESSAGE_TYPE_VPN_HELPER
Type of messages between the gnunet-vpn-helper and the daemon.
#define GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT
Type of messages containing an TCP packet of an established connection.
#define GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE
Type of messages containing an ICMP packet for a service.
#define GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START
Type of messages containing an TCP packet for the Internet.
#define GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP
Client asks VPN service to setup an IP to redirect traffic via an exit node to some global IP address...
#define GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START
Type of messages containing an TCP packet for a service.
#define GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_SERVICE
Client asks VPN service to setup an IP to redirect traffic to some peer offering a service.
#define GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE
Type of messages containing an UDP packet for a service.
#define GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET
Type of messages containing an ICMP packet for the Internet.
#define GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN
Type of messages containing an TCP packet of an established connection.
#define GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET
Type of messages containing an UDP packet for the Internet.
#define GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN
Type of messages containing an ICMP packet for the VPN.
struct GNUNET_REGEX_Search * GNUNET_REGEX_search(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *string, GNUNET_REGEX_Found callback, void *callback_cls)
Search for a peer offering a regex matching certain string in the DHT.
void GNUNET_REGEX_search_cancel(struct GNUNET_REGEX_Search *s)
Stop search and free all data used by a GNUNET_REGEX_search call.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:562
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition: scheduler.c:1334
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2330
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2443
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2249
@ GNUNET_SERVICE_OPTION_NONE
Use defaults.
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:737
void GNUNET_TUN_initialize_ipv6_header(struct GNUNET_TUN_IPv6Header *ip, uint8_t protocol, uint16_t payload_length, const struct in6_addr *src, const struct in6_addr *dst)
Initialize an IPv6 header.
Definition: tun.c:82
void GNUNET_TUN_ipv6toregexsearch(const struct in6_addr *ipv6, uint16_t port, char *rxstr)
Create a regex in rxstr from the given ipv6 and port.
Definition: regex.c:50
void GNUNET_TUN_calculate_udp4_checksum(const struct GNUNET_TUN_IPv4Header *ip, struct GNUNET_TUN_UdpHeader *udp, const void *payload, uint16_t payload_length)
Calculate IPv4 UDP checksum.
Definition: tun.c:160
#define GNUNET_TUN_IPV4_REGEXLEN
Maximum regex string length for use with GNUNET_TUN_ipv4toregexsearch.
GNUNET_NETWORK_STRUCT_END void GNUNET_TUN_initialize_ipv4_header(struct GNUNET_TUN_IPv4Header *ip, uint8_t protocol, uint16_t payload_length, const struct in_addr *src, const struct in_addr *dst)
Initialize an IPv4 header.
Definition: tun.c:47
#define GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM
void GNUNET_TUN_calculate_icmp_checksum(struct GNUNET_TUN_IcmpHeader *icmp, const void *payload, uint16_t payload_length)
Calculate ICMP checksum.
Definition: tun.c:222
#define GNUNET_TUN_IPV6_REGEXLEN
Maximum regex string length for use with GNUNET_TUN_ipv6toregexsearch.
#define GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST
#define GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED
#define GNUNET_TUN_ICMPTYPE6_ECHO_REPLY
#define ETH_P_IPV6
Number for IPv6.
void GNUNET_TUN_compute_service_cadet_port(const struct GNUNET_HashCode *desc, uint16_t ip_port, struct GNUNET_HashCode *cadet_port)
Compute the CADET port given a service descriptor (returned from GNUNET_TUN_service_name_to_hash) and...
Definition: regex.c:791
#define ETH_P_IPV4
Number for IPv4.
#define GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED
void GNUNET_TUN_calculate_tcp6_checksum(const struct GNUNET_TUN_IPv6Header *ip, struct GNUNET_TUN_TcpHeader *tcp, const void *payload, uint16_t payload_length)
Calculate IPv6 TCP checksum.
Definition: tun.c:132
#define GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE
#define GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH
void GNUNET_TUN_calculate_tcp4_checksum(const struct GNUNET_TUN_IPv4Header *ip, struct GNUNET_TUN_TcpHeader *tcp, const void *payload, uint16_t payload_length)
Calculate IPv4 TCP checksum.
Definition: tun.c:102
void GNUNET_TUN_ipv4toregexsearch(const struct in_addr *ip, uint16_t port, char *rxstr)
Create a regex in rxstr from the given ip and port.
Definition: regex.c:37
#define GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE
#define GNUNET_TUN_ICMPTYPE_ECHO_REQUEST
#define GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG
#define GNUNET_TUN_ICMPTYPE_ECHO_REPLY
void GNUNET_TUN_calculate_udp6_checksum(const struct GNUNET_TUN_IPv6Header *ip, struct GNUNET_TUN_UdpHeader *udp, const void *payload, uint16_t payload_length)
Calculate IPv6 UDP checksum.
Definition: tun.c:191
static unsigned int size
Size of the "table".
Definition: peer.c:68
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
A messages we have in queue for a particular channel.
const void * msg
Message to transmit, allocated at the end of this struct.
struct ChannelMessageQueueEntry * prev
This is a doubly-linked list.
size_t len
Number of bytes in msg.
struct ChannelMessageQueueEntry * next
This is a doubly-linked list.
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
unsigned int tmq_length
Length of the doubly linked 'tmq_head/tmq_tail' list.
struct DestinationEntry destination
Destination to which this channel leads.
union ChannelState::@78 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
struct GNUNET_REGEX_Search * search
Active query with REGEX to locate exit.
struct ChannelMessageQueueEntry * tmq_head
Head of list of messages scheduled for transmission.
struct ChannelMessageQueueEntry * tmq_tail
Tail of list of messages scheduled for transmission.
union ChannelState::@77 source_ip
IP address of the source on our end, initially uninitialized.
int af
Address family used for this channel on the local TUN interface.
uint16_t source_port
Source port used by the sender on our end; 0 for uninitialized.
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
int is_established
Is this channel new (GNUNET_NO), or did we exchange messages with the other side already (GNUNET_YES)...
struct GNUNET_CONTAINER_HeapNode * heap_node
Heap node for this state in the connections_heap.
uint8_t protocol
IPPROTO_TCP or IPPROTO_UDP once bound.
uint16_t destination_port
Destination port used by the sender on our end; 0 for uninitialized.
struct in_addr v4
Address if af is AF_INET.
struct in6_addr v6
Address if af is AF_INET6.
List of channels we keep for each destination port for a given destination entry.
struct DestinationChannel * prev
Kept in a DLL.
uint16_t destination_port
Destination port this channel state is used for.
struct DestinationEntry * destination
Destination entry list this struct DestinationChannel belongs with.
struct DestinationChannel * next
Kept in a DLL.
Information we track for each IP address to determine which channel to send the traffic over to the d...
struct DestinationChannel * dt_head
Head of DLL of channels associated with this destination.
int af
Address family used (AF_INET or AF_INET6).
struct GNUNET_PeerIdentity target
Peer offering the service.
struct GNUNET_CONTAINER_HeapNode * heap_node
Entry for this entry in the destination_heap.
struct GNUNET_HashCode key
Key under which this entry is in the 'destination_map' (only valid if 'heap_node !...
struct DestinationEntry::@73::@74 service_destination
union DestinationEntry::@73 details
Details about the connection (depending on is_service).
struct GNUNET_HashCode service_descriptor
The description of the service (only used for service channels).
int is_service
GNUNET_NO if this is a channel to an Internet-exit, GNUNET_YES if this channel is to a service.
struct DestinationEntry::@73::@75 exit_destination
union DestinationEntry::@73::@75::@76 ip
IP address of the ultimate destination (only used for exit channels).
struct in_addr v4
Address if af is AF_INET.
struct DestinationChannel * dt_tail
Tail of DLL of channels associated with this destination.
struct in6_addr v6
Address if af is AF_INET6.
Opaque handle to a channel.
Definition: cadet.h:116
Opaque handle to the service.
Definition: cadet_api.c:39
Handle to a node in a heap.
Internal representation of the hash map.
Message send via cadet to an exit daemon to forward ICMP data to the Internet.
Definition: exit.h:237
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:249
struct GNUNET_TUN_IcmpHeader icmp_header
ICMP header to use.
Definition: exit.h:255
Message send via cadet to an exit daemon to send ICMP data to a local service.
Definition: exit.h:206
struct GNUNET_TUN_IcmpHeader icmp_header
ICMP header to use.
Definition: exit.h:223
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:218
Message send via cadet to the vpn service to send ICMP data to the VPN's TUN interface.
Definition: exit.h:272
struct GNUNET_TUN_IcmpHeader icmp_header
ICMP header to use.
Definition: exit.h:287
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:282
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN.
Definition: exit.h:276
Message send via cadet between VPN and entry and an exit daemon to transmit TCP data between the VPN ...
Definition: exit.h:95
uint32_t reserved
Always 0.
Definition: exit.h:104
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:110
Message send via cadet to an exit daemon to initiate forwarding of TCP data to the Internet.
Definition: exit.h:64
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:79
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:73
Message send via cadet to an exit daemon to initiate forwarding of TCP data to a local service.
Definition: exit.h:38
uint32_t reserved
Always 0.
Definition: exit.h:47
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:53
Message send via cadet to an exit daemon to forward UDP data to the Internet.
Definition: exit.h:146
uint16_t source_port
Source port to use for the UDP request (0 to use a random port).
Definition: exit.h:160
uint16_t destination_port
Destination port to use for the UDP request.
Definition: exit.h:165
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:155
Message send from exit daemon back to the UDP entry point (used for both Internet and Service exit re...
Definition: exit.h:179
uint16_t source_port
Source port to use for the UDP reply (0 to use the same port as for the original request).
Definition: exit.h:189
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY.
Definition: exit.h:183
uint16_t destination_port
Destination port to use for the UDP reply (0 to use the same port as for the original request).
Definition: exit.h:195
Message send via cadet to an exit daemon to send UDP data to a local service.
Definition: exit.h:121
uint16_t destination_port
Destination port to use for the UDP request.
Definition: exit.h:135
uint16_t source_port
Source port to use for the UDP request (0 to use a random port).
Definition: exit.h:130
The handle to a helper process.
Definition: helper.c:79
A 512-bit hashcode.
Handle to a message queue.
Definition: mq.c:87
Message handler for a specific message type.
Header for all communications.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
The identity of the host (wraps the signing key of the peer).
Handle to store data about a regex search.
Handle to a client that is connected to a service.
Definition: service.c:252
Handle to a service.
Definition: service.c:118
Handle for the service.
uint64_t abs_value_us
The actual value.
Standard IPv4 header.
uint8_t protocol
L4-protocol, for example, IPPROTO_UDP or IPPROTO_TCP.
struct in_addr source_address
Origin of the packet.
struct in_addr destination_address
Destination of the packet.
unsigned int header_length
Standard IPv6 header.
struct in6_addr source_address
Origin of the packet.
uint8_t next_header
For example, IPPROTO_UDP or IPPROTO_TCP.
struct in6_addr destination_address
Destination of the packet.
Header from Linux TUN interface.
uint16_t proto
Here we get an ETH_P_-number.
uint16_t flags
Some flags (unused).
TCP packet header.
UDP packet header.
Message send by the VPN client to the VPN service requesting the setup of a redirection from some IP ...
Definition: vpn.h:39
int32_t addr_af
Address family used for the destination address (AF_INET or AF_INET6, in nbo)
Definition: vpn.h:63
int32_t result_af
Address family desired for the result (AF_INET or AF_INET6 or AF_UNSPEC, in nbo)
Definition: vpn.h:58
Response from the VPN service to a VPN client informing about the IP that was assigned for the reques...
Definition: vpn.h:130
int32_t result_af
Address family of the allocated address that follows; will match "result_af" from the request,...
Definition: vpn.h:140
Message send by the VPN client to the VPN service requesting the setup of a redirection from some IP ...
Definition: vpn.h:81
IPC messages between VPN library and VPN service.