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 
92 struct SocketAddress {
96  int af;
97 
101  union {
105  struct in_addr ipv4;
106 
110  struct in6_addr ipv6;
111  } address;
112 
116  uint8_t proto;
117 
121  uint16_t port;
122 };
123 
124 
130 struct LocalService {
135 
139  struct GNUNET_HashCode descriptor;
140 
144  char *name;
145 
150 
154  int16_t is_udp;
155 };
156 
157 
168  struct SocketAddress remote_address;
169 
175  struct SocketAddress local_address;
176 
177  /*
178  Note 1: additional information might be added here in the
179  future to support protocols that require special handling,
180  such as ftp/tftp
181 
182  Note 2: we might also sometimes not match on all components
183  of the tuple, to support protocols where things do not always
184  fully map.
185  */
186 };
187 
188 
195 struct ChannelState {
200 
206 
212  int is_dns;
213 
214  union {
215  struct {
220 
224  struct GNUNET_HashCode state_key;
225 
230 
235  } tcp_udp;
236 
237  struct {
243 
247  uint16_t original_id;
248 
252  uint16_t my_id;
253  } dns;
254  } specifics;
255 };
256 
257 
261 static int global_ret;
262 
267 
272 
276 static const struct GNUNET_CONFIGURATION_Handle *cfg;
277 
282 
286 static char *exit_argv[8];
287 
291 static struct in6_addr exit_ipv6addr;
292 
296 static unsigned long long ipv6prefix;
297 
301 static struct in_addr exit_ipv4addr;
302 
306 static struct in_addr exit_ipv4mask;
307 
312 
317 
323 
328 
332 static unsigned long long max_connections;
333 
338 
342 static struct ChannelState *channels[UINT16_MAX + 1];
343 
348 
353 
357 static struct GNUNET_DHT_Handle *dht;
358 
363 
369 
374 
379 
384 
389 
394 
398 static int ipv4_exit;
399 
403 static int ipv6_exit;
404 
408 static int ipv4_enabled;
409 
413 static int ipv6_enabled;
414 
415 
417 
425  struct GNUNET_MessageHeader header;
426 
431 
432  /* Followed by more DNS payload */
433 };
434 
436 
437 
446 static void
448  const struct GNUNET_TUN_DnsHeader *dns,
449  size_t r)
450 {
451  struct ChannelState *ts;
452  struct GNUNET_MQ_Envelope *env;
453  struct DnsResponseMessage *resp;
454 
456  "Processing DNS result from stub resolver\n");
457  GNUNET_assert(NULL == cls);
458  if (NULL == dns)
459  return;
460  /* Handle case that this is a reply to a request from a CADET DNS channel */
461  ts = channels[dns->id];
462  if (NULL == ts)
463  return;
465  "Got a response from the stub resolver for DNS request received via CADET!\n");
466  channels[dns->id] = NULL;
467  env = GNUNET_MQ_msg_extra(resp,
468  r - sizeof(struct GNUNET_TUN_DnsHeader),
470  GNUNET_memcpy(&resp->dns,
471  dns,
472  r);
473  resp->dns.id = ts->specifics.dns.original_id;
475  env);
476 }
477 
478 
487 static int
489  const struct DnsResponseMessage *msg)
490 {
491  struct ChannelState *ts = cls;
492 
493  if (NULL == dnsstub)
494  {
495  GNUNET_break(0);
496  return GNUNET_SYSERR;
497  }
498  if (GNUNET_NO == ts->is_dns)
499  {
500  GNUNET_break_op(0);
501  return GNUNET_SYSERR;
502  }
503  return GNUNET_OK;
504 }
505 
506 
513 static void
515  const struct DnsResponseMessage *msg)
516 {
517  struct ChannelState *ts = cls;
518  size_t mlen = ntohs(msg->header.size);
519  size_t dlen = mlen - sizeof(struct GNUNET_MessageHeader);
520  char buf[dlen] GNUNET_ALIGN;
521  struct GNUNET_TUN_DnsHeader *dout;
522 
523  if (GNUNET_SYSERR == ts->is_dns)
524  {
525  /* channel is DNS from now on */
526  ts->is_dns = GNUNET_YES;
527  }
528  ts->specifics.dns.original_id = msg->dns.id;
529  if (channels[ts->specifics.dns.my_id] == ts)
530  channels[ts->specifics.dns.my_id] = NULL;
532  UINT16_MAX + 1);
533  channels[ts->specifics.dns.my_id] = ts;
535  &msg->dns,
536  dlen);
537  dout = (struct GNUNET_TUN_DnsHeader *)buf;
538  dout->id = ts->specifics.dns.my_id;
539  ts->specifics.dns.rs = GNUNET_DNSSTUB_resolve(dnsstub,
540  buf,
541  dlen,
543  NULL);
544  if (NULL == ts->specifics.dns.rs)
545  {
546  GNUNET_break_op(0);
547  return;
548  }
550 }
551 
552 
560 static void
562  const struct RedirectInformation *ri)
563 {
564  char *off;
565 
566  memset(hash,
567  0,
568  sizeof(struct GNUNET_HashCode));
569  /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
570  so we put the IP address in there (and hope for few collisions) */
571  off = (char*)hash;
572  switch (ri->remote_address.af)
573  {
574  case AF_INET:
575  GNUNET_memcpy(off,
577  sizeof(struct in_addr));
578  off += sizeof(struct in_addr);
579  break;
580 
581  case AF_INET6:
582  GNUNET_memcpy(off,
584  sizeof(struct in6_addr));
585  off += sizeof(struct in_addr);
586  break;
587 
588  default:
589  GNUNET_assert(0);
590  }
591  GNUNET_memcpy(off,
592  &ri->remote_address.port,
593  sizeof(uint16_t));
594  off += sizeof(uint16_t);
595  switch (ri->local_address.af)
596  {
597  case AF_INET:
598  GNUNET_memcpy(off,
600  sizeof(struct in_addr));
601  off += sizeof(struct in_addr);
602  break;
603 
604  case AF_INET6:
605  GNUNET_memcpy(off,
607  sizeof(struct in6_addr));
608  off += sizeof(struct in_addr);
609  break;
610 
611  default:
612  GNUNET_assert(0);
613  }
614  GNUNET_memcpy(off,
615  &ri->local_address.port,
616  sizeof(uint16_t));
617  off += sizeof(uint16_t);
618  GNUNET_memcpy(off,
619  &ri->remote_address.proto,
620  sizeof(uint8_t));
621  /* off += sizeof (uint8_t); */
622 }
623 
624 
638 static struct ChannelState *
640  int protocol,
641  const void *destination_ip,
642  uint16_t destination_port,
643  const void *local_ip,
644  uint16_t local_port,
645  struct GNUNET_HashCode *state_key)
646 {
647  struct RedirectInformation ri;
648  struct GNUNET_HashCode key;
649  struct ChannelState *state;
650 
651  if (((af == AF_INET) && (protocol == IPPROTO_ICMP)) ||
652  ((af == AF_INET6) && (protocol == IPPROTO_ICMPV6)))
653  {
654  /* ignore ports */
655  destination_port = 0;
656  local_port = 0;
657  }
658  ri.remote_address.af = af;
659  if (af == AF_INET)
660  ri.remote_address.address.ipv4 = *((struct in_addr*)destination_ip);
661  else
662  ri.remote_address.address.ipv6 = *((struct in6_addr*)destination_ip);
663  ri.remote_address.port = destination_port;
664  ri.remote_address.proto = protocol;
665  ri.local_address.af = af;
666  if (af == AF_INET)
667  ri.local_address.address.ipv4 = *((struct in_addr*)local_ip);
668  else
669  ri.local_address.address.ipv6 = *((struct in6_addr*)local_ip);
670  ri.local_address.port = local_port;
671  ri.local_address.proto = protocol;
672  hash_redirect_info(&key,
673  &ri);
674  if (NULL != state_key)
675  *state_key = key;
676  state = GNUNET_CONTAINER_multihashmap_get(connections_map,
677  &key);
678  if (NULL == state)
679  return NULL;
680  /* Mark this connection as freshly used */
681  if (NULL == state_key)
683  GNUNET_TIME_absolute_get().abs_value_us);
684  return state;
685 }
686 
687 
688 
698 static int
701 {
702  struct ChannelState *state = cls;
703 
704  if (NULL == state)
705  {
706  GNUNET_break_op(0);
707  return GNUNET_SYSERR;
708  }
709  if (GNUNET_YES == state->is_dns)
710  {
711  GNUNET_break_op(0);
712  return GNUNET_SYSERR;
713  }
714  if (NULL == state->specifics.tcp_udp.serv)
715  {
716  GNUNET_break_op(0);
717  return GNUNET_SYSERR;
718  }
719  if (NULL != state->specifics.tcp_udp.heap_node)
720  {
721  GNUNET_break_op(0);
722  return GNUNET_SYSERR;
723  }
724  if (start->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
725  {
726  GNUNET_break_op(0);
727  return GNUNET_SYSERR;
728  }
729  return GNUNET_OK;
730 }
731 
732 
751 static void
753  size_t payload_length,
754  int protocol,
755  const struct GNUNET_TUN_TcpHeader *tcp_header,
756  const struct SocketAddress *src_address,
757  const struct SocketAddress *dst_address,
758  struct GNUNET_TUN_IPv4Header *pkt4)
759 {
760  size_t len;
761 
762  len = payload_length;
763  switch (protocol)
764  {
765  case IPPROTO_UDP:
766  len += sizeof(struct GNUNET_TUN_UdpHeader);
767  break;
768 
769  case IPPROTO_TCP:
770  len += sizeof(struct GNUNET_TUN_TcpHeader);
771  GNUNET_assert(NULL != tcp_header);
772  break;
773 
774  default:
775  GNUNET_break(0);
776  return;
777  }
778  if (len + sizeof(struct GNUNET_TUN_IPv4Header) > UINT16_MAX)
779  {
780  GNUNET_break(0);
781  return;
782  }
783 
785  protocol,
786  len,
787  &src_address->address.ipv4,
788  &dst_address->address.ipv4);
789  switch (protocol)
790  {
791  case IPPROTO_UDP:
792  {
793  struct GNUNET_TUN_UdpHeader *pkt4_udp = (struct GNUNET_TUN_UdpHeader *)&pkt4[1];
794 
795  pkt4_udp->source_port = htons(src_address->port);
796  pkt4_udp->destination_port = htons(dst_address->port);
797  pkt4_udp->len = htons((uint16_t)payload_length);
799  pkt4_udp,
800  payload,
801  payload_length);
802  GNUNET_memcpy(&pkt4_udp[1],
803  payload,
804  payload_length);
805  }
806  break;
807 
808  case IPPROTO_TCP:
809  {
810  struct GNUNET_TUN_TcpHeader *pkt4_tcp = (struct GNUNET_TUN_TcpHeader *)&pkt4[1];
811 
812  *pkt4_tcp = *tcp_header;
814  "Sending TCP packet from port %u to port %u\n",
815  src_address->port,
816  dst_address->port);
817  pkt4_tcp->source_port = htons(src_address->port);
818  pkt4_tcp->destination_port = htons(dst_address->port);
820  pkt4_tcp,
821  payload,
822  payload_length);
823  GNUNET_memcpy(&pkt4_tcp[1],
824  payload,
825  payload_length);
826  }
827  break;
828 
829  default:
830  GNUNET_assert(0);
831  }
832 }
833 
834 
853 static void
855  size_t payload_length,
856  int protocol,
857  const struct GNUNET_TUN_TcpHeader *tcp_header,
858  const struct SocketAddress *src_address,
859  const struct SocketAddress *dst_address,
860  struct GNUNET_TUN_IPv6Header *pkt6)
861 {
862  size_t len;
863 
864  len = payload_length;
865  switch (protocol)
866  {
867  case IPPROTO_UDP:
868  len += sizeof(struct GNUNET_TUN_UdpHeader);
869  break;
870 
871  case IPPROTO_TCP:
872  len += sizeof(struct GNUNET_TUN_TcpHeader);
873  break;
874 
875  default:
876  GNUNET_break(0);
877  return;
878  }
879  if (len > UINT16_MAX)
880  {
881  GNUNET_break(0);
882  return;
883  }
884 
886  protocol,
887  len,
888  &src_address->address.ipv6,
889  &dst_address->address.ipv6);
890 
891  switch (protocol)
892  {
893  case IPPROTO_UDP:
894  {
895  struct GNUNET_TUN_UdpHeader *pkt6_udp = (struct GNUNET_TUN_UdpHeader *)&pkt6[1];
896 
897  pkt6_udp->source_port = htons(src_address->port);
898  pkt6_udp->destination_port = htons(dst_address->port);
899  pkt6_udp->len = htons((uint16_t)payload_length);
901  pkt6_udp,
902  payload,
903  payload_length);
904  GNUNET_memcpy(&pkt6_udp[1],
905  payload,
906  payload_length);
907  }
908  break;
909 
910  case IPPROTO_TCP:
911  {
912  struct GNUNET_TUN_TcpHeader *pkt6_tcp = (struct GNUNET_TUN_TcpHeader *)&pkt6[1];
913 
914  /* GNUNET_memcpy first here as some TCP header fields are initialized this way! */
915  *pkt6_tcp = *tcp_header;
916  pkt6_tcp->source_port = htons(src_address->port);
917  pkt6_tcp->destination_port = htons(dst_address->port);
919  pkt6_tcp,
920  payload,
921  payload_length);
922  GNUNET_memcpy(&pkt6_tcp[1],
923  payload,
924  payload_length);
925  }
926  break;
927 
928  default:
929  GNUNET_assert(0);
930  break;
931  }
932 }
933 
934 
944 static void
945 send_tcp_packet_via_tun(const struct SocketAddress *destination_address,
946  const struct SocketAddress *source_address,
947  const struct GNUNET_TUN_TcpHeader *tcp_header,
948  const void *payload,
949  size_t payload_length)
950 {
951  size_t len;
952 
954  gettext_noop("# TCP packets sent via TUN"),
955  1,
956  GNUNET_NO);
958  "Sending packet with %u bytes TCP payload via TUN\n",
959  (unsigned int)payload_length);
960  len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct GNUNET_TUN_Layer2PacketHeader);
961  switch (source_address->af)
962  {
963  case AF_INET:
964  len += sizeof(struct GNUNET_TUN_IPv4Header);
965  break;
966 
967  case AF_INET6:
968  len += sizeof(struct GNUNET_TUN_IPv6Header);
969  break;
970 
971  default:
972  GNUNET_break(0);
973  return;
974  }
975  len += sizeof(struct GNUNET_TUN_TcpHeader);
976  len += payload_length;
977  if (len >= GNUNET_MAX_MESSAGE_SIZE)
978  {
979  GNUNET_break(0);
980  return;
981  }
982  {
983  char buf[len] GNUNET_ALIGN;
984  struct GNUNET_MessageHeader *hdr;
985  struct GNUNET_TUN_Layer2PacketHeader *tun;
986 
987  hdr = (struct GNUNET_MessageHeader *)buf;
988  hdr->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
989  hdr->size = htons(len);
990  tun = (struct GNUNET_TUN_Layer2PacketHeader*)&hdr[1];
991  tun->flags = htons(0);
992  switch (source_address->af)
993  {
994  case AF_INET:
995  {
997  = (struct GNUNET_TUN_IPv4Header*)&tun[1];
998 
999  tun->proto = htons(ETH_P_IPV4);
1000  prepare_ipv4_packet(payload,
1001  payload_length,
1002  IPPROTO_TCP,
1003  tcp_header,
1004  source_address,
1005  destination_address,
1006  ipv4);
1007  }
1008  break;
1009 
1010  case AF_INET6:
1011  {
1012  struct GNUNET_TUN_IPv6Header *ipv6
1013  = (struct GNUNET_TUN_IPv6Header*)&tun[1];
1014 
1015  tun->proto = htons(ETH_P_IPV6);
1016  prepare_ipv6_packet(payload,
1017  payload_length,
1018  IPPROTO_TCP,
1019  tcp_header,
1020  source_address,
1021  destination_address,
1022  ipv6);
1023  }
1024  break;
1025 
1026  default:
1027  GNUNET_assert(0);
1028  break;
1029  }
1030  if (NULL != helper_handle)
1031  (void)GNUNET_HELPER_send(helper_handle,
1032  (const struct GNUNET_MessageHeader*)buf,
1033  GNUNET_YES,
1034  NULL,
1035  NULL);
1036  }
1037 }
1038 
1039 
1049 static void
1051  const struct SocketAddress *source_address,
1052  const struct GNUNET_TUN_IcmpHeader *icmp_header,
1053  const void *payload, size_t payload_length)
1054 {
1055  size_t len;
1056  struct GNUNET_TUN_IcmpHeader *icmp;
1057 
1059  gettext_noop("# ICMP packets sent via TUN"),
1060  1, GNUNET_NO);
1062  "Sending packet with %u bytes ICMP payload via TUN\n",
1063  (unsigned int)payload_length);
1064  len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct GNUNET_TUN_Layer2PacketHeader);
1065  switch (destination_address->af)
1066  {
1067  case AF_INET:
1068  len += sizeof(struct GNUNET_TUN_IPv4Header);
1069  break;
1070 
1071  case AF_INET6:
1072  len += sizeof(struct GNUNET_TUN_IPv6Header);
1073  break;
1074 
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 
1112  case AF_INET6:
1113  {
1114  struct GNUNET_TUN_IPv6Header * ipv6 = (struct GNUNET_TUN_IPv6Header*)&tun[1];
1115 
1116  tun->proto = htons(ETH_P_IPV6);
1118  IPPROTO_ICMPV6,
1119  sizeof(struct GNUNET_TUN_IcmpHeader) + payload_length,
1120  &source_address->address.ipv6,
1121  &destination_address->address.ipv6);
1122  icmp = (struct GNUNET_TUN_IcmpHeader*)&ipv6[1];
1123  }
1124  break;
1125 
1126  default:
1127  GNUNET_assert(0);
1128  break;
1129  }
1130  *icmp = *icmp_header;
1131  GNUNET_memcpy(&icmp[1],
1132  payload,
1133  payload_length);
1135  payload,
1136  payload_length);
1137  if (NULL != helper_handle)
1138  (void)GNUNET_HELPER_send(helper_handle,
1139  (const struct GNUNET_MessageHeader*)buf,
1140  GNUNET_YES,
1141  NULL, NULL);
1142  }
1143 }
1144 
1145 
1154 static void
1156  uint8_t proto,
1157  struct SocketAddress *local_address)
1158 {
1159  local_address->af = af;
1160  local_address->proto = (uint8_t)proto;
1161  /* default "local" port range is often 32768--61000,
1162  so we pick a random value in that range */
1163  if (((af == AF_INET) && (proto == IPPROTO_ICMP)) ||
1164  ((af == AF_INET6) && (proto == IPPROTO_ICMPV6)))
1165  local_address->port = 0;
1166  else
1167  local_address->port
1169  28232);
1170  switch (af)
1171  {
1172  case AF_INET:
1173  {
1174  struct in_addr addr;
1175  struct in_addr mask;
1176  struct in_addr rnd;
1177 
1178  addr = exit_ipv4addr;
1179  mask = exit_ipv4mask;
1180  if (0 == ~mask.s_addr)
1181  {
1182  /* only one valid IP anyway */
1183  local_address->address.ipv4 = addr;
1184  return;
1185  }
1186  /* Given 192.168.0.1/255.255.0.0, we want a mask
1187  of '192.168.255.255', thus: */
1188  mask.s_addr = addr.s_addr | ~mask.s_addr;
1189  /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
1190  do
1191  {
1193  UINT32_MAX);
1194  local_address->address.ipv4.s_addr = (addr.s_addr | rnd.s_addr) & mask.s_addr;
1195  }
1196  while ((local_address->address.ipv4.s_addr == addr.s_addr) ||
1197  (local_address->address.ipv4.s_addr == mask.s_addr));
1198  }
1199  break;
1200 
1201  case AF_INET6:
1202  {
1203  struct in6_addr addr;
1204  struct in6_addr mask;
1205  struct in6_addr rnd;
1206  int i;
1207 
1208  addr = exit_ipv6addr;
1209  GNUNET_assert(ipv6prefix < 128);
1210  if (ipv6prefix == 127)
1211  {
1212  /* only one valid IP anyway */
1213  local_address->address.ipv6 = addr;
1214  return;
1215  }
1216  /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
1217  thus: */
1218  mask = addr;
1219  for (i = 127; i >= ipv6prefix; i--)
1220  mask.s6_addr[i / 8] |= (1 << (i % 8));
1221 
1222  /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */
1223  do
1224  {
1225  for (i = 0; i < 16; i++)
1226  {
1227  rnd.s6_addr[i] = (unsigned char)GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK,
1228  256);
1229  local_address->address.ipv6.s6_addr[i]
1230  = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
1231  }
1232  }
1233  while ((0 == GNUNET_memcmp(&local_address->address.ipv6,
1234  &addr)) ||
1235  (0 == GNUNET_memcmp(&local_address->address.ipv6,
1236  &mask)));
1237  }
1238  break;
1239 
1240  default:
1241  GNUNET_assert(0);
1242  }
1243 }
1244 
1245 
1267 static void
1269 {
1270  struct GNUNET_HashCode key;
1271  struct ChannelState *s;
1272 
1273  /* generate fresh, unique address */
1274  do
1275  {
1276  if (NULL == state->specifics.tcp_udp.serv)
1277  setup_fresh_address(state->specifics.tcp_udp.ri.remote_address.af,
1278  state->specifics.tcp_udp.ri.remote_address.proto,
1279  &state->specifics.tcp_udp.ri.local_address);
1280  else
1281  setup_fresh_address(state->specifics.tcp_udp.serv->address.af,
1282  state->specifics.tcp_udp.serv->address.proto,
1283  &state->specifics.tcp_udp.ri.local_address);
1284  }
1285  while (NULL !=
1286  get_redirect_state(state->specifics.tcp_udp.ri.remote_address.af,
1287  state->specifics.tcp_udp.ri.remote_address.proto,
1288  &state->specifics.tcp_udp.ri.remote_address.address,
1289  state->specifics.tcp_udp.ri.remote_address.port,
1290  &state->specifics.tcp_udp.ri.local_address.address,
1291  state->specifics.tcp_udp.ri.local_address.port,
1292  &key));
1293  {
1294  char buf[INET6_ADDRSTRLEN];
1296  "Picked local address %s:%u for new connection\n",
1297  inet_ntop(state->specifics.tcp_udp.ri.local_address.af,
1298  &state->specifics.tcp_udp.ri.local_address.address,
1299  buf,
1300  sizeof(buf)),
1301  (unsigned int)state->specifics.tcp_udp.ri.local_address.port);
1302  }
1303  state->specifics.tcp_udp.state_key = key;
1305  GNUNET_CONTAINER_multihashmap_put(connections_map,
1306  &key, state,
1308  state->specifics.tcp_udp.heap_node
1309  = GNUNET_CONTAINER_heap_insert(connections_heap,
1310  state,
1311  GNUNET_TIME_absolute_get().abs_value_us);
1312  while (GNUNET_CONTAINER_heap_get_size(connections_heap) > max_connections)
1313  {
1314  s = GNUNET_CONTAINER_heap_remove_root(connections_heap);
1315  GNUNET_assert(state != s);
1316  s->specifics.tcp_udp.heap_node = NULL;
1319  GNUNET_CONTAINER_multihashmap_remove(connections_map,
1320  &s->specifics.tcp_udp.state_key,
1321  s));
1322  GNUNET_free(s);
1323  }
1324 }
1325 
1326 
1335 static void
1336 send_udp_packet_via_tun(const struct SocketAddress *destination_address,
1337  const struct SocketAddress *source_address,
1338  const void *payload, size_t payload_length)
1339 {
1340  size_t len;
1341 
1343  gettext_noop("# UDP packets sent via TUN"),
1344  1, GNUNET_NO);
1346  "Sending packet with %u bytes UDP payload via TUN\n",
1347  (unsigned int)payload_length);
1348  len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct GNUNET_TUN_Layer2PacketHeader);
1349  switch (source_address->af)
1350  {
1351  case AF_INET:
1352  len += sizeof(struct GNUNET_TUN_IPv4Header);
1353  break;
1354 
1355  case AF_INET6:
1356  len += sizeof(struct GNUNET_TUN_IPv6Header);
1357  break;
1358 
1359  default:
1360  GNUNET_break(0);
1361  return;
1362  }
1363  len += sizeof(struct GNUNET_TUN_UdpHeader);
1364  len += payload_length;
1365  if (len >= GNUNET_MAX_MESSAGE_SIZE)
1366  {
1367  GNUNET_break(0);
1368  return;
1369  }
1370  {
1371  char buf[len] GNUNET_ALIGN;
1372  struct GNUNET_MessageHeader *hdr;
1373  struct GNUNET_TUN_Layer2PacketHeader *tun;
1374 
1375  hdr = (struct GNUNET_MessageHeader *)buf;
1376  hdr->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
1377  hdr->size = htons(len);
1378  tun = (struct GNUNET_TUN_Layer2PacketHeader*)&hdr[1];
1379  tun->flags = htons(0);
1380  switch (source_address->af)
1381  {
1382  case AF_INET:
1383  {
1384  struct GNUNET_TUN_IPv4Header * ipv4 = (struct GNUNET_TUN_IPv4Header*)&tun[1];
1385 
1386  tun->proto = htons(ETH_P_IPV4);
1387  prepare_ipv4_packet(payload,
1388  payload_length,
1389  IPPROTO_UDP,
1390  NULL,
1391  source_address,
1392  destination_address,
1393  ipv4);
1394  }
1395  break;
1396 
1397  case AF_INET6:
1398  {
1399  struct GNUNET_TUN_IPv6Header * ipv6 = (struct GNUNET_TUN_IPv6Header*)&tun[1];
1400 
1401  tun->proto = htons(ETH_P_IPV6);
1402  prepare_ipv6_packet(payload,
1403  payload_length,
1404  IPPROTO_UDP,
1405  NULL,
1406  source_address,
1407  destination_address,
1408  ipv6);
1409  }
1410  break;
1411 
1412  default:
1413  GNUNET_assert(0);
1414  break;
1415  }
1416  if (NULL != helper_handle)
1417  (void)GNUNET_HELPER_send(helper_handle,
1418  (const struct GNUNET_MessageHeader*)buf,
1419  GNUNET_YES,
1420  NULL, NULL);
1421  }
1422 }
1423 
1424 
1433 static int
1435  const struct GNUNET_EXIT_UdpInternetMessage *msg)
1436 {
1437  struct ChannelState *state = cls;
1438 
1439  if (GNUNET_YES == state->is_dns)
1440  {
1441  GNUNET_break_op(0);
1442  return GNUNET_SYSERR;
1443  }
1444  return GNUNET_OK;
1445 }
1446 
1447 
1454 static void
1456  const struct GNUNET_EXIT_UdpInternetMessage *msg)
1457 {
1458  struct ChannelState *state = cls;
1459  uint16_t pkt_len = ntohs(msg->header.size) - sizeof(struct GNUNET_EXIT_UdpInternetMessage);
1460  const struct in_addr *v4;
1461  const struct in6_addr *v6;
1462  const void *payload;
1463  int af;
1464 
1465  if (GNUNET_SYSERR == state->is_dns)
1466  {
1467  /* channel is UDP/TCP from now on */
1468  state->is_dns = GNUNET_NO;
1469  }
1471  gettext_noop("# Bytes received from CADET"),
1472  pkt_len, GNUNET_NO);
1474  gettext_noop("# UDP IP-exit requests received via cadet"),
1475  1, GNUNET_NO);
1476  af = (int)ntohl(msg->af);
1477  state->specifics.tcp_udp.ri.remote_address.af = af;
1478  switch (af)
1479  {
1480  case AF_INET:
1481  if (pkt_len < sizeof(struct in_addr))
1482  {
1483  GNUNET_break_op(0);
1484  return;
1485  }
1486  if (!ipv4_exit)
1487  {
1488  GNUNET_break_op(0);
1489  return;
1490  }
1491  v4 = (const struct in_addr*)&msg[1];
1492  payload = &v4[1];
1493  pkt_len -= sizeof(struct in_addr);
1494  state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
1495  break;
1496 
1497  case AF_INET6:
1498  if (pkt_len < sizeof(struct in6_addr))
1499  {
1500  GNUNET_break_op(0);
1501  return;
1502  }
1503  if (!ipv6_exit)
1504  {
1505  GNUNET_break_op(0);
1506  return;
1507  }
1508  v6 = (const struct in6_addr*)&msg[1];
1509  payload = &v6[1];
1510  pkt_len -= sizeof(struct in6_addr);
1511  state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
1512  break;
1513 
1514  default:
1515  GNUNET_break_op(0);
1516  return;
1517  }
1518  {
1519  char buf[INET6_ADDRSTRLEN];
1521  "Received data from %s for forwarding to UDP %s:%u\n",
1522  GNUNET_i2s(&state->peer),
1523  inet_ntop(af,
1524  &state->specifics.tcp_udp.ri.remote_address.address,
1525  buf, sizeof(buf)),
1526  (unsigned int)ntohs(msg->destination_port));
1527  }
1528  state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_UDP;
1529  state->specifics.tcp_udp.ri.remote_address.port = msg->destination_port;
1530  if (NULL == state->specifics.tcp_udp.heap_node)
1531  setup_state_record(state);
1532  if (0 != ntohs(msg->source_port))
1533  state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
1534  send_udp_packet_via_tun(&state->specifics.tcp_udp.ri.remote_address,
1535  &state->specifics.tcp_udp.ri.local_address,
1536  payload,
1537  pkt_len);
1539 }
1540 
1541 
1551 static int
1553  const struct GNUNET_EXIT_UdpServiceMessage *msg)
1554 {
1555  struct ChannelState *state = cls;
1556 
1557  if (NULL == state->specifics.tcp_udp.serv)
1558  {
1559  GNUNET_break_op(0);
1560  return GNUNET_SYSERR;
1561  }
1562  return GNUNET_OK;
1563 }
1564 
1565 
1573 static void
1575  const struct GNUNET_EXIT_UdpServiceMessage *msg)
1576 {
1577  struct ChannelState *state = cls;
1578  uint16_t pkt_len = ntohs(msg->header.size) - sizeof(struct GNUNET_EXIT_UdpServiceMessage);
1579 
1581  gettext_noop("# Bytes received from CADET"),
1582  pkt_len, GNUNET_NO);
1584  gettext_noop("# UDP service requests received via cadet"),
1585  1, GNUNET_NO);
1587  "Received data from %s for forwarding to UDP service %s on port %u\n",
1588  GNUNET_i2s(&state->peer),
1589  GNUNET_h2s(&state->specifics.tcp_udp.serv->descriptor),
1590  (unsigned int)ntohs(msg->destination_port));
1591  setup_state_record(state);
1592  if (0 != ntohs(msg->source_port))
1593  state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
1594  send_udp_packet_via_tun(&state->specifics.tcp_udp.ri.remote_address,
1595  &state->specifics.tcp_udp.ri.local_address,
1596  &msg[1],
1597  pkt_len);
1599 }
1600 
1601 
1611 static void
1614 {
1615  struct ChannelState *state = cls;
1616  uint16_t pkt_len = ntohs(start->header.size) - sizeof(struct GNUNET_EXIT_TcpServiceStartMessage);
1617 
1618  if (GNUNET_SYSERR == state->is_dns)
1619  {
1620  /* channel is UDP/TCP from now on */
1621  state->is_dns = GNUNET_NO;
1622  }
1624  gettext_noop("# TCP service creation requests received via cadet"),
1625  1,
1626  GNUNET_NO);
1628  gettext_noop("# Bytes received from CADET"),
1629  pkt_len,
1630  GNUNET_NO);
1631  GNUNET_break_op(ntohl(start->reserved) == 0);
1632  /* setup fresh connection */
1634  "Received data from %s for forwarding to TCP service %s on port %u\n",
1635  GNUNET_i2s(&state->peer),
1636  GNUNET_h2s(&state->specifics.tcp_udp.serv->descriptor),
1637  (unsigned int)ntohs(start->tcp_header.destination_port));
1638  setup_state_record(state);
1639  send_tcp_packet_via_tun(&state->specifics.tcp_udp.ri.remote_address,
1640  &state->specifics.tcp_udp.ri.local_address,
1641  &start->tcp_header,
1642  &start[1],
1643  pkt_len);
1645 }
1646 
1647 
1656 static int
1659 {
1660  struct ChannelState *state = cls;
1661 
1662  if (NULL == state)
1663  {
1664  GNUNET_break_op(0);
1665  return GNUNET_SYSERR;
1666  }
1667  if (GNUNET_YES == state->is_dns)
1668  {
1669  GNUNET_break_op(0);
1670  return GNUNET_SYSERR;
1671  }
1672  if ((NULL != state->specifics.tcp_udp.serv) ||
1673  (NULL != state->specifics.tcp_udp.heap_node))
1674  {
1675  GNUNET_break_op(0);
1676  return GNUNET_SYSERR;
1677  }
1678  if (start->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1679  {
1680  GNUNET_break_op(0);
1681  return GNUNET_SYSERR;
1682  }
1683  return GNUNET_OK;
1684 }
1685 
1686 
1693 static void
1696 {
1697  struct ChannelState *state = cls;
1698  uint16_t pkt_len = ntohs(start->header.size) - sizeof(struct GNUNET_EXIT_TcpInternetStartMessage);
1699  const struct in_addr *v4;
1700  const struct in6_addr *v6;
1701  const void *payload;
1702  int af;
1703 
1704  if (GNUNET_SYSERR == state->is_dns)
1705  {
1706  /* channel is UDP/TCP from now on */
1707  state->is_dns = GNUNET_NO;
1708  }
1710  gettext_noop("# Bytes received from CADET"),
1711  pkt_len, GNUNET_NO);
1713  gettext_noop("# TCP IP-exit creation requests received via cadet"),
1714  1, GNUNET_NO);
1715  af = (int)ntohl(start->af);
1716  state->specifics.tcp_udp.ri.remote_address.af = af;
1717  switch (af)
1718  {
1719  case AF_INET:
1720  if (pkt_len < sizeof(struct in_addr))
1721  {
1722  GNUNET_break_op(0);
1723  return;
1724  }
1725  if (!ipv4_exit)
1726  {
1727  GNUNET_break_op(0);
1728  return;
1729  }
1730  v4 = (const struct in_addr*)&start[1];
1731  payload = &v4[1];
1732  pkt_len -= sizeof(struct in_addr);
1733  state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
1734  break;
1735 
1736  case AF_INET6:
1737  if (pkt_len < sizeof(struct in6_addr))
1738  {
1739  GNUNET_break_op(0);
1740  return;
1741  }
1742  if (!ipv6_exit)
1743  {
1744  GNUNET_break_op(0);
1745  return;
1746  }
1747  v6 = (const struct in6_addr*)&start[1];
1748  payload = &v6[1];
1749  pkt_len -= sizeof(struct in6_addr);
1750  state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
1751  break;
1752 
1753  default:
1754  GNUNET_break_op(0);
1755  return;
1756  }
1757  {
1758  char buf[INET6_ADDRSTRLEN];
1760  "Received payload from %s for existing TCP stream to %s:%u\n",
1761  GNUNET_i2s(&state->peer),
1762  inet_ntop(af,
1763  &state->specifics.tcp_udp.ri.remote_address.address,
1764  buf, sizeof(buf)),
1765  (unsigned int)ntohs(start->tcp_header.destination_port));
1766  }
1767  state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_TCP;
1768  state->specifics.tcp_udp.ri.remote_address.port = ntohs(start->tcp_header.destination_port);
1769  setup_state_record(state);
1770  send_tcp_packet_via_tun(&state->specifics.tcp_udp.ri.remote_address,
1771  &state->specifics.tcp_udp.ri.local_address,
1772  &start->tcp_header,
1773  payload,
1774  pkt_len);
1776 }
1777 
1778 
1788 static int
1789 check_tcp_data(void *cls,
1790  const struct GNUNET_EXIT_TcpDataMessage *data)
1791 {
1792  struct ChannelState *state = cls;
1793 
1794  if ((NULL == state) ||
1795  (NULL == state->specifics.tcp_udp.heap_node))
1796  {
1797  /* connection should have been up! */
1799  gettext_noop("# TCP DATA requests dropped (no session)"),
1800  1, GNUNET_NO);
1801  GNUNET_break_op(0);
1802  return GNUNET_SYSERR;
1803  }
1804  if (data->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1805  {
1806  GNUNET_break_op(0);
1807  return GNUNET_SYSERR;
1808  }
1809  if (GNUNET_YES == state->is_dns)
1810  {
1811  GNUNET_break_op(0);
1812  return GNUNET_SYSERR;
1813  }
1814  return GNUNET_OK;
1815 }
1816 
1817 
1825 static void
1827  const struct GNUNET_EXIT_TcpDataMessage *data)
1828 {
1829  struct ChannelState *state = cls;
1830  uint16_t pkt_len = ntohs(data->header.size) - sizeof(struct GNUNET_EXIT_TcpDataMessage);
1831 
1833  gettext_noop("# Bytes received from CADET"),
1834  pkt_len, GNUNET_NO);
1836  gettext_noop("# TCP data requests received via cadet"),
1837  1, GNUNET_NO);
1838  if (GNUNET_SYSERR == state->is_dns)
1839  {
1840  /* channel is UDP/TCP from now on */
1841  state->is_dns = GNUNET_NO;
1842  }
1843 
1844  GNUNET_break_op(ntohl(data->reserved) == 0);
1845  {
1846  char buf[INET6_ADDRSTRLEN];
1848  "Received additional %u bytes of data from %s for TCP stream to %s:%u\n",
1849  pkt_len,
1850  GNUNET_i2s(&state->peer),
1851  inet_ntop(state->specifics.tcp_udp.ri.remote_address.af,
1852  &state->specifics.tcp_udp.ri.remote_address.address,
1853  buf, sizeof(buf)),
1854  (unsigned int)state->specifics.tcp_udp.ri.remote_address.port);
1855  }
1856 
1857  send_tcp_packet_via_tun(&state->specifics.tcp_udp.ri.remote_address,
1858  &state->specifics.tcp_udp.ri.local_address,
1859  &data->tcp_header,
1860  &data[1], pkt_len);
1862 }
1863 
1864 
1874 static void
1876  struct GNUNET_TUN_IPv4Header *ipp,
1877  struct GNUNET_TUN_UdpHeader *udp)
1878 {
1880  state->specifics.tcp_udp.ri.remote_address.proto,
1881  sizeof(struct GNUNET_TUN_TcpHeader),
1882  &state->specifics.tcp_udp.ri.remote_address.address.ipv4,
1883  &state->specifics.tcp_udp.ri.local_address.address.ipv4);
1884  udp->source_port = htons(state->specifics.tcp_udp.ri.remote_address.port);
1885  udp->destination_port = htons(state->specifics.tcp_udp.ri.local_address.port);
1886  udp->len = htons(0);
1887  udp->crc = htons(0);
1888 }
1889 
1890 
1900 static void
1902  struct GNUNET_TUN_IPv6Header *ipp,
1903  struct GNUNET_TUN_UdpHeader *udp)
1904 {
1906  state->specifics.tcp_udp.ri.remote_address.proto,
1907  sizeof(struct GNUNET_TUN_TcpHeader),
1908  &state->specifics.tcp_udp.ri.remote_address.address.ipv6,
1909  &state->specifics.tcp_udp.ri.local_address.address.ipv6);
1910  udp->source_port = htons(state->specifics.tcp_udp.ri.remote_address.port);
1911  udp->destination_port = htons(state->specifics.tcp_udp.ri.local_address.port);
1912  udp->len = htons(0);
1913  udp->crc = htons(0);
1914 }
1915 
1916 
1925 static int
1927  const struct GNUNET_EXIT_IcmpInternetMessage *msg)
1928 {
1929  struct ChannelState *state = cls;
1930 
1931  if (GNUNET_YES == state->is_dns)
1932  {
1933  GNUNET_break_op(0);
1934  return GNUNET_SYSERR;
1935  }
1936  return GNUNET_OK;
1937 }
1938 
1939 
1946 static void
1948  const struct GNUNET_EXIT_IcmpInternetMessage *msg)
1949 {
1950  struct ChannelState *state = cls;
1951  uint16_t pkt_len = ntohs(msg->header.size) - sizeof(struct GNUNET_EXIT_IcmpInternetMessage);
1952  const struct in_addr *v4;
1953  const struct in6_addr *v6;
1954  const void *payload;
1955  char buf[sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
1956  int af;
1957 
1958  if (GNUNET_SYSERR == state->is_dns)
1959  {
1960  /* channel is UDP/TCP from now on */
1961  state->is_dns = GNUNET_NO;
1962  }
1964  gettext_noop("# Bytes received from CADET"),
1965  pkt_len, GNUNET_NO);
1967  gettext_noop("# ICMP IP-exit requests received via cadet"),
1968  1, GNUNET_NO);
1969 
1970  af = (int)ntohl(msg->af);
1971  if ((NULL != state->specifics.tcp_udp.heap_node) &&
1972  (af != state->specifics.tcp_udp.ri.remote_address.af))
1973  {
1974  /* other peer switched AF on this channel; not allowed */
1975  GNUNET_break_op(0);
1976  return;
1977  }
1978 
1979  switch (af)
1980  {
1981  case AF_INET:
1982  if (pkt_len < sizeof(struct in_addr))
1983  {
1984  GNUNET_break_op(0);
1985  return;
1986  }
1987  if (!ipv4_exit)
1988  {
1989  GNUNET_break_op(0);
1990  return;
1991  }
1992  v4 = (const struct in_addr*)&msg[1];
1993  payload = &v4[1];
1994  pkt_len -= sizeof(struct in_addr);
1995  state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
1996  if (NULL == state->specifics.tcp_udp.heap_node)
1997  {
1998  state->specifics.tcp_udp.ri.remote_address.af = af;
1999  state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMP;
2000  setup_state_record(state);
2001  }
2002  /* check that ICMP type is something we want to support
2003  and possibly make up payload! */
2004  switch (msg->icmp_header.type)
2005  {
2008  break;
2009 
2013  if (0 != pkt_len)
2014  {
2015  GNUNET_break_op(0);
2016  return;
2017  }
2018  /* make up payload */
2019  {
2020  struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header *)buf;
2021  struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *)&ipp[1];
2022 
2023  GNUNET_assert(8 == sizeof(struct GNUNET_TUN_UdpHeader));
2024  pkt_len = sizeof(struct GNUNET_TUN_IPv4Header) + 8;
2025  make_up_icmpv4_payload(state,
2026  ipp,
2027  udp);
2028  payload = ipp;
2029  }
2030  break;
2031 
2032  default:
2033  GNUNET_break_op(0);
2035  gettext_noop("# ICMPv4 packets dropped (type not allowed)"),
2036  1, GNUNET_NO);
2037  return;
2038  }
2039  /* end AF_INET */
2040  break;
2041 
2042  case AF_INET6:
2043  if (pkt_len < sizeof(struct in6_addr))
2044  {
2045  GNUNET_break_op(0);
2046  return;
2047  }
2048  if (!ipv6_exit)
2049  {
2050  GNUNET_break_op(0);
2051  return;
2052  }
2053  v6 = (const struct in6_addr*)&msg[1];
2054  payload = &v6[1];
2055  pkt_len -= sizeof(struct in6_addr);
2056  state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
2057  if (NULL == state->specifics.tcp_udp.heap_node)
2058  {
2059  state->specifics.tcp_udp.ri.remote_address.af = af;
2060  state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMPV6;
2061  setup_state_record(state);
2062  }
2063  /* check that ICMP type is something we want to support
2064  and possibly make up payload! */
2065  switch (msg->icmp_header.type)
2066  {
2069  break;
2070 
2075  if (0 != pkt_len)
2076  {
2077  GNUNET_break_op(0);
2078  return;
2079  }
2080  /* make up payload */
2081  {
2082  struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header *)buf;
2083  struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *)&ipp[1];
2084 
2085  GNUNET_assert(8 == sizeof(struct GNUNET_TUN_UdpHeader));
2086  pkt_len = sizeof(struct GNUNET_TUN_IPv6Header) + 8;
2087  make_up_icmpv6_payload(state,
2088  ipp,
2089  udp);
2090  payload = ipp;
2091  }
2092  break;
2093 
2094  default:
2095  GNUNET_break_op(0);
2097  gettext_noop("# ICMPv6 packets dropped (type not allowed)"),
2098  1, GNUNET_NO);
2099  return;
2100  }
2101  /* end AF_INET6 */
2102  break;
2103 
2104  default:
2105  /* bad AF */
2106  GNUNET_break_op(0);
2107  return;
2108  }
2109 
2110  {
2111  char buf[INET6_ADDRSTRLEN];
2113  "Received ICMP data from %s for forwarding to %s\n",
2114  GNUNET_i2s(&state->peer),
2115  inet_ntop(af,
2116  &state->specifics.tcp_udp.ri.remote_address.address,
2117  buf, sizeof(buf)));
2118  }
2119  send_icmp_packet_via_tun(&state->specifics.tcp_udp.ri.remote_address,
2120  &state->specifics.tcp_udp.ri.local_address,
2121  &msg->icmp_header,
2122  payload, pkt_len);
2124 }
2125 
2126 
2136 static uint16_t
2138  char *buf)
2139 {
2140  switch (state->specifics.tcp_udp.serv->address.af)
2141  {
2142  case AF_INET:
2143  {
2144  struct GNUNET_TUN_IPv4Header *ipv4;
2145  struct GNUNET_TUN_UdpHeader *udp;
2146 
2147  ipv4 = (struct GNUNET_TUN_IPv4Header *)buf;
2148  udp = (struct GNUNET_TUN_UdpHeader *)&ipv4[1];
2149  make_up_icmpv4_payload(state,
2150  ipv4,
2151  udp);
2152  GNUNET_assert(8 == sizeof(struct GNUNET_TUN_UdpHeader));
2153  return sizeof(struct GNUNET_TUN_IPv4Header) + 8;
2154  }
2155  break;
2156 
2157  case AF_INET6:
2158  {
2159  struct GNUNET_TUN_IPv6Header *ipv6;
2160  struct GNUNET_TUN_UdpHeader *udp;
2161 
2162  ipv6 = (struct GNUNET_TUN_IPv6Header *)buf;
2163  udp = (struct GNUNET_TUN_UdpHeader *)&ipv6[1];
2164  make_up_icmpv6_payload(state,
2165  ipv6,
2166  udp);
2167  GNUNET_assert(8 == sizeof(struct GNUNET_TUN_UdpHeader));
2168  return sizeof(struct GNUNET_TUN_IPv6Header) + 8;
2169  }
2170  break;
2171 
2172  default:
2173  GNUNET_break(0);
2174  }
2175  return 0;
2176 }
2177 
2178 
2188 static int
2190  const struct GNUNET_EXIT_IcmpServiceMessage *msg)
2191 {
2192  struct ChannelState *state = cls;
2193 
2194  if (GNUNET_YES == state->is_dns)
2195  {
2196  GNUNET_break_op(0);
2197  return GNUNET_SYSERR;
2198  }
2199  if (NULL == state->specifics.tcp_udp.serv)
2200  {
2201  GNUNET_break_op(0);
2202  return GNUNET_SYSERR;
2203  }
2204  return GNUNET_OK;
2205 }
2206 
2207 
2215 static void
2217  const struct GNUNET_EXIT_IcmpServiceMessage *msg)
2218 {
2219  struct ChannelState *state = cls;
2220  uint16_t pkt_len = ntohs(msg->header.size) - sizeof(struct GNUNET_EXIT_IcmpServiceMessage);
2221  struct GNUNET_TUN_IcmpHeader icmp;
2222  char buf[sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
2223  const void *payload;
2224 
2226  gettext_noop("# Bytes received from CADET"),
2227  pkt_len, GNUNET_NO);
2229  gettext_noop("# ICMP service requests received via cadet"),
2230  1, GNUNET_NO);
2231  /* check that we got at least a valid header */
2233  "Received data from %s for forwarding to ICMP service %s\n",
2234  GNUNET_i2s(&state->peer),
2235  GNUNET_h2s(&state->specifics.tcp_udp.serv->descriptor));
2236  icmp = msg->icmp_header;
2237  payload = &msg[1];
2238  state->specifics.tcp_udp.ri.remote_address
2239  = state->specifics.tcp_udp.serv->address;
2240  setup_state_record(state);
2241 
2242  /* check that ICMP type is something we want to support,
2243  perform ICMP PT if needed ans possibly make up payload */
2244  switch (msg->af)
2245  {
2246  case AF_INET:
2247  switch (msg->icmp_header.type)
2248  {
2250  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2252  break;
2253 
2255  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2257  break;
2258 
2260  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2262  if (0 != pkt_len)
2263  {
2264  GNUNET_break_op(0);
2265  return;
2266  }
2267  payload = buf;
2268  pkt_len = make_up_icmp_service_payload(state, buf);
2269  break;
2270 
2272  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2274  if (0 != pkt_len)
2275  {
2276  GNUNET_break_op(0);
2277  return;
2278  }
2279  payload = buf;
2280  pkt_len = make_up_icmp_service_payload(state, buf);
2281  break;
2282 
2284  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2285  {
2287  gettext_noop("# ICMPv4 packets dropped (impossible PT to v6)"),
2288  1, GNUNET_NO);
2289  return;
2290  }
2291  if (0 != pkt_len)
2292  {
2293  GNUNET_break_op(0);
2294  return;
2295  }
2296  payload = buf;
2297  pkt_len = make_up_icmp_service_payload(state, buf);
2298  break;
2299 
2300  default:
2301  GNUNET_break_op(0);
2303  gettext_noop("# ICMPv4 packets dropped (type not allowed)"),
2304  1, GNUNET_NO);
2305  return;
2306  }
2307  /* end of AF_INET */
2308  break;
2309 
2310  case AF_INET6:
2311  switch (msg->icmp_header.type)
2312  {
2314  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2316  break;
2317 
2319  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2321  break;
2322 
2324  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2326  if (0 != pkt_len)
2327  {
2328  GNUNET_break_op(0);
2329  return;
2330  }
2331  payload = buf;
2332  pkt_len = make_up_icmp_service_payload(state, buf);
2333  break;
2334 
2336  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2338  if (0 != pkt_len)
2339  {
2340  GNUNET_break_op(0);
2341  return;
2342  }
2343  payload = buf;
2344  pkt_len = make_up_icmp_service_payload(state, buf);
2345  break;
2346 
2349  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2350  {
2352  gettext_noop("# ICMPv6 packets dropped (impossible PT to v4)"),
2353  1, GNUNET_NO);
2354  return;
2355  }
2356  if (0 != pkt_len)
2357  {
2358  GNUNET_break_op(0);
2359  return;
2360  }
2361  payload = buf;
2362  pkt_len = make_up_icmp_service_payload(state, buf);
2363  break;
2364 
2365  default:
2366  GNUNET_break_op(0);
2368  gettext_noop("# ICMPv6 packets dropped (type not allowed)"),
2369  1, GNUNET_NO);
2370  return;
2371  }
2372  /* end of AF_INET6 */
2373  break;
2374 
2375  default:
2376  GNUNET_break_op(0);
2377  return;
2378  }
2379 
2380  send_icmp_packet_via_tun(&state->specifics.tcp_udp.ri.remote_address,
2381  &state->specifics.tcp_udp.ri.local_address,
2382  &icmp,
2383  payload,
2384  pkt_len);
2386 }
2387 
2388 
2397 static int
2399  const struct GNUNET_HashCode *key,
2400  void *value)
2401 {
2402  struct LocalService *service = value;
2403 
2406  key,
2407  service));
2408  GNUNET_CADET_close_port(service->port);
2409  GNUNET_free_non_null(service->name);
2410  GNUNET_free(service);
2411  return GNUNET_OK;
2412 }
2413 
2414 
2423 static void *
2425  struct GNUNET_CADET_Channel *channel,
2426  const struct GNUNET_PeerIdentity *initiator)
2427 {
2428  struct LocalService *ls = cls;
2429  struct ChannelState *s = GNUNET_new(struct ChannelState);
2430 
2431  s->peer = *initiator;
2433  gettext_noop("# Inbound CADET channels created"),
2434  1,
2435  GNUNET_NO);
2437  "Received inbound channel from `%s'\n",
2438  GNUNET_i2s(initiator));
2439  s->channel = channel;
2440  s->specifics.tcp_udp.serv = ls;
2441  s->specifics.tcp_udp.ri.remote_address = ls->address;
2442  return s;
2443 }
2444 
2445 
2453 static void
2454 clean_channel(void *cls,
2455  const struct GNUNET_CADET_Channel *channel)
2456 {
2457  struct ChannelState *s = cls;
2458 
2460  "Channel destroyed\n");
2461  if (GNUNET_SYSERR == s->is_dns)
2462  {
2463  GNUNET_free(s);
2464  return;
2465  }
2466  if (GNUNET_YES == s->is_dns)
2467  {
2468  if (channels[s->specifics.dns.my_id] == s)
2469  channels[s->specifics.dns.my_id] = NULL;
2470  }
2471  else
2472  {
2473  if (NULL != s->specifics.tcp_udp.heap_node)
2474  {
2476  GNUNET_CONTAINER_multihashmap_remove(connections_map,
2477  &s->specifics.tcp_udp.state_key,
2478  s));
2480  s->specifics.tcp_udp.heap_node = NULL;
2481  }
2482  }
2483  GNUNET_free(s);
2484 }
2485 
2486 
2496 static void
2498  const char *name,
2499  uint16_t destination_port,
2500  struct LocalService *service)
2501 {
2502  struct GNUNET_MQ_MessageHandler handlers[] = {
2503  GNUNET_MQ_hd_var_size(icmp_service,
2506  service),
2507  GNUNET_MQ_hd_var_size(udp_service,
2510  service),
2511  GNUNET_MQ_hd_var_size(tcp_service,
2514  service),
2515  GNUNET_MQ_hd_var_size(tcp_data,
2518  service),
2520  };
2521 
2522  struct GNUNET_HashCode cadet_port;
2523 
2524  service->name = GNUNET_strdup(name);
2526  &service->descriptor);
2528  destination_port,
2529  &cadet_port);
2531  "Opening CADET port %s for SERVICE exit %s on port %u\n",
2532  GNUNET_h2s(&cadet_port),
2533  name,
2534  (unsigned int)destination_port);
2535  service->port = GNUNET_CADET_open_port(cadet_handle,
2536  &cadet_port,
2538  service,
2539  NULL,
2540  &clean_channel,
2541  handlers);
2542  service->is_udp = (IPPROTO_UDP == proto);
2543  if (GNUNET_OK !=
2545  &cadet_port,
2546  service,
2548  {
2549  GNUNET_CADET_close_port(service->port);
2550  GNUNET_free_non_null(service->name);
2551  GNUNET_free(service);
2553  _("Got duplicate service records for `%s:%u'\n"),
2554  name,
2555  (unsigned int)destination_port);
2556  }
2557 }
2558 
2559 
2566 static void
2568  struct GNUNET_MQ_Envelope *env)
2569 {
2570  GNUNET_assert(NULL != s);
2572  gettext_noop("# Messages transmitted via cadet channels"),
2573  1,
2574  GNUNET_NO);
2576  env);
2577 }
2578 
2579 
2591 static void
2593  size_t pktlen,
2594  int af,
2595  const void *destination_ip,
2596  const void *source_ip)
2597 {
2598  struct ChannelState *state;
2599  struct GNUNET_MQ_Envelope *env;
2600  struct GNUNET_EXIT_IcmpToVPNMessage *i2v;
2601  const struct GNUNET_TUN_IPv4Header *ipv4;
2602  const struct GNUNET_TUN_IPv6Header *ipv6;
2603  const struct GNUNET_TUN_UdpHeader *udp;
2604  uint16_t source_port;
2605  uint16_t destination_port;
2606  uint8_t protocol;
2607 
2608  {
2609  char sbuf[INET6_ADDRSTRLEN];
2610  char dbuf[INET6_ADDRSTRLEN];
2612  "Received ICMP packet going from %s to %s\n",
2613  inet_ntop(af,
2614  source_ip,
2615  sbuf, sizeof(sbuf)),
2616  inet_ntop(af,
2617  destination_ip,
2618  dbuf, sizeof(dbuf)));
2619  }
2620 
2621  if (pktlen < sizeof(struct GNUNET_TUN_IcmpHeader))
2622  {
2623  /* blame kernel */
2624  GNUNET_break(0);
2625  return;
2626  }
2627 
2628  /* Find out if this is an ICMP packet in response to an existing
2629  TCP/UDP packet and if so, figure out ports / protocol of the
2630  existing session from the IP data in the ICMP payload */
2631  source_port = 0;
2632  destination_port = 0;
2633  switch (af)
2634  {
2635  case AF_INET:
2636  protocol = IPPROTO_ICMP;
2637  switch (icmp->type)
2638  {
2641  break;
2642 
2646  if (pktlen <
2647  sizeof(struct GNUNET_TUN_IcmpHeader) +
2648  sizeof(struct GNUNET_TUN_IPv4Header) + 8)
2649  {
2650  /* blame kernel */
2651  GNUNET_break(0);
2652  return;
2653  }
2654  ipv4 = (const struct GNUNET_TUN_IPv4Header *)&icmp[1];
2655  protocol = ipv4->protocol;
2656  /* could be TCP or UDP, but both have the ports in the right
2657  place, so that doesn't matter here */
2658  udp = (const struct GNUNET_TUN_UdpHeader *)&ipv4[1];
2659  /* swap ports, as they are from the original message */
2660  destination_port = ntohs(udp->source_port);
2661  source_port = ntohs(udp->destination_port);
2662  /* throw away ICMP payload, won't be useful for the other side anyway */
2663  pktlen = sizeof(struct GNUNET_TUN_IcmpHeader);
2664  break;
2665 
2666  default:
2668  gettext_noop("# ICMPv4 packets dropped (type not allowed)"),
2669  1, GNUNET_NO);
2670  return;
2671  }
2672  break;
2673 
2674  case AF_INET6:
2675  protocol = IPPROTO_ICMPV6;
2676  switch (icmp->type)
2677  {
2682  if (pktlen <
2683  sizeof(struct GNUNET_TUN_IcmpHeader) +
2684  sizeof(struct GNUNET_TUN_IPv6Header) + 8)
2685  {
2686  /* blame kernel */
2687  GNUNET_break(0);
2688  return;
2689  }
2690  ipv6 = (const struct GNUNET_TUN_IPv6Header *)&icmp[1];
2691  protocol = ipv6->next_header;
2692  /* could be TCP or UDP, but both have the ports in the right
2693  place, so that doesn't matter here */
2694  udp = (const struct GNUNET_TUN_UdpHeader *)&ipv6[1];
2695  /* swap ports, as they are from the original message */
2696  destination_port = ntohs(udp->source_port);
2697  source_port = ntohs(udp->destination_port);
2698  /* throw away ICMP payload, won't be useful for the other side anyway */
2699  pktlen = sizeof(struct GNUNET_TUN_IcmpHeader);
2700  break;
2701 
2704  break;
2705 
2706  default:
2708  gettext_noop("# ICMPv6 packets dropped (type not allowed)"),
2709  1, GNUNET_NO);
2710  return;
2711  }
2712  break;
2713 
2714  default:
2715  GNUNET_assert(0);
2716  }
2717  switch (protocol)
2718  {
2719  case IPPROTO_ICMP:
2720  state = get_redirect_state(af,
2721  IPPROTO_ICMP,
2722  source_ip,
2723  0,
2724  destination_ip,
2725  0,
2726  NULL);
2727  break;
2728 
2729  case IPPROTO_ICMPV6:
2730  state = get_redirect_state(af,
2731  IPPROTO_ICMPV6,
2732  source_ip,
2733  0,
2734  destination_ip,
2735  0,
2736  NULL);
2737  break;
2738 
2739  case IPPROTO_UDP:
2740  state = get_redirect_state(af,
2741  IPPROTO_UDP,
2742  source_ip,
2743  source_port,
2744  destination_ip,
2745  destination_port,
2746  NULL);
2747  break;
2748 
2749  case IPPROTO_TCP:
2750  state = get_redirect_state(af,
2751  IPPROTO_TCP,
2752  source_ip,
2753  source_port,
2754  destination_ip,
2755  destination_port,
2756  NULL);
2757  break;
2758 
2759  default:
2761  gettext_noop("# ICMP packets dropped (not allowed)"),
2762  1,
2763  GNUNET_NO);
2764  return;
2765  }
2766  if (NULL == state)
2767  {
2769  _("ICMP Packet dropped, have no matching connection information\n"));
2770  return;
2771  }
2772  env = GNUNET_MQ_msg_extra(i2v,
2773  pktlen - sizeof(struct GNUNET_TUN_IcmpHeader),
2775  i2v->af = htonl(af);
2776  GNUNET_memcpy(&i2v->icmp_header,
2777  icmp,
2778  pktlen);
2780  env);
2781 }
2782 
2783 
2795 static void
2797  size_t pktlen,
2798  int af,
2799  const void *destination_ip,
2800  const void *source_ip)
2801 {
2802  struct ChannelState *state;
2803  struct GNUNET_MQ_Envelope *env;
2804  struct GNUNET_EXIT_UdpReplyMessage *urm;
2805 
2806  {
2807  char sbuf[INET6_ADDRSTRLEN];
2808  char dbuf[INET6_ADDRSTRLEN];
2809 
2811  "Received UDP packet going from %s:%u to %s:%u\n",
2812  inet_ntop(af,
2813  source_ip,
2814  sbuf, sizeof(sbuf)),
2815  (unsigned int)ntohs(udp->source_port),
2816  inet_ntop(af,
2817  destination_ip,
2818  dbuf, sizeof(dbuf)),
2819  (unsigned int)ntohs(udp->destination_port));
2820  }
2821 
2822  if (pktlen < sizeof(struct GNUNET_TUN_UdpHeader))
2823  {
2824  /* blame kernel */
2825  GNUNET_break(0);
2826  return;
2827  }
2828  if (pktlen != ntohs(udp->len))
2829  {
2830  /* blame kernel */
2831  GNUNET_break(0);
2832  return;
2833  }
2834  state = get_redirect_state(af,
2835  IPPROTO_UDP,
2836  source_ip,
2837  ntohs(udp->source_port),
2838  destination_ip,
2839  ntohs(udp->destination_port),
2840  NULL);
2841  if (NULL == state)
2842  {
2844  _("UDP Packet dropped, have no matching connection information\n"));
2845  return;
2846  }
2847  env = GNUNET_MQ_msg_extra(urm,
2848  pktlen - sizeof(struct GNUNET_TUN_UdpHeader),
2850  urm->source_port = htons(0);
2851  urm->destination_port = htons(0);
2852  GNUNET_memcpy(&urm[1],
2853  &udp[1],
2854  pktlen - sizeof(struct GNUNET_TUN_UdpHeader));
2856  env);
2857 }
2858 
2859 
2871 static void
2873  size_t pktlen,
2874  int af,
2875  const void *destination_ip,
2876  const void *source_ip)
2877 {
2878  struct ChannelState *state;
2879  char buf[pktlen] GNUNET_ALIGN;
2880  struct GNUNET_TUN_TcpHeader *mtcp;
2881  struct GNUNET_EXIT_TcpDataMessage *tdm;
2882  struct GNUNET_MQ_Envelope *env;
2883  size_t mlen;
2884 
2885  {
2886  char sbuf[INET6_ADDRSTRLEN];
2887  char dbuf[INET6_ADDRSTRLEN];
2889  "Received TCP packet with %u bytes going from %s:%u to %s:%u\n",
2890  (unsigned int)(pktlen - sizeof(struct GNUNET_TUN_TcpHeader)),
2891  inet_ntop(af,
2892  source_ip,
2893  sbuf, sizeof(sbuf)),
2894  (unsigned int)ntohs(tcp->source_port),
2895  inet_ntop(af,
2896  destination_ip,
2897  dbuf, sizeof(dbuf)),
2898  (unsigned int)ntohs(tcp->destination_port));
2899  }
2900 
2901  if (pktlen < sizeof(struct GNUNET_TUN_TcpHeader))
2902  {
2903  /* blame kernel */
2904  GNUNET_break(0);
2905  return;
2906  }
2907  state = get_redirect_state(af,
2908  IPPROTO_TCP,
2909  source_ip,
2910  ntohs(tcp->source_port),
2911  destination_ip,
2912  ntohs(tcp->destination_port),
2913  NULL);
2914  if (NULL == state)
2915  {
2917  _("TCP Packet dropped, have no matching connection information\n"));
2918 
2919  return;
2920  }
2921  /* mug port numbers and crc to avoid information leakage;
2922  sender will need to lookup the correct values anyway */
2923  GNUNET_memcpy(buf, tcp, pktlen);
2924  mtcp = (struct GNUNET_TUN_TcpHeader *)buf;
2925  mtcp->source_port = 0;
2926  mtcp->destination_port = 0;
2927  mtcp->crc = 0;
2928 
2929  mlen = sizeof(struct GNUNET_EXIT_TcpDataMessage) + (pktlen - sizeof(struct GNUNET_TUN_TcpHeader));
2930  if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
2931  {
2932  GNUNET_break(0);
2933  return;
2934  }
2935  env = GNUNET_MQ_msg_extra(tdm,
2936  pktlen - sizeof(struct GNUNET_TUN_TcpHeader),
2938  tdm->reserved = htonl(0);
2939  GNUNET_memcpy(&tdm->tcp_header,
2940  buf,
2941  pktlen);
2943  env);
2944 }
2945 
2946 
2953 static int
2955  const struct GNUNET_MessageHeader *message)
2956 {
2957  const struct GNUNET_TUN_Layer2PacketHeader *pkt_tun;
2958  size_t size;
2959 
2961  "Got %u-byte message of type %u from gnunet-helper-exit\n",
2962  ntohs(message->size),
2963  ntohs(message->type));
2965  gettext_noop("# Packets received from TUN"),
2966  1, GNUNET_NO);
2967  if (ntohs(message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER)
2968  {
2969  GNUNET_break(0);
2970  return GNUNET_OK;
2971  }
2972  size = ntohs(message->size);
2973  if (size < sizeof(struct GNUNET_TUN_Layer2PacketHeader) + sizeof(struct GNUNET_MessageHeader))
2974  {
2975  GNUNET_break(0);
2976  return GNUNET_OK;
2977  }
2979  gettext_noop("# Bytes received from TUN"),
2980  size, GNUNET_NO);
2981  pkt_tun = (const struct GNUNET_TUN_Layer2PacketHeader *)&message[1];
2982  size -= sizeof(struct GNUNET_TUN_Layer2PacketHeader) + sizeof(struct GNUNET_MessageHeader);
2983  switch (ntohs(pkt_tun->proto))
2984  {
2985  case ETH_P_IPV4:
2986  {
2987  const struct GNUNET_TUN_IPv4Header *pkt4;
2988 
2989  if (size < sizeof(struct GNUNET_TUN_IPv4Header))
2990  {
2991  /* Kernel to blame? */
2992  GNUNET_break(0);
2993  return GNUNET_OK;
2994  }
2995  pkt4 = (const struct GNUNET_TUN_IPv4Header *)&pkt_tun[1];
2996  if (size != ntohs(pkt4->total_length))
2997  {
2998  /* Kernel to blame? */
2999  GNUNET_break(0);
3000  return GNUNET_OK;
3001  }
3002  if (pkt4->header_length * 4 != sizeof(struct GNUNET_TUN_IPv4Header))
3003  {
3005  _("IPv4 packet options received. Ignored.\n"));
3006  return GNUNET_OK;
3007  }
3008 
3009  size -= sizeof(struct GNUNET_TUN_IPv4Header);
3010  switch (pkt4->protocol)
3011  {
3012  case IPPROTO_UDP:
3013  udp_from_helper((const struct GNUNET_TUN_UdpHeader *)&pkt4[1], size,
3014  AF_INET,
3015  &pkt4->destination_address,
3016  &pkt4->source_address);
3017  break;
3018 
3019  case IPPROTO_TCP:
3020  tcp_from_helper((const struct GNUNET_TUN_TcpHeader *)&pkt4[1], size,
3021  AF_INET,
3022  &pkt4->destination_address,
3023  &pkt4->source_address);
3024  break;
3025 
3026  case IPPROTO_ICMP:
3027  icmp_from_helper((const struct GNUNET_TUN_IcmpHeader *)&pkt4[1], size,
3028  AF_INET,
3029  &pkt4->destination_address,
3030  &pkt4->source_address);
3031  break;
3032 
3033  default:
3035  _("IPv4 packet with unsupported next header %u received. Ignored.\n"),
3036  (int)pkt4->protocol);
3037  return GNUNET_OK;
3038  }
3039  }
3040  break;
3041 
3042  case ETH_P_IPV6:
3043  {
3044  const struct GNUNET_TUN_IPv6Header *pkt6;
3045 
3046  if (size < sizeof(struct GNUNET_TUN_IPv6Header))
3047  {
3048  /* Kernel to blame? */
3049  GNUNET_break(0);
3050  return GNUNET_OK;
3051  }
3052  pkt6 = (struct GNUNET_TUN_IPv6Header *)&pkt_tun[1];
3053  if (size != ntohs(pkt6->payload_length) + sizeof(struct GNUNET_TUN_IPv6Header))
3054  {
3055  /* Kernel to blame? */
3056  GNUNET_break(0);
3057  return GNUNET_OK;
3058  }
3059  size -= sizeof(struct GNUNET_TUN_IPv6Header);
3060  switch (pkt6->next_header)
3061  {
3062  case IPPROTO_UDP:
3063  udp_from_helper((const struct GNUNET_TUN_UdpHeader *)&pkt6[1], size,
3064  AF_INET6,
3065  &pkt6->destination_address,
3066  &pkt6->source_address);
3067  break;
3068 
3069  case IPPROTO_TCP:
3070  tcp_from_helper((const struct GNUNET_TUN_TcpHeader *)&pkt6[1], size,
3071  AF_INET6,
3072  &pkt6->destination_address,
3073  &pkt6->source_address);
3074  break;
3075 
3076  case IPPROTO_ICMPV6:
3077  icmp_from_helper((const struct GNUNET_TUN_IcmpHeader *)&pkt6[1], size,
3078  AF_INET6,
3079  &pkt6->destination_address,
3080  &pkt6->source_address);
3081  break;
3082 
3083  default:
3085  _("IPv6 packet with unsupported next header %d received. Ignored.\n"),
3086  pkt6->next_header);
3087  return GNUNET_OK;
3088  }
3089  }
3090  break;
3091 
3092  default:
3094  _("Packet from unknown protocol %u received. Ignored.\n"),
3095  ntohs(pkt_tun->proto));
3096  break;
3097  }
3098  return GNUNET_OK;
3099 }
3100 
3101 
3110 static void *
3111 new_channel(void *cls,
3112  struct GNUNET_CADET_Channel *channel,
3113  const struct GNUNET_PeerIdentity *initiator)
3114 {
3115  struct ChannelState *s = GNUNET_new(struct ChannelState);
3116 
3117  s->is_dns = GNUNET_SYSERR;
3118  s->peer = *initiator;
3120  gettext_noop("# Inbound CADET channels created"),
3121  1,
3122  GNUNET_NO);
3124  "Received inbound channel from `%s'\n",
3125  GNUNET_i2s(initiator));
3126  s->channel = channel;
3127  return s;
3128 }
3129 
3130 
3138 static int
3139 free_iterate(void *cls,
3140  const struct GNUNET_HashCode * hash,
3141  void *value)
3142 {
3143  GNUNET_free(value);
3144  return GNUNET_YES;
3145 }
3146 
3147 
3157 static void
3158 dummy_task(void *cls)
3159 {
3160  /* just terminate */
3161 }
3162 
3163 
3169 static void
3170 cleanup(void *cls)
3171 {
3172  unsigned int i;
3173 
3175  "Exit service is shutting down now\n");
3176 
3177  if (NULL != helper_handle)
3178  {
3179  GNUNET_HELPER_stop(helper_handle, GNUNET_NO);
3180  helper_handle = NULL;
3181  }
3182  if (NULL != regex4)
3183  {
3185  regex4 = NULL;
3186  }
3187  if (NULL != regex6)
3188  {
3190  regex6 = NULL;
3191  }
3192  if (NULL != services)
3193  {
3196  NULL);
3198  }
3199  if (NULL != dns_port)
3200  {
3201  GNUNET_CADET_close_port(dns_port);
3202  dns_port = NULL;
3203  }
3204  if (NULL != cadet_port4)
3205  {
3206  GNUNET_CADET_close_port(cadet_port4);
3207  cadet_port4 = NULL;
3208  }
3209  if (NULL != cadet_port6)
3210  {
3211  GNUNET_CADET_close_port(cadet_port6);
3212  cadet_port6 = NULL;
3213  }
3214  if (NULL != cadet_handle)
3215  {
3216  GNUNET_CADET_disconnect(cadet_handle);
3217  cadet_handle = NULL;
3218  }
3219  if (NULL != connections_map)
3220  {
3221  GNUNET_CONTAINER_multihashmap_iterate(connections_map,
3222  &free_iterate,
3223  NULL);
3224  GNUNET_CONTAINER_multihashmap_destroy(connections_map);
3225  connections_map = NULL;
3226  }
3227  if (NULL != connections_heap)
3228  {
3229  GNUNET_CONTAINER_heap_destroy(connections_heap);
3230  connections_heap = NULL;
3231  }
3232  if (NULL != dnsstub)
3233  {
3234  GNUNET_DNSSTUB_stop(dnsstub);
3235  dnsstub = NULL;
3236  }
3237  if (NULL != peer_key)
3238  {
3239  GNUNET_free(peer_key);
3240  peer_key = NULL;
3241  }
3242  if (NULL != dht_task)
3243  {
3244  GNUNET_SCHEDULER_cancel(dht_task);
3245  dht_task = NULL;
3246  }
3247  if (NULL != dht_put)
3248  {
3249  GNUNET_DHT_put_cancel(dht_put);
3250  dht_put = NULL;
3251  }
3252  if (NULL != dht)
3253  {
3254  GNUNET_DHT_disconnect(dht);
3255  dht = NULL;
3256  }
3257  if (NULL != stats)
3258  {
3260  GNUNET_NO);
3261  stats = NULL;
3262  }
3263  for (i = 0; i < 8; i++)
3265 }
3266 
3267 
3275 static void
3277  char *cpy,
3278  const char *name)
3279 {
3280  char *redirect;
3281  char *hostname;
3282  char *hostport;
3283  struct LocalService *serv;
3284  char *n;
3285  size_t slen;
3286 
3287  slen = strlen(name);
3288  GNUNET_assert(slen >= 8);
3289  n = GNUNET_strndup(name, slen - 8 /* remove .gnunet. */);
3290 
3291  for (redirect = strtok(cpy, " ;"); redirect != NULL;
3292  redirect = strtok(NULL, " ;"))
3293  {
3294  if (NULL == (hostname = strstr(redirect, ":")))
3295  {
3297  _("Option `%s' for domain `%s' is not formatted correctly!\n"),
3298  redirect,
3299  name);
3300  continue;
3301  }
3302  hostname[0] = '\0';
3303  hostname++;
3304  if (NULL == (hostport = strstr(hostname, ":")))
3305  {
3307  _("Option `%s' for domain `%s' is not formatted correctly!\n"),
3308  redirect,
3309  name);
3310  continue;
3311  }
3312  hostport[0] = '\0';
3313  hostport++;
3314 
3315  int local_port = atoi(redirect);
3316  int remote_port = atoi(hostport);
3317 
3318  if (!((local_port > 0) && (local_port < 65536)))
3319  {
3321  _("`%s' is not a valid port number (for domain `%s')!"),
3322  redirect,
3323  name);
3324  continue;
3325  }
3326  if (!((remote_port > 0) && (remote_port < 65536)))
3327  {
3329  _("`%s' is not a valid port number (for domain `%s')!"),
3330  hostport,
3331  name);
3332  continue;
3333  }
3334 
3335  serv = GNUNET_new(struct LocalService);
3336  serv->address.proto = proto;
3337  serv->address.port = remote_port;
3338  if (0 == strcmp("localhost4",
3339  hostname))
3340  {
3341  const char *ip4addr = exit_argv[5];
3342 
3343  serv->address.af = AF_INET;
3344  GNUNET_assert(1 == inet_pton(AF_INET,
3345  ip4addr,
3346  &serv->address.address.ipv4));
3347  }
3348  else if (0 == strcmp("localhost6",
3349  hostname))
3350  {
3351  const char *ip6addr = exit_argv[3];
3352 
3353  serv->address.af = AF_INET6;
3354  GNUNET_assert(1 == inet_pton(AF_INET6,
3355  ip6addr,
3356  &serv->address.address.ipv6));
3357  }
3358  else
3359  {
3360  struct addrinfo *res;
3361  int ret;
3362 
3363  ret = getaddrinfo(hostname,
3364  NULL,
3365  NULL,
3366  &res);
3367  if ((0 != ret) || (NULL == res))
3368  {
3370  _("No addresses found for hostname `%s' of service `%s'!\n"),
3371  hostname,
3372  n);
3373  GNUNET_free(serv);
3374  continue;
3375  }
3376 
3377  serv->address.af = res->ai_family;
3378  switch (res->ai_family)
3379  {
3380  case AF_INET:
3381  if (!ipv4_enabled)
3382  {
3384  _("Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
3385  n);
3386  freeaddrinfo(res);
3387  GNUNET_free(serv);
3388  continue;
3389  }
3390  serv->address.address.ipv4
3391  = ((struct sockaddr_in *)res->ai_addr)->sin_addr;
3392  break;
3393 
3394  case AF_INET6:
3395  if (!ipv6_enabled)
3396  {
3398  _("Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
3399  n);
3400  freeaddrinfo(res);
3401  GNUNET_free(serv);
3402  continue;
3403  }
3404  serv->address.address.ipv6
3405  = ((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
3406  break;
3407 
3408  default:
3409  freeaddrinfo(res);
3411  _("No IP addresses found for hostname `%s' of service `%s'!\n"),
3412  hostname,
3413  n);
3414  GNUNET_free(serv);
3415  continue;
3416  }
3417  freeaddrinfo(res);
3418  }
3419  store_service(proto,
3420  n,
3421  local_port,
3422  serv);
3423  }
3424  GNUNET_free(n);
3425 }
3426 
3427 
3434 static void
3436  const char *section)
3437 {
3438  char *cpy;
3439 
3440  if ((strlen(section) < 8) ||
3441  (0 != strcmp(".gnunet.", section + (strlen(section) - 8))))
3442  return;
3443  if (GNUNET_OK ==
3445  section,
3446  "UDP_REDIRECTS",
3447  &cpy))
3448  {
3449  add_services(IPPROTO_UDP,
3450  cpy,
3451  section);
3452  GNUNET_free(cpy);
3453  }
3454  if (GNUNET_OK ==
3456  section,
3457  "TCP_REDIRECTS",
3458  &cpy))
3459  {
3460  add_services(IPPROTO_TCP,
3461  cpy,
3462  section);
3463  GNUNET_free(cpy);
3464  }
3465 }
3466 
3467 
3474 static void
3475 do_dht_put(void *cls);
3476 
3477 
3484 static void
3485 dht_put_cont(void *cls)
3486 {
3487  dht_put = NULL;
3488 }
3489 
3490 
3497 static void
3498 do_dht_put(void *cls)
3499 {
3500  struct GNUNET_TIME_Absolute expiration;
3501 
3503  &do_dht_put,
3504  NULL);
3506  if (GNUNET_TIME_absolute_get_remaining(expiration).rel_value_us <
3507  GNUNET_TIME_UNIT_HOURS.rel_value_us)
3508  {
3509  /* refresh advertisement */
3513  GNUNET_CRYPTO_eddsa_sign(peer_key,
3516  }
3517  if (NULL != dht_put)
3518  GNUNET_DHT_put_cancel(dht_put);
3519  dht_put = GNUNET_DHT_put(dht,
3520  &dht_put_key,
3521  1 /* replication */,
3524  sizeof(struct GNUNET_DNS_Advertisement),
3526  expiration,
3527  &dht_put_cont,
3528  NULL);
3529 }
3530 
3531 
3536 static void
3538 {
3540  "exit",
3541  "EXIT_IPV4");
3543  "exit",
3544  "EXIT_IPV6");
3546  "exit",
3547  "ENABLE_IPV4");
3549  "exit",
3550  "ENABLE_IPV6");
3551  if ((ipv4_exit || ipv4_enabled) &&
3552  GNUNET_OK != GNUNET_NETWORK_test_pf(PF_INET))
3553  {
3555  _("This system does not support IPv4, will disable IPv4 functions despite them being enabled in the configuration\n"));
3556  ipv4_exit = GNUNET_NO;
3558  }
3559  if ((ipv6_exit || ipv6_enabled) &&
3560  GNUNET_OK != GNUNET_NETWORK_test_pf(PF_INET6))
3561  {
3563  _("This system does not support IPv6, will disable IPv6 functions despite them being enabled in the configuration\n"));
3564  ipv6_exit = GNUNET_NO;
3566  }
3567  if (ipv4_exit && (!ipv4_enabled))
3568  {
3570  _("Cannot enable IPv4 exit but disable IPv4 on TUN interface, will use ENABLE_IPv4=YES\n"));
3572  }
3573  if (ipv6_exit && (!ipv6_enabled))
3574  {
3576  _("Cannot enable IPv6 exit but disable IPv6 on TUN interface, will use ENABLE_IPv6=YES\n"));
3578  }
3579 }
3580 
3581 
3586 static void
3588 {
3589  struct GNUNET_MQ_MessageHandler handlers[] = {
3590  GNUNET_MQ_hd_var_size(dns_request,
3592  struct DnsResponseMessage,
3593  NULL),
3595  };
3596  char *dns_exit;
3597  struct GNUNET_HashCode port;
3598 
3599  if (GNUNET_YES !=
3601  "exit",
3602  "EXIT_DNS"))
3603  return;
3604  GNUNET_assert(NULL != (dnsstub = GNUNET_DNSSTUB_start(128)));
3605  dns_exit = NULL;
3606  /* TODO: support using multiple DNS resolvers */
3607  if ((GNUNET_OK !=
3609  "exit",
3610  "DNS_RESOLVER",
3611  &dns_exit)) ||
3612  (GNUNET_OK !=
3613  GNUNET_DNSSTUB_add_dns_ip(dnsstub,
3614  dns_exit)))
3615  {
3617  "dns",
3618  "DNS_RESOLVER",
3619  _("need a valid IPv4 or IPv6 address\n"));
3620  GNUNET_free_non_null(dns_exit);
3621  return;
3622  }
3623  /* open port */
3626  &port);
3628  "Opening CADET port %s for DNS exit service\n",
3629  GNUNET_h2s(&port));
3630  dns_port = GNUNET_CADET_open_port(cadet_handle,
3631  &port,
3632  &new_channel,
3633  NULL,
3634  NULL,
3635  &clean_channel,
3636  handlers);
3637  /* advertise exit */
3638  dht = GNUNET_DHT_connect(cfg,
3639  1);
3643  dns_advertisement.purpose.size = htonl(sizeof(struct GNUNET_DNS_Advertisement) -
3644  sizeof(struct GNUNET_CRYPTO_EddsaSignature));
3646  GNUNET_CRYPTO_hash("dns",
3647  strlen("dns"),
3648  &dht_put_key);
3650  NULL);
3651  GNUNET_free(dns_exit);
3652 }
3653 
3654 
3660 static int
3662 {
3663  char *exit_ifname;
3664  char *tun_ifname;
3665  char *ipv6addr;
3666  char *ipv6prefix_s;
3667  char *ipv4addr;
3668  char *ipv4mask;
3669 
3670  exit_argv[0] = GNUNET_strdup("exit-gnunet");
3671  if (GNUNET_SYSERR ==
3673  "exit",
3674  "TUN_IFNAME",
3675  &tun_ifname))
3676  {
3678  "EXIT",
3679  "TUN_IFNAME");
3680  return GNUNET_SYSERR;
3681  }
3682  exit_argv[1] = tun_ifname;
3683  if (ipv4_enabled)
3684  {
3685  if (GNUNET_SYSERR ==
3687  "exit",
3688  "EXIT_IFNAME",
3689  &exit_ifname))
3690  {
3692  "EXIT",
3693  "EXIT_IFNAME");
3694  return GNUNET_SYSERR;
3695  }
3696  exit_argv[2] = exit_ifname;
3697  }
3698  else
3699  {
3700  exit_argv[2] = GNUNET_strdup("-");
3701  }
3702 
3703  if (GNUNET_YES == ipv6_enabled)
3704  {
3705  ipv6addr = NULL;
3706  if ((GNUNET_SYSERR ==
3708  "exit",
3709  "IPV6ADDR",
3710  &ipv6addr) ||
3711  (1 != inet_pton(AF_INET6,
3712  ipv6addr,
3713  &exit_ipv6addr))))
3714  {
3716  "EXIT",
3717  "IPV6ADDR");
3718  GNUNET_free_non_null(ipv6addr);
3719  return GNUNET_SYSERR;
3720  }
3721  exit_argv[3] = ipv6addr;
3722  if (GNUNET_SYSERR ==
3724  "exit",
3725  "IPV6PREFIX",
3726  &ipv6prefix_s))
3727  {
3729  "EXIT",
3730  "IPV6PREFIX");
3731  return GNUNET_SYSERR;
3732  }
3733  exit_argv[4] = ipv6prefix_s;
3734  if ((GNUNET_OK !=
3736  "exit",
3737  "IPV6PREFIX",
3738  &ipv6prefix)) ||
3739  (ipv6prefix >= 127))
3740  {
3742  "EXIT",
3743  "IPV6PREFIX",
3744  _("Must be a number"));
3745  return GNUNET_SYSERR;
3746  }
3747  }
3748  else
3749  {
3750  /* IPv6 explicitly disabled */
3751  exit_argv[3] = GNUNET_strdup("-");
3752  exit_argv[4] = GNUNET_strdup("-");
3753  }
3754  if (GNUNET_YES == ipv4_enabled)
3755  {
3756  ipv4addr = NULL;
3757  if ((GNUNET_SYSERR ==
3759  "exit",
3760  "IPV4ADDR",
3761  &ipv4addr) ||
3762  (1 != inet_pton(AF_INET,
3763  ipv4addr,
3764  &exit_ipv4addr))))
3765  {
3767  "EXIT",
3768  "IPV4ADDR");
3769  GNUNET_free_non_null(ipv4addr);
3770  return GNUNET_SYSERR;
3771  }
3772  exit_argv[5] = ipv4addr;
3773  ipv4mask = NULL;
3774  if ((GNUNET_SYSERR ==
3776  "exit",
3777  "IPV4MASK",
3778  &ipv4mask) ||
3779  (1 != inet_pton(AF_INET,
3780  ipv4mask,
3781  &exit_ipv4mask))))
3782  {
3784  "EXIT",
3785  "IPV4MASK");
3786  GNUNET_free_non_null(ipv4mask);
3787  return GNUNET_SYSERR;
3788  }
3789  exit_argv[6] = ipv4mask;
3790  }
3791  else
3792  {
3793  /* IPv4 explicitly disabled */
3794  exit_argv[5] = GNUNET_strdup("-");
3795  exit_argv[6] = GNUNET_strdup("-");
3796  }
3797  exit_argv[7] = NULL;
3798  return GNUNET_OK;
3799 }
3800 
3801 
3810 static void
3811 run(void *cls,
3812  char *const *args,
3813  const char *cfgfile,
3814  const struct GNUNET_CONFIGURATION_Handle *cfg_)
3815 {
3816  struct GNUNET_MQ_MessageHandler handlers[] = {
3817  GNUNET_MQ_hd_var_size(icmp_remote,
3820  NULL),
3821  GNUNET_MQ_hd_var_size(udp_remote,
3824  NULL),
3825  GNUNET_MQ_hd_var_size(tcp_remote,
3828  NULL),
3829  GNUNET_MQ_hd_var_size(tcp_data,
3832  NULL),
3834  };
3835  struct GNUNET_HashCode port;
3836  char *policy;
3837  char *binary;
3838  char *regex;
3839  char *prefixed_regex;
3840 
3841  cfg = cfg_;
3842  if (GNUNET_OK !=
3844  "exit",
3845  "MAX_CONNECTIONS",
3846  &max_connections))
3847  max_connections = 1024;
3848  parse_ip_options();
3849  binary = GNUNET_OS_get_suid_binary_path(cfg, "gnunet-helper-exit");
3850  if ((ipv4_exit) || (ipv6_exit))
3851  {
3852  if (GNUNET_YES !=
3854  GNUNET_YES,
3855  "gnunet-vpn - - - 169.1.3.7 255.255.255.0")) //no nat, ipv4 only
3856  {
3857  GNUNET_free(binary);
3859  _("`%s' is not SUID or the path is invalid, EXIT will not work\n"),
3860  "gnunet-helper-exit");
3862  NULL);
3863  global_ret = 1;
3864  return;
3865  }
3866  }
3867  if (!(ipv4_enabled || ipv6_enabled))
3868  {
3869  GNUNET_free(binary);
3871  _("No useful service enabled. Exiting.\n"));
3873  return;
3874  }
3875 
3877  NULL);
3878  stats = GNUNET_STATISTICS_create("exit",
3879  cfg);
3880  cadet_handle = GNUNET_CADET_connect(cfg);
3881  if (NULL == cadet_handle)
3882  {
3883  GNUNET_free(binary);
3885  return;
3886  }
3888  if (GNUNET_OK !=
3890  {
3891  GNUNET_free(binary);
3893  return;
3894  }
3895 
3896  services = GNUNET_CONTAINER_multihashmap_create(65536,
3897  GNUNET_NO);
3898  connections_map = GNUNET_CONTAINER_multihashmap_create(65536,
3899  GNUNET_NO);
3903  NULL);
3904 
3905  /* Cadet handle acquired, now open ports and announce regular
3906  expressions matching our exit */
3907  if ((GNUNET_YES == ipv4_enabled) &&
3908  (GNUNET_YES == ipv4_exit))
3909  {
3912  &port);
3914  "Opening CADET port %s for IPv4 gateway service\n",
3915  GNUNET_h2s(&port));
3916  cadet_port4 = GNUNET_CADET_open_port(cadet_handle,
3917  &port,
3918  &new_channel,
3919  NULL,
3920  NULL,
3921  &clean_channel,
3922  handlers);
3923  policy = NULL;
3924  if (GNUNET_OK !=
3926  "exit",
3927  "EXIT_RANGE_IPV4_POLICY",
3928  &policy))
3929  regex = NULL;
3930  else
3931  regex = GNUNET_TUN_ipv4policy2regex(policy);
3932  GNUNET_free_non_null(policy);
3933  if (NULL != regex)
3934  {
3935  (void)GNUNET_asprintf(&prefixed_regex,
3936  "%s%s",
3938  regex);
3939  regex4 = GNUNET_REGEX_announce(cfg,
3940  prefixed_regex,
3943  GNUNET_free(regex);
3944  GNUNET_free(prefixed_regex);
3945  }
3946  }
3947 
3948  if ((GNUNET_YES == ipv6_enabled) && (GNUNET_YES == ipv6_exit))
3949  {
3952  &port);
3954  "Opening CADET port %s for IPv6 gateway service\n",
3955  GNUNET_h2s(&port));
3956  cadet_port6 = GNUNET_CADET_open_port(cadet_handle,
3957  &port,
3958  &new_channel,
3959  NULL,
3960  NULL,
3961  &clean_channel,
3962  handlers);
3963  policy = NULL;
3964  if (GNUNET_OK !=
3966  "exit",
3967  "EXIT_RANGE_IPV6_POLICY",
3968  &policy))
3969  regex = NULL;
3970  else
3971  regex = GNUNET_TUN_ipv6policy2regex(policy);
3972  GNUNET_free_non_null(policy);
3973  if (NULL != regex)
3974  {
3975  (void)GNUNET_asprintf(&prefixed_regex,
3976  "%s%s",
3978  regex);
3979  regex6 = GNUNET_REGEX_announce(cfg,
3980  prefixed_regex,
3983  GNUNET_free(regex);
3984  GNUNET_free(prefixed_regex);
3985  }
3986  }
3987  helper_handle = GNUNET_HELPER_start(GNUNET_NO,
3988  binary,
3989  exit_argv,
3990  &message_token,
3991  NULL,
3992  NULL);
3993  GNUNET_free(binary);
3994 }
3995 
3996 
4004 int
4005 main(int argc,
4006  char *const *argv)
4007 {
4008  static const struct GNUNET_GETOPT_CommandLineOption options[] = {
4010  };
4011 
4012  if (GNUNET_OK !=
4014  argv,
4015  &argc,
4016  &argv))
4017  return 2;
4018 
4019  return (GNUNET_OK ==
4020  GNUNET_PROGRAM_run(argc,
4021  argv,
4022  "gnunet-daemon-exit",
4023  gettext_noop("Daemon to run to provide an IP exit node for the VPN"),
4024  options,
4025  &run,
4026  NULL)) ? global_ret : 1;
4027 }
4028 
4029 
4030 /* 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:838
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:671
This is the structure describing an DNS exit service.
Definition: block_dns.h:40
static void handle_tcp_data(void *cls, const struct GNUNET_EXIT_TcpDataMessage *data)
Process a request to forward TCP data on an established connection via this peer. ...
static void setup_fresh_address(int af, uint8_t proto, struct SocketAddress *local_address)
We need to create a (unique) fresh local address (IP+port).
#define GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE
Type of messages containing an ICMP packet for a service.
int GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
static struct in6_addr exit_ipv6addr
IPv6 address of our TUN interface.
char * GNUNET_TUN_ipv4policy2regex(const char *policy)
Convert an exit policy to a regular expression.
Definition: regex.c:707
uint16_t proto
Here we get an ETH_P_-number.
void GNUNET_DHT_put_cancel(struct GNUNET_DHT_PutHandle *ph)
Cancels a DHT PUT operation.
Definition: dht_api.c:1030
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:77
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:487
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:1284
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:1439
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:246
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:241
#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:687
#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:588
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:563
struct in_addr ipv4
Address, if af is AF_INET.
Handle to store cached data about a regex announce.
UDP packet header.
#define GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET
Type of messages containing an UDP packet for the Internet.
#define ETH_P_IPV6
Number for IPv6.
static void read_service_conf(void *cls, const char *section)
Reads the configuration and populates #udp_services and #tcp_services.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static 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:278
#define GNUNET_NO
Definition: gnunet_common.h:78
Opaque handle to a channel.
Definition: cadet_api.c:79
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
Standard IPv4 header.
static int check_udp_remote(void *cls, const struct GNUNET_EXIT_UdpInternetMessage *msg)
Check a request to forward UDP data to the Internet via this peer.
struct GNUNET_CRYPTO_EddsaSignature signature
Signature of the peer affirming that it is offering the service.
Definition: block_dns.h:44
#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:71
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:107
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:50
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:517
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:52
#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:121
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:198
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition: cadet_api.c:973
#define DHT_PUT_FREQUENCY
How frequently do we re-announce the DNS exit in the DHT?
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
static char * section
Name of the section.
Definition: gnunet-config.c:33
static void handle_tcp_remote(void *cls, const struct GNUNET_EXIT_TcpInternetStartMessage *start)
Process a request to forward TCP data to the Internet via this peer.
Block for storing DNS exit service advertisements.
#define GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT
Type of messages containing an TCP packet of an established connection.
#define GNUNET_MESSAGE_TYPE_VPN_DNS_TO_INTERNET
Type of messages containing an DNS request for a DNS exit service.
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:150
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:199
#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:1237
#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:1007
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:77
#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:561
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:160
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:1264
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:46
Message send via cadet to an exit daemon to forward ICMP data to the Internet.
Definition: exit.h:229
#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:812
Handle to a node in a heap.
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:273
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:121
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:173
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:60
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:501
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:183
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:831
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:961
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static unsigned int size
Size of the "table".
Definition: peer.c:66
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:885
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:913
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:263
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:117
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:951
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:145
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:83
char * GNUNET_TUN_ipv6policy2regex(const char *policy)
Convert an exit policy to a regular expression.
Definition: regex.c:759
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:653
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:66
uint16_t destination_port
Destination port used by the sender on our end; 0 for uninitialized.
void GNUNET_CONFIGURATION_iterate_sections(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_CONFIGURATION_Section_Iterator iter, void *iter_cls)
Iterate over all sections in the configuration.
static struct GNUNET_CADET_Port * cadet_port6
Port for IPv6 exit.
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:131
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:62
Opaque handle to a port.
Definition: cadet_api.c:143
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:211
int is_dns
GNUNET_NO if this is a channel for TCP/UDP, GNUNET_YES if this is a channel for DNS, GNUNET_SYSERR if the channel is not yet initialized.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
Information about an address.
int GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration, parse options).
Definition: program.c:367
#define REGEX_MAX_PATH_LEN_IPV6
Maximum path compression length for cadet regex announcing for IPv6 address based regex...
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:189
struct GNUNET_MessageHeader header
Type is #GNUNET_MESSAGE_TYPE_VPN_TCP_DATA.
Definition: exit.h:96
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:871
Time for absolute times used by GNUnet, in microseconds.
static struct GNUNET_CADET_Port * cadet_port4
Port for IPv4 exit.
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GNUNET_DNSSTUB_RequestSocket * rs
Socket we are using to transmit this request (must match if we receive a response).
#define REGEX_REFRESH_FREQUENCY
How frequently do we re-announce the regex for the exit?
static struct GNUNET_SCHEDULER_Task * dht_task
Task for doing DHT PUTs to advertise exit service.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:351
#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:55
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:44
int GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START.
Definition: exit.h:41
uint16_t source_port
Source port to use for the UDP request (0 to use a random port).
Definition: exit.h:155
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:655
Message send via cadet between VPN and entry and an exit daemon to transmit TCP data between the VPN ...
Definition: exit.h:92
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:900
uint32_t reserved
Always 0.
Definition: exit.h:101
struct GNUNET_TUN_IcmpHeader icmp_header
ICMP header to use.
Definition: exit.h:216
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:126
uint16_t crc
Checksum.
struct GNUNET_TUN_IcmpHeader icmp_header
ICMP header to use.
Definition: exit.h:247
union ChannelState::@89 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
static void send_udp_packet_via_tun(const struct SocketAddress *destination_address, const struct SocketAddress *source_address, const void *payload, size_t payload_length)
Send a UDP packet via the TUN interface.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE.
Definition: exit.h:203
#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:78
Message send via cadet to an exit daemon to forward UDP data to the Internet.
Definition: exit.h:141
#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:1116
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:956
uint16_t destination_port
Destination port to use for the UDP request.
Definition: exit.h:131
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET.
Definition: exit.h:233