GNUnet  0.10.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 (GNUNET_TIME_UNIT_MINUTES, 30)
70 
74 #define DHT_PUT_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)
75 
79 #define DNS_ADVERTISEMENT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 3)
80 
81 
85 #define LOG(kind, ...) \
86  GNUNET_log_from (kind, "exit", __VA_ARGS__);
87 
88 
93 {
97  int af;
98 
102  union
103  {
107  struct in_addr ipv4;
108 
112  struct in6_addr ipv6;
113  } address;
114 
118  uint8_t proto;
119 
123  uint16_t port;
124 
125 };
126 
127 
134 {
135 
140 
144  struct GNUNET_HashCode descriptor;
145 
149  char *name;
150 
155 
159  int16_t is_udp;
160 
161 };
162 
163 
170 {
171 
176  struct SocketAddress remote_address;
177 
183  struct SocketAddress local_address;
184 
185  /*
186  Note 1: additional information might be added here in the
187  future to support protocols that require special handling,
188  such as ftp/tftp
189 
190  Note 2: we might also sometimes not match on all components
191  of the tuple, to support protocols where things do not always
192  fully map.
193  */
194 };
195 
196 
204 {
209 
215 
221  int is_dns;
222 
223  union
224  {
225  struct
226  {
227 
232 
236  struct GNUNET_HashCode state_key;
237 
242 
247  } tcp_udp;
248 
249  struct
250  {
251 
257 
261  uint16_t original_id;
262 
266  uint16_t my_id;
267 
268  } dns;
269 
270  } specifics;
271 
272 };
273 
274 
278 static int global_ret;
279 
284 
289 
293 static const struct GNUNET_CONFIGURATION_Handle *cfg;
294 
299 
303 static char *exit_argv[8];
304 
308 static struct in6_addr exit_ipv6addr;
309 
313 static unsigned long long ipv6prefix;
314 
318 static struct in_addr exit_ipv4addr;
319 
323 static struct in_addr exit_ipv4mask;
324 
329 
334 
340 
345 
349 static unsigned long long max_connections;
350 
355 
359 static struct ChannelState *channels[UINT16_MAX + 1];
360 
365 
370 
374 static struct GNUNET_DHT_Handle *dht;
375 
380 
386 
391 
396 
401 
406 
411 
415 static int ipv4_exit;
416 
420 static int ipv6_exit;
421 
425 static int ipv4_enabled;
426 
430 static int ipv6_enabled;
431 
432 
434 
439 {
443  struct GNUNET_MessageHeader header;
444 
449 
450  /* Followed by more DNS payload */
451 };
452 
454 
455 
464 static void
466  const struct GNUNET_TUN_DnsHeader *dns,
467  size_t r)
468 {
469  struct ChannelState *ts;
470  struct GNUNET_MQ_Envelope *env;
471  struct DnsResponseMessage *resp;
472 
474  "Processing DNS result from stub resolver\n");
475  GNUNET_assert (NULL == cls);
476  if (NULL == dns)
477  return;
478  /* Handle case that this is a reply to a request from a CADET DNS channel */
479  ts = channels[dns->id];
480  if (NULL == ts)
481  return;
483  "Got a response from the stub resolver for DNS request received via CADET!\n");
484  channels[dns->id] = NULL;
485  env = GNUNET_MQ_msg_extra (resp,
486  r - sizeof (struct GNUNET_TUN_DnsHeader),
488  GNUNET_memcpy (&resp->dns,
489  dns,
490  r);
491  resp->dns.id = ts->specifics.dns.original_id;
493  env);
494 }
495 
496 
505 static int
506 check_dns_request (void *cls,
507  const struct DnsResponseMessage *msg)
508 {
509  struct ChannelState *ts = cls;
510 
511  if (NULL == dnsstub)
512  {
513  GNUNET_break (0);
514  return GNUNET_SYSERR;
515  }
516  if (GNUNET_NO == ts->is_dns)
517  {
518  GNUNET_break_op (0);
519  return GNUNET_SYSERR;
520  }
521  return GNUNET_OK;
522 }
523 
524 
531 static void
533  const struct DnsResponseMessage *msg)
534 {
535  struct ChannelState *ts = cls;
536  size_t mlen = ntohs (msg->header.size);
537  size_t dlen = mlen - sizeof (struct GNUNET_MessageHeader);
538  char buf[dlen] GNUNET_ALIGN;
539  struct GNUNET_TUN_DnsHeader *dout;
540 
541  if (GNUNET_SYSERR == ts->is_dns)
542  {
543  /* channel is DNS from now on */
544  ts->is_dns = GNUNET_YES;
545  }
546  ts->specifics.dns.original_id = msg->dns.id;
547  if (channels[ts->specifics.dns.my_id] == ts)
548  channels[ts->specifics.dns.my_id] = NULL;
550  UINT16_MAX + 1);
551  channels[ts->specifics.dns.my_id] = ts;
553  &msg->dns,
554  dlen);
555  dout = (struct GNUNET_TUN_DnsHeader *) buf;
556  dout->id = ts->specifics.dns.my_id;
557  ts->specifics.dns.rs = GNUNET_DNSSTUB_resolve (dnsstub,
558  buf,
559  dlen,
561  NULL);
562  if (NULL == ts->specifics.dns.rs)
563  {
564  GNUNET_break_op (0);
565  return;
566  }
568 }
569 
570 
578 static void
580  const struct RedirectInformation *ri)
581 {
582  char *off;
583 
584  memset (hash,
585  0,
586  sizeof (struct GNUNET_HashCode));
587  /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
588  so we put the IP address in there (and hope for few collisions) */
589  off = (char*) hash;
590  switch (ri->remote_address.af)
591  {
592  case AF_INET:
593  GNUNET_memcpy (off,
595  sizeof (struct in_addr));
596  off += sizeof (struct in_addr);
597  break;
598  case AF_INET6:
599  GNUNET_memcpy (off,
601  sizeof (struct in6_addr));
602  off += sizeof (struct in_addr);
603  break;
604  default:
605  GNUNET_assert (0);
606  }
607  GNUNET_memcpy (off,
608  &ri->remote_address.port,
609  sizeof (uint16_t));
610  off += sizeof (uint16_t);
611  switch (ri->local_address.af)
612  {
613  case AF_INET:
614  GNUNET_memcpy (off,
616  sizeof (struct in_addr));
617  off += sizeof (struct in_addr);
618  break;
619  case AF_INET6:
620  GNUNET_memcpy (off,
622  sizeof (struct in6_addr));
623  off += sizeof (struct in_addr);
624  break;
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 
702 
712 static int
713 check_tcp_service (void *cls,
715 {
716  struct ChannelState *state = cls;
717 
718  if (NULL == state)
719  {
720  GNUNET_break_op (0);
721  return GNUNET_SYSERR;
722  }
723  if (GNUNET_YES == state->is_dns)
724  {
725  GNUNET_break_op (0);
726  return GNUNET_SYSERR;
727  }
728  if (NULL == state->specifics.tcp_udp.serv)
729  {
730  GNUNET_break_op (0);
731  return GNUNET_SYSERR;
732  }
733  if (NULL != state->specifics.tcp_udp.heap_node)
734  {
735  GNUNET_break_op (0);
736  return GNUNET_SYSERR;
737  }
738  if (start->tcp_header.off * 4 < sizeof (struct GNUNET_TUN_TcpHeader))
739  {
740  GNUNET_break_op (0);
741  return GNUNET_SYSERR;
742  }
743  return GNUNET_OK;
744 }
745 
746 
765 static void
767  size_t payload_length,
768  int protocol,
769  const struct GNUNET_TUN_TcpHeader *tcp_header,
770  const struct SocketAddress *src_address,
771  const struct SocketAddress *dst_address,
772  struct GNUNET_TUN_IPv4Header *pkt4)
773 {
774  size_t len;
775 
776  len = payload_length;
777  switch (protocol)
778  {
779  case IPPROTO_UDP:
780  len += sizeof (struct GNUNET_TUN_UdpHeader);
781  break;
782  case IPPROTO_TCP:
783  len += sizeof (struct GNUNET_TUN_TcpHeader);
784  GNUNET_assert (NULL != tcp_header);
785  break;
786  default:
787  GNUNET_break (0);
788  return;
789  }
790  if (len + sizeof (struct GNUNET_TUN_IPv4Header) > UINT16_MAX)
791  {
792  GNUNET_break (0);
793  return;
794  }
795 
797  protocol,
798  len,
799  &src_address->address.ipv4,
800  &dst_address->address.ipv4);
801  switch (protocol)
802  {
803  case IPPROTO_UDP:
804  {
805  struct GNUNET_TUN_UdpHeader *pkt4_udp = (struct GNUNET_TUN_UdpHeader *) &pkt4[1];
806 
807  pkt4_udp->source_port = htons (src_address->port);
808  pkt4_udp->destination_port = htons (dst_address->port);
809  pkt4_udp->len = htons ((uint16_t) payload_length);
811  pkt4_udp,
812  payload,
813  payload_length);
814  GNUNET_memcpy (&pkt4_udp[1],
815  payload,
816  payload_length);
817  }
818  break;
819  case IPPROTO_TCP:
820  {
821  struct GNUNET_TUN_TcpHeader *pkt4_tcp = (struct GNUNET_TUN_TcpHeader *) &pkt4[1];
822 
823  *pkt4_tcp = *tcp_header;
825  "Sending TCP packet from port %u to port %u\n",
826  src_address->port,
827  dst_address->port);
828  pkt4_tcp->source_port = htons (src_address->port);
829  pkt4_tcp->destination_port = htons (dst_address->port);
831  pkt4_tcp,
832  payload,
833  payload_length);
834  GNUNET_memcpy (&pkt4_tcp[1],
835  payload,
836  payload_length);
837  }
838  break;
839  default:
840  GNUNET_assert (0);
841  }
842 }
843 
844 
863 static void
865  size_t payload_length,
866  int protocol,
867  const struct GNUNET_TUN_TcpHeader *tcp_header,
868  const struct SocketAddress *src_address,
869  const struct SocketAddress *dst_address,
870  struct GNUNET_TUN_IPv6Header *pkt6)
871 {
872  size_t len;
873 
874  len = payload_length;
875  switch (protocol)
876  {
877  case IPPROTO_UDP:
878  len += sizeof (struct GNUNET_TUN_UdpHeader);
879  break;
880  case IPPROTO_TCP:
881  len += sizeof (struct GNUNET_TUN_TcpHeader);
882  break;
883  default:
884  GNUNET_break (0);
885  return;
886  }
887  if (len > UINT16_MAX)
888  {
889  GNUNET_break (0);
890  return;
891  }
892 
894  protocol,
895  len,
896  &src_address->address.ipv6,
897  &dst_address->address.ipv6);
898 
899  switch (protocol)
900  {
901  case IPPROTO_UDP:
902  {
903  struct GNUNET_TUN_UdpHeader *pkt6_udp = (struct GNUNET_TUN_UdpHeader *) &pkt6[1];
904 
905  pkt6_udp->source_port = htons (src_address->port);
906  pkt6_udp->destination_port = htons (dst_address->port);
907  pkt6_udp->len = htons ((uint16_t) payload_length);
909  pkt6_udp,
910  payload,
911  payload_length);
912  GNUNET_memcpy (&pkt6_udp[1],
913  payload,
914  payload_length);
915  }
916  break;
917  case IPPROTO_TCP:
918  {
919  struct GNUNET_TUN_TcpHeader *pkt6_tcp = (struct GNUNET_TUN_TcpHeader *) &pkt6[1];
920 
921  /* GNUNET_memcpy first here as some TCP header fields are initialized this way! */
922  *pkt6_tcp = *tcp_header;
923  pkt6_tcp->source_port = htons (src_address->port);
924  pkt6_tcp->destination_port = htons (dst_address->port);
926  pkt6_tcp,
927  payload,
928  payload_length);
929  GNUNET_memcpy (&pkt6_tcp[1],
930  payload,
931  payload_length);
932  }
933  break;
934  default:
935  GNUNET_assert (0);
936  break;
937  }
938 }
939 
940 
950 static void
951 send_tcp_packet_via_tun (const struct SocketAddress *destination_address,
952  const struct SocketAddress *source_address,
953  const struct GNUNET_TUN_TcpHeader *tcp_header,
954  const void *payload,
955  size_t payload_length)
956 {
957  size_t len;
958 
960  gettext_noop ("# TCP packets sent via TUN"),
961  1,
962  GNUNET_NO);
964  "Sending packet with %u bytes TCP payload via TUN\n",
965  (unsigned int) payload_length);
966  len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader);
967  switch (source_address->af)
968  {
969  case AF_INET:
970  len += sizeof (struct GNUNET_TUN_IPv4Header);
971  break;
972  case AF_INET6:
973  len += sizeof (struct GNUNET_TUN_IPv6Header);
974  break;
975  default:
976  GNUNET_break (0);
977  return;
978  }
979  len += sizeof (struct GNUNET_TUN_TcpHeader);
980  len += payload_length;
981  if (len >= GNUNET_MAX_MESSAGE_SIZE)
982  {
983  GNUNET_break (0);
984  return;
985  }
986  {
987  char buf[len] GNUNET_ALIGN;
988  struct GNUNET_MessageHeader *hdr;
989  struct GNUNET_TUN_Layer2PacketHeader *tun;
990 
991  hdr = (struct GNUNET_MessageHeader *) buf;
992  hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
993  hdr->size = htons (len);
994  tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
995  tun->flags = htons (0);
996  switch (source_address->af)
997  {
998  case AF_INET:
999  {
1000  struct GNUNET_TUN_IPv4Header *ipv4
1001  = (struct GNUNET_TUN_IPv4Header*) &tun[1];
1002 
1003  tun->proto = htons (ETH_P_IPV4);
1004  prepare_ipv4_packet (payload,
1005  payload_length,
1006  IPPROTO_TCP,
1007  tcp_header,
1008  source_address,
1009  destination_address,
1010  ipv4);
1011  }
1012  break;
1013  case AF_INET6:
1014  {
1015  struct GNUNET_TUN_IPv6Header *ipv6
1016  = (struct GNUNET_TUN_IPv6Header*) &tun[1];
1017 
1018  tun->proto = htons (ETH_P_IPV6);
1019  prepare_ipv6_packet (payload,
1020  payload_length,
1021  IPPROTO_TCP,
1022  tcp_header,
1023  source_address,
1024  destination_address,
1025  ipv6);
1026  }
1027  break;
1028  default:
1029  GNUNET_assert (0);
1030  break;
1031  }
1032  if (NULL != helper_handle)
1033  (void) GNUNET_HELPER_send (helper_handle,
1034  (const struct GNUNET_MessageHeader*) buf,
1035  GNUNET_YES,
1036  NULL,
1037  NULL);
1038  }
1039 }
1040 
1041 
1051 static void
1053  const struct SocketAddress *source_address,
1054  const struct GNUNET_TUN_IcmpHeader *icmp_header,
1055  const void *payload, size_t payload_length)
1056 {
1057  size_t len;
1058  struct GNUNET_TUN_IcmpHeader *icmp;
1059 
1060  GNUNET_STATISTICS_update (stats,
1061  gettext_noop ("# ICMP packets sent via TUN"),
1062  1, GNUNET_NO);
1064  "Sending packet with %u bytes ICMP payload via TUN\n",
1065  (unsigned int) payload_length);
1066  len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader);
1067  switch (destination_address->af)
1068  {
1069  case AF_INET:
1070  len += sizeof (struct GNUNET_TUN_IPv4Header);
1071  break;
1072  case AF_INET6:
1073  len += sizeof (struct GNUNET_TUN_IPv6Header);
1074  break;
1075  default:
1076  GNUNET_break (0);
1077  return;
1078  }
1079  len += sizeof (struct GNUNET_TUN_IcmpHeader);
1080  len += payload_length;
1081  if (len >= GNUNET_MAX_MESSAGE_SIZE)
1082  {
1083  GNUNET_break (0);
1084  return;
1085  }
1086  {
1087  char buf[len] GNUNET_ALIGN;
1088  struct GNUNET_MessageHeader *hdr;
1089  struct GNUNET_TUN_Layer2PacketHeader *tun;
1090 
1091  hdr= (struct GNUNET_MessageHeader *) buf;
1092  hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1093  hdr->size = htons (len);
1094  tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1095  tun->flags = htons (0);
1096  switch (source_address->af)
1097  {
1098  case AF_INET:
1099  {
1100  struct GNUNET_TUN_IPv4Header * ipv4 = (struct GNUNET_TUN_IPv4Header*) &tun[1];
1101 
1102  tun->proto = htons (ETH_P_IPV4);
1104  IPPROTO_ICMP,
1105  sizeof (struct GNUNET_TUN_IcmpHeader) + payload_length,
1106  &source_address->address.ipv4,
1107  &destination_address->address.ipv4);
1108  icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv4[1];
1109  }
1110  break;
1111  case AF_INET6:
1112  {
1113  struct GNUNET_TUN_IPv6Header * ipv6 = (struct GNUNET_TUN_IPv6Header*) &tun[1];
1114 
1115  tun->proto = htons (ETH_P_IPV6);
1117  IPPROTO_ICMPV6,
1118  sizeof (struct GNUNET_TUN_IcmpHeader) + payload_length,
1119  &source_address->address.ipv6,
1120  &destination_address->address.ipv6);
1121  icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv6[1];
1122  }
1123  break;
1124  default:
1125  GNUNET_assert (0);
1126  break;
1127  }
1128  *icmp = *icmp_header;
1129  GNUNET_memcpy (&icmp[1],
1130  payload,
1131  payload_length);
1133  payload,
1134  payload_length);
1135  if (NULL != helper_handle)
1136  (void) GNUNET_HELPER_send (helper_handle,
1137  (const struct GNUNET_MessageHeader*) buf,
1138  GNUNET_YES,
1139  NULL, NULL);
1140  }
1141 }
1142 
1143 
1152 static void
1154  uint8_t proto,
1155  struct SocketAddress *local_address)
1156 {
1157  local_address->af = af;
1158  local_address->proto = (uint8_t) proto;
1159  /* default "local" port range is often 32768--61000,
1160  so we pick a random value in that range */
1161  if ( ( (af == AF_INET) && (proto == IPPROTO_ICMP) ) ||
1162  ( (af == AF_INET6) && (proto == IPPROTO_ICMPV6) ) )
1163  local_address->port = 0;
1164  else
1165  local_address->port
1167  28232);
1168  switch (af)
1169  {
1170  case AF_INET:
1171  {
1172  struct in_addr addr;
1173  struct in_addr mask;
1174  struct in_addr rnd;
1175 
1176  addr = exit_ipv4addr;
1177  mask = exit_ipv4mask;
1178  if (0 == ~mask.s_addr)
1179  {
1180  /* only one valid IP anyway */
1181  local_address->address.ipv4 = addr;
1182  return;
1183  }
1184  /* Given 192.168.0.1/255.255.0.0, we want a mask
1185  of '192.168.255.255', thus: */
1186  mask.s_addr = addr.s_addr | ~mask.s_addr;
1187  /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
1188  do
1189  {
1191  UINT32_MAX);
1192  local_address->address.ipv4.s_addr = (addr.s_addr | rnd.s_addr) & mask.s_addr;
1193  }
1194  while ( (local_address->address.ipv4.s_addr == addr.s_addr) ||
1195  (local_address->address.ipv4.s_addr == mask.s_addr) );
1196  }
1197  break;
1198  case AF_INET6:
1199  {
1200  struct in6_addr addr;
1201  struct in6_addr mask;
1202  struct in6_addr rnd;
1203  int i;
1204 
1205  addr = exit_ipv6addr;
1206  GNUNET_assert (ipv6prefix < 128);
1207  if (ipv6prefix == 127)
1208  {
1209  /* only one valid IP anyway */
1210  local_address->address.ipv6 = addr;
1211  return;
1212  }
1213  /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
1214  thus: */
1215  mask = addr;
1216  for (i=127;i>=ipv6prefix;i--)
1217  mask.s6_addr[i / 8] |= (1 << (i % 8));
1218 
1219  /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */
1220  do
1221  {
1222  for (i=0;i<16;i++)
1223  {
1224  rnd.s6_addr[i] = (unsigned char) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
1225  256);
1226  local_address->address.ipv6.s6_addr[i]
1227  = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
1228  }
1229  }
1230  while ( (0 == GNUNET_memcmp (&local_address->address.ipv6,
1231  &addr)) ||
1232  (0 == GNUNET_memcmp (&local_address->address.ipv6,
1233  &mask)) );
1234  }
1235  break;
1236  default:
1237  GNUNET_assert (0);
1238  }
1239 }
1240 
1241 
1263 static void
1265 {
1266  struct GNUNET_HashCode key;
1267  struct ChannelState *s;
1268 
1269  /* generate fresh, unique address */
1270  do
1271  {
1272  if (NULL == state->specifics.tcp_udp.serv)
1273  setup_fresh_address (state->specifics.tcp_udp.ri.remote_address.af,
1274  state->specifics.tcp_udp.ri.remote_address.proto,
1275  &state->specifics.tcp_udp.ri.local_address);
1276  else
1277  setup_fresh_address (state->specifics.tcp_udp.serv->address.af,
1278  state->specifics.tcp_udp.serv->address.proto,
1279  &state->specifics.tcp_udp.ri.local_address);
1280  } while (NULL !=
1281  get_redirect_state (state->specifics.tcp_udp.ri.remote_address.af,
1282  state->specifics.tcp_udp.ri.remote_address.proto,
1283  &state->specifics.tcp_udp.ri.remote_address.address,
1284  state->specifics.tcp_udp.ri.remote_address.port,
1285  &state->specifics.tcp_udp.ri.local_address.address,
1286  state->specifics.tcp_udp.ri.local_address.port,
1287  &key));
1288  {
1289  char buf[INET6_ADDRSTRLEN];
1291  "Picked local address %s:%u for new connection\n",
1292  inet_ntop (state->specifics.tcp_udp.ri.local_address.af,
1293  &state->specifics.tcp_udp.ri.local_address.address,
1294  buf,
1295  sizeof (buf)),
1296  (unsigned int) state->specifics.tcp_udp.ri.local_address.port);
1297  }
1298  state->specifics.tcp_udp.state_key = key;
1300  GNUNET_CONTAINER_multihashmap_put (connections_map,
1301  &key, state,
1303  state->specifics.tcp_udp.heap_node
1304  = GNUNET_CONTAINER_heap_insert (connections_heap,
1305  state,
1306  GNUNET_TIME_absolute_get ().abs_value_us);
1307  while (GNUNET_CONTAINER_heap_get_size (connections_heap) > max_connections)
1308  {
1309  s = GNUNET_CONTAINER_heap_remove_root (connections_heap);
1310  GNUNET_assert (state != s);
1311  s->specifics.tcp_udp.heap_node = NULL;
1314  GNUNET_CONTAINER_multihashmap_remove (connections_map,
1315  &s->specifics.tcp_udp.state_key,
1316  s));
1317  GNUNET_free (s);
1318  }
1319 }
1320 
1321 
1330 static void
1331 send_udp_packet_via_tun (const struct SocketAddress *destination_address,
1332  const struct SocketAddress *source_address,
1333  const void *payload, size_t payload_length)
1334 {
1335  size_t len;
1336 
1337  GNUNET_STATISTICS_update (stats,
1338  gettext_noop ("# UDP packets sent via TUN"),
1339  1, GNUNET_NO);
1341  "Sending packet with %u bytes UDP payload via TUN\n",
1342  (unsigned int) payload_length);
1343  len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader);
1344  switch (source_address->af)
1345  {
1346  case AF_INET:
1347  len += sizeof (struct GNUNET_TUN_IPv4Header);
1348  break;
1349  case AF_INET6:
1350  len += sizeof (struct GNUNET_TUN_IPv6Header);
1351  break;
1352  default:
1353  GNUNET_break (0);
1354  return;
1355  }
1356  len += sizeof (struct GNUNET_TUN_UdpHeader);
1357  len += payload_length;
1358  if (len >= GNUNET_MAX_MESSAGE_SIZE)
1359  {
1360  GNUNET_break (0);
1361  return;
1362  }
1363  {
1364  char buf[len] GNUNET_ALIGN;
1365  struct GNUNET_MessageHeader *hdr;
1366  struct GNUNET_TUN_Layer2PacketHeader *tun;
1367 
1368  hdr= (struct GNUNET_MessageHeader *) buf;
1369  hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1370  hdr->size = htons (len);
1371  tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1372  tun->flags = htons (0);
1373  switch (source_address->af)
1374  {
1375  case AF_INET:
1376  {
1377  struct GNUNET_TUN_IPv4Header * ipv4 = (struct GNUNET_TUN_IPv4Header*) &tun[1];
1378 
1379  tun->proto = htons (ETH_P_IPV4);
1380  prepare_ipv4_packet (payload,
1381  payload_length,
1382  IPPROTO_UDP,
1383  NULL,
1384  source_address,
1385  destination_address,
1386  ipv4);
1387  }
1388  break;
1389  case AF_INET6:
1390  {
1391  struct GNUNET_TUN_IPv6Header * ipv6 = (struct GNUNET_TUN_IPv6Header*) &tun[1];
1392 
1393  tun->proto = htons (ETH_P_IPV6);
1394  prepare_ipv6_packet (payload,
1395  payload_length,
1396  IPPROTO_UDP,
1397  NULL,
1398  source_address,
1399  destination_address,
1400  ipv6);
1401  }
1402  break;
1403  default:
1404  GNUNET_assert (0);
1405  break;
1406  }
1407  if (NULL != helper_handle)
1408  (void) GNUNET_HELPER_send (helper_handle,
1409  (const struct GNUNET_MessageHeader*) buf,
1410  GNUNET_YES,
1411  NULL, NULL);
1412  }
1413 }
1414 
1415 
1424 static int
1425 check_udp_remote (void *cls,
1426  const struct GNUNET_EXIT_UdpInternetMessage *msg)
1427 {
1428  struct ChannelState *state = cls;
1429 
1430  if (GNUNET_YES == state->is_dns)
1431  {
1432  GNUNET_break_op (0);
1433  return GNUNET_SYSERR;
1434  }
1435  return GNUNET_OK;
1436 }
1437 
1438 
1445 static void
1447  const struct GNUNET_EXIT_UdpInternetMessage *msg)
1448 {
1449  struct ChannelState *state = cls;
1450  uint16_t pkt_len = ntohs (msg->header.size) - sizeof (struct GNUNET_EXIT_UdpInternetMessage);
1451  const struct in_addr *v4;
1452  const struct in6_addr *v6;
1453  const void *payload;
1454  int af;
1455 
1456  if (GNUNET_SYSERR == state->is_dns)
1457  {
1458  /* channel is UDP/TCP from now on */
1459  state->is_dns = GNUNET_NO;
1460  }
1461  GNUNET_STATISTICS_update (stats,
1462  gettext_noop ("# Bytes received from CADET"),
1463  pkt_len, GNUNET_NO);
1464  GNUNET_STATISTICS_update (stats,
1465  gettext_noop ("# UDP IP-exit requests received via cadet"),
1466  1, GNUNET_NO);
1467  af = (int) ntohl (msg->af);
1468  state->specifics.tcp_udp.ri.remote_address.af = af;
1469  switch (af)
1470  {
1471  case AF_INET:
1472  if (pkt_len < sizeof (struct in_addr))
1473  {
1474  GNUNET_break_op (0);
1475  return;
1476  }
1477  if (! ipv4_exit)
1478  {
1479  GNUNET_break_op (0);
1480  return;
1481  }
1482  v4 = (const struct in_addr*) &msg[1];
1483  payload = &v4[1];
1484  pkt_len -= sizeof (struct in_addr);
1485  state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
1486  break;
1487  case AF_INET6:
1488  if (pkt_len < sizeof (struct in6_addr))
1489  {
1490  GNUNET_break_op (0);
1491  return;
1492  }
1493  if (! ipv6_exit)
1494  {
1495  GNUNET_break_op (0);
1496  return;
1497  }
1498  v6 = (const struct in6_addr*) &msg[1];
1499  payload = &v6[1];
1500  pkt_len -= sizeof (struct in6_addr);
1501  state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
1502  break;
1503  default:
1504  GNUNET_break_op (0);
1505  return;
1506  }
1507  {
1508  char buf[INET6_ADDRSTRLEN];
1510  "Received data from %s for forwarding to UDP %s:%u\n",
1511  GNUNET_i2s (&state->peer),
1512  inet_ntop (af,
1513  &state->specifics.tcp_udp.ri.remote_address.address,
1514  buf, sizeof (buf)),
1515  (unsigned int) ntohs (msg->destination_port));
1516  }
1517  state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_UDP;
1518  state->specifics.tcp_udp.ri.remote_address.port = msg->destination_port;
1519  if (NULL == state->specifics.tcp_udp.heap_node)
1520  setup_state_record (state);
1521  if (0 != ntohs (msg->source_port))
1522  state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
1523  send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1524  &state->specifics.tcp_udp.ri.local_address,
1525  payload,
1526  pkt_len);
1528 }
1529 
1530 
1540 static int
1542  const struct GNUNET_EXIT_UdpServiceMessage *msg)
1543 {
1544  struct ChannelState *state = cls;
1545 
1546  if (NULL == state->specifics.tcp_udp.serv)
1547  {
1548  GNUNET_break_op (0);
1549  return GNUNET_SYSERR;
1550  }
1551  return GNUNET_OK;
1552 }
1553 
1554 
1562 static void
1564  const struct GNUNET_EXIT_UdpServiceMessage *msg)
1565 {
1566  struct ChannelState *state = cls;
1567  uint16_t pkt_len = ntohs (msg->header.size) - sizeof (struct GNUNET_EXIT_UdpServiceMessage);
1568 
1569  GNUNET_STATISTICS_update (stats,
1570  gettext_noop ("# Bytes received from CADET"),
1571  pkt_len, GNUNET_NO);
1572  GNUNET_STATISTICS_update (stats,
1573  gettext_noop ("# UDP service requests received via cadet"),
1574  1, GNUNET_NO);
1576  "Received data from %s for forwarding to UDP service %s on port %u\n",
1577  GNUNET_i2s (&state->peer),
1578  GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor),
1579  (unsigned int) ntohs (msg->destination_port));
1580  setup_state_record (state);
1581  if (0 != ntohs (msg->source_port))
1582  state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
1583  send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1584  &state->specifics.tcp_udp.ri.local_address,
1585  &msg[1],
1586  pkt_len);
1588 }
1589 
1590 
1600 static void
1603 {
1604  struct ChannelState *state = cls;
1605  uint16_t pkt_len = ntohs (start->header.size) - sizeof (struct GNUNET_EXIT_TcpServiceStartMessage);
1606 
1607  if (GNUNET_SYSERR == state->is_dns)
1608  {
1609  /* channel is UDP/TCP from now on */
1610  state->is_dns = GNUNET_NO;
1611  }
1612  GNUNET_STATISTICS_update (stats,
1613  gettext_noop ("# TCP service creation requests received via cadet"),
1614  1,
1615  GNUNET_NO);
1616  GNUNET_STATISTICS_update (stats,
1617  gettext_noop ("# Bytes received from CADET"),
1618  pkt_len,
1619  GNUNET_NO);
1620  GNUNET_break_op (ntohl (start->reserved) == 0);
1621  /* setup fresh connection */
1623  "Received data from %s for forwarding to TCP service %s on port %u\n",
1624  GNUNET_i2s (&state->peer),
1625  GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor),
1626  (unsigned int) ntohs (start->tcp_header.destination_port));
1627  setup_state_record (state);
1628  send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1629  &state->specifics.tcp_udp.ri.local_address,
1630  &start->tcp_header,
1631  &start[1],
1632  pkt_len);
1634 }
1635 
1636 
1645 static int
1646 check_tcp_remote (void *cls,
1648 {
1649  struct ChannelState *state = cls;
1650 
1651  if (NULL == state)
1652  {
1653  GNUNET_break_op (0);
1654  return GNUNET_SYSERR;
1655  }
1656  if (GNUNET_YES == state->is_dns)
1657  {
1658  GNUNET_break_op (0);
1659  return GNUNET_SYSERR;
1660  }
1661  if ( (NULL != state->specifics.tcp_udp.serv) ||
1662  (NULL != state->specifics.tcp_udp.heap_node) )
1663  {
1664  GNUNET_break_op (0);
1665  return GNUNET_SYSERR;
1666  }
1667  if (start->tcp_header.off * 4 < sizeof (struct GNUNET_TUN_TcpHeader))
1668  {
1669  GNUNET_break_op (0);
1670  return GNUNET_SYSERR;
1671  }
1672  return GNUNET_OK;
1673 }
1674 
1675 
1682 static void
1685 {
1686  struct ChannelState *state = cls;
1687  uint16_t pkt_len = ntohs (start->header.size) - sizeof (struct GNUNET_EXIT_TcpInternetStartMessage);
1688  const struct in_addr *v4;
1689  const struct in6_addr *v6;
1690  const void *payload;
1691  int af;
1692 
1693  if (GNUNET_SYSERR == state->is_dns)
1694  {
1695  /* channel is UDP/TCP from now on */
1696  state->is_dns = GNUNET_NO;
1697  }
1698  GNUNET_STATISTICS_update (stats,
1699  gettext_noop ("# Bytes received from CADET"),
1700  pkt_len, GNUNET_NO);
1701  GNUNET_STATISTICS_update (stats,
1702  gettext_noop ("# TCP IP-exit creation requests received via cadet"),
1703  1, GNUNET_NO);
1704  af = (int) ntohl (start->af);
1705  state->specifics.tcp_udp.ri.remote_address.af = af;
1706  switch (af)
1707  {
1708  case AF_INET:
1709  if (pkt_len < sizeof (struct in_addr))
1710  {
1711  GNUNET_break_op (0);
1712  return;
1713  }
1714  if (! ipv4_exit)
1715  {
1716  GNUNET_break_op (0);
1717  return;
1718  }
1719  v4 = (const struct in_addr*) &start[1];
1720  payload = &v4[1];
1721  pkt_len -= sizeof (struct in_addr);
1722  state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
1723  break;
1724  case AF_INET6:
1725  if (pkt_len < sizeof (struct in6_addr))
1726  {
1727  GNUNET_break_op (0);
1728  return;
1729  }
1730  if (! ipv6_exit)
1731  {
1732  GNUNET_break_op (0);
1733  return;
1734  }
1735  v6 = (const struct in6_addr*) &start[1];
1736  payload = &v6[1];
1737  pkt_len -= sizeof (struct in6_addr);
1738  state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
1739  break;
1740  default:
1741  GNUNET_break_op (0);
1742  return;
1743  }
1744  {
1745  char buf[INET6_ADDRSTRLEN];
1747  "Received payload from %s for existing TCP stream to %s:%u\n",
1748  GNUNET_i2s (&state->peer),
1749  inet_ntop (af,
1750  &state->specifics.tcp_udp.ri.remote_address.address,
1751  buf, sizeof (buf)),
1752  (unsigned int) ntohs (start->tcp_header.destination_port));
1753  }
1754  state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_TCP;
1755  state->specifics.tcp_udp.ri.remote_address.port = ntohs (start->tcp_header.destination_port);
1756  setup_state_record (state);
1757  send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1758  &state->specifics.tcp_udp.ri.local_address,
1759  &start->tcp_header,
1760  payload,
1761  pkt_len);
1763 }
1764 
1765 
1775 static int
1776 check_tcp_data (void *cls,
1777  const struct GNUNET_EXIT_TcpDataMessage *data)
1778 {
1779  struct ChannelState *state = cls;
1780 
1781  if ( (NULL == state) ||
1782  (NULL == state->specifics.tcp_udp.heap_node) )
1783  {
1784  /* connection should have been up! */
1785  GNUNET_STATISTICS_update (stats,
1786  gettext_noop ("# TCP DATA requests dropped (no session)"),
1787  1, GNUNET_NO);
1788  GNUNET_break_op (0);
1789  return GNUNET_SYSERR;
1790  }
1791  if (data->tcp_header.off * 4 < sizeof (struct GNUNET_TUN_TcpHeader))
1792  {
1793  GNUNET_break_op (0);
1794  return GNUNET_SYSERR;
1795  }
1796  if (GNUNET_YES == state->is_dns)
1797  {
1798  GNUNET_break_op (0);
1799  return GNUNET_SYSERR;
1800  }
1801  return GNUNET_OK;
1802 }
1803 
1804 
1812 static void
1813 handle_tcp_data (void *cls,
1814  const struct GNUNET_EXIT_TcpDataMessage *data)
1815 {
1816  struct ChannelState *state = cls;
1817  uint16_t pkt_len = ntohs (data->header.size) - sizeof (struct GNUNET_EXIT_TcpDataMessage);
1818 
1819  GNUNET_STATISTICS_update (stats,
1820  gettext_noop ("# Bytes received from CADET"),
1821  pkt_len, GNUNET_NO);
1822  GNUNET_STATISTICS_update (stats,
1823  gettext_noop ("# TCP data requests received via cadet"),
1824  1, GNUNET_NO);
1825  if (GNUNET_SYSERR == state->is_dns)
1826  {
1827  /* channel is UDP/TCP from now on */
1828  state->is_dns = GNUNET_NO;
1829  }
1830 
1831  GNUNET_break_op (ntohl (data->reserved) == 0);
1832  {
1833  char buf[INET6_ADDRSTRLEN];
1835  "Received additional %u bytes of data from %s for TCP stream to %s:%u\n",
1836  pkt_len,
1837  GNUNET_i2s (&state->peer),
1838  inet_ntop (state->specifics.tcp_udp.ri.remote_address.af,
1839  &state->specifics.tcp_udp.ri.remote_address.address,
1840  buf, sizeof (buf)),
1841  (unsigned int) state->specifics.tcp_udp.ri.remote_address.port);
1842  }
1843 
1844  send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1845  &state->specifics.tcp_udp.ri.local_address,
1846  &data->tcp_header,
1847  &data[1], pkt_len);
1849 }
1850 
1851 
1861 static void
1863  struct GNUNET_TUN_IPv4Header *ipp,
1864  struct GNUNET_TUN_UdpHeader *udp)
1865 {
1867  state->specifics.tcp_udp.ri.remote_address.proto,
1868  sizeof (struct GNUNET_TUN_TcpHeader),
1869  &state->specifics.tcp_udp.ri.remote_address.address.ipv4,
1870  &state->specifics.tcp_udp.ri.local_address.address.ipv4);
1871  udp->source_port = htons (state->specifics.tcp_udp.ri.remote_address.port);
1872  udp->destination_port = htons (state->specifics.tcp_udp.ri.local_address.port);
1873  udp->len = htons (0);
1874  udp->crc = htons (0);
1875 }
1876 
1877 
1887 static void
1889  struct GNUNET_TUN_IPv6Header *ipp,
1890  struct GNUNET_TUN_UdpHeader *udp)
1891 {
1893  state->specifics.tcp_udp.ri.remote_address.proto,
1894  sizeof (struct GNUNET_TUN_TcpHeader),
1895  &state->specifics.tcp_udp.ri.remote_address.address.ipv6,
1896  &state->specifics.tcp_udp.ri.local_address.address.ipv6);
1897  udp->source_port = htons (state->specifics.tcp_udp.ri.remote_address.port);
1898  udp->destination_port = htons (state->specifics.tcp_udp.ri.local_address.port);
1899  udp->len = htons (0);
1900  udp->crc = htons (0);
1901 }
1902 
1903 
1912 static int
1914  const struct GNUNET_EXIT_IcmpInternetMessage *msg)
1915 {
1916  struct ChannelState *state = cls;
1917 
1918  if (GNUNET_YES == state->is_dns)
1919  {
1920  GNUNET_break_op (0);
1921  return GNUNET_SYSERR;
1922  }
1923  return GNUNET_OK;
1924 }
1925 
1926 
1933 static void
1935  const struct GNUNET_EXIT_IcmpInternetMessage *msg)
1936 {
1937  struct ChannelState *state = cls;
1938  uint16_t pkt_len = ntohs (msg->header.size) - sizeof (struct GNUNET_EXIT_IcmpInternetMessage);
1939  const struct in_addr *v4;
1940  const struct in6_addr *v6;
1941  const void *payload;
1942  char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
1943  int af;
1944 
1945  if (GNUNET_SYSERR == state->is_dns)
1946  {
1947  /* channel is UDP/TCP from now on */
1948  state->is_dns = GNUNET_NO;
1949  }
1950  GNUNET_STATISTICS_update (stats,
1951  gettext_noop ("# Bytes received from CADET"),
1952  pkt_len, GNUNET_NO);
1953  GNUNET_STATISTICS_update (stats,
1954  gettext_noop ("# ICMP IP-exit requests received via cadet"),
1955  1, GNUNET_NO);
1956 
1957  af = (int) ntohl (msg->af);
1958  if ( (NULL != state->specifics.tcp_udp.heap_node) &&
1959  (af != state->specifics.tcp_udp.ri.remote_address.af) )
1960  {
1961  /* other peer switched AF on this channel; not allowed */
1962  GNUNET_break_op (0);
1963  return;
1964  }
1965 
1966  switch (af)
1967  {
1968  case AF_INET:
1969  if (pkt_len < sizeof (struct in_addr))
1970  {
1971  GNUNET_break_op (0);
1972  return;
1973  }
1974  if (! ipv4_exit)
1975  {
1976  GNUNET_break_op (0);
1977  return;
1978  }
1979  v4 = (const struct in_addr*) &msg[1];
1980  payload = &v4[1];
1981  pkt_len -= sizeof (struct in_addr);
1982  state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
1983  if (NULL == state->specifics.tcp_udp.heap_node)
1984  {
1985  state->specifics.tcp_udp.ri.remote_address.af = af;
1986  state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMP;
1987  setup_state_record (state);
1988  }
1989  /* check that ICMP type is something we want to support
1990  and possibly make up payload! */
1991  switch (msg->icmp_header.type)
1992  {
1995  break;
1999  if (0 != pkt_len)
2000  {
2001  GNUNET_break_op (0);
2002  return;
2003  }
2004  /* make up payload */
2005  {
2006  struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header *) buf;
2007  struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1];
2008 
2009  GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
2010  pkt_len = sizeof (struct GNUNET_TUN_IPv4Header) + 8;
2011  make_up_icmpv4_payload (state,
2012  ipp,
2013  udp);
2014  payload = ipp;
2015  }
2016  break;
2017  default:
2018  GNUNET_break_op (0);
2019  GNUNET_STATISTICS_update (stats,
2020  gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
2021  1, GNUNET_NO);
2022  return;
2023  }
2024  /* end AF_INET */
2025  break;
2026  case AF_INET6:
2027  if (pkt_len < sizeof (struct in6_addr))
2028  {
2029  GNUNET_break_op (0);
2030  return;
2031  }
2032  if (! ipv6_exit)
2033  {
2034  GNUNET_break_op (0);
2035  return;
2036  }
2037  v6 = (const struct in6_addr*) &msg[1];
2038  payload = &v6[1];
2039  pkt_len -= sizeof (struct in6_addr);
2040  state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
2041  if (NULL == state->specifics.tcp_udp.heap_node)
2042  {
2043  state->specifics.tcp_udp.ri.remote_address.af = af;
2044  state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMPV6;
2045  setup_state_record (state);
2046  }
2047  /* check that ICMP type is something we want to support
2048  and possibly make up payload! */
2049  switch (msg->icmp_header.type)
2050  {
2053  break;
2058  if (0 != pkt_len)
2059  {
2060  GNUNET_break_op (0);
2061  return;
2062  }
2063  /* make up payload */
2064  {
2065  struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header *) buf;
2066  struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1];
2067 
2068  GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
2069  pkt_len = sizeof (struct GNUNET_TUN_IPv6Header) + 8;
2070  make_up_icmpv6_payload (state,
2071  ipp,
2072  udp);
2073  payload = ipp;
2074  }
2075  break;
2076  default:
2077  GNUNET_break_op (0);
2078  GNUNET_STATISTICS_update (stats,
2079  gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
2080  1, GNUNET_NO);
2081  return;
2082  }
2083  /* end AF_INET6 */
2084  break;
2085  default:
2086  /* bad AF */
2087  GNUNET_break_op (0);
2088  return;
2089  }
2090 
2091  {
2092  char buf[INET6_ADDRSTRLEN];
2094  "Received ICMP data from %s for forwarding to %s\n",
2095  GNUNET_i2s (&state->peer),
2096  inet_ntop (af,
2097  &state->specifics.tcp_udp.ri.remote_address.address,
2098  buf, sizeof (buf)));
2099  }
2100  send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2101  &state->specifics.tcp_udp.ri.local_address,
2102  &msg->icmp_header,
2103  payload, pkt_len);
2105 }
2106 
2107 
2117 static uint16_t
2119  char *buf)
2120 {
2121  switch (state->specifics.tcp_udp.serv->address.af)
2122  {
2123  case AF_INET:
2124  {
2125  struct GNUNET_TUN_IPv4Header *ipv4;
2126  struct GNUNET_TUN_UdpHeader *udp;
2127 
2128  ipv4 = (struct GNUNET_TUN_IPv4Header *)buf;
2129  udp = (struct GNUNET_TUN_UdpHeader *) &ipv4[1];
2130  make_up_icmpv4_payload (state,
2131  ipv4,
2132  udp);
2133  GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
2134  return sizeof (struct GNUNET_TUN_IPv4Header) + 8;
2135  }
2136  break;
2137  case AF_INET6:
2138  {
2139  struct GNUNET_TUN_IPv6Header *ipv6;
2140  struct GNUNET_TUN_UdpHeader *udp;
2141 
2142  ipv6 = (struct GNUNET_TUN_IPv6Header *)buf;
2143  udp = (struct GNUNET_TUN_UdpHeader *) &ipv6[1];
2144  make_up_icmpv6_payload (state,
2145  ipv6,
2146  udp);
2147  GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
2148  return sizeof (struct GNUNET_TUN_IPv6Header) + 8;
2149  }
2150  break;
2151  default:
2152  GNUNET_break (0);
2153  }
2154  return 0;
2155 }
2156 
2157 
2167 static int
2169  const struct GNUNET_EXIT_IcmpServiceMessage *msg)
2170 {
2171  struct ChannelState *state = cls;
2172 
2173  if (GNUNET_YES == state->is_dns)
2174  {
2175  GNUNET_break_op (0);
2176  return GNUNET_SYSERR;
2177  }
2178  if (NULL == state->specifics.tcp_udp.serv)
2179  {
2180  GNUNET_break_op (0);
2181  return GNUNET_SYSERR;
2182  }
2183  return GNUNET_OK;
2184 }
2185 
2186 
2194 static void
2196  const struct GNUNET_EXIT_IcmpServiceMessage *msg)
2197 {
2198  struct ChannelState *state = cls;
2199  uint16_t pkt_len = ntohs (msg->header.size) - sizeof (struct GNUNET_EXIT_IcmpServiceMessage);
2200  struct GNUNET_TUN_IcmpHeader icmp;
2201  char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
2202  const void *payload;
2203 
2204  GNUNET_STATISTICS_update (stats,
2205  gettext_noop ("# Bytes received from CADET"),
2206  pkt_len, GNUNET_NO);
2207  GNUNET_STATISTICS_update (stats,
2208  gettext_noop ("# ICMP service requests received via cadet"),
2209  1, GNUNET_NO);
2210  /* check that we got at least a valid header */
2212  "Received data from %s for forwarding to ICMP service %s\n",
2213  GNUNET_i2s (&state->peer),
2214  GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor));
2215  icmp = msg->icmp_header;
2216  payload = &msg[1];
2217  state->specifics.tcp_udp.ri.remote_address
2218  = state->specifics.tcp_udp.serv->address;
2219  setup_state_record (state);
2220 
2221  /* check that ICMP type is something we want to support,
2222  perform ICMP PT if needed ans possibly make up payload */
2223  switch (msg->af)
2224  {
2225  case AF_INET:
2226  switch (msg->icmp_header.type)
2227  {
2229  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2231  break;
2233  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2235  break;
2237  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2239  if (0 != pkt_len)
2240  {
2241  GNUNET_break_op (0);
2242  return;
2243  }
2244  payload = buf;
2245  pkt_len = make_up_icmp_service_payload (state, buf);
2246  break;
2248  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2250  if (0 != pkt_len)
2251  {
2252  GNUNET_break_op (0);
2253  return;
2254  }
2255  payload = buf;
2256  pkt_len = make_up_icmp_service_payload (state, buf);
2257  break;
2259  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2260  {
2261  GNUNET_STATISTICS_update (stats,
2262  gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"),
2263  1, GNUNET_NO);
2264  return;
2265  }
2266  if (0 != pkt_len)
2267  {
2268  GNUNET_break_op (0);
2269  return;
2270  }
2271  payload = buf;
2272  pkt_len = make_up_icmp_service_payload (state, buf);
2273  break;
2274  default:
2275  GNUNET_break_op (0);
2276  GNUNET_STATISTICS_update (stats,
2277  gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
2278  1, GNUNET_NO);
2279  return;
2280  }
2281  /* end of AF_INET */
2282  break;
2283  case AF_INET6:
2284  switch (msg->icmp_header.type)
2285  {
2287  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2289  break;
2291  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2293  break;
2295  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2297  if (0 != pkt_len)
2298  {
2299  GNUNET_break_op (0);
2300  return;
2301  }
2302  payload = buf;
2303  pkt_len = make_up_icmp_service_payload (state, buf);
2304  break;
2306  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2308  if (0 != pkt_len)
2309  {
2310  GNUNET_break_op (0);
2311  return;
2312  }
2313  payload = buf;
2314  pkt_len = make_up_icmp_service_payload (state, buf);
2315  break;
2318  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2319  {
2320  GNUNET_STATISTICS_update (stats,
2321  gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"),
2322  1, GNUNET_NO);
2323  return;
2324  }
2325  if (0 != pkt_len)
2326  {
2327  GNUNET_break_op (0);
2328  return;
2329  }
2330  payload = buf;
2331  pkt_len = make_up_icmp_service_payload (state, buf);
2332  break;
2333  default:
2334  GNUNET_break_op (0);
2335  GNUNET_STATISTICS_update (stats,
2336  gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
2337  1, GNUNET_NO);
2338  return;
2339  }
2340  /* end of AF_INET6 */
2341  break;
2342  default:
2343  GNUNET_break_op (0);
2344  return;
2345  }
2346 
2347  send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2348  &state->specifics.tcp_udp.ri.local_address,
2349  &icmp,
2350  payload,
2351  pkt_len);
2353 }
2354 
2355 
2364 static int
2366  const struct GNUNET_HashCode *key,
2367  void *value)
2368 {
2369  struct LocalService *service = value;
2370 
2373  key,
2374  service));
2375  GNUNET_CADET_close_port (service->port);
2376  GNUNET_free_non_null (service->name);
2377  GNUNET_free (service);
2378  return GNUNET_OK;
2379 }
2380 
2381 
2390 static void *
2392  struct GNUNET_CADET_Channel *channel,
2393  const struct GNUNET_PeerIdentity *initiator)
2394 {
2395  struct LocalService *ls = cls;
2396  struct ChannelState *s = GNUNET_new (struct ChannelState);
2397 
2398  s->peer = *initiator;
2399  GNUNET_STATISTICS_update (stats,
2400  gettext_noop ("# Inbound CADET channels created"),
2401  1,
2402  GNUNET_NO);
2404  "Received inbound channel from `%s'\n",
2405  GNUNET_i2s (initiator));
2406  s->channel = channel;
2407  s->specifics.tcp_udp.serv = ls;
2408  s->specifics.tcp_udp.ri.remote_address = ls->address;
2409  return s;
2410 }
2411 
2412 
2420 static void
2421 clean_channel (void *cls,
2422  const struct GNUNET_CADET_Channel *channel)
2423 {
2424  struct ChannelState *s = cls;
2425 
2427  "Channel destroyed\n");
2428  if (GNUNET_SYSERR == s->is_dns)
2429  {
2430  GNUNET_free (s);
2431  return;
2432  }
2433  if (GNUNET_YES == s->is_dns)
2434  {
2435  if (channels[s->specifics.dns.my_id] == s)
2436  channels[s->specifics.dns.my_id] = NULL;
2437  }
2438  else
2439  {
2440  if (NULL != s->specifics.tcp_udp.heap_node)
2441  {
2443  GNUNET_CONTAINER_multihashmap_remove (connections_map,
2444  &s->specifics.tcp_udp.state_key,
2445  s));
2447  s->specifics.tcp_udp.heap_node = NULL;
2448  }
2449  }
2450  GNUNET_free (s);
2451 }
2452 
2453 
2463 static void
2465  const char *name,
2466  uint16_t destination_port,
2467  struct LocalService *service)
2468 {
2469  struct GNUNET_MQ_MessageHandler handlers[] = {
2470  GNUNET_MQ_hd_var_size (icmp_service,
2473  service),
2474  GNUNET_MQ_hd_var_size (udp_service,
2477  service),
2478  GNUNET_MQ_hd_var_size (tcp_service,
2481  service),
2482  GNUNET_MQ_hd_var_size (tcp_data,
2485  service),
2487  };
2488 
2489  struct GNUNET_HashCode cadet_port;
2490 
2491  service->name = GNUNET_strdup (name);
2493  &service->descriptor);
2495  destination_port,
2496  &cadet_port);
2498  "Opening CADET port %s for SERVICE exit %s on port %u\n",
2499  GNUNET_h2s (&cadet_port),
2500  name,
2501  (unsigned int) destination_port);
2502  service->port = GNUNET_CADET_open_port (cadet_handle,
2503  &cadet_port,
2505  service,
2506  NULL,
2507  &clean_channel,
2508  handlers);
2509  service->is_udp = (IPPROTO_UDP == proto);
2510  if (GNUNET_OK !=
2512  &cadet_port,
2513  service,
2515  {
2516  GNUNET_CADET_close_port (service->port);
2517  GNUNET_free_non_null (service->name);
2518  GNUNET_free (service);
2520  _("Got duplicate service records for `%s:%u'\n"),
2521  name,
2522  (unsigned int) destination_port);
2523  }
2524 }
2525 
2526 
2533 static void
2535  struct GNUNET_MQ_Envelope *env)
2536 {
2537  GNUNET_assert (NULL != s);
2538  GNUNET_STATISTICS_update (stats,
2539  gettext_noop ("# Messages transmitted via cadet channels"),
2540  1,
2541  GNUNET_NO);
2543  env);
2544 }
2545 
2546 
2558 static void
2560  size_t pktlen,
2561  int af,
2562  const void *destination_ip,
2563  const void *source_ip)
2564 {
2565  struct ChannelState *state;
2566  struct GNUNET_MQ_Envelope *env;
2567  struct GNUNET_EXIT_IcmpToVPNMessage *i2v;
2568  const struct GNUNET_TUN_IPv4Header *ipv4;
2569  const struct GNUNET_TUN_IPv6Header *ipv6;
2570  const struct GNUNET_TUN_UdpHeader *udp;
2571  uint16_t source_port;
2572  uint16_t destination_port;
2573  uint8_t protocol;
2574 
2575  {
2576  char sbuf[INET6_ADDRSTRLEN];
2577  char dbuf[INET6_ADDRSTRLEN];
2579  "Received ICMP packet going from %s to %s\n",
2580  inet_ntop (af,
2581  source_ip,
2582  sbuf, sizeof (sbuf)),
2583  inet_ntop (af,
2584  destination_ip,
2585  dbuf, sizeof (dbuf)));
2586  }
2587  if (pktlen < sizeof (struct GNUNET_TUN_IcmpHeader))
2588  {
2589  /* blame kernel */
2590  GNUNET_break (0);
2591  return;
2592  }
2593 
2594  /* Find out if this is an ICMP packet in response to an existing
2595  TCP/UDP packet and if so, figure out ports / protocol of the
2596  existing session from the IP data in the ICMP payload */
2597  source_port = 0;
2598  destination_port = 0;
2599  switch (af)
2600  {
2601  case AF_INET:
2602  protocol = IPPROTO_ICMP;
2603  switch (icmp->type)
2604  {
2607  break;
2611  if (pktlen <
2612  sizeof (struct GNUNET_TUN_IcmpHeader) +
2613  sizeof (struct GNUNET_TUN_IPv4Header) + 8)
2614  {
2615  /* blame kernel */
2616  GNUNET_break (0);
2617  return;
2618  }
2619  ipv4 = (const struct GNUNET_TUN_IPv4Header *) &icmp[1];
2620  protocol = ipv4->protocol;
2621  /* could be TCP or UDP, but both have the ports in the right
2622  place, so that doesn't matter here */
2623  udp = (const struct GNUNET_TUN_UdpHeader *) &ipv4[1];
2624  /* swap ports, as they are from the original message */
2625  destination_port = ntohs (udp->source_port);
2626  source_port = ntohs (udp->destination_port);
2627  /* throw away ICMP payload, won't be useful for the other side anyway */
2628  pktlen = sizeof (struct GNUNET_TUN_IcmpHeader);
2629  break;
2630  default:
2631  GNUNET_STATISTICS_update (stats,
2632  gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
2633  1, GNUNET_NO);
2634  return;
2635  }
2636  break;
2637  case AF_INET6:
2638  protocol = IPPROTO_ICMPV6;
2639  switch (icmp->type)
2640  {
2645  if (pktlen <
2646  sizeof (struct GNUNET_TUN_IcmpHeader) +
2647  sizeof (struct GNUNET_TUN_IPv6Header) + 8)
2648  {
2649  /* blame kernel */
2650  GNUNET_break (0);
2651  return;
2652  }
2653  ipv6 = (const struct GNUNET_TUN_IPv6Header *) &icmp[1];
2654  protocol = ipv6->next_header;
2655  /* could be TCP or UDP, but both have the ports in the right
2656  place, so that doesn't matter here */
2657  udp = (const struct GNUNET_TUN_UdpHeader *) &ipv6[1];
2658  /* swap ports, as they are from the original message */
2659  destination_port = ntohs (udp->source_port);
2660  source_port = ntohs (udp->destination_port);
2661  /* throw away ICMP payload, won't be useful for the other side anyway */
2662  pktlen = sizeof (struct GNUNET_TUN_IcmpHeader);
2663  break;
2666  break;
2667  default:
2668  GNUNET_STATISTICS_update (stats,
2669  gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
2670  1, GNUNET_NO);
2671  return;
2672  }
2673  break;
2674  default:
2675  GNUNET_assert (0);
2676  }
2677  switch (protocol)
2678  {
2679  case IPPROTO_ICMP:
2680  state = get_redirect_state (af,
2681  IPPROTO_ICMP,
2682  source_ip,
2683  0,
2684  destination_ip,
2685  0,
2686  NULL);
2687  break;
2688  case IPPROTO_ICMPV6:
2689  state = get_redirect_state (af,
2690  IPPROTO_ICMPV6,
2691  source_ip,
2692  0,
2693  destination_ip,
2694  0,
2695  NULL);
2696  break;
2697  case IPPROTO_UDP:
2698  state = get_redirect_state (af,
2699  IPPROTO_UDP,
2700  source_ip,
2701  source_port,
2702  destination_ip,
2703  destination_port,
2704  NULL);
2705  break;
2706  case IPPROTO_TCP:
2707  state = get_redirect_state (af,
2708  IPPROTO_TCP,
2709  source_ip,
2710  source_port,
2711  destination_ip,
2712  destination_port,
2713  NULL);
2714  break;
2715  default:
2716  GNUNET_STATISTICS_update (stats,
2717  gettext_noop ("# ICMP packets dropped (not allowed)"),
2718  1,
2719  GNUNET_NO);
2720  return;
2721  }
2722  if (NULL == state)
2723  {
2725  _("ICMP Packet dropped, have no matching connection information\n"));
2726  return;
2727  }
2728  env = GNUNET_MQ_msg_extra (i2v,
2729  pktlen - sizeof (struct GNUNET_TUN_IcmpHeader),
2731  i2v->af = htonl (af);
2732  GNUNET_memcpy (&i2v->icmp_header,
2733  icmp,
2734  pktlen);
2736  env);
2737 }
2738 
2739 
2751 static void
2753  size_t pktlen,
2754  int af,
2755  const void *destination_ip,
2756  const void *source_ip)
2757 {
2758  struct ChannelState *state;
2759  struct GNUNET_MQ_Envelope *env;
2760  struct GNUNET_EXIT_UdpReplyMessage *urm;
2761 
2762  {
2763  char sbuf[INET6_ADDRSTRLEN];
2764  char dbuf[INET6_ADDRSTRLEN];
2765 
2767  "Received UDP packet going from %s:%u to %s:%u\n",
2768  inet_ntop (af,
2769  source_ip,
2770  sbuf, sizeof (sbuf)),
2771  (unsigned int) ntohs (udp->source_port),
2772  inet_ntop (af,
2773  destination_ip,
2774  dbuf, sizeof (dbuf)),
2775  (unsigned int) ntohs (udp->destination_port));
2776  }
2777  if (pktlen < sizeof (struct GNUNET_TUN_UdpHeader))
2778  {
2779  /* blame kernel */
2780  GNUNET_break (0);
2781  return;
2782  }
2783  if (pktlen != ntohs (udp->len))
2784  {
2785  /* blame kernel */
2786  GNUNET_break (0);
2787  return;
2788  }
2789  state = get_redirect_state (af,
2790  IPPROTO_UDP,
2791  source_ip,
2792  ntohs (udp->source_port),
2793  destination_ip,
2794  ntohs (udp->destination_port),
2795  NULL);
2796  if (NULL == state)
2797  {
2799  _("UDP Packet dropped, have no matching connection information\n"));
2800  return;
2801  }
2802  env = GNUNET_MQ_msg_extra (urm,
2803  pktlen - sizeof (struct GNUNET_TUN_UdpHeader),
2805  urm->source_port = htons (0);
2806  urm->destination_port = htons (0);
2807  GNUNET_memcpy (&urm[1],
2808  &udp[1],
2809  pktlen - sizeof (struct GNUNET_TUN_UdpHeader));
2811  env);
2812 }
2813 
2814 
2826 static void
2828  size_t pktlen,
2829  int af,
2830  const void *destination_ip,
2831  const void *source_ip)
2832 {
2833  struct ChannelState *state;
2834  char buf[pktlen] GNUNET_ALIGN;
2835  struct GNUNET_TUN_TcpHeader *mtcp;
2836  struct GNUNET_EXIT_TcpDataMessage *tdm;
2837  struct GNUNET_MQ_Envelope *env;
2838  size_t mlen;
2839 
2840  {
2841  char sbuf[INET6_ADDRSTRLEN];
2842  char dbuf[INET6_ADDRSTRLEN];
2844  "Received TCP packet with %u bytes going from %s:%u to %s:%u\n",
2845  (unsigned int) (pktlen - sizeof (struct GNUNET_TUN_TcpHeader)),
2846  inet_ntop (af,
2847  source_ip,
2848  sbuf, sizeof (sbuf)),
2849  (unsigned int) ntohs (tcp->source_port),
2850  inet_ntop (af,
2851  destination_ip,
2852  dbuf, sizeof (dbuf)),
2853  (unsigned int) ntohs (tcp->destination_port));
2854  }
2855  if (pktlen < sizeof (struct GNUNET_TUN_TcpHeader))
2856  {
2857  /* blame kernel */
2858  GNUNET_break (0);
2859  return;
2860  }
2861  state = get_redirect_state (af,
2862  IPPROTO_TCP,
2863  source_ip,
2864  ntohs (tcp->source_port),
2865  destination_ip,
2866  ntohs (tcp->destination_port),
2867  NULL);
2868  if (NULL == state)
2869  {
2871  _("TCP Packet dropped, have no matching connection information\n"));
2872 
2873  return;
2874  }
2875  /* mug port numbers and crc to avoid information leakage;
2876  sender will need to lookup the correct values anyway */
2877  GNUNET_memcpy (buf, tcp, pktlen);
2878  mtcp = (struct GNUNET_TUN_TcpHeader *) buf;
2879  mtcp->source_port = 0;
2880  mtcp->destination_port = 0;
2881  mtcp->crc = 0;
2882 
2883  mlen = sizeof (struct GNUNET_EXIT_TcpDataMessage) + (pktlen - sizeof (struct GNUNET_TUN_TcpHeader));
2884  if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
2885  {
2886  GNUNET_break (0);
2887  return;
2888  }
2889  env = GNUNET_MQ_msg_extra (tdm,
2890  pktlen - sizeof (struct GNUNET_TUN_TcpHeader),
2892  tdm->reserved = htonl (0);
2893  GNUNET_memcpy (&tdm->tcp_header,
2894  buf,
2895  pktlen);
2897  env);
2898 }
2899 
2900 
2907 static int
2909  const struct GNUNET_MessageHeader *message)
2910 {
2911  const struct GNUNET_TUN_Layer2PacketHeader *pkt_tun;
2912  size_t size;
2913 
2915  "Got %u-byte message of type %u from gnunet-helper-exit\n",
2916  ntohs (message->size),
2917  ntohs (message->type));
2918  GNUNET_STATISTICS_update (stats,
2919  gettext_noop ("# Packets received from TUN"),
2920  1, GNUNET_NO);
2921  if (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER)
2922  {
2923  GNUNET_break (0);
2924  return GNUNET_OK;
2925  }
2926  size = ntohs (message->size);
2927  if (size < sizeof (struct GNUNET_TUN_Layer2PacketHeader) + sizeof (struct GNUNET_MessageHeader))
2928  {
2929  GNUNET_break (0);
2930  return GNUNET_OK;
2931  }
2932  GNUNET_STATISTICS_update (stats,
2933  gettext_noop ("# Bytes received from TUN"),
2934  size, GNUNET_NO);
2935  pkt_tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1];
2936  size -= sizeof (struct GNUNET_TUN_Layer2PacketHeader) + sizeof (struct GNUNET_MessageHeader);
2937  switch (ntohs (pkt_tun->proto))
2938  {
2939  case ETH_P_IPV4:
2940  {
2941  const struct GNUNET_TUN_IPv4Header *pkt4;
2942 
2943  if (size < sizeof (struct GNUNET_TUN_IPv4Header))
2944  {
2945  /* Kernel to blame? */
2946  GNUNET_break (0);
2947  return GNUNET_OK;
2948  }
2949  pkt4 = (const struct GNUNET_TUN_IPv4Header *) &pkt_tun[1];
2950  if (size != ntohs (pkt4->total_length))
2951  {
2952  /* Kernel to blame? */
2953  GNUNET_break (0);
2954  return GNUNET_OK;
2955  }
2956  if (pkt4->header_length * 4 != sizeof (struct GNUNET_TUN_IPv4Header))
2957  {
2959  _("IPv4 packet options received. Ignored.\n"));
2960  return GNUNET_OK;
2961  }
2962 
2963  size -= sizeof (struct GNUNET_TUN_IPv4Header);
2964  switch (pkt4->protocol)
2965  {
2966  case IPPROTO_UDP:
2967  udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt4[1], size,
2968  AF_INET,
2969  &pkt4->destination_address,
2970  &pkt4->source_address);
2971  break;
2972  case IPPROTO_TCP:
2973  tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt4[1], size,
2974  AF_INET,
2975  &pkt4->destination_address,
2976  &pkt4->source_address);
2977  break;
2978  case IPPROTO_ICMP:
2979  icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt4[1], size,
2980  AF_INET,
2981  &pkt4->destination_address,
2982  &pkt4->source_address);
2983  break;
2984  default:
2986  _("IPv4 packet with unsupported next header %u received. Ignored.\n"),
2987  (int) pkt4->protocol);
2988  return GNUNET_OK;
2989  }
2990  }
2991  break;
2992  case ETH_P_IPV6:
2993  {
2994  const struct GNUNET_TUN_IPv6Header *pkt6;
2995 
2996  if (size < sizeof (struct GNUNET_TUN_IPv6Header))
2997  {
2998  /* Kernel to blame? */
2999  GNUNET_break (0);
3000  return GNUNET_OK;
3001  }
3002  pkt6 = (struct GNUNET_TUN_IPv6Header *) &pkt_tun[1];
3003  if (size != ntohs (pkt6->payload_length) + sizeof (struct GNUNET_TUN_IPv6Header))
3004  {
3005  /* Kernel to blame? */
3006  GNUNET_break (0);
3007  return GNUNET_OK;
3008  }
3009  size -= sizeof (struct GNUNET_TUN_IPv6Header);
3010  switch (pkt6->next_header)
3011  {
3012  case IPPROTO_UDP:
3013  udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt6[1], size,
3014  AF_INET6,
3015  &pkt6->destination_address,
3016  &pkt6->source_address);
3017  break;
3018  case IPPROTO_TCP:
3019  tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt6[1], size,
3020  AF_INET6,
3021  &pkt6->destination_address,
3022  &pkt6->source_address);
3023  break;
3024  case IPPROTO_ICMPV6:
3025  icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt6[1], size,
3026  AF_INET6,
3027  &pkt6->destination_address,
3028  &pkt6->source_address);
3029  break;
3030  default:
3032  _("IPv6 packet with unsupported next header %d received. Ignored.\n"),
3033  pkt6->next_header);
3034  return GNUNET_OK;
3035  }
3036  }
3037  break;
3038  default:
3040  _("Packet from unknown protocol %u received. Ignored.\n"),
3041  ntohs (pkt_tun->proto));
3042  break;
3043  }
3044  return GNUNET_OK;
3045 }
3046 
3047 
3056 static void *
3057 new_channel (void *cls,
3058  struct GNUNET_CADET_Channel *channel,
3059  const struct GNUNET_PeerIdentity *initiator)
3060 {
3061  struct ChannelState *s = GNUNET_new (struct ChannelState);
3062 
3063  s->is_dns = GNUNET_SYSERR;
3064  s->peer = *initiator;
3065  GNUNET_STATISTICS_update (stats,
3066  gettext_noop ("# Inbound CADET channels created"),
3067  1,
3068  GNUNET_NO);
3070  "Received inbound channel from `%s'\n",
3071  GNUNET_i2s (initiator));
3072  s->channel = channel;
3073  return s;
3074 }
3075 
3076 
3084 static int
3085 free_iterate (void *cls,
3086  const struct GNUNET_HashCode * hash,
3087  void *value)
3088 {
3089  GNUNET_free (value);
3090  return GNUNET_YES;
3091 }
3092 
3093 
3103 static void
3104 dummy_task (void *cls)
3105 {
3106  /* just terminate */
3107 }
3108 
3109 
3115 static void
3116 cleanup (void *cls)
3117 {
3118  unsigned int i;
3119 
3121  "Exit service is shutting down now\n");
3122 
3123  if (NULL != helper_handle)
3124  {
3125  GNUNET_HELPER_stop (helper_handle, GNUNET_NO);
3126  helper_handle = NULL;
3127  }
3128  if (NULL != regex4)
3129  {
3131  regex4 = NULL;
3132  }
3133  if (NULL != regex6)
3134  {
3136  regex6 = NULL;
3137  }
3138  if (NULL != services)
3139  {
3142  NULL);
3144  }
3145  if (NULL != dns_port)
3146  {
3147  GNUNET_CADET_close_port (dns_port);
3148  dns_port = NULL;
3149  }
3150  if (NULL != cadet_port4)
3151  {
3152  GNUNET_CADET_close_port (cadet_port4);
3153  cadet_port4 = NULL;
3154  }
3155  if (NULL != cadet_port6)
3156  {
3157  GNUNET_CADET_close_port (cadet_port6);
3158  cadet_port6 = NULL;
3159  }
3160  if (NULL != cadet_handle)
3161  {
3162  GNUNET_CADET_disconnect (cadet_handle);
3163  cadet_handle = NULL;
3164  }
3165  if (NULL != connections_map)
3166  {
3167  GNUNET_CONTAINER_multihashmap_iterate (connections_map,
3168  &free_iterate,
3169  NULL);
3170  GNUNET_CONTAINER_multihashmap_destroy (connections_map);
3171  connections_map = NULL;
3172  }
3173  if (NULL != connections_heap)
3174  {
3175  GNUNET_CONTAINER_heap_destroy (connections_heap);
3176  connections_heap = NULL;
3177  }
3178  if (NULL != dnsstub)
3179  {
3180  GNUNET_DNSSTUB_stop (dnsstub);
3181  dnsstub = NULL;
3182  }
3183  if (NULL != peer_key)
3184  {
3185  GNUNET_free (peer_key);
3186  peer_key = NULL;
3187  }
3188  if (NULL != dht_task)
3189  {
3190  GNUNET_SCHEDULER_cancel (dht_task);
3191  dht_task = NULL;
3192  }
3193  if (NULL != dht_put)
3194  {
3195  GNUNET_DHT_put_cancel (dht_put);
3196  dht_put = NULL;
3197  }
3198  if (NULL != dht)
3199  {
3200  GNUNET_DHT_disconnect (dht);
3201  dht = NULL;
3202  }
3203  if (NULL != stats)
3204  {
3206  GNUNET_NO);
3207  stats = NULL;
3208  }
3209  for (i=0;i<8;i++)
3211 }
3212 
3213 
3221 static void
3223  char *cpy,
3224  const char *name)
3225 {
3226  char *redirect;
3227  char *hostname;
3228  char *hostport;
3229  struct LocalService *serv;
3230  char *n;
3231  size_t slen;
3232 
3233  slen = strlen (name);
3234  GNUNET_assert (slen >= 8);
3235  n = GNUNET_strndup (name, slen - 8 /* remove .gnunet. */);
3236 
3237  for (redirect = strtok (cpy, " ;"); redirect != NULL;
3238  redirect = strtok (NULL, " ;"))
3239  {
3240  if (NULL == (hostname = strstr (redirect, ":")))
3241  {
3243  _("Option `%s' for domain `%s' is not formatted correctly!\n"),
3244  redirect,
3245  name);
3246  continue;
3247  }
3248  hostname[0] = '\0';
3249  hostname++;
3250  if (NULL == (hostport = strstr (hostname, ":")))
3251  {
3253  _("Option `%s' for domain `%s' is not formatted correctly!\n"),
3254  redirect,
3255  name);
3256  continue;
3257  }
3258  hostport[0] = '\0';
3259  hostport++;
3260 
3261  int local_port = atoi (redirect);
3262  int remote_port = atoi (hostport);
3263 
3264  if (! ((local_port > 0) && (local_port < 65536)))
3265  {
3267  _("`%s' is not a valid port number (for domain `%s')!"),
3268  redirect,
3269  name);
3270  continue;
3271  }
3272  if (! ((remote_port > 0) && (remote_port < 65536)))
3273  {
3275  _("`%s' is not a valid port number (for domain `%s')!"),
3276  hostport,
3277  name);
3278  continue;
3279  }
3280 
3281  serv = GNUNET_new (struct LocalService);
3282  serv->address.proto = proto;
3283  serv->address.port = remote_port;
3284  if (0 == strcmp ("localhost4",
3285  hostname))
3286  {
3287  const char *ip4addr = exit_argv[5];
3288 
3289  serv->address.af = AF_INET;
3290  GNUNET_assert (1 == inet_pton (AF_INET,
3291  ip4addr,
3292  &serv->address.address.ipv4));
3293  }
3294  else if (0 == strcmp ("localhost6",
3295  hostname))
3296  {
3297  const char *ip6addr = exit_argv[3];
3298 
3299  serv->address.af = AF_INET6;
3300  GNUNET_assert (1 == inet_pton (AF_INET6,
3301  ip6addr,
3302  &serv->address.address.ipv6));
3303  }
3304  else
3305  {
3306  struct addrinfo *res;
3307  int ret;
3308 
3309  ret = getaddrinfo (hostname,
3310  NULL,
3311  NULL,
3312  &res);
3313  if ( (0 != ret) || (NULL == res) )
3314  {
3316  _("No addresses found for hostname `%s' of service `%s'!\n"),
3317  hostname,
3318  n);
3319  GNUNET_free (serv);
3320  continue;
3321  }
3322 
3323  serv->address.af = res->ai_family;
3324  switch (res->ai_family)
3325  {
3326  case AF_INET:
3327  if (! ipv4_enabled)
3328  {
3330  _("Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
3331  n);
3332  freeaddrinfo (res);
3333  GNUNET_free (serv);
3334  continue;
3335  }
3336  serv->address.address.ipv4
3337  = ((struct sockaddr_in *) res->ai_addr)->sin_addr;
3338  break;
3339  case AF_INET6:
3340  if (! ipv6_enabled)
3341  {
3343  _("Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
3344  n);
3345  freeaddrinfo (res);
3346  GNUNET_free (serv);
3347  continue;
3348  }
3349  serv->address.address.ipv6
3350  = ((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
3351  break;
3352  default:
3353  freeaddrinfo (res);
3355  _("No IP addresses found for hostname `%s' of service `%s'!\n"),
3356  hostname,
3357  n);
3358  GNUNET_free (serv);
3359  continue;
3360  }
3361  freeaddrinfo (res);
3362  }
3363  store_service (proto,
3364  n,
3365  local_port,
3366  serv);
3367  }
3368  GNUNET_free (n);
3369 }
3370 
3371 
3378 static void
3380  const char *section)
3381 {
3382  char *cpy;
3383 
3384  if ((strlen (section) < 8) ||
3385  (0 != strcmp (".gnunet.", section + (strlen (section) - 8))))
3386  return;
3387  if (GNUNET_OK ==
3389  section,
3390  "UDP_REDIRECTS",
3391  &cpy))
3392  {
3393  add_services (IPPROTO_UDP,
3394  cpy,
3395  section);
3396  GNUNET_free (cpy);
3397  }
3398  if (GNUNET_OK ==
3400  section,
3401  "TCP_REDIRECTS",
3402  &cpy))
3403  {
3404  add_services (IPPROTO_TCP,
3405  cpy,
3406  section);
3407  GNUNET_free (cpy);
3408  }
3409 }
3410 
3411 
3418 static void
3419 do_dht_put (void *cls);
3420 
3421 
3428 static void
3429 dht_put_cont (void *cls)
3430 {
3431  dht_put = NULL;
3432 }
3433 
3434 
3441 static void
3442 do_dht_put (void *cls)
3443 {
3444  struct GNUNET_TIME_Absolute expiration;
3445 
3447  &do_dht_put,
3448  NULL);
3450  if (GNUNET_TIME_absolute_get_remaining (expiration).rel_value_us <
3451  GNUNET_TIME_UNIT_HOURS.rel_value_us)
3452  {
3453  /* refresh advertisement */
3457  GNUNET_CRYPTO_eddsa_sign (peer_key,
3460  }
3461  if (NULL != dht_put)
3462  GNUNET_DHT_put_cancel (dht_put);
3463  dht_put = GNUNET_DHT_put (dht,
3464  &dht_put_key,
3465  1 /* replication */,
3468  sizeof (struct GNUNET_DNS_Advertisement),
3470  expiration,
3471  &dht_put_cont,
3472  NULL);
3473 }
3474 
3475 
3480 static void
3482 {
3484  "exit",
3485  "EXIT_IPV4");
3487  "exit",
3488  "EXIT_IPV6");
3490  "exit",
3491  "ENABLE_IPV4");
3493  "exit",
3494  "ENABLE_IPV6");
3495  if ( (ipv4_exit || ipv4_enabled) &&
3496  GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET))
3497  {
3499  _("This system does not support IPv4, will disable IPv4 functions despite them being enabled in the configuration\n"));
3500  ipv4_exit = GNUNET_NO;
3502  }
3503  if ( (ipv6_exit || ipv6_enabled) &&
3504  GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET6))
3505  {
3507  _("This system does not support IPv6, will disable IPv6 functions despite them being enabled in the configuration\n"));
3508  ipv6_exit = GNUNET_NO;
3510  }
3511  if (ipv4_exit && (! ipv4_enabled))
3512  {
3514  _("Cannot enable IPv4 exit but disable IPv4 on TUN interface, will use ENABLE_IPv4=YES\n"));
3516  }
3517  if (ipv6_exit && (! ipv6_enabled))
3518  {
3520  _("Cannot enable IPv6 exit but disable IPv6 on TUN interface, will use ENABLE_IPv6=YES\n"));
3522  }
3523 }
3524 
3525 
3530 static void
3532 {
3533  struct GNUNET_MQ_MessageHandler handlers[] = {
3534  GNUNET_MQ_hd_var_size (dns_request,
3536  struct DnsResponseMessage,
3537  NULL),
3539  };
3540  char *dns_exit;
3541  struct GNUNET_HashCode port;
3542 
3543  if (GNUNET_YES !=
3545  "exit",
3546  "EXIT_DNS"))
3547  return;
3548  GNUNET_assert (NULL != (dnsstub = GNUNET_DNSSTUB_start (128)));
3549  dns_exit = NULL;
3550  /* TODO: support using multiple DNS resolvers */
3551  if ( (GNUNET_OK !=
3553  "exit",
3554  "DNS_RESOLVER",
3555  &dns_exit)) ||
3556  (GNUNET_OK !=
3557  GNUNET_DNSSTUB_add_dns_ip (dnsstub,
3558  dns_exit)) )
3559  {
3561  "dns",
3562  "DNS_RESOLVER",
3563  _("need a valid IPv4 or IPv6 address\n"));
3564  GNUNET_free_non_null (dns_exit);
3565  return;
3566  }
3567  /* open port */
3570  &port);
3572  "Opening CADET port %s for DNS exit service\n",
3573  GNUNET_h2s (&port));
3574  dns_port = GNUNET_CADET_open_port (cadet_handle,
3575  &port,
3576  &new_channel,
3577  NULL,
3578  NULL,
3579  &clean_channel,
3580  handlers);
3581  /* advertise exit */
3582  dht = GNUNET_DHT_connect (cfg,
3583  1);
3587  dns_advertisement.purpose.size = htonl (sizeof (struct GNUNET_DNS_Advertisement) -
3588  sizeof (struct GNUNET_CRYPTO_EddsaSignature));
3590  GNUNET_CRYPTO_hash ("dns",
3591  strlen ("dns"),
3592  &dht_put_key);
3593  dht_task = GNUNET_SCHEDULER_add_now (&do_dht_put,
3594  NULL);
3595  GNUNET_free (dns_exit);
3596 }
3597 
3598 
3604 static int
3606 {
3607  char *exit_ifname;
3608  char *tun_ifname;
3609  char *ipv6addr;
3610  char *ipv6prefix_s;
3611  char *ipv4addr;
3612  char *ipv4mask;
3613 
3614  exit_argv[0] = GNUNET_strdup ("exit-gnunet");
3615  if (GNUNET_SYSERR ==
3617  "exit",
3618  "TUN_IFNAME",
3619  &tun_ifname))
3620  {
3622  "EXIT",
3623  "TUN_IFNAME");
3624  return GNUNET_SYSERR;
3625  }
3626  exit_argv[1] = tun_ifname;
3627  if (ipv4_enabled)
3628  {
3629  if (GNUNET_SYSERR ==
3631  "exit",
3632  "EXIT_IFNAME",
3633  &exit_ifname))
3634  {
3636  "EXIT",
3637  "EXIT_IFNAME");
3638  return GNUNET_SYSERR;
3639  }
3640  exit_argv[2] = exit_ifname;
3641  }
3642  else
3643  {
3644  exit_argv[2] = GNUNET_strdup ("-");
3645  }
3646 
3647  if (GNUNET_YES == ipv6_enabled)
3648  {
3649  ipv6addr = NULL;
3650  if ( (GNUNET_SYSERR ==
3652  "exit",
3653  "IPV6ADDR",
3654  &ipv6addr) ||
3655  (1 != inet_pton (AF_INET6,
3656  ipv6addr,
3657  &exit_ipv6addr))) )
3658  {
3660  "EXIT",
3661  "IPV6ADDR");
3662  GNUNET_free_non_null (ipv6addr);
3663  return GNUNET_SYSERR;
3664  }
3665  exit_argv[3] = ipv6addr;
3666  if (GNUNET_SYSERR ==
3668  "exit",
3669  "IPV6PREFIX",
3670  &ipv6prefix_s))
3671  {
3673  "EXIT",
3674  "IPV6PREFIX");
3675  return GNUNET_SYSERR;
3676  }
3677  exit_argv[4] = ipv6prefix_s;
3678  if ( (GNUNET_OK !=
3680  "exit",
3681  "IPV6PREFIX",
3682  &ipv6prefix)) ||
3683  (ipv6prefix >= 127) )
3684  {
3686  "EXIT",
3687  "IPV6PREFIX",
3688  _("Must be a number"));
3689  return GNUNET_SYSERR;
3690  }
3691  }
3692  else
3693  {
3694  /* IPv6 explicitly disabled */
3695  exit_argv[3] = GNUNET_strdup ("-");
3696  exit_argv[4] = GNUNET_strdup ("-");
3697  }
3698  if (GNUNET_YES == ipv4_enabled)
3699  {
3700  ipv4addr = NULL;
3701  if ( (GNUNET_SYSERR ==
3703  "exit",
3704  "IPV4ADDR",
3705  &ipv4addr) ||
3706  (1 != inet_pton (AF_INET,
3707  ipv4addr,
3708  &exit_ipv4addr))) )
3709  {
3711  "EXIT",
3712  "IPV4ADDR");
3713  GNUNET_free_non_null (ipv4addr);
3714  return GNUNET_SYSERR;
3715  }
3716  exit_argv[5] = ipv4addr;
3717  ipv4mask = NULL;
3718  if ( (GNUNET_SYSERR ==
3720  "exit",
3721  "IPV4MASK",
3722  &ipv4mask) ||
3723  (1 != inet_pton (AF_INET,
3724  ipv4mask,
3725  &exit_ipv4mask))) )
3726  {
3728  "EXIT",
3729  "IPV4MASK");
3730  GNUNET_free_non_null (ipv4mask);
3731  return GNUNET_SYSERR;
3732  }
3733  exit_argv[6] = ipv4mask;
3734  }
3735  else
3736  {
3737  /* IPv4 explicitly disabled */
3738  exit_argv[5] = GNUNET_strdup ("-");
3739  exit_argv[6] = GNUNET_strdup ("-");
3740  }
3741  exit_argv[7] = NULL;
3742  return GNUNET_OK;
3743 }
3744 
3745 
3754 static void
3755 run (void *cls,
3756  char *const *args,
3757  const char *cfgfile,
3758  const struct GNUNET_CONFIGURATION_Handle *cfg_)
3759 {
3760  struct GNUNET_MQ_MessageHandler handlers[] = {
3761  GNUNET_MQ_hd_var_size (icmp_remote,
3764  NULL),
3765  GNUNET_MQ_hd_var_size (udp_remote,
3768  NULL),
3769  GNUNET_MQ_hd_var_size (tcp_remote,
3772  NULL),
3773  GNUNET_MQ_hd_var_size (tcp_data,
3776  NULL),
3778  };
3779  struct GNUNET_HashCode port;
3780  char *policy;
3781  char *binary;
3782  char *regex;
3783  char *prefixed_regex;
3784 
3785  cfg = cfg_;
3786  if (GNUNET_OK !=
3788  "exit",
3789  "MAX_CONNECTIONS",
3790  &max_connections))
3791  max_connections = 1024;
3792  parse_ip_options ();
3793  binary = GNUNET_OS_get_suid_binary_path (cfg, "gnunet-helper-exit");
3794  if ( (ipv4_exit) || (ipv6_exit) )
3795  {
3796  if (GNUNET_YES !=
3798  GNUNET_YES,
3799  "gnunet-vpn - - - 169.1.3.7 255.255.255.0")) //no nat, ipv4 only
3800  {
3801  GNUNET_free (binary);
3803  _("`%s' is not SUID or the path is invalid, EXIT will not work\n"),
3804  "gnunet-helper-exit");
3806  NULL);
3807  global_ret = 1;
3808  return;
3809  }
3810  }
3811  if (! (ipv4_enabled || ipv6_enabled))
3812  {
3813  GNUNET_free (binary);
3815  _("No useful service enabled. Exiting.\n"));
3817  return;
3818  }
3819 
3821  NULL);
3822  stats = GNUNET_STATISTICS_create ("exit",
3823  cfg);
3824  cadet_handle = GNUNET_CADET_connect (cfg);
3825  if (NULL == cadet_handle)
3826  {
3827  GNUNET_free (binary);
3829  return;
3830  }
3831  advertise_dns_exit ();
3832  if (GNUNET_OK !=
3834  {
3835  GNUNET_free (binary);
3837  return;
3838  }
3839 
3840  services = GNUNET_CONTAINER_multihashmap_create (65536,
3841  GNUNET_NO);
3842  connections_map = GNUNET_CONTAINER_multihashmap_create (65536,
3843  GNUNET_NO);
3847  NULL);
3848 
3849  /* Cadet handle acquired, now open ports and announce regular
3850  expressions matching our exit */
3851  if ( (GNUNET_YES == ipv4_enabled) &&
3852  (GNUNET_YES == ipv4_exit) )
3853  {
3856  &port);
3858  "Opening CADET port %s for IPv4 gateway service\n",
3859  GNUNET_h2s (&port));
3860  cadet_port4 = GNUNET_CADET_open_port (cadet_handle,
3861  &port,
3862  &new_channel,
3863  NULL,
3864  NULL,
3865  &clean_channel,
3866  handlers);
3867  policy = NULL;
3868  if (GNUNET_OK !=
3870  "exit",
3871  "EXIT_RANGE_IPV4_POLICY",
3872  &policy))
3873  regex = NULL;
3874  else
3875  regex = GNUNET_TUN_ipv4policy2regex (policy);
3876  GNUNET_free_non_null (policy);
3877  if (NULL != regex)
3878  {
3879  (void) GNUNET_asprintf (&prefixed_regex,
3880  "%s%s",
3882  regex);
3883  regex4 = GNUNET_REGEX_announce (cfg,
3884  prefixed_regex,
3887  GNUNET_free (regex);
3888  GNUNET_free (prefixed_regex);
3889  }
3890  }
3891 
3892  if ( (GNUNET_YES == ipv6_enabled) && (GNUNET_YES == ipv6_exit) )
3893  {
3896  &port);
3898  "Opening CADET port %s for IPv6 gateway service\n",
3899  GNUNET_h2s (&port));
3900  cadet_port6 = GNUNET_CADET_open_port (cadet_handle,
3901  &port,
3902  &new_channel,
3903  NULL,
3904  NULL,
3905  &clean_channel,
3906  handlers);
3907  policy = NULL;
3908  if (GNUNET_OK !=
3910  "exit",
3911  "EXIT_RANGE_IPV6_POLICY",
3912  &policy))
3913  regex = NULL;
3914  else
3915  regex = GNUNET_TUN_ipv6policy2regex (policy);
3916  GNUNET_free_non_null (policy);
3917  if (NULL != regex)
3918  {
3919  (void) GNUNET_asprintf (&prefixed_regex,
3920  "%s%s",
3922  regex);
3923  regex6 = GNUNET_REGEX_announce (cfg,
3924  prefixed_regex,
3927  GNUNET_free (regex);
3928  GNUNET_free (prefixed_regex);
3929  }
3930  }
3931  helper_handle = GNUNET_HELPER_start (GNUNET_NO,
3932  binary,
3933  exit_argv,
3934  &message_token,
3935  NULL,
3936  NULL);
3937  GNUNET_free (binary);
3938 }
3939 
3940 
3948 int
3949 main (int argc,
3950  char *const *argv)
3951 {
3952  static const struct GNUNET_GETOPT_CommandLineOption options[] = {
3954  };
3955 
3956  if (GNUNET_OK !=
3958  argv,
3959  &argc,
3960  &argv))
3961  return 2;
3962 
3963  return (GNUNET_OK ==
3964  GNUNET_PROGRAM_run (argc,
3965  argv,
3966  "gnunet-daemon-exit",
3967  gettext_noop ("Daemon to run to provide an IP exit node for the VPN"),
3968  options,
3969  &run,
3970  NULL)) ? global_ret : 1;
3971 }
3972 
3973 
3974 /* 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:843
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:670
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:699
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:1040
union ChannelState::@114 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
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.
union SocketAddress::@12 address
Remote address information.
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:80
struct GNUNET_HELPER_Handle * GNUNET_HELPER_start(int with_control_pipe, const char *binary_name, char *const binary_argv[], GNUNET_MessageTokenizerCallback cb, GNUNET_HELPER_ExceptionCallback exp_cb, void *cb_cls)
Starts a helper and begins reading from it.
Definition: helper.c:491
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1293
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:1521
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:245
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:731
#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:622
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:989
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:569
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.
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:81
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:78
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.
struct ChannelState::@13::@15 dns
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:524
static int ret
Final status code.
Definition: gnunet-arm.c:89
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.
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
#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:205
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition: cadet_api.c:977
#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:208
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:1246
#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:1011
#define GNUNET_memcpy(dst, src, n)
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:595
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
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:1273
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:804
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:125
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:533
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:823
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:971
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
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:895
uint8_t proto
IPPROTO_TCP or IPPROTO_UDP;.
#define GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE
const char * name
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:923
static void do_dht_put(void *cls)
We are running a DNS exit service, advertise it in the DHT.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
void GNUNET_TUN_calculate_icmp_checksum(struct GNUNET_TUN_IcmpHeader *icmp, const void *payload, uint16_t payload_length)
Calculate ICMP checksum.
Definition: tun.c:260
Message send via cadet to the vpn service to send ICMP data to the VPN&#39;s TUN interface.
Definition: exit.h:271
struct GNUNET_TUN_DnsHeader dns
DNS header.
TCP packet header.
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
static unsigned long long payload
How much data are we currently storing in the database?
static struct GNUNET_CONTAINER_Heap * connections_heap
Heap so we can quickly find "old" connections.
static struct GNUNET_CRYPTO_EddsaPrivateKey * peer_key
Private key for this peer.
static struct GNUNET_NETWORK_Handle * ls
Listen socket for STUN processing.
Definition: gnunet-nat.c:85
uint16_t crc
Checksum.
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
an ECC signature using EdDSA.
static int tcp
Option -t: TCP requested.
Definition: gnunet-vpn.c:71
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
void GNUNET_CRYPTO_eddsa_key_get_public(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:272
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:955
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:751
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:660
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.
static int inet_pton(int af, const char *cp, struct in_addr *buf)
Convert IPv4 address from text to binary form.
#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.
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:146
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:361
#define REGEX_MAX_PATH_LEN_IPV6
Maximum path compression length for cadet regex announcing for IPv6 address based regex...
union ChannelState::@13 specifics
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:876
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:80
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.
struct ChannelState::@13::@14 tcp_udp
UDP socket we are using for sending DNS requests to the Internet.
Definition: dnsstub.c:43
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:654
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:905
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:84
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:1121
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:965
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