GNUnet  0.11.x
gnunet-daemon-exit.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2010-2013, 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 
37 #include "platform.h"
38 #include "gnunet_util_lib.h"
39 #include "gnunet_protocols.h"
40 #include "gnunet_applications.h"
41 #include "gnunet_dht_service.h"
42 #include "gnunet_cadet_service.h"
43 #include "gnunet_dnsparser_lib.h"
44 #include "gnunet_dnsstub_lib.h"
46 #include "gnunet_constants.h"
47 #include "gnunet_signatures.h"
48 #include "gnunet_tun_lib.h"
49 #include "gnunet_regex_service.h"
50 #include "exit.h"
51 #include "block_dns.h"
52 
53 
58 #define REGEX_MAX_PATH_LEN_IPV4 4
59 
64 #define REGEX_MAX_PATH_LEN_IPV6 8
65 
69 #define REGEX_REFRESH_FREQUENCY GNUNET_TIME_relative_multiply ( \
70  GNUNET_TIME_UNIT_MINUTES, 30)
71 
75 #define DHT_PUT_FREQUENCY GNUNET_TIME_relative_multiply ( \
76  GNUNET_TIME_UNIT_MINUTES, 15)
77 
81 #define DNS_ADVERTISEMENT_TIMEOUT GNUNET_TIME_relative_multiply ( \
82  GNUNET_TIME_UNIT_HOURS, 3)
83 
84 
88 #define LOG(kind, ...) \
89  GNUNET_log_from (kind, "exit", __VA_ARGS__);
90 
91 
96 {
100  int af;
101 
105  union
106  {
110  struct in_addr ipv4;
111 
115  struct in6_addr ipv6;
116  } address;
117 
121  uint8_t proto;
122 
126  uint16_t port;
127 };
128 
129 
136 {
141 
145  struct GNUNET_HashCode descriptor;
146 
150  char *name;
151 
156 
160  int16_t is_udp;
161 };
162 
163 
170 {
175  struct SocketAddress remote_address;
176 
182  struct SocketAddress local_address;
183 
184  /*
185  Note 1: additional information might be added here in the
186  future to support protocols that require special handling,
187  such as ftp/tftp
188 
189  Note 2: we might also sometimes not match on all components
190  of the tuple, to support protocols where things do not always
191  fully map.
192  */
193 };
194 
195 
203 {
208 
214 
220  int is_dns;
221 
222  union
223  {
224  struct
225  {
230 
234  struct GNUNET_HashCode state_key;
235 
240 
245  } tcp_udp;
246 
247  struct
248  {
254 
258  uint16_t original_id;
259 
263  uint16_t my_id;
264  } dns;
265  } specifics;
266 };
267 
268 
272 static int global_ret;
273 
278 
283 
287 static const struct GNUNET_CONFIGURATION_Handle *cfg;
288 
293 
297 static char *exit_argv[8];
298 
302 static struct in6_addr exit_ipv6addr;
303 
307 static unsigned long long ipv6prefix;
308 
312 static struct in_addr exit_ipv4addr;
313 
317 static struct in_addr exit_ipv4mask;
318 
323 
328 
334 
339 
343 static unsigned long long max_connections;
344 
349 
353 static struct ChannelState *channels[UINT16_MAX + 1];
354 
359 
364 
368 static struct GNUNET_DHT_Handle *dht;
369 
374 
380 
385 
390 
395 
400 
405 
409 static int ipv4_exit;
410 
414 static int ipv6_exit;
415 
419 static int ipv4_enabled;
420 
424 static int ipv6_enabled;
425 
426 
428 
433 {
437  struct GNUNET_MessageHeader header;
438 
443 
444  /* Followed by more DNS payload */
445 };
446 
448 
449 
458 static void
460  const struct GNUNET_TUN_DnsHeader *dns,
461  size_t r)
462 {
463  struct ChannelState *ts;
464  struct GNUNET_MQ_Envelope *env;
465  struct DnsResponseMessage *resp;
466 
468  "Processing DNS result from stub resolver\n");
469  GNUNET_assert (NULL == cls);
470  if (NULL == dns)
471  return;
472  /* Handle case that this is a reply to a request from a CADET DNS channel */
473  ts = channels[dns->id];
474  if (NULL == ts)
475  return;
477  "Got a response from the stub resolver for DNS request received via CADET!\n");
478  channels[dns->id] = NULL;
479  env = GNUNET_MQ_msg_extra (resp,
480  r - sizeof(struct GNUNET_TUN_DnsHeader),
482  GNUNET_memcpy (&resp->dns,
483  dns,
484  r);
485  resp->dns.id = ts->specifics.dns.original_id;
487  env);
488 }
489 
490 
499 static int
500 check_dns_request (void *cls,
501  const struct DnsResponseMessage *msg)
502 {
503  struct ChannelState *ts = cls;
504 
505  if (NULL == dnsstub)
506  {
507  GNUNET_break (0);
508  return GNUNET_SYSERR;
509  }
510  if (GNUNET_NO == ts->is_dns)
511  {
512  GNUNET_break_op (0);
513  return GNUNET_SYSERR;
514  }
515  return GNUNET_OK;
516 }
517 
518 
525 static void
527  const struct DnsResponseMessage *msg)
528 {
529  struct ChannelState *ts = cls;
530  size_t mlen = ntohs (msg->header.size);
531  size_t dlen = mlen - sizeof(struct GNUNET_MessageHeader);
532  char buf[dlen] GNUNET_ALIGN;
533  struct GNUNET_TUN_DnsHeader *dout;
534 
535  if (GNUNET_SYSERR == ts->is_dns)
536  {
537  /* channel is DNS from now on */
538  ts->is_dns = GNUNET_YES;
539  }
540  ts->specifics.dns.original_id = msg->dns.id;
541  if (channels[ts->specifics.dns.my_id] == ts)
542  channels[ts->specifics.dns.my_id] = NULL;
543  ts->specifics.dns.my_id = (uint16_t) GNUNET_CRYPTO_random_u32 (
545  UINT16_MAX
546  + 1);
547  channels[ts->specifics.dns.my_id] = ts;
549  &msg->dns,
550  dlen);
551  dout = (struct GNUNET_TUN_DnsHeader *) buf;
552  dout->id = ts->specifics.dns.my_id;
553  ts->specifics.dns.rs = GNUNET_DNSSTUB_resolve (dnsstub,
554  buf,
555  dlen,
557  NULL);
558  if (NULL == ts->specifics.dns.rs)
559  {
560  GNUNET_break_op (0);
561  return;
562  }
564 }
565 
566 
574 static void
576  const struct RedirectInformation *ri)
577 {
578  char *off;
579 
580  memset (hash,
581  0,
582  sizeof(struct GNUNET_HashCode));
583  /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
584  so we put the IP address in there (and hope for few collisions) */
585  off = (char *) hash;
586  switch (ri->remote_address.af)
587  {
588  case AF_INET:
589  GNUNET_memcpy (off,
591  sizeof(struct in_addr));
592  off += sizeof(struct in_addr);
593  break;
594 
595  case AF_INET6:
596  GNUNET_memcpy (off,
598  sizeof(struct in6_addr));
599  off += sizeof(struct in_addr);
600  break;
601 
602  default:
603  GNUNET_assert (0);
604  }
605  GNUNET_memcpy (off,
606  &ri->remote_address.port,
607  sizeof(uint16_t));
608  off += sizeof(uint16_t);
609  switch (ri->local_address.af)
610  {
611  case AF_INET:
612  GNUNET_memcpy (off,
614  sizeof(struct in_addr));
615  off += sizeof(struct in_addr);
616  break;
617 
618  case AF_INET6:
619  GNUNET_memcpy (off,
621  sizeof(struct in6_addr));
622  off += sizeof(struct in_addr);
623  break;
624 
625  default:
626  GNUNET_assert (0);
627  }
628  GNUNET_memcpy (off,
629  &ri->local_address.port,
630  sizeof(uint16_t));
631  off += sizeof(uint16_t);
632  GNUNET_memcpy (off,
633  &ri->remote_address.proto,
634  sizeof(uint8_t));
635  /* off += sizeof (uint8_t); */
636 }
637 
638 
652 static struct ChannelState *
654  int protocol,
655  const void *destination_ip,
656  uint16_t destination_port,
657  const void *local_ip,
658  uint16_t local_port,
659  struct GNUNET_HashCode *state_key)
660 {
661  struct RedirectInformation ri;
662  struct GNUNET_HashCode key;
663  struct ChannelState *state;
664 
665  if (((af == AF_INET) && (protocol == IPPROTO_ICMP)) ||
666  ((af == AF_INET6) && (protocol == IPPROTO_ICMPV6)))
667  {
668  /* ignore ports */
669  destination_port = 0;
670  local_port = 0;
671  }
672  ri.remote_address.af = af;
673  if (af == AF_INET)
674  ri.remote_address.address.ipv4 = *((struct in_addr*) destination_ip);
675  else
676  ri.remote_address.address.ipv6 = *((struct in6_addr*) destination_ip);
677  ri.remote_address.port = destination_port;
678  ri.remote_address.proto = protocol;
679  ri.local_address.af = af;
680  if (af == AF_INET)
681  ri.local_address.address.ipv4 = *((struct in_addr*) local_ip);
682  else
683  ri.local_address.address.ipv6 = *((struct in6_addr*) local_ip);
684  ri.local_address.port = local_port;
685  ri.local_address.proto = protocol;
686  hash_redirect_info (&key,
687  &ri);
688  if (NULL != state_key)
689  *state_key = key;
690  state = GNUNET_CONTAINER_multihashmap_get (connections_map,
691  &key);
692  if (NULL == state)
693  return NULL;
694  /* Mark this connection as freshly used */
695  if (NULL == state_key)
697  GNUNET_TIME_absolute_get ().abs_value_us);
698  return state;
699 }
700 
701 
711 static int
712 check_tcp_service (void *cls,
714 {
715  struct ChannelState *state = cls;
716 
717  if (NULL == state)
718  {
719  GNUNET_break_op (0);
720  return GNUNET_SYSERR;
721  }
722  if (GNUNET_YES == state->is_dns)
723  {
724  GNUNET_break_op (0);
725  return GNUNET_SYSERR;
726  }
727  if (NULL == state->specifics.tcp_udp.serv)
728  {
729  GNUNET_break_op (0);
730  return GNUNET_SYSERR;
731  }
732  if (NULL != state->specifics.tcp_udp.heap_node)
733  {
734  GNUNET_break_op (0);
735  return GNUNET_SYSERR;
736  }
737  if (start->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
738  {
739  GNUNET_break_op (0);
740  return GNUNET_SYSERR;
741  }
742  return GNUNET_OK;
743 }
744 
745 
764 static void
766  size_t payload_length,
767  int protocol,
768  const struct GNUNET_TUN_TcpHeader *tcp_header,
769  const struct SocketAddress *src_address,
770  const struct SocketAddress *dst_address,
771  struct GNUNET_TUN_IPv4Header *pkt4)
772 {
773  size_t len;
774 
775  len = payload_length;
776  switch (protocol)
777  {
778  case IPPROTO_UDP:
779  len += sizeof(struct GNUNET_TUN_UdpHeader);
780  break;
781 
782  case IPPROTO_TCP:
783  len += sizeof(struct GNUNET_TUN_TcpHeader);
784  GNUNET_assert (NULL != tcp_header);
785  break;
786 
787  default:
788  GNUNET_break (0);
789  return;
790  }
791  if (len + sizeof(struct GNUNET_TUN_IPv4Header) > UINT16_MAX)
792  {
793  GNUNET_break (0);
794  return;
795  }
796 
798  protocol,
799  len,
800  &src_address->address.ipv4,
801  &dst_address->address.ipv4);
802  switch (protocol)
803  {
804  case IPPROTO_UDP:
805  {
806  struct GNUNET_TUN_UdpHeader *pkt4_udp = (struct
807  GNUNET_TUN_UdpHeader *) &pkt4[1];
808 
809  pkt4_udp->source_port = htons (src_address->port);
810  pkt4_udp->destination_port = htons (dst_address->port);
811  pkt4_udp->len = htons ((uint16_t) payload_length);
813  pkt4_udp,
814  payload,
815  payload_length);
816  GNUNET_memcpy (&pkt4_udp[1],
817  payload,
818  payload_length);
819  }
820  break;
821 
822  case IPPROTO_TCP:
823  {
824  struct GNUNET_TUN_TcpHeader *pkt4_tcp = (struct
825  GNUNET_TUN_TcpHeader *) &pkt4[1];
826 
827  *pkt4_tcp = *tcp_header;
829  "Sending TCP packet from port %u to port %u\n",
830  src_address->port,
831  dst_address->port);
832  pkt4_tcp->source_port = htons (src_address->port);
833  pkt4_tcp->destination_port = htons (dst_address->port);
835  pkt4_tcp,
836  payload,
837  payload_length);
838  GNUNET_memcpy (&pkt4_tcp[1],
839  payload,
840  payload_length);
841  }
842  break;
843 
844  default:
845  GNUNET_assert (0);
846  }
847 }
848 
849 
868 static void
870  size_t payload_length,
871  int protocol,
872  const struct GNUNET_TUN_TcpHeader *tcp_header,
873  const struct SocketAddress *src_address,
874  const struct SocketAddress *dst_address,
875  struct GNUNET_TUN_IPv6Header *pkt6)
876 {
877  size_t len;
878 
879  len = payload_length;
880  switch (protocol)
881  {
882  case IPPROTO_UDP:
883  len += sizeof(struct GNUNET_TUN_UdpHeader);
884  break;
885 
886  case IPPROTO_TCP:
887  len += sizeof(struct GNUNET_TUN_TcpHeader);
888  break;
889 
890  default:
891  GNUNET_break (0);
892  return;
893  }
894  if (len > UINT16_MAX)
895  {
896  GNUNET_break (0);
897  return;
898  }
899 
901  protocol,
902  len,
903  &src_address->address.ipv6,
904  &dst_address->address.ipv6);
905 
906  switch (protocol)
907  {
908  case IPPROTO_UDP:
909  {
910  struct GNUNET_TUN_UdpHeader *pkt6_udp = (struct
911  GNUNET_TUN_UdpHeader *) &pkt6[1];
912 
913  pkt6_udp->source_port = htons (src_address->port);
914  pkt6_udp->destination_port = htons (dst_address->port);
915  pkt6_udp->len = htons ((uint16_t) payload_length);
917  pkt6_udp,
918  payload,
919  payload_length);
920  GNUNET_memcpy (&pkt6_udp[1],
921  payload,
922  payload_length);
923  }
924  break;
925 
926  case IPPROTO_TCP:
927  {
928  struct GNUNET_TUN_TcpHeader *pkt6_tcp = (struct
929  GNUNET_TUN_TcpHeader *) &pkt6[1];
930 
931  /* GNUNET_memcpy first here as some TCP header fields are initialized this way! */
932  *pkt6_tcp = *tcp_header;
933  pkt6_tcp->source_port = htons (src_address->port);
934  pkt6_tcp->destination_port = htons (dst_address->port);
936  pkt6_tcp,
937  payload,
938  payload_length);
939  GNUNET_memcpy (&pkt6_tcp[1],
940  payload,
941  payload_length);
942  }
943  break;
944 
945  default:
946  GNUNET_assert (0);
947  break;
948  }
949 }
950 
951 
961 static void
962 send_tcp_packet_via_tun (const struct SocketAddress *destination_address,
963  const struct SocketAddress *source_address,
964  const struct GNUNET_TUN_TcpHeader *tcp_header,
965  const void *payload,
966  size_t payload_length)
967 {
968  size_t len;
969 
971  gettext_noop ("# TCP packets sent via TUN"),
972  1,
973  GNUNET_NO);
975  "Sending packet with %u bytes TCP payload via TUN\n",
976  (unsigned int) payload_length);
977  len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct
978  GNUNET_TUN_Layer2PacketHeader);
979  switch (source_address->af)
980  {
981  case AF_INET:
982  len += sizeof(struct GNUNET_TUN_IPv4Header);
983  break;
984 
985  case AF_INET6:
986  len += sizeof(struct GNUNET_TUN_IPv6Header);
987  break;
988 
989  default:
990  GNUNET_break (0);
991  return;
992  }
993  len += sizeof(struct GNUNET_TUN_TcpHeader);
994  len += payload_length;
995  if (len >= GNUNET_MAX_MESSAGE_SIZE)
996  {
997  GNUNET_break (0);
998  return;
999  }
1000  {
1001  char buf[len] GNUNET_ALIGN;
1002  struct GNUNET_MessageHeader *hdr;
1003  struct GNUNET_TUN_Layer2PacketHeader *tun;
1004 
1005  hdr = (struct GNUNET_MessageHeader *) buf;
1006  hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1007  hdr->size = htons (len);
1008  tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1009  tun->flags = htons (0);
1010  switch (source_address->af)
1011  {
1012  case AF_INET:
1013  {
1014  struct GNUNET_TUN_IPv4Header *ipv4
1015  = (struct GNUNET_TUN_IPv4Header*) &tun[1];
1016 
1017  tun->proto = htons (ETH_P_IPV4);
1018  prepare_ipv4_packet (payload,
1019  payload_length,
1020  IPPROTO_TCP,
1021  tcp_header,
1022  source_address,
1023  destination_address,
1024  ipv4);
1025  }
1026  break;
1027 
1028  case AF_INET6:
1029  {
1030  struct GNUNET_TUN_IPv6Header *ipv6
1031  = (struct GNUNET_TUN_IPv6Header*) &tun[1];
1032 
1033  tun->proto = htons (ETH_P_IPV6);
1034  prepare_ipv6_packet (payload,
1035  payload_length,
1036  IPPROTO_TCP,
1037  tcp_header,
1038  source_address,
1039  destination_address,
1040  ipv6);
1041  }
1042  break;
1043 
1044  default:
1045  GNUNET_assert (0);
1046  break;
1047  }
1048  if (NULL != helper_handle)
1049  (void) GNUNET_HELPER_send (helper_handle,
1050  (const struct GNUNET_MessageHeader*) buf,
1051  GNUNET_YES,
1052  NULL,
1053  NULL);
1054  }
1055 }
1056 
1057 
1067 static void
1069  const struct SocketAddress *source_address,
1070  const struct GNUNET_TUN_IcmpHeader *icmp_header,
1071  const void *payload, size_t payload_length)
1072 {
1073  size_t len;
1074  struct GNUNET_TUN_IcmpHeader *icmp;
1075 
1076  GNUNET_STATISTICS_update (stats,
1077  gettext_noop ("# ICMP packets sent via TUN"),
1078  1, GNUNET_NO);
1080  "Sending packet with %u bytes ICMP payload via TUN\n",
1081  (unsigned int) payload_length);
1082  len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct
1083  GNUNET_TUN_Layer2PacketHeader);
1084  switch (destination_address->af)
1085  {
1086  case AF_INET:
1087  len += sizeof(struct GNUNET_TUN_IPv4Header);
1088  break;
1089 
1090  case AF_INET6:
1091  len += sizeof(struct GNUNET_TUN_IPv6Header);
1092  break;
1093 
1094  default:
1095  GNUNET_break (0);
1096  return;
1097  }
1098  len += sizeof(struct GNUNET_TUN_IcmpHeader);
1099  len += payload_length;
1100  if (len >= GNUNET_MAX_MESSAGE_SIZE)
1101  {
1102  GNUNET_break (0);
1103  return;
1104  }
1105  {
1106  char buf[len] GNUNET_ALIGN;
1107  struct GNUNET_MessageHeader *hdr;
1108  struct GNUNET_TUN_Layer2PacketHeader *tun;
1109 
1110  hdr = (struct GNUNET_MessageHeader *) buf;
1111  hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1112  hdr->size = htons (len);
1113  tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1114  tun->flags = htons (0);
1115  switch (source_address->af)
1116  {
1117  case AF_INET:
1118  {
1119  struct GNUNET_TUN_IPv4Header *ipv4 = (struct
1120  GNUNET_TUN_IPv4Header*) &tun[1];
1121 
1122  tun->proto = htons (ETH_P_IPV4);
1124  IPPROTO_ICMP,
1125  sizeof(struct
1127  + payload_length,
1128  &source_address->address.ipv4,
1129  &destination_address->address.ipv4);
1130  icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv4[1];
1131  }
1132  break;
1133 
1134  case AF_INET6:
1135  {
1136  struct GNUNET_TUN_IPv6Header *ipv6 = (struct
1137  GNUNET_TUN_IPv6Header*) &tun[1];
1138 
1139  tun->proto = htons (ETH_P_IPV6);
1141  IPPROTO_ICMPV6,
1142  sizeof(struct
1144  + payload_length,
1145  &source_address->address.ipv6,
1146  &destination_address->address.ipv6);
1147  icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv6[1];
1148  }
1149  break;
1150 
1151  default:
1152  GNUNET_assert (0);
1153  break;
1154  }
1155  *icmp = *icmp_header;
1156  GNUNET_memcpy (&icmp[1],
1157  payload,
1158  payload_length);
1160  payload,
1161  payload_length);
1162  if (NULL != helper_handle)
1163  (void) GNUNET_HELPER_send (helper_handle,
1164  (const struct GNUNET_MessageHeader*) buf,
1165  GNUNET_YES,
1166  NULL, NULL);
1167  }
1168 }
1169 
1170 
1179 static void
1181  uint8_t proto,
1182  struct SocketAddress *local_address)
1183 {
1184  local_address->af = af;
1185  local_address->proto = (uint8_t) proto;
1186  /* default "local" port range is often 32768--61000,
1187  so we pick a random value in that range */
1188  if (((af == AF_INET) && (proto == IPPROTO_ICMP)) ||
1189  ((af == AF_INET6) && (proto == IPPROTO_ICMPV6)))
1190  local_address->port = 0;
1191  else
1192  local_address->port
1194  28232);
1195  switch (af)
1196  {
1197  case AF_INET:
1198  {
1199  struct in_addr addr;
1200  struct in_addr mask;
1201  struct in_addr rnd;
1202 
1203  addr = exit_ipv4addr;
1204  mask = exit_ipv4mask;
1205  if (0 == ~mask.s_addr)
1206  {
1207  /* only one valid IP anyway */
1208  local_address->address.ipv4 = addr;
1209  return;
1210  }
1211  /* Given 192.168.0.1/255.255.0.0, we want a mask
1212  of '192.168.255.255', thus: */
1213  mask.s_addr = addr.s_addr | ~mask.s_addr;
1214  /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
1215  do
1216  {
1218  UINT32_MAX);
1219  local_address->address.ipv4.s_addr = (addr.s_addr | rnd.s_addr)
1220  & mask.s_addr;
1221  }
1222  while ((local_address->address.ipv4.s_addr == addr.s_addr) ||
1223  (local_address->address.ipv4.s_addr == mask.s_addr));
1224  }
1225  break;
1226 
1227  case AF_INET6:
1228  {
1229  struct in6_addr addr;
1230  struct in6_addr mask;
1231  struct in6_addr rnd;
1232  int i;
1233 
1234  addr = exit_ipv6addr;
1235  GNUNET_assert (ipv6prefix < 128);
1236  if (ipv6prefix == 127)
1237  {
1238  /* only one valid IP anyway */
1239  local_address->address.ipv6 = addr;
1240  return;
1241  }
1242  /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
1243  thus: */
1244  mask = addr;
1245  for (i = 127; i >= ipv6prefix; i--)
1246  mask.s6_addr[i / 8] |= (1 << (i % 8));
1247 
1248  /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */
1249  do
1250  {
1251  for (i = 0; i < 16; i++)
1252  {
1253  rnd.s6_addr[i] = (unsigned char) GNUNET_CRYPTO_random_u32 (
1255  256);
1256  local_address->address.ipv6.s6_addr[i]
1257  = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
1258  }
1259  }
1260  while ((0 == GNUNET_memcmp (&local_address->address.ipv6,
1261  &addr)) ||
1262  (0 == GNUNET_memcmp (&local_address->address.ipv6,
1263  &mask)));
1264  }
1265  break;
1266 
1267  default:
1268  GNUNET_assert (0);
1269  }
1270 }
1271 
1272 
1294 static void
1296 {
1297  struct GNUNET_HashCode key;
1298  struct ChannelState *s;
1299 
1300  /* generate fresh, unique address */
1301  do
1302  {
1303  if (NULL == state->specifics.tcp_udp.serv)
1304  setup_fresh_address (state->specifics.tcp_udp.ri.remote_address.af,
1305  state->specifics.tcp_udp.ri.remote_address.proto,
1306  &state->specifics.tcp_udp.ri.local_address);
1307  else
1308  setup_fresh_address (state->specifics.tcp_udp.serv->address.af,
1309  state->specifics.tcp_udp.serv->address.proto,
1310  &state->specifics.tcp_udp.ri.local_address);
1311  }
1312  while (NULL !=
1313  get_redirect_state (state->specifics.tcp_udp.ri.remote_address.af,
1314  state->specifics.tcp_udp.ri.remote_address.proto,
1315  &state->specifics.tcp_udp.ri.remote_address.address,
1316  state->specifics.tcp_udp.ri.remote_address.port,
1317  &state->specifics.tcp_udp.ri.local_address.address,
1318  state->specifics.tcp_udp.ri.local_address.port,
1319  &key));
1320  {
1321  char buf[INET6_ADDRSTRLEN];
1323  "Picked local address %s:%u for new connection\n",
1324  inet_ntop (state->specifics.tcp_udp.ri.local_address.af,
1325  &state->specifics.tcp_udp.ri.local_address.address,
1326  buf,
1327  sizeof(buf)),
1328  (unsigned int) state->specifics.tcp_udp.ri.local_address.port);
1329  }
1330  state->specifics.tcp_udp.state_key = key;
1332  GNUNET_CONTAINER_multihashmap_put (connections_map,
1333  &key, state,
1335  state->specifics.tcp_udp.heap_node
1336  = GNUNET_CONTAINER_heap_insert (connections_heap,
1337  state,
1338  GNUNET_TIME_absolute_get ().abs_value_us);
1339  while (GNUNET_CONTAINER_heap_get_size (connections_heap) > max_connections)
1340  {
1341  s = GNUNET_CONTAINER_heap_remove_root (connections_heap);
1342  GNUNET_assert (state != s);
1343  s->specifics.tcp_udp.heap_node = NULL;
1346  GNUNET_CONTAINER_multihashmap_remove (connections_map,
1347  &s->specifics.tcp_udp.
1348  state_key,
1349  s));
1350  GNUNET_free (s);
1351  }
1352 }
1353 
1354 
1363 static void
1364 send_udp_packet_via_tun (const struct SocketAddress *destination_address,
1365  const struct SocketAddress *source_address,
1366  const void *payload, size_t payload_length)
1367 {
1368  size_t len;
1369 
1370  GNUNET_STATISTICS_update (stats,
1371  gettext_noop ("# UDP packets sent via TUN"),
1372  1, GNUNET_NO);
1374  "Sending packet with %u bytes UDP payload via TUN\n",
1375  (unsigned int) payload_length);
1376  len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct
1377  GNUNET_TUN_Layer2PacketHeader);
1378  switch (source_address->af)
1379  {
1380  case AF_INET:
1381  len += sizeof(struct GNUNET_TUN_IPv4Header);
1382  break;
1383 
1384  case AF_INET6:
1385  len += sizeof(struct GNUNET_TUN_IPv6Header);
1386  break;
1387 
1388  default:
1389  GNUNET_break (0);
1390  return;
1391  }
1392  len += sizeof(struct GNUNET_TUN_UdpHeader);
1393  len += payload_length;
1394  if (len >= GNUNET_MAX_MESSAGE_SIZE)
1395  {
1396  GNUNET_break (0);
1397  return;
1398  }
1399  {
1400  char buf[len] GNUNET_ALIGN;
1401  struct GNUNET_MessageHeader *hdr;
1402  struct GNUNET_TUN_Layer2PacketHeader *tun;
1403 
1404  hdr = (struct GNUNET_MessageHeader *) buf;
1405  hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1406  hdr->size = htons (len);
1407  tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1408  tun->flags = htons (0);
1409  switch (source_address->af)
1410  {
1411  case AF_INET:
1412  {
1413  struct GNUNET_TUN_IPv4Header *ipv4 = (struct
1414  GNUNET_TUN_IPv4Header*) &tun[1];
1415 
1416  tun->proto = htons (ETH_P_IPV4);
1417  prepare_ipv4_packet (payload,
1418  payload_length,
1419  IPPROTO_UDP,
1420  NULL,
1421  source_address,
1422  destination_address,
1423  ipv4);
1424  }
1425  break;
1426 
1427  case AF_INET6:
1428  {
1429  struct GNUNET_TUN_IPv6Header *ipv6 = (struct
1430  GNUNET_TUN_IPv6Header*) &tun[1];
1431 
1432  tun->proto = htons (ETH_P_IPV6);
1433  prepare_ipv6_packet (payload,
1434  payload_length,
1435  IPPROTO_UDP,
1436  NULL,
1437  source_address,
1438  destination_address,
1439  ipv6);
1440  }
1441  break;
1442 
1443  default:
1444  GNUNET_assert (0);
1445  break;
1446  }
1447  if (NULL != helper_handle)
1448  (void) GNUNET_HELPER_send (helper_handle,
1449  (const struct GNUNET_MessageHeader*) buf,
1450  GNUNET_YES,
1451  NULL, NULL);
1452  }
1453 }
1454 
1455 
1464 static int
1465 check_udp_remote (void *cls,
1466  const struct GNUNET_EXIT_UdpInternetMessage *msg)
1467 {
1468  struct ChannelState *state = cls;
1469 
1470  if (GNUNET_YES == state->is_dns)
1471  {
1472  GNUNET_break_op (0);
1473  return GNUNET_SYSERR;
1474  }
1475  return GNUNET_OK;
1476 }
1477 
1478 
1485 static void
1487  const struct GNUNET_EXIT_UdpInternetMessage *msg)
1488 {
1489  struct ChannelState *state = cls;
1490  uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
1492  const struct in_addr *v4;
1493  const struct in6_addr *v6;
1494  const void *payload;
1495  int af;
1496 
1497  if (GNUNET_SYSERR == state->is_dns)
1498  {
1499  /* channel is UDP/TCP from now on */
1500  state->is_dns = GNUNET_NO;
1501  }
1502  GNUNET_STATISTICS_update (stats,
1503  gettext_noop ("# Bytes received from CADET"),
1504  pkt_len, GNUNET_NO);
1505  GNUNET_STATISTICS_update (stats,
1506  gettext_noop (
1507  "# UDP IP-exit requests received via cadet"),
1508  1, GNUNET_NO);
1509  af = (int) ntohl (msg->af);
1510  state->specifics.tcp_udp.ri.remote_address.af = af;
1511  switch (af)
1512  {
1513  case AF_INET:
1514  if (pkt_len < sizeof(struct in_addr))
1515  {
1516  GNUNET_break_op (0);
1517  return;
1518  }
1519  if (! ipv4_exit)
1520  {
1521  GNUNET_break_op (0);
1522  return;
1523  }
1524  v4 = (const struct in_addr*) &msg[1];
1525  payload = &v4[1];
1526  pkt_len -= sizeof(struct in_addr);
1527  state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
1528  break;
1529 
1530  case AF_INET6:
1531  if (pkt_len < sizeof(struct in6_addr))
1532  {
1533  GNUNET_break_op (0);
1534  return;
1535  }
1536  if (! ipv6_exit)
1537  {
1538  GNUNET_break_op (0);
1539  return;
1540  }
1541  v6 = (const struct in6_addr*) &msg[1];
1542  payload = &v6[1];
1543  pkt_len -= sizeof(struct in6_addr);
1544  state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
1545  break;
1546 
1547  default:
1548  GNUNET_break_op (0);
1549  return;
1550  }
1551  {
1552  char buf[INET6_ADDRSTRLEN];
1554  "Received data from %s for forwarding to UDP %s:%u\n",
1555  GNUNET_i2s (&state->peer),
1556  inet_ntop (af,
1557  &state->specifics.tcp_udp.ri.remote_address.address,
1558  buf, sizeof(buf)),
1559  (unsigned int) ntohs (msg->destination_port));
1560  }
1561  state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_UDP;
1562  state->specifics.tcp_udp.ri.remote_address.port = msg->destination_port;
1563  if (NULL == state->specifics.tcp_udp.heap_node)
1564  setup_state_record (state);
1565  if (0 != ntohs (msg->source_port))
1566  state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
1567  send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1568  &state->specifics.tcp_udp.ri.local_address,
1569  payload,
1570  pkt_len);
1572 }
1573 
1574 
1584 static int
1586  const struct GNUNET_EXIT_UdpServiceMessage *msg)
1587 {
1588  struct ChannelState *state = cls;
1589 
1590  if (NULL == state->specifics.tcp_udp.serv)
1591  {
1592  GNUNET_break_op (0);
1593  return GNUNET_SYSERR;
1594  }
1595  return GNUNET_OK;
1596 }
1597 
1598 
1606 static void
1608  const struct GNUNET_EXIT_UdpServiceMessage *msg)
1609 {
1610  struct ChannelState *state = cls;
1611  uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
1613 
1614  GNUNET_STATISTICS_update (stats,
1615  gettext_noop ("# Bytes received from CADET"),
1616  pkt_len, GNUNET_NO);
1617  GNUNET_STATISTICS_update (stats,
1618  gettext_noop (
1619  "# UDP service requests received via cadet"),
1620  1, GNUNET_NO);
1622  "Received data from %s for forwarding to UDP service %s on port %u\n",
1623  GNUNET_i2s (&state->peer),
1624  GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor),
1625  (unsigned int) ntohs (msg->destination_port));
1626  setup_state_record (state);
1627  if (0 != ntohs (msg->source_port))
1628  state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
1629  send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1630  &state->specifics.tcp_udp.ri.local_address,
1631  &msg[1],
1632  pkt_len);
1634 }
1635 
1636 
1646 static void
1649 {
1650  struct ChannelState *state = cls;
1651  uint16_t pkt_len = ntohs (start->header.size) - sizeof(struct
1653 
1654  if (GNUNET_SYSERR == state->is_dns)
1655  {
1656  /* channel is UDP/TCP from now on */
1657  state->is_dns = GNUNET_NO;
1658  }
1659  GNUNET_STATISTICS_update (stats,
1660  gettext_noop (
1661  "# TCP service creation requests received via cadet"),
1662  1,
1663  GNUNET_NO);
1664  GNUNET_STATISTICS_update (stats,
1665  gettext_noop ("# Bytes received from CADET"),
1666  pkt_len,
1667  GNUNET_NO);
1668  GNUNET_break_op (ntohl (start->reserved) == 0);
1669  /* setup fresh connection */
1671  "Received data from %s for forwarding to TCP service %s on port %u\n",
1672  GNUNET_i2s (&state->peer),
1673  GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor),
1674  (unsigned int) ntohs (start->tcp_header.destination_port));
1675  setup_state_record (state);
1676  send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1677  &state->specifics.tcp_udp.ri.local_address,
1678  &start->tcp_header,
1679  &start[1],
1680  pkt_len);
1682 }
1683 
1684 
1693 static int
1694 check_tcp_remote (void *cls,
1696 {
1697  struct ChannelState *state = cls;
1698 
1699  if (NULL == state)
1700  {
1701  GNUNET_break_op (0);
1702  return GNUNET_SYSERR;
1703  }
1704  if (GNUNET_YES == state->is_dns)
1705  {
1706  GNUNET_break_op (0);
1707  return GNUNET_SYSERR;
1708  }
1709  if ((NULL != state->specifics.tcp_udp.serv) ||
1710  (NULL != state->specifics.tcp_udp.heap_node))
1711  {
1712  GNUNET_break_op (0);
1713  return GNUNET_SYSERR;
1714  }
1715  if (start->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1716  {
1717  GNUNET_break_op (0);
1718  return GNUNET_SYSERR;
1719  }
1720  return GNUNET_OK;
1721 }
1722 
1723 
1730 static void
1733 {
1734  struct ChannelState *state = cls;
1735  uint16_t pkt_len = ntohs (start->header.size) - sizeof(struct
1737  const struct in_addr *v4;
1738  const struct in6_addr *v6;
1739  const void *payload;
1740  int af;
1741 
1742  if (GNUNET_SYSERR == state->is_dns)
1743  {
1744  /* channel is UDP/TCP from now on */
1745  state->is_dns = GNUNET_NO;
1746  }
1747  GNUNET_STATISTICS_update (stats,
1748  gettext_noop ("# Bytes received from CADET"),
1749  pkt_len, GNUNET_NO);
1750  GNUNET_STATISTICS_update (stats,
1751  gettext_noop (
1752  "# TCP IP-exit creation requests received via cadet"),
1753  1, GNUNET_NO);
1754  af = (int) ntohl (start->af);
1755  state->specifics.tcp_udp.ri.remote_address.af = af;
1756  switch (af)
1757  {
1758  case AF_INET:
1759  if (pkt_len < sizeof(struct in_addr))
1760  {
1761  GNUNET_break_op (0);
1762  return;
1763  }
1764  if (! ipv4_exit)
1765  {
1766  GNUNET_break_op (0);
1767  return;
1768  }
1769  v4 = (const struct in_addr*) &start[1];
1770  payload = &v4[1];
1771  pkt_len -= sizeof(struct in_addr);
1772  state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
1773  break;
1774 
1775  case AF_INET6:
1776  if (pkt_len < sizeof(struct in6_addr))
1777  {
1778  GNUNET_break_op (0);
1779  return;
1780  }
1781  if (! ipv6_exit)
1782  {
1783  GNUNET_break_op (0);
1784  return;
1785  }
1786  v6 = (const struct in6_addr*) &start[1];
1787  payload = &v6[1];
1788  pkt_len -= sizeof(struct in6_addr);
1789  state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
1790  break;
1791 
1792  default:
1793  GNUNET_break_op (0);
1794  return;
1795  }
1796  {
1797  char buf[INET6_ADDRSTRLEN];
1799  "Received payload from %s for existing TCP stream to %s:%u\n",
1800  GNUNET_i2s (&state->peer),
1801  inet_ntop (af,
1802  &state->specifics.tcp_udp.ri.remote_address.address,
1803  buf, sizeof(buf)),
1804  (unsigned int) ntohs (start->tcp_header.destination_port));
1805  }
1806  state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_TCP;
1807  state->specifics.tcp_udp.ri.remote_address.port = ntohs (
1808  start->tcp_header.destination_port);
1809  setup_state_record (state);
1810  send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1811  &state->specifics.tcp_udp.ri.local_address,
1812  &start->tcp_header,
1813  payload,
1814  pkt_len);
1816 }
1817 
1818 
1828 static int
1829 check_tcp_data (void *cls,
1830  const struct GNUNET_EXIT_TcpDataMessage *data)
1831 {
1832  struct ChannelState *state = cls;
1833 
1834  if ((NULL == state) ||
1835  (NULL == state->specifics.tcp_udp.heap_node))
1836  {
1837  /* connection should have been up! */
1838  GNUNET_STATISTICS_update (stats,
1839  gettext_noop (
1840  "# TCP DATA requests dropped (no session)"),
1841  1, GNUNET_NO);
1842  GNUNET_break_op (0);
1843  return GNUNET_SYSERR;
1844  }
1845  if (data->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1846  {
1847  GNUNET_break_op (0);
1848  return GNUNET_SYSERR;
1849  }
1850  if (GNUNET_YES == state->is_dns)
1851  {
1852  GNUNET_break_op (0);
1853  return GNUNET_SYSERR;
1854  }
1855  return GNUNET_OK;
1856 }
1857 
1858 
1866 static void
1867 handle_tcp_data (void *cls,
1868  const struct GNUNET_EXIT_TcpDataMessage *data)
1869 {
1870  struct ChannelState *state = cls;
1871  uint16_t pkt_len = ntohs (data->header.size) - sizeof(struct
1873 
1874  GNUNET_STATISTICS_update (stats,
1875  gettext_noop ("# Bytes received from CADET"),
1876  pkt_len, GNUNET_NO);
1877  GNUNET_STATISTICS_update (stats,
1878  gettext_noop (
1879  "# TCP data requests received via cadet"),
1880  1, GNUNET_NO);
1881  if (GNUNET_SYSERR == state->is_dns)
1882  {
1883  /* channel is UDP/TCP from now on */
1884  state->is_dns = GNUNET_NO;
1885  }
1886 
1887  GNUNET_break_op (ntohl (data->reserved) == 0);
1888  {
1889  char buf[INET6_ADDRSTRLEN];
1891  "Received additional %u bytes of data from %s for TCP stream to %s:%u\n",
1892  pkt_len,
1893  GNUNET_i2s (&state->peer),
1894  inet_ntop (state->specifics.tcp_udp.ri.remote_address.af,
1895  &state->specifics.tcp_udp.ri.remote_address.address,
1896  buf, sizeof(buf)),
1897  (unsigned int) state->specifics.tcp_udp.ri.remote_address.port);
1898  }
1899 
1900  send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1901  &state->specifics.tcp_udp.ri.local_address,
1902  &data->tcp_header,
1903  &data[1], pkt_len);
1905 }
1906 
1907 
1917 static void
1919  struct GNUNET_TUN_IPv4Header *ipp,
1920  struct GNUNET_TUN_UdpHeader *udp)
1921 {
1923  state->specifics.tcp_udp.ri.remote_address.
1924  proto,
1925  sizeof(struct GNUNET_TUN_TcpHeader),
1926  &state->specifics.tcp_udp.ri.remote_address
1927  .address.ipv4,
1928  &state->specifics.tcp_udp.ri.local_address.
1929  address.ipv4);
1930  udp->source_port = htons (state->specifics.tcp_udp.ri.remote_address.port);
1931  udp->destination_port = htons (
1932  state->specifics.tcp_udp.ri.local_address.port);
1933  udp->len = htons (0);
1934  udp->crc = htons (0);
1935 }
1936 
1937 
1947 static void
1949  struct GNUNET_TUN_IPv6Header *ipp,
1950  struct GNUNET_TUN_UdpHeader *udp)
1951 {
1953  state->specifics.tcp_udp.ri.remote_address.
1954  proto,
1955  sizeof(struct GNUNET_TUN_TcpHeader),
1956  &state->specifics.tcp_udp.ri.remote_address
1957  .address.ipv6,
1958  &state->specifics.tcp_udp.ri.local_address.
1959  address.ipv6);
1960  udp->source_port = htons (state->specifics.tcp_udp.ri.remote_address.port);
1961  udp->destination_port = htons (
1962  state->specifics.tcp_udp.ri.local_address.port);
1963  udp->len = htons (0);
1964  udp->crc = htons (0);
1965 }
1966 
1967 
1976 static int
1978  const struct GNUNET_EXIT_IcmpInternetMessage *msg)
1979 {
1980  struct ChannelState *state = cls;
1981 
1982  if (GNUNET_YES == state->is_dns)
1983  {
1984  GNUNET_break_op (0);
1985  return GNUNET_SYSERR;
1986  }
1987  return GNUNET_OK;
1988 }
1989 
1990 
1997 static void
1999  const struct GNUNET_EXIT_IcmpInternetMessage *msg)
2000 {
2001  struct ChannelState *state = cls;
2002  uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
2004  const struct in_addr *v4;
2005  const struct in6_addr *v6;
2006  const void *payload;
2007  char buf[sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
2008  int af;
2009 
2010  if (GNUNET_SYSERR == state->is_dns)
2011  {
2012  /* channel is UDP/TCP from now on */
2013  state->is_dns = GNUNET_NO;
2014  }
2015  GNUNET_STATISTICS_update (stats,
2016  gettext_noop ("# Bytes received from CADET"),
2017  pkt_len, GNUNET_NO);
2018  GNUNET_STATISTICS_update (stats,
2019  gettext_noop (
2020  "# ICMP IP-exit requests received via cadet"),
2021  1, GNUNET_NO);
2022 
2023  af = (int) ntohl (msg->af);
2024  if ((NULL != state->specifics.tcp_udp.heap_node) &&
2025  (af != state->specifics.tcp_udp.ri.remote_address.af))
2026  {
2027  /* other peer switched AF on this channel; not allowed */
2028  GNUNET_break_op (0);
2029  return;
2030  }
2031 
2032  switch (af)
2033  {
2034  case AF_INET:
2035  if (pkt_len < sizeof(struct in_addr))
2036  {
2037  GNUNET_break_op (0);
2038  return;
2039  }
2040  if (! ipv4_exit)
2041  {
2042  GNUNET_break_op (0);
2043  return;
2044  }
2045  v4 = (const struct in_addr*) &msg[1];
2046  payload = &v4[1];
2047  pkt_len -= sizeof(struct in_addr);
2048  state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
2049  if (NULL == state->specifics.tcp_udp.heap_node)
2050  {
2051  state->specifics.tcp_udp.ri.remote_address.af = af;
2052  state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMP;
2053  setup_state_record (state);
2054  }
2055  /* check that ICMP type is something we want to support
2056  and possibly make up payload! */
2057  switch (msg->icmp_header.type)
2058  {
2061  break;
2062 
2066  if (0 != pkt_len)
2067  {
2068  GNUNET_break_op (0);
2069  return;
2070  }
2071  /* make up payload */
2072  {
2073  struct GNUNET_TUN_IPv4Header *ipp = (struct
2075  struct GNUNET_TUN_UdpHeader *udp = (struct
2076  GNUNET_TUN_UdpHeader *) &ipp[1];
2077 
2078  GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2079  pkt_len = sizeof(struct GNUNET_TUN_IPv4Header) + 8;
2080  make_up_icmpv4_payload (state,
2081  ipp,
2082  udp);
2083  payload = ipp;
2084  }
2085  break;
2086 
2087  default:
2088  GNUNET_break_op (0);
2089  GNUNET_STATISTICS_update (stats,
2090  gettext_noop (
2091  "# ICMPv4 packets dropped (type not allowed)"),
2092  1, GNUNET_NO);
2093  return;
2094  }
2095  /* end AF_INET */
2096  break;
2097 
2098  case AF_INET6:
2099  if (pkt_len < sizeof(struct in6_addr))
2100  {
2101  GNUNET_break_op (0);
2102  return;
2103  }
2104  if (! ipv6_exit)
2105  {
2106  GNUNET_break_op (0);
2107  return;
2108  }
2109  v6 = (const struct in6_addr*) &msg[1];
2110  payload = &v6[1];
2111  pkt_len -= sizeof(struct in6_addr);
2112  state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
2113  if (NULL == state->specifics.tcp_udp.heap_node)
2114  {
2115  state->specifics.tcp_udp.ri.remote_address.af = af;
2116  state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMPV6;
2117  setup_state_record (state);
2118  }
2119  /* check that ICMP type is something we want to support
2120  and possibly make up payload! */
2121  switch (msg->icmp_header.type)
2122  {
2125  break;
2126 
2131  if (0 != pkt_len)
2132  {
2133  GNUNET_break_op (0);
2134  return;
2135  }
2136  /* make up payload */
2137  {
2138  struct GNUNET_TUN_IPv6Header *ipp = (struct
2140  struct GNUNET_TUN_UdpHeader *udp = (struct
2141  GNUNET_TUN_UdpHeader *) &ipp[1];
2142 
2143  GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2144  pkt_len = sizeof(struct GNUNET_TUN_IPv6Header) + 8;
2145  make_up_icmpv6_payload (state,
2146  ipp,
2147  udp);
2148  payload = ipp;
2149  }
2150  break;
2151 
2152  default:
2153  GNUNET_break_op (0);
2154  GNUNET_STATISTICS_update (stats,
2155  gettext_noop (
2156  "# ICMPv6 packets dropped (type not allowed)"),
2157  1, GNUNET_NO);
2158  return;
2159  }
2160  /* end AF_INET6 */
2161  break;
2162 
2163  default:
2164  /* bad AF */
2165  GNUNET_break_op (0);
2166  return;
2167  }
2168 
2169  {
2170  char buf[INET6_ADDRSTRLEN];
2172  "Received ICMP data from %s for forwarding to %s\n",
2173  GNUNET_i2s (&state->peer),
2174  inet_ntop (af,
2175  &state->specifics.tcp_udp.ri.remote_address.address,
2176  buf, sizeof(buf)));
2177  }
2178  send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2179  &state->specifics.tcp_udp.ri.local_address,
2180  &msg->icmp_header,
2181  payload, pkt_len);
2183 }
2184 
2185 
2195 static uint16_t
2197  char *buf)
2198 {
2199  switch (state->specifics.tcp_udp.serv->address.af)
2200  {
2201  case AF_INET:
2202  {
2203  struct GNUNET_TUN_IPv4Header *ipv4;
2204  struct GNUNET_TUN_UdpHeader *udp;
2205 
2206  ipv4 = (struct GNUNET_TUN_IPv4Header *) buf;
2207  udp = (struct GNUNET_TUN_UdpHeader *) &ipv4[1];
2208  make_up_icmpv4_payload (state,
2209  ipv4,
2210  udp);
2211  GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2212  return sizeof(struct GNUNET_TUN_IPv4Header) + 8;
2213  }
2214  break;
2215 
2216  case AF_INET6:
2217  {
2218  struct GNUNET_TUN_IPv6Header *ipv6;
2219  struct GNUNET_TUN_UdpHeader *udp;
2220 
2221  ipv6 = (struct GNUNET_TUN_IPv6Header *) buf;
2222  udp = (struct GNUNET_TUN_UdpHeader *) &ipv6[1];
2223  make_up_icmpv6_payload (state,
2224  ipv6,
2225  udp);
2226  GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2227  return sizeof(struct GNUNET_TUN_IPv6Header) + 8;
2228  }
2229  break;
2230 
2231  default:
2232  GNUNET_break (0);
2233  }
2234  return 0;
2235 }
2236 
2237 
2247 static int
2249  const struct GNUNET_EXIT_IcmpServiceMessage *msg)
2250 {
2251  struct ChannelState *state = cls;
2252 
2253  if (GNUNET_YES == state->is_dns)
2254  {
2255  GNUNET_break_op (0);
2256  return GNUNET_SYSERR;
2257  }
2258  if (NULL == state->specifics.tcp_udp.serv)
2259  {
2260  GNUNET_break_op (0);
2261  return GNUNET_SYSERR;
2262  }
2263  return GNUNET_OK;
2264 }
2265 
2266 
2274 static void
2276  const struct GNUNET_EXIT_IcmpServiceMessage *msg)
2277 {
2278  struct ChannelState *state = cls;
2279  uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
2281  struct GNUNET_TUN_IcmpHeader icmp;
2282  char buf[sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
2283  const void *payload;
2284 
2285  GNUNET_STATISTICS_update (stats,
2286  gettext_noop ("# Bytes received from CADET"),
2287  pkt_len, GNUNET_NO);
2288  GNUNET_STATISTICS_update (stats,
2289  gettext_noop (
2290  "# ICMP service requests received via cadet"),
2291  1, GNUNET_NO);
2292  /* check that we got at least a valid header */
2294  "Received data from %s for forwarding to ICMP service %s\n",
2295  GNUNET_i2s (&state->peer),
2296  GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor));
2297  icmp = msg->icmp_header;
2298  payload = &msg[1];
2299  state->specifics.tcp_udp.ri.remote_address
2300  = state->specifics.tcp_udp.serv->address;
2301  setup_state_record (state);
2302 
2303  /* check that ICMP type is something we want to support,
2304  perform ICMP PT if needed ans possibly make up payload */
2305  switch (msg->af)
2306  {
2307  case AF_INET:
2308  switch (msg->icmp_header.type)
2309  {
2311  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2313  break;
2314 
2316  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2318  break;
2319 
2321  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2323  if (0 != pkt_len)
2324  {
2325  GNUNET_break_op (0);
2326  return;
2327  }
2328  payload = buf;
2329  pkt_len = make_up_icmp_service_payload (state, buf);
2330  break;
2331 
2333  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2335  if (0 != pkt_len)
2336  {
2337  GNUNET_break_op (0);
2338  return;
2339  }
2340  payload = buf;
2341  pkt_len = make_up_icmp_service_payload (state, buf);
2342  break;
2343 
2345  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2346  {
2347  GNUNET_STATISTICS_update (stats,
2348  gettext_noop (
2349  "# ICMPv4 packets dropped (impossible PT to v6)"),
2350  1, GNUNET_NO);
2351  return;
2352  }
2353  if (0 != pkt_len)
2354  {
2355  GNUNET_break_op (0);
2356  return;
2357  }
2358  payload = buf;
2359  pkt_len = make_up_icmp_service_payload (state, buf);
2360  break;
2361 
2362  default:
2363  GNUNET_break_op (0);
2364  GNUNET_STATISTICS_update (stats,
2365  gettext_noop (
2366  "# ICMPv4 packets dropped (type not allowed)"),
2367  1, GNUNET_NO);
2368  return;
2369  }
2370  /* end of AF_INET */
2371  break;
2372 
2373  case AF_INET6:
2374  switch (msg->icmp_header.type)
2375  {
2377  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2379  break;
2380 
2382  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2384  break;
2385 
2387  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2389  if (0 != pkt_len)
2390  {
2391  GNUNET_break_op (0);
2392  return;
2393  }
2394  payload = buf;
2395  pkt_len = make_up_icmp_service_payload (state, buf);
2396  break;
2397 
2399  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2401  if (0 != pkt_len)
2402  {
2403  GNUNET_break_op (0);
2404  return;
2405  }
2406  payload = buf;
2407  pkt_len = make_up_icmp_service_payload (state, buf);
2408  break;
2409 
2412  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2413  {
2414  GNUNET_STATISTICS_update (stats,
2415  gettext_noop (
2416  "# ICMPv6 packets dropped (impossible PT to v4)"),
2417  1, GNUNET_NO);
2418  return;
2419  }
2420  if (0 != pkt_len)
2421  {
2422  GNUNET_break_op (0);
2423  return;
2424  }
2425  payload = buf;
2426  pkt_len = make_up_icmp_service_payload (state, buf);
2427  break;
2428 
2429  default:
2430  GNUNET_break_op (0);
2431  GNUNET_STATISTICS_update (stats,
2432  gettext_noop (
2433  "# ICMPv6 packets dropped (type not allowed)"),
2434  1, GNUNET_NO);
2435  return;
2436  }
2437  /* end of AF_INET6 */
2438  break;
2439 
2440  default:
2441  GNUNET_break_op (0);
2442  return;
2443  }
2444 
2445  send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2446  &state->specifics.tcp_udp.ri.local_address,
2447  &icmp,
2448  payload,
2449  pkt_len);
2451 }
2452 
2453 
2462 static int
2464  const struct GNUNET_HashCode *key,
2465  void *value)
2466 {
2467  struct LocalService *service = value;
2468 
2471  key,
2472  service));
2473  GNUNET_CADET_close_port (service->port);
2474  GNUNET_free (service->name);
2475  GNUNET_free (service);
2476  return GNUNET_OK;
2477 }
2478 
2479 
2488 static void *
2490  struct GNUNET_CADET_Channel *channel,
2491  const struct GNUNET_PeerIdentity *initiator)
2492 {
2493  struct LocalService *ls = cls;
2494  struct ChannelState *s = GNUNET_new (struct ChannelState);
2495 
2496  s->peer = *initiator;
2497  GNUNET_STATISTICS_update (stats,
2498  gettext_noop ("# Inbound CADET channels created"),
2499  1,
2500  GNUNET_NO);
2502  "Received inbound channel from `%s'\n",
2503  GNUNET_i2s (initiator));
2504  s->channel = channel;
2505  s->specifics.tcp_udp.serv = ls;
2506  s->specifics.tcp_udp.ri.remote_address = ls->address;
2507  return s;
2508 }
2509 
2510 
2518 static void
2519 clean_channel (void *cls,
2520  const struct GNUNET_CADET_Channel *channel)
2521 {
2522  struct ChannelState *s = cls;
2523 
2525  "Channel destroyed\n");
2526  if (GNUNET_SYSERR == s->is_dns)
2527  {
2528  GNUNET_free (s);
2529  return;
2530  }
2531  if (GNUNET_YES == s->is_dns)
2532  {
2533  if (channels[s->specifics.dns.my_id] == s)
2534  channels[s->specifics.dns.my_id] = NULL;
2535  }
2536  else
2537  {
2538  if (NULL != s->specifics.tcp_udp.heap_node)
2539  {
2541  GNUNET_CONTAINER_multihashmap_remove (connections_map,
2542  &s->specifics.tcp_udp
2543  .state_key,
2544  s));
2546  s->specifics.tcp_udp.heap_node = NULL;
2547  }
2548  }
2549  GNUNET_free (s);
2550 }
2551 
2552 
2562 static void
2564  const char *name,
2565  uint16_t destination_port,
2566  struct LocalService *service)
2567 {
2568  struct GNUNET_MQ_MessageHandler handlers[] = {
2569  GNUNET_MQ_hd_var_size (icmp_service,
2572  service),
2573  GNUNET_MQ_hd_var_size (udp_service,
2576  service),
2577  GNUNET_MQ_hd_var_size (tcp_service,
2580  service),
2581  GNUNET_MQ_hd_var_size (tcp_data,
2584  service),
2586  };
2587 
2588  struct GNUNET_HashCode cadet_port;
2589 
2590  service->name = GNUNET_strdup (name);
2592  &service->descriptor);
2594  destination_port,
2595  &cadet_port);
2597  "Opening CADET port %s for SERVICE exit %s on port %u\n",
2598  GNUNET_h2s (&cadet_port),
2599  name,
2600  (unsigned int) destination_port);
2601  service->port = GNUNET_CADET_open_port (cadet_handle,
2602  &cadet_port,
2604  service,
2605  NULL,
2606  &clean_channel,
2607  handlers);
2608  service->is_udp = (IPPROTO_UDP == proto);
2609  if (GNUNET_OK !=
2611  &cadet_port,
2612  service,
2614  {
2615  GNUNET_CADET_close_port (service->port);
2616  GNUNET_free (service->name);
2617  GNUNET_free (service);
2619  _ ("Got duplicate service records for `%s:%u'\n"),
2620  name,
2621  (unsigned int) destination_port);
2622  }
2623 }
2624 
2625 
2632 static void
2634  struct GNUNET_MQ_Envelope *env)
2635 {
2636  GNUNET_assert (NULL != s);
2637  GNUNET_STATISTICS_update (stats,
2638  gettext_noop (
2639  "# Messages transmitted via cadet channels"),
2640  1,
2641  GNUNET_NO);
2643  env);
2644 }
2645 
2646 
2658 static void
2660  size_t pktlen,
2661  int af,
2662  const void *destination_ip,
2663  const void *source_ip)
2664 {
2665  struct ChannelState *state;
2666  struct GNUNET_MQ_Envelope *env;
2667  struct GNUNET_EXIT_IcmpToVPNMessage *i2v;
2668  const struct GNUNET_TUN_IPv4Header *ipv4;
2669  const struct GNUNET_TUN_IPv6Header *ipv6;
2670  const struct GNUNET_TUN_UdpHeader *udp;
2671  uint16_t source_port;
2672  uint16_t destination_port;
2673  uint8_t protocol;
2674 
2675  {
2676  char sbuf[INET6_ADDRSTRLEN];
2677  char dbuf[INET6_ADDRSTRLEN];
2679  "Received ICMP packet going from %s to %s\n",
2680  inet_ntop (af,
2681  source_ip,
2682  sbuf, sizeof(sbuf)),
2683  inet_ntop (af,
2684  destination_ip,
2685  dbuf, sizeof(dbuf)));
2686  }
2687 
2688  if (pktlen < sizeof(struct GNUNET_TUN_IcmpHeader))
2689  {
2690  /* blame kernel */
2691  GNUNET_break (0);
2692  return;
2693  }
2694 
2695  /* Find out if this is an ICMP packet in response to an existing
2696  TCP/UDP packet and if so, figure out ports / protocol of the
2697  existing session from the IP data in the ICMP payload */
2698  source_port = 0;
2699  destination_port = 0;
2700  switch (af)
2701  {
2702  case AF_INET:
2703  protocol = IPPROTO_ICMP;
2704  switch (icmp->type)
2705  {
2708  break;
2709 
2713  if (pktlen <
2714  sizeof(struct GNUNET_TUN_IcmpHeader)
2715  + sizeof(struct GNUNET_TUN_IPv4Header) + 8)
2716  {
2717  /* blame kernel */
2718  GNUNET_break (0);
2719  return;
2720  }
2721  ipv4 = (const struct GNUNET_TUN_IPv4Header *) &icmp[1];
2722  protocol = ipv4->protocol;
2723  /* could be TCP or UDP, but both have the ports in the right
2724  place, so that doesn't matter here */
2725  udp = (const struct GNUNET_TUN_UdpHeader *) &ipv4[1];
2726  /* swap ports, as they are from the original message */
2727  destination_port = ntohs (udp->source_port);
2728  source_port = ntohs (udp->destination_port);
2729  /* throw away ICMP payload, won't be useful for the other side anyway */
2730  pktlen = sizeof(struct GNUNET_TUN_IcmpHeader);
2731  break;
2732 
2733  default:
2734  GNUNET_STATISTICS_update (stats,
2735  gettext_noop (
2736  "# ICMPv4 packets dropped (type not allowed)"),
2737  1, GNUNET_NO);
2738  return;
2739  }
2740  break;
2741 
2742  case AF_INET6:
2743  protocol = IPPROTO_ICMPV6;
2744  switch (icmp->type)
2745  {
2750  if (pktlen <
2751  sizeof(struct GNUNET_TUN_IcmpHeader)
2752  + sizeof(struct GNUNET_TUN_IPv6Header) + 8)
2753  {
2754  /* blame kernel */
2755  GNUNET_break (0);
2756  return;
2757  }
2758  ipv6 = (const struct GNUNET_TUN_IPv6Header *) &icmp[1];
2759  protocol = ipv6->next_header;
2760  /* could be TCP or UDP, but both have the ports in the right
2761  place, so that doesn't matter here */
2762  udp = (const struct GNUNET_TUN_UdpHeader *) &ipv6[1];
2763  /* swap ports, as they are from the original message */
2764  destination_port = ntohs (udp->source_port);
2765  source_port = ntohs (udp->destination_port);
2766  /* throw away ICMP payload, won't be useful for the other side anyway */
2767  pktlen = sizeof(struct GNUNET_TUN_IcmpHeader);
2768  break;
2769 
2772  break;
2773 
2774  default:
2775  GNUNET_STATISTICS_update (stats,
2776  gettext_noop (
2777  "# ICMPv6 packets dropped (type not allowed)"),
2778  1, GNUNET_NO);
2779  return;
2780  }
2781  break;
2782 
2783  default:
2784  GNUNET_assert (0);
2785  }
2786  switch (protocol)
2787  {
2788  case IPPROTO_ICMP:
2789  state = get_redirect_state (af,
2790  IPPROTO_ICMP,
2791  source_ip,
2792  0,
2793  destination_ip,
2794  0,
2795  NULL);
2796  break;
2797 
2798  case IPPROTO_ICMPV6:
2799  state = get_redirect_state (af,
2800  IPPROTO_ICMPV6,
2801  source_ip,
2802  0,
2803  destination_ip,
2804  0,
2805  NULL);
2806  break;
2807 
2808  case IPPROTO_UDP:
2809  state = get_redirect_state (af,
2810  IPPROTO_UDP,
2811  source_ip,
2812  source_port,
2813  destination_ip,
2814  destination_port,
2815  NULL);
2816  break;
2817 
2818  case IPPROTO_TCP:
2819  state = get_redirect_state (af,
2820  IPPROTO_TCP,
2821  source_ip,
2822  source_port,
2823  destination_ip,
2824  destination_port,
2825  NULL);
2826  break;
2827 
2828  default:
2829  GNUNET_STATISTICS_update (stats,
2830  gettext_noop (
2831  "# ICMP packets dropped (not allowed)"),
2832  1,
2833  GNUNET_NO);
2834  return;
2835  }
2836  if (NULL == state)
2837  {
2839  _ (
2840  "ICMP Packet dropped, have no matching connection information\n"));
2841  return;
2842  }
2843  env = GNUNET_MQ_msg_extra (i2v,
2844  pktlen - sizeof(struct GNUNET_TUN_IcmpHeader),
2846  i2v->af = htonl (af);
2847  GNUNET_memcpy (&i2v->icmp_header,
2848  icmp,
2849  pktlen);
2851  env);
2852 }
2853 
2854 
2866 static void
2868  size_t pktlen,
2869  int af,
2870  const void *destination_ip,
2871  const void *source_ip)
2872 {
2873  struct ChannelState *state;
2874  struct GNUNET_MQ_Envelope *env;
2875  struct GNUNET_EXIT_UdpReplyMessage *urm;
2876 
2877  {
2878  char sbuf[INET6_ADDRSTRLEN];
2879  char dbuf[INET6_ADDRSTRLEN];
2880 
2882  "Received UDP packet going from %s:%u to %s:%u\n",
2883  inet_ntop (af,
2884  source_ip,
2885  sbuf, sizeof(sbuf)),
2886  (unsigned int) ntohs (udp->source_port),
2887  inet_ntop (af,
2888  destination_ip,
2889  dbuf, sizeof(dbuf)),
2890  (unsigned int) ntohs (udp->destination_port));
2891  }
2892 
2893  if (pktlen < sizeof(struct GNUNET_TUN_UdpHeader))
2894  {
2895  /* blame kernel */
2896  GNUNET_break (0);
2897  return;
2898  }
2899  if (pktlen != ntohs (udp->len))
2900  {
2901  /* blame kernel */
2902  GNUNET_break (0);
2903  return;
2904  }
2905  state = get_redirect_state (af,
2906  IPPROTO_UDP,
2907  source_ip,
2908  ntohs (udp->source_port),
2909  destination_ip,
2910  ntohs (udp->destination_port),
2911  NULL);
2912  if (NULL == state)
2913  {
2915  _ (
2916  "UDP Packet dropped, have no matching connection information\n"));
2917  return;
2918  }
2919  env = GNUNET_MQ_msg_extra (urm,
2920  pktlen - sizeof(struct GNUNET_TUN_UdpHeader),
2922  urm->source_port = htons (0);
2923  urm->destination_port = htons (0);
2924  GNUNET_memcpy (&urm[1],
2925  &udp[1],
2926  pktlen - sizeof(struct GNUNET_TUN_UdpHeader));
2928  env);
2929 }
2930 
2931 
2943 static void
2945  size_t pktlen,
2946  int af,
2947  const void *destination_ip,
2948  const void *source_ip)
2949 {
2950  struct ChannelState *state;
2951  char buf[pktlen] GNUNET_ALIGN;
2952  struct GNUNET_TUN_TcpHeader *mtcp;
2953  struct GNUNET_EXIT_TcpDataMessage *tdm;
2954  struct GNUNET_MQ_Envelope *env;
2955  size_t mlen;
2956 
2957  {
2958  char sbuf[INET6_ADDRSTRLEN];
2959  char dbuf[INET6_ADDRSTRLEN];
2961  "Received TCP packet with %u bytes going from %s:%u to %s:%u\n",
2962  (unsigned int) (pktlen - sizeof(struct GNUNET_TUN_TcpHeader)),
2963  inet_ntop (af,
2964  source_ip,
2965  sbuf, sizeof(sbuf)),
2966  (unsigned int) ntohs (tcp->source_port),
2967  inet_ntop (af,
2968  destination_ip,
2969  dbuf, sizeof(dbuf)),
2970  (unsigned int) ntohs (tcp->destination_port));
2971  }
2972 
2973  if (pktlen < sizeof(struct GNUNET_TUN_TcpHeader))
2974  {
2975  /* blame kernel */
2976  GNUNET_break (0);
2977  return;
2978  }
2979  state = get_redirect_state (af,
2980  IPPROTO_TCP,
2981  source_ip,
2982  ntohs (tcp->source_port),
2983  destination_ip,
2984  ntohs (tcp->destination_port),
2985  NULL);
2986  if (NULL == state)
2987  {
2989  _ (
2990  "TCP Packet dropped, have no matching connection information\n"));
2991 
2992  return;
2993  }
2994  /* mug port numbers and crc to avoid information leakage;
2995  sender will need to lookup the correct values anyway */
2996  GNUNET_memcpy (buf, tcp, pktlen);
2997  mtcp = (struct GNUNET_TUN_TcpHeader *) buf;
2998  mtcp->source_port = 0;
2999  mtcp->destination_port = 0;
3000  mtcp->crc = 0;
3001 
3002  mlen = sizeof(struct GNUNET_EXIT_TcpDataMessage) + (pktlen - sizeof(struct
3003  GNUNET_TUN_TcpHeader));
3004  if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
3005  {
3006  GNUNET_break (0);
3007  return;
3008  }
3009  env = GNUNET_MQ_msg_extra (tdm,
3010  pktlen - sizeof(struct GNUNET_TUN_TcpHeader),
3012  tdm->reserved = htonl (0);
3013  GNUNET_memcpy (&tdm->tcp_header,
3014  buf,
3015  pktlen);
3017  env);
3018 }
3019 
3020 
3027 static int
3029  const struct GNUNET_MessageHeader *message)
3030 {
3031  const struct GNUNET_TUN_Layer2PacketHeader *pkt_tun;
3032  size_t size;
3033 
3035  "Got %u-byte message of type %u from gnunet-helper-exit\n",
3036  ntohs (message->size),
3037  ntohs (message->type));
3038  GNUNET_STATISTICS_update (stats,
3039  gettext_noop ("# Packets received from TUN"),
3040  1, GNUNET_NO);
3041  if (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER)
3042  {
3043  GNUNET_break (0);
3044  return GNUNET_OK;
3045  }
3046  size = ntohs (message->size);
3047  if (size < sizeof(struct GNUNET_TUN_Layer2PacketHeader) + sizeof(struct
3049  {
3050  GNUNET_break (0);
3051  return GNUNET_OK;
3052  }
3053  GNUNET_STATISTICS_update (stats,
3054  gettext_noop ("# Bytes received from TUN"),
3055  size, GNUNET_NO);
3056  pkt_tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1];
3057  size -= sizeof(struct GNUNET_TUN_Layer2PacketHeader) + sizeof(struct
3058  GNUNET_MessageHeader);
3059  switch (ntohs (pkt_tun->proto))
3060  {
3061  case ETH_P_IPV4:
3062  {
3063  const struct GNUNET_TUN_IPv4Header *pkt4;
3064 
3065  if (size < sizeof(struct GNUNET_TUN_IPv4Header))
3066  {
3067  /* Kernel to blame? */
3068  GNUNET_break (0);
3069  return GNUNET_OK;
3070  }
3071  pkt4 = (const struct GNUNET_TUN_IPv4Header *) &pkt_tun[1];
3072  if (size != ntohs (pkt4->total_length))
3073  {
3074  /* Kernel to blame? */
3075  GNUNET_break (0);
3076  return GNUNET_OK;
3077  }
3078  if (pkt4->header_length * 4 != sizeof(struct GNUNET_TUN_IPv4Header))
3079  {
3081  _ ("IPv4 packet options received. Ignored.\n"));
3082  return GNUNET_OK;
3083  }
3084 
3085  size -= sizeof(struct GNUNET_TUN_IPv4Header);
3086  switch (pkt4->protocol)
3087  {
3088  case IPPROTO_UDP:
3089  udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt4[1], size,
3090  AF_INET,
3091  &pkt4->destination_address,
3092  &pkt4->source_address);
3093  break;
3094 
3095  case IPPROTO_TCP:
3096  tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt4[1], size,
3097  AF_INET,
3098  &pkt4->destination_address,
3099  &pkt4->source_address);
3100  break;
3101 
3102  case IPPROTO_ICMP:
3103  icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt4[1], size,
3104  AF_INET,
3105  &pkt4->destination_address,
3106  &pkt4->source_address);
3107  break;
3108 
3109  default:
3111  _ (
3112  "IPv4 packet with unsupported next header %u received. Ignored.\n"),
3113  (int) pkt4->protocol);
3114  return GNUNET_OK;
3115  }
3116  }
3117  break;
3118 
3119  case ETH_P_IPV6:
3120  {
3121  const struct GNUNET_TUN_IPv6Header *pkt6;
3122 
3123  if (size < sizeof(struct GNUNET_TUN_IPv6Header))
3124  {
3125  /* Kernel to blame? */
3126  GNUNET_break (0);
3127  return GNUNET_OK;
3128  }
3129  pkt6 = (struct GNUNET_TUN_IPv6Header *) &pkt_tun[1];
3130  if (size != ntohs (pkt6->payload_length) + sizeof(struct
3132  {
3133  /* Kernel to blame? */
3134  GNUNET_break (0);
3135  return GNUNET_OK;
3136  }
3137  size -= sizeof(struct GNUNET_TUN_IPv6Header);
3138  switch (pkt6->next_header)
3139  {
3140  case IPPROTO_UDP:
3141  udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt6[1], size,
3142  AF_INET6,
3143  &pkt6->destination_address,
3144  &pkt6->source_address);
3145  break;
3146 
3147  case IPPROTO_TCP:
3148  tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt6[1], size,
3149  AF_INET6,
3150  &pkt6->destination_address,
3151  &pkt6->source_address);
3152  break;
3153 
3154  case IPPROTO_ICMPV6:
3155  icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt6[1], size,
3156  AF_INET6,
3157  &pkt6->destination_address,
3158  &pkt6->source_address);
3159  break;
3160 
3161  default:
3163  _ (
3164  "IPv6 packet with unsupported next header %d received. Ignored.\n"),
3165  pkt6->next_header);
3166  return GNUNET_OK;
3167  }
3168  }
3169  break;
3170 
3171  default:
3173  _ ("Packet from unknown protocol %u received. Ignored.\n"),
3174  ntohs (pkt_tun->proto));
3175  break;
3176  }
3177  return GNUNET_OK;
3178 }
3179 
3180 
3189 static void *
3190 new_channel (void *cls,
3191  struct GNUNET_CADET_Channel *channel,
3192  const struct GNUNET_PeerIdentity *initiator)
3193 {
3194  struct ChannelState *s = GNUNET_new (struct ChannelState);
3195 
3196  s->is_dns = GNUNET_SYSERR;
3197  s->peer = *initiator;
3198  GNUNET_STATISTICS_update (stats,
3199  gettext_noop ("# Inbound CADET channels created"),
3200  1,
3201  GNUNET_NO);
3203  "Received inbound channel from `%s'\n",
3204  GNUNET_i2s (initiator));
3205  s->channel = channel;
3206  return s;
3207 }
3208 
3209 
3217 static int
3218 free_iterate (void *cls,
3219  const struct GNUNET_HashCode *hash,
3220  void *value)
3221 {
3222  GNUNET_free (value);
3223  return GNUNET_YES;
3224 }
3225 
3226 
3236 static void
3237 dummy_task (void *cls)
3238 {
3239  /* just terminate */
3240 }
3241 
3242 
3248 static void
3249 cleanup (void *cls)
3250 {
3251  unsigned int i;
3252 
3254  "Exit service is shutting down now\n");
3255 
3256  if (NULL != helper_handle)
3257  {
3258  GNUNET_HELPER_stop (helper_handle, GNUNET_NO);
3259  helper_handle = NULL;
3260  }
3261  if (NULL != regex4)
3262  {
3264  regex4 = NULL;
3265  }
3266  if (NULL != regex6)
3267  {
3269  regex6 = NULL;
3270  }
3271  if (NULL != services)
3272  {
3275  NULL);
3277  }
3278  if (NULL != dns_port)
3279  {
3280  GNUNET_CADET_close_port (dns_port);
3281  dns_port = NULL;
3282  }
3283  if (NULL != cadet_port4)
3284  {
3285  GNUNET_CADET_close_port (cadet_port4);
3286  cadet_port4 = NULL;
3287  }
3288  if (NULL != cadet_port6)
3289  {
3290  GNUNET_CADET_close_port (cadet_port6);
3291  cadet_port6 = NULL;
3292  }
3293  if (NULL != cadet_handle)
3294  {
3295  GNUNET_CADET_disconnect (cadet_handle);
3296  cadet_handle = NULL;
3297  }
3298  if (NULL != connections_map)
3299  {
3300  GNUNET_CONTAINER_multihashmap_iterate (connections_map,
3301  &free_iterate,
3302  NULL);
3303  GNUNET_CONTAINER_multihashmap_destroy (connections_map);
3304  connections_map = NULL;
3305  }
3306  if (NULL != connections_heap)
3307  {
3308  GNUNET_CONTAINER_heap_destroy (connections_heap);
3309  connections_heap = NULL;
3310  }
3311  if (NULL != dnsstub)
3312  {
3313  GNUNET_DNSSTUB_stop (dnsstub);
3314  dnsstub = NULL;
3315  }
3316  if (NULL != peer_key)
3317  {
3318  GNUNET_free (peer_key);
3319  peer_key = NULL;
3320  }
3321  if (NULL != dht_task)
3322  {
3323  GNUNET_SCHEDULER_cancel (dht_task);
3324  dht_task = NULL;
3325  }
3326  if (NULL != dht_put)
3327  {
3328  GNUNET_DHT_put_cancel (dht_put);
3329  dht_put = NULL;
3330  }
3331  if (NULL != dht)
3332  {
3333  GNUNET_DHT_disconnect (dht);
3334  dht = NULL;
3335  }
3336  if (NULL != stats)
3337  {
3339  GNUNET_NO);
3340  stats = NULL;
3341  }
3342  for (i = 0; i < 8; i++)
3343  GNUNET_free (exit_argv[i]);
3344 }
3345 
3346 
3354 static void
3356  char *cpy,
3357  const char *name)
3358 {
3359  char *redirect;
3360  char *hostname;
3361  char *hostport;
3362  struct LocalService *serv;
3363  char *n;
3364  size_t slen;
3365 
3366  slen = strlen (name);
3367  GNUNET_assert (slen >= 8);
3368  n = GNUNET_strndup (name, slen - 8 /* remove .gnunet. */);
3369 
3370  for (redirect = strtok (cpy, " ;"); redirect != NULL;
3371  redirect = strtok (NULL, " ;"))
3372  {
3373  if (NULL == (hostname = strstr (redirect, ":")))
3374  {
3376  _ (
3377  "Option `%s' for domain `%s' is not formatted correctly!\n"),
3378  redirect,
3379  name);
3380  continue;
3381  }
3382  hostname[0] = '\0';
3383  hostname++;
3384  if (NULL == (hostport = strstr (hostname, ":")))
3385  {
3387  _ (
3388  "Option `%s' for domain `%s' is not formatted correctly!\n"),
3389  redirect,
3390  name);
3391  continue;
3392  }
3393  hostport[0] = '\0';
3394  hostport++;
3395 
3396  int local_port = atoi (redirect);
3397  int remote_port = atoi (hostport);
3398 
3399  if (! ((local_port > 0) && (local_port < 65536)))
3400  {
3402  _ ("`%s' is not a valid port number (for domain `%s')!"),
3403  redirect,
3404  name);
3405  continue;
3406  }
3407  if (! ((remote_port > 0) && (remote_port < 65536)))
3408  {
3410  _ ("`%s' is not a valid port number (for domain `%s')!"),
3411  hostport,
3412  name);
3413  continue;
3414  }
3415 
3416  serv = GNUNET_new (struct LocalService);
3417  serv->address.proto = proto;
3418  serv->address.port = remote_port;
3419  if (0 == strcmp ("localhost4",
3420  hostname))
3421  {
3422  const char *ip4addr = exit_argv[5];
3423 
3424  serv->address.af = AF_INET;
3425  GNUNET_assert (1 == inet_pton (AF_INET,
3426  ip4addr,
3427  &serv->address.address.ipv4));
3428  }
3429  else if (0 == strcmp ("localhost6",
3430  hostname))
3431  {
3432  const char *ip6addr = exit_argv[3];
3433 
3434  serv->address.af = AF_INET6;
3435  GNUNET_assert (1 == inet_pton (AF_INET6,
3436  ip6addr,
3437  &serv->address.address.ipv6));
3438  }
3439  else
3440  {
3441  struct addrinfo *res;
3442  int ret;
3443 
3444  ret = getaddrinfo (hostname,
3445  NULL,
3446  NULL,
3447  &res);
3448  if ((0 != ret) || (NULL == res))
3449  {
3451  _ (
3452  "No addresses found for hostname `%s' of service `%s'!\n"),
3453  hostname,
3454  n);
3455  GNUNET_free (serv);
3456  continue;
3457  }
3458 
3459  serv->address.af = res->ai_family;
3460  switch (res->ai_family)
3461  {
3462  case AF_INET:
3463  if (! ipv4_enabled)
3464  {
3466  _ (
3467  "Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
3468  n);
3469  freeaddrinfo (res);
3470  GNUNET_free (serv);
3471  continue;
3472  }
3473  serv->address.address.ipv4
3474  = ((struct sockaddr_in *) res->ai_addr)->sin_addr;
3475  break;
3476 
3477  case AF_INET6:
3478  if (! ipv6_enabled)
3479  {
3481  _ (
3482  "Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
3483  n);
3484  freeaddrinfo (res);
3485  GNUNET_free (serv);
3486  continue;
3487  }
3488  serv->address.address.ipv6
3489  = ((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
3490  break;
3491 
3492  default:
3493  freeaddrinfo (res);
3495  _ (
3496  "No IP addresses found for hostname `%s' of service `%s'!\n"),
3497  hostname,
3498  n);
3499  GNUNET_free (serv);
3500  continue;
3501  }
3502  freeaddrinfo (res);
3503  }
3504  store_service (proto,
3505  n,
3506  local_port,
3507  serv);
3508  }
3509  GNUNET_free (n);
3510 }
3511 
3512 
3519 static void
3521  const char *section)
3522 {
3523  char *cpy;
3524 
3525  if ((strlen (section) < 8) ||
3526  (0 != strcmp (".gnunet.", section + (strlen (section) - 8))))
3527  return;
3528  if (GNUNET_OK ==
3530  section,
3531  "UDP_REDIRECTS",
3532  &cpy))
3533  {
3534  add_services (IPPROTO_UDP,
3535  cpy,
3536  section);
3537  GNUNET_free (cpy);
3538  }
3539  if (GNUNET_OK ==
3541  section,
3542  "TCP_REDIRECTS",
3543  &cpy))
3544  {
3545  add_services (IPPROTO_TCP,
3546  cpy,
3547  section);
3548  GNUNET_free (cpy);
3549  }
3550 }
3551 
3552 
3559 static void
3560 do_dht_put (void *cls);
3561 
3562 
3569 static void
3570 dht_put_cont (void *cls)
3571 {
3572  dht_put = NULL;
3573 }
3574 
3575 
3582 static void
3583 do_dht_put (void *cls)
3584 {
3585  struct GNUNET_TIME_Absolute expiration;
3586 
3588  &do_dht_put,
3589  NULL);
3591  if (GNUNET_TIME_absolute_get_remaining (expiration).rel_value_us <
3592  GNUNET_TIME_UNIT_HOURS.rel_value_us)
3593  {
3594  /* refresh advertisement */
3598  GNUNET_CRYPTO_eddsa_sign_ (peer_key,
3601  }
3602  if (NULL != dht_put)
3603  GNUNET_DHT_put_cancel (dht_put);
3604  dht_put = GNUNET_DHT_put (dht,
3605  &dht_put_key,
3606  1 /* replication */,
3609  sizeof(struct GNUNET_DNS_Advertisement),
3611  expiration,
3612  &dht_put_cont,
3613  NULL);
3614 }
3615 
3616 
3621 static void
3623 {
3625  "exit",
3626  "EXIT_IPV4");
3628  "exit",
3629  "EXIT_IPV6");
3631  "exit",
3632  "ENABLE_IPV4");
3634  "exit",
3635  "ENABLE_IPV6");
3636  if ((ipv4_exit || ipv4_enabled) &&
3637  (GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET)) )
3638  {
3640  _ (
3641  "This system does not support IPv4, will disable IPv4 functions despite them being enabled in the configuration\n"));
3642  ipv4_exit = GNUNET_NO;
3644  }
3645  if ((ipv6_exit || ipv6_enabled) &&
3646  (GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET6)) )
3647  {
3649  _ (
3650  "This system does not support IPv6, will disable IPv6 functions despite them being enabled in the configuration\n"));
3651  ipv6_exit = GNUNET_NO;
3653  }
3654  if (ipv4_exit && (! ipv4_enabled))
3655  {
3657  _ (
3658  "Cannot enable IPv4 exit but disable IPv4 on TUN interface, will use ENABLE_IPv4=YES\n"));
3660  }
3661  if (ipv6_exit && (! ipv6_enabled))
3662  {
3664  _ (
3665  "Cannot enable IPv6 exit but disable IPv6 on TUN interface, will use ENABLE_IPv6=YES\n"));
3667  }
3668 }
3669 
3670 
3675 static void
3677 {
3678  struct GNUNET_MQ_MessageHandler handlers[] = {
3679  GNUNET_MQ_hd_var_size (dns_request,
3681  struct DnsResponseMessage,
3682  NULL),
3684  };
3685  char *dns_exit;
3686  struct GNUNET_HashCode port;
3687 
3688  if (GNUNET_YES !=
3690  "exit",
3691  "EXIT_DNS"))
3692  return;
3693  GNUNET_assert (NULL != (dnsstub = GNUNET_DNSSTUB_start (128)));
3694  dns_exit = NULL;
3695  /* TODO: support using multiple DNS resolvers */
3696  if ((GNUNET_OK !=
3698  "exit",
3699  "DNS_RESOLVER",
3700  &dns_exit)) ||
3701  (GNUNET_OK !=
3702  GNUNET_DNSSTUB_add_dns_ip (dnsstub,
3703  dns_exit)))
3704  {
3706  "dns",
3707  "DNS_RESOLVER",
3708  _ ("need a valid IPv4 or IPv6 address\n"));
3709  GNUNET_free (dns_exit);
3710  return;
3711  }
3712  /* open port */
3715  &port);
3717  "Opening CADET port %s for DNS exit service\n",
3718  GNUNET_h2s (&port));
3719  dns_port = GNUNET_CADET_open_port (cadet_handle,
3720  &port,
3721  &new_channel,
3722  NULL,
3723  NULL,
3724  &clean_channel,
3725  handlers);
3726  /* advertise exit */
3727  dht = GNUNET_DHT_connect (cfg,
3728  1);
3732  dns_advertisement.purpose.size = htonl (sizeof(struct
3734  - sizeof(struct
3738  GNUNET_CRYPTO_hash ("dns",
3739  strlen ("dns"),
3740  &dht_put_key);
3741  dht_task = GNUNET_SCHEDULER_add_now (&do_dht_put,
3742  NULL);
3743  GNUNET_free (dns_exit);
3744 }
3745 
3746 
3752 static int
3754 {
3755  char *exit_ifname;
3756  char *tun_ifname;
3757  char *ipv6addr;
3758  char *ipv6prefix_s;
3759  char *ipv4addr;
3760  char *ipv4mask;
3761 
3762  exit_argv[0] = GNUNET_strdup ("exit-gnunet");
3763  if (GNUNET_SYSERR ==
3765  "exit",
3766  "TUN_IFNAME",
3767  &tun_ifname))
3768  {
3770  "EXIT",
3771  "TUN_IFNAME");
3772  return GNUNET_SYSERR;
3773  }
3774  exit_argv[1] = tun_ifname;
3775  if (ipv4_enabled)
3776  {
3777  if (GNUNET_SYSERR ==
3779  "exit",
3780  "EXIT_IFNAME",
3781  &exit_ifname))
3782  {
3784  "EXIT",
3785  "EXIT_IFNAME");
3786  return GNUNET_SYSERR;
3787  }
3788  exit_argv[2] = exit_ifname;
3789  }
3790  else
3791  {
3792  exit_argv[2] = GNUNET_strdup ("-");
3793  }
3794 
3795  if (GNUNET_YES == ipv6_enabled)
3796  {
3797  ipv6addr = NULL;
3798  if (((GNUNET_SYSERR ==
3800  "exit",
3801  "IPV6ADDR",
3802  &ipv6addr)) ||
3803  (1 != inet_pton (AF_INET6,
3804  ipv6addr,
3805  &exit_ipv6addr))))
3806  {
3808  "EXIT",
3809  "IPV6ADDR");
3810  GNUNET_free (ipv6addr);
3811  return GNUNET_SYSERR;
3812  }
3813  exit_argv[3] = ipv6addr;
3814  if (GNUNET_SYSERR ==
3816  "exit",
3817  "IPV6PREFIX",
3818  &ipv6prefix_s))
3819  {
3821  "EXIT",
3822  "IPV6PREFIX");
3823  return GNUNET_SYSERR;
3824  }
3825  exit_argv[4] = ipv6prefix_s;
3826  if ((GNUNET_OK !=
3828  "exit",
3829  "IPV6PREFIX",
3830  &ipv6prefix)) ||
3831  (ipv6prefix >= 127))
3832  {
3834  "EXIT",
3835  "IPV6PREFIX",
3836  _ ("Must be a number"));
3837  return GNUNET_SYSERR;
3838  }
3839  }
3840  else
3841  {
3842  /* IPv6 explicitly disabled */
3843  exit_argv[3] = GNUNET_strdup ("-");
3844  exit_argv[4] = GNUNET_strdup ("-");
3845  }
3846  if (GNUNET_YES == ipv4_enabled)
3847  {
3848  ipv4addr = NULL;
3849  if (((GNUNET_SYSERR ==
3851  "exit",
3852  "IPV4ADDR",
3853  &ipv4addr)) ||
3854  (1 != inet_pton (AF_INET,
3855  ipv4addr,
3856  &exit_ipv4addr))))
3857  {
3859  "EXIT",
3860  "IPV4ADDR");
3861  GNUNET_free (ipv4addr);
3862  return GNUNET_SYSERR;
3863  }
3864  exit_argv[5] = ipv4addr;
3865  ipv4mask = NULL;
3866  if (((GNUNET_SYSERR ==
3868  "exit",
3869  "IPV4MASK",
3870  &ipv4mask)) ||
3871  (1 != inet_pton (AF_INET,
3872  ipv4mask,
3873  &exit_ipv4mask))))
3874  {
3876  "EXIT",
3877  "IPV4MASK");
3878  GNUNET_free (ipv4mask);
3879  return GNUNET_SYSERR;
3880  }
3881  exit_argv[6] = ipv4mask;
3882  }
3883  else
3884  {
3885  /* IPv4 explicitly disabled */
3886  exit_argv[5] = GNUNET_strdup ("-");
3887  exit_argv[6] = GNUNET_strdup ("-");
3888  }
3889  exit_argv[7] = NULL;
3890  return GNUNET_OK;
3891 }
3892 
3893 
3902 static void
3903 run (void *cls,
3904  char *const *args,
3905  const char *cfgfile,
3906  const struct GNUNET_CONFIGURATION_Handle *cfg_)
3907 {
3908  struct GNUNET_MQ_MessageHandler handlers[] = {
3909  GNUNET_MQ_hd_var_size (icmp_remote,
3912  NULL),
3913  GNUNET_MQ_hd_var_size (udp_remote,
3916  NULL),
3917  GNUNET_MQ_hd_var_size (tcp_remote,
3920  NULL),
3921  GNUNET_MQ_hd_var_size (tcp_data,
3924  NULL),
3926  };
3927  struct GNUNET_HashCode port;
3928  char *policy;
3929  char *binary;
3930  char *regex;
3931  char *prefixed_regex;
3932 
3933  cfg = cfg_;
3934  if (GNUNET_OK !=
3936  "exit",
3937  "MAX_CONNECTIONS",
3938  &max_connections))
3939  max_connections = 1024;
3940  parse_ip_options ();
3941  binary = GNUNET_OS_get_suid_binary_path (cfg, "gnunet-helper-exit");
3942  if ((ipv4_exit) || (ipv6_exit))
3943  {
3944  if (GNUNET_YES !=
3946  GNUNET_YES,
3947  "gnunet-vpn - - - 169.1.3.7 255.255.255.0")) // no nat, ipv4 only
3948  {
3949  GNUNET_free (binary);
3951  _ (
3952  "`%s' is not SUID or the path is invalid, EXIT will not work\n"),
3953  "gnunet-helper-exit");
3955  NULL);
3956  global_ret = 1;
3957  return;
3958  }
3959  }
3960  if (! (ipv4_enabled || ipv6_enabled))
3961  {
3962  GNUNET_free (binary);
3964  _ ("No useful service enabled. Exiting.\n"));
3966  return;
3967  }
3968 
3970  NULL);
3971  stats = GNUNET_STATISTICS_create ("exit",
3972  cfg);
3973  cadet_handle = GNUNET_CADET_connect (cfg);
3974  if (NULL == cadet_handle)
3975  {
3976  GNUNET_free (binary);
3978  return;
3979  }
3980  advertise_dns_exit ();
3981  if (GNUNET_OK !=
3983  {
3984  GNUNET_free (binary);
3986  return;
3987  }
3988 
3989  services = GNUNET_CONTAINER_multihashmap_create (65536,
3990  GNUNET_NO);
3991  connections_map = GNUNET_CONTAINER_multihashmap_create (65536,
3992  GNUNET_NO);
3993  connections_heap = GNUNET_CONTAINER_heap_create (
3997  NULL);
3998 
3999  /* Cadet handle acquired, now open ports and announce regular
4000  expressions matching our exit */
4001  if ((GNUNET_YES == ipv4_enabled) &&
4002  (GNUNET_YES == ipv4_exit))
4003  {
4006  &port);
4008  "Opening CADET port %s for IPv4 gateway service\n",
4009  GNUNET_h2s (&port));
4010  cadet_port4 = GNUNET_CADET_open_port (cadet_handle,
4011  &port,
4012  &new_channel,
4013  NULL,
4014  NULL,
4015  &clean_channel,
4016  handlers);
4017  policy = NULL;
4018  if (GNUNET_OK !=
4020  "exit",
4021  "EXIT_RANGE_IPV4_POLICY",
4022  &policy))
4023  regex = NULL;
4024  else
4025  regex = GNUNET_TUN_ipv4policy2regex (policy);
4026  GNUNET_free (policy);
4027  if (NULL != regex)
4028  {
4029  (void) GNUNET_asprintf (&prefixed_regex,
4030  "%s%s",
4032  regex);
4033  regex4 = GNUNET_REGEX_announce (cfg,
4034  prefixed_regex,
4037  GNUNET_free (regex);
4038  GNUNET_free (prefixed_regex);
4039  }
4040  }
4041 
4042  if ((GNUNET_YES == ipv6_enabled) && (GNUNET_YES == ipv6_exit))
4043  {
4046  &port);
4048  "Opening CADET port %s for IPv6 gateway service\n",
4049  GNUNET_h2s (&port));
4050  cadet_port6 = GNUNET_CADET_open_port (cadet_handle,
4051  &port,
4052  &new_channel,
4053  NULL,
4054  NULL,
4055  &clean_channel,
4056  handlers);
4057  policy = NULL;
4058  if (GNUNET_OK !=
4060  "exit",
4061  "EXIT_RANGE_IPV6_POLICY",
4062  &policy))
4063  regex = NULL;
4064  else
4065  regex = GNUNET_TUN_ipv6policy2regex (policy);
4066  GNUNET_free (policy);
4067  if (NULL != regex)
4068  {
4069  (void) GNUNET_asprintf (&prefixed_regex,
4070  "%s%s",
4072  regex);
4073  regex6 = GNUNET_REGEX_announce (cfg,
4074  prefixed_regex,
4077  GNUNET_free (regex);
4078  GNUNET_free (prefixed_regex);
4079  }
4080  }
4081  helper_handle = GNUNET_HELPER_start (GNUNET_NO,
4082  binary,
4083  exit_argv,
4084  &message_token,
4085  NULL,
4086  NULL);
4087  GNUNET_free (binary);
4088 }
4089 
4090 
4098 int
4099 main (int argc,
4100  char *const *argv)
4101 {
4102  static const struct GNUNET_GETOPT_CommandLineOption options[] = {
4104  };
4105 
4106  if (GNUNET_OK !=
4108  argv,
4109  &argc,
4110  &argv))
4111  return 2;
4112 
4113  return (GNUNET_OK ==
4114  GNUNET_PROGRAM_run (argc,
4115  argv,
4116  "gnunet-daemon-exit",
4117  gettext_noop (
4118  "Daemon to run to provide an IP exit node for the VPN"),
4119  options,
4120  &run,
4121  NULL)) ? global_ret : 1;
4122 }
4123 
4124 
4125 /* end of gnunet-daemon-exit.c */
static int check_icmp_service(void *cls, const struct GNUNET_EXIT_IcmpServiceMessage *msg)
Check a request via cadet to send ICMP data to a service offered by this system.
static uint16_t make_up_icmp_service_payload(struct ChannelState *state, char *buf)
Setup ICMP payload for ICMP error messages.
static unsigned long long remote_port
Remote host&#39;s port.
unsigned int header_length
static struct GNUNET_HELPER_Handle * helper_handle
The handle to the helper.
static struct GNUNET_CADET_Handle * cadet_handle
The handle to cadet.
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:775
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 in6_addr source_address
Origin of the packet.
static int free_service_record(void *cls, const struct GNUNET_HashCode *key, void *value)
Free memory associated with a service record.
static struct GNUNET_REGEX_Announcement * regex4
Handle to our regex announcement for IPv4.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static struct in_addr exit_ipv4mask
IPv4 netmask of our TUN interface.
static int udp
Option -u: UDP requested.
Definition: gnunet-vpn.c:76
static int check_tcp_remote(void *cls, const struct GNUNET_EXIT_TcpInternetStartMessage *start)
Check a request to forward TCP data to the Internet via this peer.
struct in6_addr ipv6
Address, if af is AF_INET6.
char * name
DNS name of the service.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
void GNUNET_REGEX_announce_cancel(struct GNUNET_REGEX_Announcement *a)
Stop announcing the regex specified by the given handle.
#define GNUNET_TIME_UNIT_HOURS
One hour.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:673
This is the structure describing an DNS exit service.
Definition: block_dns.h:40
static void handle_tcp_data(void *cls, const struct GNUNET_EXIT_TcpDataMessage *data)
Process a request to forward TCP data on an established connection via this peer. ...
static void setup_fresh_address(int af, uint8_t proto, struct SocketAddress *local_address)
We need to create a (unique) fresh local address (IP+port).
#define GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE
Type of messages containing an ICMP packet for a service.
int 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.
static struct in6_addr exit_ipv6addr
IPv6 address of our TUN interface.
char * GNUNET_TUN_ipv4policy2regex(const char *policy)
Convert an exit policy to a regular expression.
Definition: regex.c:707
uint16_t proto
Here we get an ETH_P_-number.
void GNUNET_DHT_put_cancel(struct GNUNET_DHT_PutHandle *ph)
Cancels a DHT PUT operation.
Definition: dht_api.c:1035
static void handle_icmp_service(void *cls, const struct GNUNET_EXIT_IcmpServiceMessage *msg)
Process a request via cadet to send ICMP data to a service offered by this system.
#define GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET
Type of messages containing an ICMP packet for the Internet.
struct in6_addr destination_address
Destination of the packet.
static void tcp_from_helper(const struct GNUNET_TUN_TcpHeader *tcp, size_t pktlen, int af, const void *destination_ip, const void *source_ip)
Handles a TCP packet received from the helper.
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.
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
Opaque handle to the service.
Definition: cadet_api.c:38
#define GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED
uint8_t protocol
IPPROTO_TCP or IPPROTO_UDP once bound.
static void handle_udp_service(void *cls, const struct GNUNET_EXIT_UdpServiceMessage *msg)
Process a request via cadet to send a request to a UDP service offered by this system.
#define GNUNET_UNUSED
gcc-ism to document unused arguments
The handle to a helper process.
Definition: helper.c:78
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:491
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, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1331
static struct GNUNET_DNS_Advertisement dns_advertisement
Advertisement message we put into the DHT to advertise us as a DNS exit.
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
static unsigned long long max_connections
If there are at least this many connections, old ones will be removed.
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
int GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1458
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:246
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:249
#define GNUNET_SIGNATURE_PURPOSE_DNS_RECORD
Signature of an GNUNET_DNS_Advertisement.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
void GNUNET_DNSSTUB_stop(struct GNUNET_DNSSTUB_Context *ctx)
Cleanup DNSSTUB resolver.
Definition: dnsstub.c:690
#define REGEX_MAX_PATH_LEN_IPV4
Maximum path compression length for cadet regex announcing for IPv4 address based regex...
static void prepare_ipv6_packet(const void *payload, size_t payload_length, int protocol, const struct GNUNET_TUN_TcpHeader *tcp_header, const struct SocketAddress *src_address, const struct SocketAddress *dst_address, struct GNUNET_TUN_IPv6Header *pkt6)
Prepare an IPv6 packet for transmission via the TUN interface.
struct GNUNET_MessageHeader header
GNUnet header, of type GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET.
#define GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE
Type of messages containing an UDP packet for a service.
int GNUNET_DNSSTUB_add_dns_ip(struct GNUNET_DNSSTUB_Context *ctx, const char *dns_ip)
Add nameserver for use by the DNSSTUB.
Definition: dnsstub.c:591
static void hash_redirect_info(struct GNUNET_HashCode *hash, const struct RedirectInformation *ri)
Given IP information about a connection, calculate the respective hash we would use for the connectio...
static char * exit_argv[8]
Arguments to the exit helper.
#define GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START
Type of messages containing an TCP packet for a service.
void GNUNET_HELPER_stop(struct GNUNET_HELPER_Handle *h, int soft_kill)
Kills the helper, closes the pipe, frees the handle and calls wait() on the helper process...
Definition: helper.c:567
struct in_addr ipv4
Address, if af is AF_INET.
Handle to store cached data about a regex announce.
UDP packet header.
#define GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET
Type of messages containing an UDP packet for the Internet.
#define ETH_P_IPV6
Number for IPv6.
static void read_service_conf(void *cls, const char *section)
Reads the configuration and populates #udp_services and #tcp_services.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static void handle_icmp_remote(void *cls, const struct GNUNET_EXIT_IcmpInternetMessage *msg)
Process a request to forward ICMP data to the Internet via this peer.
This struct is saved into the services-hashmap to represent a service this peer is specifically offer...
struct GNUNET_TUN_IcmpHeader icmp_header
ICMP header to use.
Definition: exit.h:287
Opaque handle to a channel.
Definition: cadet.h:116
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
Standard IPv4 header.
static int check_udp_remote(void *cls, const struct GNUNET_EXIT_UdpInternetMessage *msg)
Check a request to forward UDP data to the Internet via this peer.
struct GNUNET_CRYPTO_EddsaSignature signature
Signature of the peer affirming that it is offering the service.
Definition: block_dns.h:45
int GNUNET_OS_check_helper_binary(const char *binary, int check_suid, const char *params)
Check whether an executable exists and possibly if the suid bit is set on the file.
int main(int argc, char *const *argv)
The main function.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Definition of a command line option.
uint16_t flags
Some flags (unused).
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:183
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:73
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.
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:110
struct GNUNET_CONTAINER_HeapNode * heap_node
Heap node for this state in the connections_heap.
#define GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET
Type of messages containing an DNS reply from a DNS exit service.
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Beginning of signed portion of the record, signs everything until the end of the struct.
Definition: block_dns.h:51
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
uint16_t destination_port
Destination port (in NBO).
static void udp_from_helper(const struct GNUNET_TUN_UdpHeader *udp, size_t pktlen, int af, const void *destination_ip, const void *source_ip)
Handles an UDP packet received from the helper.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
uint16_t len
Number of bytes of payload.
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:147
#define GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:531
Handle for the service.
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:53
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
static int check_tcp_data(void *cls, const struct GNUNET_EXIT_TcpDataMessage *data)
Check a request to forward TCP data on an established connection via this peer.
static int ipv6_exit
Are we an IPv6-exit?
static void parse_ip_options()
Figure out which IP versions we should support (and which are supported by the OS) according to our c...
static void make_up_icmpv6_payload(struct ChannelState *state, struct GNUNET_TUN_IPv6Header *ipp, struct GNUNET_TUN_UdpHeader *udp)
Synthesize a plausible ICMP payload for an ICMPv6 error response on the given channel.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE.
Definition: exit.h:125
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:46
#define LOG(kind,...)
Generic logging shorthand.
struct ChannelState::@10::@12 dns
uint16_t id
Unique identifier for the request/response.
Internal representation of the hash map.
static void setup_state_record(struct ChannelState *state)
We are starting a fresh connection (TCP or UDP) and need to pick a source port and IP address (within...
struct GNUNET_CADET_Port * port
Open port with CADET.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
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:222
static unsigned long long ipv6prefix
IPv6 prefix (0..127) from configuration file.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
union SocketAddress::@9 address
Remote address information.
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won&#39;t work on W32.
Connection to the DHT service.
Definition: dht_api.c:201
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition: cadet_api.c:910
#define DHT_PUT_FREQUENCY
How frequently do we re-announce the DNS exit in the DHT?
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.
#define _(String)
GNU gettext support macro.
Definition: platform.h:184
static char * section
Name of the section.
Definition: gnunet-config.c:33
static void handle_tcp_remote(void *cls, const struct GNUNET_EXIT_TcpInternetStartMessage *start)
Process a request to forward TCP data to the Internet via this peer.
Block for storing DNS exit service advertisements.
#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_DNS_TO_INTERNET
Type of messages containing an DNS request for a DNS exit service.
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:155
static void handle_udp_remote(void *cls, const struct GNUNET_EXIT_UdpInternetMessage *msg)
Process a request to forward UDP data to the Internet via this peer.
static int check_icmp_remote(void *cls, const struct GNUNET_EXIT_IcmpInternetMessage *msg)
Check a request to forward ICMP data to the Internet via this peer.
Message send via cadet to an exit daemon to send ICMP data to a local service.
Definition: exit.h:205
#define GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
static void prepare_ipv4_packet(const void *payload, size_t payload_length, int protocol, const struct GNUNET_TUN_TcpHeader *tcp_header, const struct SocketAddress *src_address, const struct SocketAddress *dst_address, struct GNUNET_TUN_IPv4Header *pkt4)
Prepare an IPv4 packet for transmission via the TUN interface.
#define GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED
#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:52
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1269
#define GNUNET_TUN_ICMPTYPE6_ECHO_REPLY
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
static int ipv6_enabled
Do we support IPv6 at all on the TUN interface?
static int free_iterate(void *cls, const struct GNUNET_HashCode *hash, void *value)
Function that frees everything from a hashmap.
static int setup_exit_helper_args()
Initialize exit_argv.
enum State state
current state of profiling
struct GNUNET_CADET_Port * GNUNET_CADET_open_port(struct GNUNET_CADET_Handle *h, const struct GNUNET_HashCode *port, GNUNET_CADET_ConnectEventHandler connects, void *connects_cls, GNUNET_CADET_WindowSizeEventHandler window_changes, GNUNET_CADET_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Open a port to receive incomming MQ-based channels.
Definition: cadet_api.c:970
static struct GNUNET_DNSSTUB_Context * dnsstub
Handle to the DNS Stub resolver.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
static char * value
Value of the record to add/remove.
#define GNUNET_APPLICATION_PORT_IPV6_GATEWAY
Internet IPv6 gateway (any TCP/UDP/ICMP).
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:79
#define GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY
Type of messages containing an UDP packet from a remote host.
static struct GNUNET_CONTAINER_MultiHashMap * services
This hashmaps saves interesting things about the configured services.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
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:109
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
struct GNUNET_DNSSTUB_Context * GNUNET_DNSSTUB_start(unsigned int num_sockets)
Start a DNS stub resolver.
Definition: dnsstub.c:564
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
int16_t is_udp
GNUNET_YES if this is a UDP service, otherwise TCP.
#define GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG
static void store_service(int proto, const char *name, uint16_t destination_port, struct LocalService *service)
Given a service descriptor and a destination port, find the respective service entry.
uint16_t destination_port
Destination port to use for the UDP request.
Definition: exit.h:165
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
static int global_ret
Return value from &#39;main&#39;.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1296
union ChannelState::@10 specifics
static struct GNUNET_CADET_Port * dns_port
Port for DNS exit.
static struct GNUNET_DHT_PutHandle * dht_put
Handle for ongoing DHT PUT operations to advertise exit service.
uint32_t reserved
Always 0.
Definition: exit.h:47
Message send via cadet to an exit daemon to forward ICMP data to the Internet.
Definition: exit.h:236
#define GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START
Type of messages containing an TCP packet for the Internet.
#define GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN
Type of messages containing an TCP packet of an established connection.
static char buf[2048]
struct SocketAddress local_address
Address information we used locally (AF and proto must match "remote_address").
static void cleanup(void *cls)
Function scheduled as very last function, cleans up after us.
int 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.
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 ...
void GNUNET_TUN_service_name_to_hash(const char *service_name, struct GNUNET_HashCode *hc)
Hash the service name of a hosted service to the hash code that is used to identify the service on th...
Definition: regex.c:814
Handle to a node in a heap.
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:282
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!)...
static struct in_addr exit_ipv4addr
IPv4 address of our TUN interface.
Heap with the minimum cost at the root.
static void * new_service_channel(void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *initiator)
Callback from CADET for new channels.
void GNUNET_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.
A 512-bit hashcode.
static int check_udp_service(void *cls, const struct GNUNET_EXIT_UdpServiceMessage *msg)
Check a request via cadet to send a request to a UDP service offered by this system.
Handle to the stub resolver.
Definition: dnsstub.c:123
Header from Linux TUN interface.
uint8_t next_header
For example, IPPROTO_UDP or IPPROTO_TCP.
Message send from exit daemon back to the UDP entry point (used for both Internet and Service exit re...
Definition: exit.h:178
static int check_dns_request(void *cls, const struct DnsResponseMessage *msg)
Check a request via cadet to perform a DNS query.
Message handler for a specific message type.
uint16_t destination_port
Destination port (in NBO).
static int res
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg_)
Main function that will be run by the scheduler.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
struct LocalService * serv
Associated service record, or NULL for no service.
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
static int ipv4_enabled
Do we support IPv4 at all on the TUN interface?
struct GNUNET_PeerIdentity peer
The peer providing this service.
Definition: block_dns.h:61
static void send_icmp_packet_via_tun(const struct SocketAddress *destination_address, const struct SocketAddress *source_address, const struct GNUNET_TUN_IcmpHeader *icmp_header, const void *payload, size_t payload_length)
Send an ICMP packet via the TUN interface.
static void icmp_from_helper(const struct GNUNET_TUN_IcmpHeader *icmp, size_t pktlen, int af, const void *destination_ip, const void *source_ip)
Handles an ICMP packet received from the helper.
struct GNUNET_HashCode state_key
Key this state has in the connections_map.
static void add_services(int proto, char *cpy, const char *name)
Add services to the service map.
int 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.
struct GNUNET_DNSSTUB_RequestSocket * GNUNET_DNSSTUB_resolve(struct GNUNET_DNSSTUB_Context *ctx, const void *request, size_t request_len, GNUNET_DNSSTUB_ResultCallback rc, void *rc_cls)
Perform DNS resolution using our default IP from init.
Definition: dnsstub.c:504
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
Node in the heap.
static const struct GNUNET_CONFIGURATION_Handle * cfg
The handle to the configuration used throughout the process.
#define GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX
Internet exit regex prefix.
unsigned int GNUNET_CONTAINER_heap_get_size(const struct GNUNET_CONTAINER_Heap *heap)
Get the current size of the heap.
static void * new_channel(void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *initiator)
Callback from CADET for new channels.
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:833
static int ipv4_exit
Are we an IPv4-exit?
static struct ChannelState * get_redirect_state(int af, int protocol, const void *destination_ip, uint16_t destination_port, const void *local_ip, uint16_t local_port, struct GNUNET_HashCode *state_key)
Get our connection tracking state.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
format for cadet messages exchanged between VPN service and exit daemon
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
struct GNUNET_HashCode key
The key used in the DHT.
struct GNUNET_DHT_PutHandle * GNUNET_DHT_put(struct GNUNET_DHT_Handle *handle, const struct GNUNET_HashCode *key, uint32_t desired_replication_level, enum GNUNET_DHT_RouteOption options, enum GNUNET_BLOCK_Type type, size_t size, const void *data, struct GNUNET_TIME_Absolute exp, GNUNET_SCHEDULER_TaskCallback cont, void *cont_cls)
Perform a PUT operation storing data in the DHT.
Definition: dht_api.c:966
static unsigned int size
Size of the "table".
Definition: peer.c:67
struct GNUNET_DHT_Handle * GNUNET_DHT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, unsigned int ht_len)
Initialize the connection with the DHT service.
Definition: dht_api.c:890
uint8_t proto
IPPROTO_TCP or IPPROTO_UDP;.
#define GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE
struct SocketAddress address
Remote address to use for the service.
void GNUNET_DHT_disconnect(struct GNUNET_DHT_Handle *handle)
Shutdown connection with the DHT service.
Definition: dht_api.c:918
static void do_dht_put(void *cls)
We are running a DNS exit service, advertise it in the DHT.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
void GNUNET_TUN_calculate_icmp_checksum(struct GNUNET_TUN_IcmpHeader *icmp, const void *payload, uint16_t payload_length)
Calculate ICMP checksum.
Definition: tun.c:260
Message send via cadet to the vpn service to send ICMP data to the VPN&#39;s TUN interface.
Definition: exit.h:271
struct GNUNET_TUN_DnsHeader dns
DNS header.
TCP packet header.
int 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.
static unsigned long long payload
How much data are we currently storing in the database?
static struct GNUNET_CONTAINER_Heap * connections_heap
Heap so we can quickly find "old" connections.
static struct GNUNET_CRYPTO_EddsaPrivateKey * peer_key
Private key for this peer.
static struct GNUNET_NETWORK_Handle * ls
Listen socket for STUN processing.
Definition: gnunet-nat.c:85
uint16_t crc
Checksum.
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
an ECC signature using EdDSA.
static int tcp
Option -t: TCP requested.
Definition: gnunet-vpn.c:71
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
void GNUNET_CRYPTO_eddsa_key_get_public(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:193
Standard IPv6 header.
static void handle_tcp_service(void *cls, const struct GNUNET_EXIT_TcpServiceStartMessage *start)
Process a request via cadet to send a request to a TCP service offered by this system.
#define GNUNET_TUN_ICMPTYPE_ECHO_REQUEST
#define GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM
Message send via cadet to an exit daemon to send UDP data to a local service.
Definition: exit.h:120
uint8_t protocol
L4-protocol, for example, IPPROTO_UDP or IPPROTO_TCP.
uint16_t source_port
Source port (in NBO).
struct GNUNET_REGEX_Announcement * GNUNET_REGEX_announce(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *regex, struct GNUNET_TIME_Relative refresh_delay, uint16_t compression)
Announce this peer under the given regular expression.
struct SocketAddress remote_address
Address information for the other party (equivalent of the arguments one would give to "connect")...
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won&#39;t work on W32;.
Private ECC key encoded for transmission.
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
static struct GNUNET_REGEX_Announcement * regex6
Handle to our regex announcement for IPv4.
static void send_packet_to_cadet_channel(struct ChannelState *s, struct GNUNET_MQ_Envelope *env)
Send the given packet via the cadet channel.
int af
AF_INET or AF_INET6.
The identity of the host (wraps the signing key of the peer).
#define GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST
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:888
uint16_t my_id
DNS request ID that we used for forwarding.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET.
Definition: exit.h:150
Handle to a PUT request.
Definition: dht_api.c:43
static char * hostname
Our hostname; we give this to all the peers we start.
static void make_up_icmpv4_payload(struct ChannelState *state, struct GNUNET_TUN_IPv4Header *ipp, struct GNUNET_TUN_UdpHeader *udp)
Synthesize a plausible ICMP payload for an ICMPv4 error response on the given channel.
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to &#39;struct&#39;s...
#define GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN
Type of messages containing an ICMP packet for the VPN.
configuration data
Definition: configuration.c:84
char * GNUNET_TUN_ipv6policy2regex(const char *policy)
Convert an exit policy to a regular expression.
Definition: regex.c:759
const char * name
static struct GNUNET_HashCode dht_put_key
Key we store the DNS advertismenet under.
uint16_t source_port
Source port (in NBO).
static void dht_put_cont(void *cls)
Function called when the DHT PUT operation is complete.
Message with a DNS response.
struct GNUNET_HashCode descriptor
Descriptor for the service (CADET port).
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
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:657
Information we use to track a connection (the classical 6-tuple of IP-version, protocol, source-IP, destination-IP, source-port and destinatin-port.
static void handle_dns_request(void *cls, const struct DnsResponseMessage *msg)
Process a request via cadet to perform a DNS query.
int GNUNET_CRYPTO_eddsa_sign_(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_EddsaSignature *sig)
EdDSA sign a given block.
Definition: crypto_ecc.c:707
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START.
Definition: exit.h:68
uint16_t destination_port
Destination port used by the sender on our end; 0 for uninitialized.
void GNUNET_CONFIGURATION_iterate_sections(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_CONFIGURATION_Section_Iterator iter, void *iter_cls)
Iterate over all sections in the configuration.
static struct GNUNET_CADET_Port * cadet_port6
Port for IPv6 exit.
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
void * GNUNET_CONTAINER_heap_remove_root(struct GNUNET_CONTAINER_Heap *heap)
Remove root of the heap.
static void send_tcp_packet_via_tun(const struct SocketAddress *destination_address, const struct SocketAddress *source_address, const struct GNUNET_TUN_TcpHeader *tcp_header, const void *payload, size_t payload_length)
Send a TCP packet via the TUN interface.
struct ChannelState::@10::@11 tcp_udp
static void advertise_dns_exit()
Helper function to open the CADET port for DNS exits and to advertise the DNS exit (if applicable)...
uint16_t payload_length
Length of the payload, excluding this header.
uint16_t port
Remote port, in host byte order!
#define GNUNET_APPLICATION_PORT_INTERNET_RESOLVER
Internet DNS resolution (external DNS gateway).
Message send via cadet to an exit daemon to initiate forwarding of TCP data to the Internet...
Definition: exit.h:63
Opaque handle to a port.
Definition: cadet_api.c:79
uint16_t original_id
Original DNS request ID as used by the client.
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:218
int is_dns
GNUNET_NO if this is a channel for TCP/UDP, GNUNET_YES if this is a channel for DNS, GNUNET_SYSERR if the channel is not yet initialized.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
Information about an address.
int GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration, parse options).
Definition: program.c:367
#define REGEX_MAX_PATH_LEN_IPV6
Maximum path compression length for cadet regex announcing for IPv6 address based regex...
struct GNUNET_CRYPTO_EddsaPrivateKey * GNUNET_CRYPTO_eddsa_key_create_from_configuration(const struct GNUNET_CONFIGURATION_Handle *cfg)
Create a new private key by reading our peer&#39;s key from the file specified in the configuration...
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:331
static int message_token(void *cls, const struct GNUNET_MessageHeader *message)
Receive packets from the helper-process.
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
struct GNUNET_MessageHeader header
Type is #GNUNET_MESSAGE_TYPE_VPN_TCP_DATA.
Definition: exit.h:99
Header for all communications.
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
void GNUNET_CADET_close_port(struct GNUNET_CADET_Port *p)
Close a port opened with GNUNET_CADET_open_port().
Definition: cadet_api.c:808
Time for absolute times used by GNUnet, in microseconds.
static struct GNUNET_CADET_Port * cadet_port4
Port for IPv4 exit.
struct GNUNET_DNSSTUB_RequestSocket * rs
Socket we are using to transmit this request (must match if we receive a response).
#define REGEX_REFRESH_FREQUENCY
How frequently do we re-announce the regex for the exit?
static struct GNUNET_SCHEDULER_Task * dht_task
Task for doing DHT PUTs to advertise exit service.
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:355
#define DNS_ADVERTISEMENT_TIMEOUT
How long do we typically sign the DNS exit advertisement for?
static struct GNUNET_CONTAINER_MultiHashMap * connections_map
This hashmaps contains the mapping from peer, service-descriptor, source-port and destination-port to...
static void dummy_task(void *cls)
Function scheduled as very last function if the service disabled itself because the helper is not ins...
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does this signature expire?
Definition: block_dns.h:56
uint16_t total_length
Length of the packet, including this header.
static struct ChannelState * channels[UINT16_MAX+1]
Array of all open DNS requests from channels.
unsigned int off
Number of 32-bit words in TCP header.
UDP socket we are using for sending DNS requests to the Internet.
Definition: dnsstub.c:44
int GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START.
Definition: exit.h:42
uint16_t source_port
Source port to use for the UDP request (0 to use a random port).
Definition: exit.h:160
Message send via cadet to an exit daemon to initiate forwarding of TCP data to a local service...
Definition: exit.h:37
uint32_t data
The data value.
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
#define GNUNET_TUN_ICMPTYPE_ECHO_REPLY
struct GNUNET_PeerIdentity peer
Who is the other end of this channel.
#define GNUNET_APPLICATION_PORT_IPV4_GATEWAY
Internet IPv4 gateway (any TCP/UDP/ICMP).
static struct GNUNET_DHT_Handle * dht
Handle to the DHT.
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:657
Message send via cadet between VPN and entry and an exit daemon to transmit TCP data between the VPN ...
Definition: exit.h:94
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:837
uint32_t reserved
Always 0.
Definition: exit.h:104
struct GNUNET_TUN_IcmpHeader icmp_header
ICMP header to use.
Definition: exit.h:223
static int check_tcp_service(void *cls, const struct GNUNET_EXIT_TcpServiceStartMessage *start)
Check a request via cadet to send a request to a TCP service offered by this system.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
static void clean_channel(void *cls, const struct GNUNET_CADET_Channel *channel)
Function called by cadet whenever an inbound channel is destroyed.
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:81
uint16_t source_port
Source port to use for the UDP request (0 to use a random port).
Definition: exit.h:130
uint16_t crc
Checksum.
struct GNUNET_TUN_IcmpHeader icmp_header
ICMP header to use.
Definition: exit.h:255
union ChannelState::@89 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
static void send_udp_packet_via_tun(const struct SocketAddress *destination_address, const struct SocketAddress *source_address, const void *payload, size_t payload_length)
Send a UDP packet via the TUN interface.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE.
Definition: exit.h:210
#define ETH_P_IPV4
Number for IPv4.
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
int GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition: network.c:85
Message send via cadet to an exit daemon to forward UDP data to the Internet.
Definition: exit.h:145
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_CRYPTO_EddsaPublicKey public_key
#define GNUNET_MESSAGE_TYPE_VPN_HELPER
Type of messages between the gnunet-vpn-helper and the daemon.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
#define gettext_noop(String)
Definition: gettext.h:69
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:1082
static GNUNET_NETWORK_STRUCT_END void process_dns_result(void *cls, const struct GNUNET_TUN_DnsHeader *dns, size_t r)
Callback called from DNSSTUB resolver when a resolution succeeded.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972
uint16_t destination_port
Destination port to use for the UDP request.
Definition: exit.h:135
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET.
Definition: exit.h:241