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_non_null (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_non_null (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++)
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_non_null (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_non_null (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_non_null (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_non_null (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_non_null (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_non_null (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:841
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:489
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:1300
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:1438
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.
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:986
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:565
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
#define GNUNET_NO
Definition: gnunet_common.h:78
Opaque handle to a channel.
Definition: cadet_api.c:80
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
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
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
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:526
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:976
#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:181
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:1253
#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:1010
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:1280
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
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
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.
union ChannelState::@86 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
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:270
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:954
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:85
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:655
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.
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:145
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:874
Time for absolute times used by GNUnet, in microseconds.
static struct GNUNET_CADET_Port * cadet_port4
Port for IPv4 exit.
#define GNUNET_YES
Definition: gnunet_common.h:77
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:353
#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:903
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
#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:1119
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:966
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