GNUnet  0.19.3
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"
44 #include "gnunet_constants.h"
45 #include "gnunet_signatures.h"
46 #include "gnunet_regex_service.h"
47 #include "exit.h"
48 #include "block_dns.h"
49 
50 
55 #define REGEX_MAX_PATH_LEN_IPV4 4
56 
61 #define REGEX_MAX_PATH_LEN_IPV6 8
62 
66 #define REGEX_REFRESH_FREQUENCY GNUNET_TIME_relative_multiply ( \
67  GNUNET_TIME_UNIT_MINUTES, 30)
68 
72 #define DHT_PUT_FREQUENCY GNUNET_TIME_relative_multiply ( \
73  GNUNET_TIME_UNIT_MINUTES, 15)
74 
78 #define DNS_ADVERTISEMENT_TIMEOUT GNUNET_TIME_relative_multiply ( \
79  GNUNET_TIME_UNIT_HOURS, 3)
80 
81 
85 #define LOG(kind, ...) \
86  GNUNET_log_from (kind, "exit", __VA_ARGS__);
87 
88 
93 {
97  int af;
98 
102  union
103  {
107  struct in_addr ipv4;
108 
112  struct in6_addr ipv6;
114 
118  uint8_t proto;
119 
123  uint16_t port;
124 };
125 
126 
133 {
137  struct SocketAddress address;
138 
143 
147  char *name;
148 
153 
157  int16_t is_udp;
158 };
159 
160 
167 {
173 
180 
181  /*
182  Note 1: additional information might be added here in the
183  future to support protocols that require special handling,
184  such as ftp/tftp
185 
186  Note 2: we might also sometimes not match on all components
187  of the tuple, to support protocols where things do not always
188  fully map.
189  */
190 };
191 
192 
200 {
205 
210  struct GNUNET_PeerIdentity peer;
211 
217  int is_dns;
218 
219  union
220  {
221  struct
222  {
227 
231  struct GNUNET_HashCode state_key;
232 
237 
241  struct RedirectInformation ri;
243 
244  struct
245  {
251 
255  uint16_t original_id;
256 
260  uint16_t my_id;
261  } dns;
263 };
264 
265 
269 static int global_ret;
270 
275 
280 
284 static const struct GNUNET_CONFIGURATION_Handle *cfg;
285 
290 
294 static char *exit_argv[8];
295 
299 static struct in6_addr exit_ipv6addr;
300 
304 static unsigned long long ipv6prefix;
305 
309 static struct in_addr exit_ipv4addr;
310 
314 static struct in_addr exit_ipv4mask;
315 
320 
325 
331 
336 
340 static unsigned long long max_connections;
341 
346 
350 static struct ChannelState *channels[UINT16_MAX + 1];
351 
356 
361 
365 static struct GNUNET_DHT_Handle *dht;
366 
371 
377 
381 static struct GNUNET_HashCode dht_put_key;
382 
387 
392 
397 
402 
406 static int ipv4_exit;
407 
411 static int ipv6_exit;
412 
416 static int ipv4_enabled;
417 
421 static int ipv6_enabled;
422 
423 
425 
430 {
435 
439  struct GNUNET_TUN_DnsHeader dns;
440 
441  /* Followed by more DNS payload */
442 };
443 
445 
446 
455 static void
457  const struct GNUNET_TUN_DnsHeader *dns,
458  size_t r)
459 {
460  struct ChannelState *ts;
461  struct GNUNET_MQ_Envelope *env;
462  struct DnsResponseMessage *resp;
463 
465  "Processing DNS result from stub resolver\n");
466  GNUNET_assert (NULL == cls);
467  if (NULL == dns)
468  return;
469  /* Handle case that this is a reply to a request from a CADET DNS channel */
470  ts = channels[dns->id];
471  if (NULL == ts)
472  return;
474  "Got a response from the stub resolver for DNS request received via CADET!\n");
475  channels[dns->id] = NULL;
476  env = GNUNET_MQ_msg_extra (resp,
477  r - sizeof(struct GNUNET_TUN_DnsHeader),
479  GNUNET_memcpy (&resp->dns,
480  dns,
481  r);
482  resp->dns.id = ts->specifics.dns.original_id;
484  env);
485 }
486 
487 
496 static int
497 check_dns_request (void *cls,
498  const struct DnsResponseMessage *msg)
499 {
500  struct ChannelState *ts = cls;
501 
502  if (NULL == dnsstub)
503  {
504  GNUNET_break (0);
505  return GNUNET_SYSERR;
506  }
507  if (GNUNET_NO == ts->is_dns)
508  {
509  GNUNET_break_op (0);
510  return GNUNET_SYSERR;
511  }
512  return GNUNET_OK;
513 }
514 
515 
522 static void
524  const struct DnsResponseMessage *msg)
525 {
526  struct ChannelState *ts = cls;
527  size_t mlen = ntohs (msg->header.size);
528  size_t dlen = mlen - sizeof(struct GNUNET_MessageHeader);
529  char buf[dlen] GNUNET_ALIGN;
530  struct GNUNET_TUN_DnsHeader *dns_out;
531 
532  if (GNUNET_SYSERR == ts->is_dns)
533  {
534  /* channel is DNS from now on */
535  ts->is_dns = GNUNET_YES;
536  }
537  ts->specifics.dns.original_id = msg->dns.id;
538  if (channels[ts->specifics.dns.my_id] == ts)
539  channels[ts->specifics.dns.my_id] = NULL;
540  ts->specifics.dns.my_id = (uint16_t) GNUNET_CRYPTO_random_u32 (
542  UINT16_MAX
543  + 1);
544  channels[ts->specifics.dns.my_id] = ts;
546  &msg->dns,
547  dlen);
548  dns_out = (struct GNUNET_TUN_DnsHeader *) buf;
549  dns_out->id = ts->specifics.dns.my_id;
551  buf,
552  dlen,
554  NULL);
555  if (NULL == ts->specifics.dns.rs)
556  {
557  GNUNET_break_op (0);
558  return;
559  }
561 }
562 
563 
571 static void
573  const struct RedirectInformation *ri)
574 {
575  char *off;
576 
577  memset (hash,
578  0,
579  sizeof(struct GNUNET_HashCode));
580  /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
581  so we put the IP address in there (and hope for few collisions) */
582  off = (char *) hash;
583  switch (ri->remote_address.af)
584  {
585  case AF_INET:
586  GNUNET_memcpy (off,
588  sizeof(struct in_addr));
589  off += sizeof(struct in_addr);
590  break;
591 
592  case AF_INET6:
593  GNUNET_memcpy (off,
595  sizeof(struct in6_addr));
596  off += sizeof(struct in_addr);
597  break;
598 
599  default:
600  GNUNET_assert (0);
601  }
602  GNUNET_memcpy (off,
603  &ri->remote_address.port,
604  sizeof(uint16_t));
605  off += sizeof(uint16_t);
606  switch (ri->local_address.af)
607  {
608  case AF_INET:
609  GNUNET_memcpy (off,
611  sizeof(struct in_addr));
612  off += sizeof(struct in_addr);
613  break;
614 
615  case AF_INET6:
616  GNUNET_memcpy (off,
618  sizeof(struct in6_addr));
619  off += sizeof(struct in_addr);
620  break;
621 
622  default:
623  GNUNET_assert (0);
624  }
625  GNUNET_memcpy (off,
626  &ri->local_address.port,
627  sizeof(uint16_t));
628  off += sizeof(uint16_t);
629  GNUNET_memcpy (off,
630  &ri->remote_address.proto,
631  sizeof(uint8_t));
632  /* off += sizeof (uint8_t); */
633 }
634 
635 
649 static struct ChannelState *
651  int protocol,
652  const void *destination_ip,
653  uint16_t destination_port,
654  const void *local_ip,
655  uint16_t local_port,
656  struct GNUNET_HashCode *state_key)
657 {
658  struct RedirectInformation ri;
659  struct GNUNET_HashCode key;
660  struct ChannelState *state;
661 
662  if (((af == AF_INET) && (protocol == IPPROTO_ICMP)) ||
663  ((af == AF_INET6) && (protocol == IPPROTO_ICMPV6)))
664  {
665  /* ignore ports */
666  destination_port = 0;
667  local_port = 0;
668  }
670  if (af == AF_INET)
671  ri.remote_address.address.ipv4 = *((struct in_addr*) destination_ip);
672  else
673  ri.remote_address.address.ipv6 = *((struct in6_addr*) destination_ip);
674  ri.remote_address.port = destination_port;
675  ri.remote_address.proto = protocol;
676  ri.local_address.af = af;
677  if (af == AF_INET)
678  ri.local_address.address.ipv4 = *((struct in_addr*) local_ip);
679  else
680  ri.local_address.address.ipv6 = *((struct in6_addr*) local_ip);
681  ri.local_address.port = local_port;
682  ri.local_address.proto = protocol;
684  &ri);
685  if (NULL != state_key)
686  *state_key = key;
688  &key);
689  if (NULL == state)
690  return NULL;
691  /* Mark this connection as freshly used */
692  if (NULL == state_key)
693  GNUNET_CONTAINER_heap_update_cost (state->specifics.tcp_udp.heap_node,
694  GNUNET_TIME_absolute_get ().abs_value_us);
695  return state;
696 }
697 
698 
708 static int
709 check_tcp_service (void *cls,
711 {
712  struct ChannelState *state = cls;
713 
714  if (NULL == state)
715  {
716  GNUNET_break_op (0);
717  return GNUNET_SYSERR;
718  }
719  if (GNUNET_YES == state->is_dns)
720  {
721  GNUNET_break_op (0);
722  return GNUNET_SYSERR;
723  }
724  if (NULL == state->specifics.tcp_udp.serv)
725  {
726  GNUNET_break_op (0);
727  return GNUNET_SYSERR;
728  }
729  if (NULL != state->specifics.tcp_udp.heap_node)
730  {
731  GNUNET_break_op (0);
732  return GNUNET_SYSERR;
733  }
734  if (start->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
735  {
736  GNUNET_break_op (0);
737  return GNUNET_SYSERR;
738  }
739  return GNUNET_OK;
740 }
741 
742 
761 static void
763  size_t payload_length,
764  int protocol,
765  const struct GNUNET_TUN_TcpHeader *tcp_header,
766  const struct SocketAddress *src_address,
767  const struct SocketAddress *dst_address,
768  struct GNUNET_TUN_IPv4Header *pkt4)
769 {
770  size_t len;
771 
772  len = payload_length;
773  switch (protocol)
774  {
775  case IPPROTO_UDP:
776  len += sizeof(struct GNUNET_TUN_UdpHeader);
777  break;
778 
779  case IPPROTO_TCP:
780  len += sizeof(struct GNUNET_TUN_TcpHeader);
781  GNUNET_assert (NULL != tcp_header);
782  break;
783 
784  default:
785  GNUNET_break (0);
786  return;
787  }
788  if (len + sizeof(struct GNUNET_TUN_IPv4Header) > UINT16_MAX)
789  {
790  GNUNET_break (0);
791  return;
792  }
793 
795  protocol,
796  len,
797  &src_address->address.ipv4,
798  &dst_address->address.ipv4);
799  switch (protocol)
800  {
801  case IPPROTO_UDP:
802  {
803  struct GNUNET_TUN_UdpHeader *pkt4_udp = (struct
804  GNUNET_TUN_UdpHeader *) &pkt4[1];
805 
806  pkt4_udp->source_port = htons (src_address->port);
807  pkt4_udp->destination_port = htons (dst_address->port);
808  pkt4_udp->len = htons ((uint16_t) payload_length);
810  pkt4_udp,
811  payload,
812  payload_length);
813  GNUNET_memcpy (&pkt4_udp[1],
814  payload,
815  payload_length);
816  }
817  break;
818 
819  case IPPROTO_TCP:
820  {
821  struct GNUNET_TUN_TcpHeader *pkt4_tcp = (struct
822  GNUNET_TUN_TcpHeader *) &pkt4[1];
823 
824  *pkt4_tcp = *tcp_header;
826  "Sending TCP packet from port %u to port %u\n",
827  src_address->port,
828  dst_address->port);
829  pkt4_tcp->source_port = htons (src_address->port);
830  pkt4_tcp->destination_port = htons (dst_address->port);
832  pkt4_tcp,
833  payload,
834  payload_length);
835  GNUNET_memcpy (&pkt4_tcp[1],
836  payload,
837  payload_length);
838  }
839  break;
840 
841  default:
842  GNUNET_assert (0);
843  }
844 }
845 
846 
865 static void
867  size_t payload_length,
868  int protocol,
869  const struct GNUNET_TUN_TcpHeader *tcp_header,
870  const struct SocketAddress *src_address,
871  const struct SocketAddress *dst_address,
872  struct GNUNET_TUN_IPv6Header *pkt6)
873 {
874  size_t len;
875 
876  len = payload_length;
877  switch (protocol)
878  {
879  case IPPROTO_UDP:
880  len += sizeof(struct GNUNET_TUN_UdpHeader);
881  break;
882 
883  case IPPROTO_TCP:
884  len += sizeof(struct GNUNET_TUN_TcpHeader);
885  break;
886 
887  default:
888  GNUNET_break (0);
889  return;
890  }
891  if (len > UINT16_MAX)
892  {
893  GNUNET_break (0);
894  return;
895  }
896 
898  protocol,
899  len,
900  &src_address->address.ipv6,
901  &dst_address->address.ipv6);
902 
903  switch (protocol)
904  {
905  case IPPROTO_UDP:
906  {
907  struct GNUNET_TUN_UdpHeader *pkt6_udp = (struct
908  GNUNET_TUN_UdpHeader *) &pkt6[1];
909 
910  pkt6_udp->source_port = htons (src_address->port);
911  pkt6_udp->destination_port = htons (dst_address->port);
912  pkt6_udp->len = htons ((uint16_t) payload_length);
914  pkt6_udp,
915  payload,
916  payload_length);
917  GNUNET_memcpy (&pkt6_udp[1],
918  payload,
919  payload_length);
920  }
921  break;
922 
923  case IPPROTO_TCP:
924  {
925  struct GNUNET_TUN_TcpHeader *pkt6_tcp = (struct
926  GNUNET_TUN_TcpHeader *) &pkt6[1];
927 
928  /* GNUNET_memcpy first here as some TCP header fields are initialized this way! */
929  *pkt6_tcp = *tcp_header;
930  pkt6_tcp->source_port = htons (src_address->port);
931  pkt6_tcp->destination_port = htons (dst_address->port);
933  pkt6_tcp,
934  payload,
935  payload_length);
936  GNUNET_memcpy (&pkt6_tcp[1],
937  payload,
938  payload_length);
939  }
940  break;
941 
942  default:
943  GNUNET_assert (0);
944  break;
945  }
946 }
947 
948 
958 static void
959 send_tcp_packet_via_tun (const struct SocketAddress *destination_address,
960  const struct SocketAddress *source_address,
961  const struct GNUNET_TUN_TcpHeader *tcp_header,
962  const void *payload,
963  size_t payload_length)
964 {
965  size_t len;
966 
968  gettext_noop ("# TCP packets sent via TUN"),
969  1,
970  GNUNET_NO);
972  "Sending packet with %u bytes TCP payload via TUN\n",
973  (unsigned int) payload_length);
974  len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct
976  switch (source_address->af)
977  {
978  case AF_INET:
979  len += sizeof(struct GNUNET_TUN_IPv4Header);
980  break;
981 
982  case AF_INET6:
983  len += sizeof(struct GNUNET_TUN_IPv6Header);
984  break;
985 
986  default:
987  GNUNET_break (0);
988  return;
989  }
990  len += sizeof(struct GNUNET_TUN_TcpHeader);
991  len += payload_length;
993  {
994  GNUNET_break (0);
995  return;
996  }
997  {
998  char buf[len] GNUNET_ALIGN;
999  struct GNUNET_MessageHeader *hdr;
1000  struct GNUNET_TUN_Layer2PacketHeader *tun;
1001 
1002  hdr = (struct GNUNET_MessageHeader *) buf;
1003  hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1004  hdr->size = htons (len);
1005  tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1006  tun->flags = htons (0);
1007  switch (source_address->af)
1008  {
1009  case AF_INET:
1010  {
1011  struct GNUNET_TUN_IPv4Header *ipv4
1012  = (struct GNUNET_TUN_IPv4Header*) &tun[1];
1013 
1014  tun->proto = htons (ETH_P_IPV4);
1016  payload_length,
1017  IPPROTO_TCP,
1018  tcp_header,
1021  ipv4);
1022  }
1023  break;
1024 
1025  case AF_INET6:
1026  {
1027  struct GNUNET_TUN_IPv6Header *ipv6
1028  = (struct GNUNET_TUN_IPv6Header*) &tun[1];
1029 
1030  tun->proto = htons (ETH_P_IPV6);
1033  IPPROTO_TCP,
1034  tcp_header,
1037  ipv6);
1038  }
1039  break;
1040 
1041  default:
1042  GNUNET_assert (0);
1043  break;
1044  }
1045  if (NULL != helper_handle)
1047  (const struct GNUNET_MessageHeader*) buf,
1048  GNUNET_YES,
1049  NULL,
1050  NULL);
1051  }
1052 }
1053 
1054 
1064 static void
1066  const struct SocketAddress *source_address,
1067  const struct GNUNET_TUN_IcmpHeader *icmp_header,
1068  const void *payload, size_t payload_length)
1069 {
1070  size_t len;
1071  struct GNUNET_TUN_IcmpHeader *icmp;
1072 
1074  gettext_noop ("# ICMP packets sent via TUN"),
1075  1, GNUNET_NO);
1077  "Sending packet with %u bytes ICMP payload via TUN\n",
1078  (unsigned int) payload_length);
1079  len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct
1081  switch (destination_address->af)
1082  {
1083  case AF_INET:
1084  len += sizeof(struct GNUNET_TUN_IPv4Header);
1085  break;
1086 
1087  case AF_INET6:
1088  len += sizeof(struct GNUNET_TUN_IPv6Header);
1089  break;
1090 
1091  default:
1092  GNUNET_break (0);
1093  return;
1094  }
1095  len += sizeof(struct GNUNET_TUN_IcmpHeader);
1096  len += payload_length;
1098  {
1099  GNUNET_break (0);
1100  return;
1101  }
1102  {
1103  char buf[len] GNUNET_ALIGN;
1104  struct GNUNET_MessageHeader *hdr;
1105  struct GNUNET_TUN_Layer2PacketHeader *tun;
1106 
1107  hdr = (struct GNUNET_MessageHeader *) buf;
1108  hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1109  hdr->size = htons (len);
1110  tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1111  tun->flags = htons (0);
1112  switch (source_address->af)
1113  {
1114  case AF_INET:
1115  {
1116  struct GNUNET_TUN_IPv4Header *ipv4 = (struct
1117  GNUNET_TUN_IPv4Header*) &tun[1];
1118 
1119  tun->proto = htons (ETH_P_IPV4);
1121  IPPROTO_ICMP,
1122  sizeof(struct
1124  + payload_length,
1125  &source_address->address.ipv4,
1126  &destination_address->address.ipv4);
1127  icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv4[1];
1128  }
1129  break;
1130 
1131  case AF_INET6:
1132  {
1133  struct GNUNET_TUN_IPv6Header *ipv6 = (struct
1134  GNUNET_TUN_IPv6Header*) &tun[1];
1135 
1136  tun->proto = htons (ETH_P_IPV6);
1138  IPPROTO_ICMPV6,
1139  sizeof(struct
1141  + payload_length,
1142  &source_address->address.ipv6,
1143  &destination_address->address.ipv6);
1144  icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv6[1];
1145  }
1146  break;
1147 
1148  default:
1149  GNUNET_assert (0);
1150  break;
1151  }
1152  *icmp = *icmp_header;
1153  GNUNET_memcpy (&icmp[1],
1154  payload,
1155  payload_length);
1157  payload,
1158  payload_length);
1159  if (NULL != helper_handle)
1161  (const struct GNUNET_MessageHeader*) buf,
1162  GNUNET_YES,
1163  NULL, NULL);
1164  }
1165 }
1166 
1167 
1176 static void
1178  uint8_t proto,
1179  struct SocketAddress *local_address)
1180 {
1181  local_address->af = af;
1182  local_address->proto = (uint8_t) proto;
1183  /* default "local" port range is often 32768--61000,
1184  so we pick a random value in that range */
1185  if (((af == AF_INET) && (proto == IPPROTO_ICMP)) ||
1186  ((af == AF_INET6) && (proto == IPPROTO_ICMPV6)))
1187  local_address->port = 0;
1188  else
1189  local_address->port
1191  28232);
1192  switch (af)
1193  {
1194  case AF_INET:
1195  {
1196  struct in_addr addr;
1197  struct in_addr mask;
1198  struct in_addr rnd;
1199 
1200  addr = exit_ipv4addr;
1201  mask = exit_ipv4mask;
1202  if (0 == ~mask.s_addr)
1203  {
1204  /* only one valid IP anyway */
1205  local_address->address.ipv4 = addr;
1206  return;
1207  }
1208  /* Given 192.168.0.1/255.255.0.0, we want a mask
1209  of '192.168.255.255', thus: */
1210  mask.s_addr = addr.s_addr | ~mask.s_addr;
1211  /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
1212  do
1213  {
1215  UINT32_MAX);
1216  local_address->address.ipv4.s_addr = (addr.s_addr | rnd.s_addr)
1217  & mask.s_addr;
1218  }
1219  while ((local_address->address.ipv4.s_addr == addr.s_addr) ||
1220  (local_address->address.ipv4.s_addr == mask.s_addr));
1221  }
1222  break;
1223 
1224  case AF_INET6:
1225  {
1226  struct in6_addr addr;
1227  struct in6_addr mask;
1228  struct in6_addr rnd;
1229  int i;
1230 
1231  addr = exit_ipv6addr;
1232  GNUNET_assert (ipv6prefix < 128);
1233  if (ipv6prefix == 127)
1234  {
1235  /* only one valid IP anyway */
1236  local_address->address.ipv6 = addr;
1237  return;
1238  }
1239  /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
1240  thus: */
1241  mask = addr;
1242  for (i = 127; i >= ipv6prefix; i--)
1243  mask.s6_addr[i / 8] |= (1 << (i % 8));
1244 
1245  /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */
1246  do
1247  {
1248  for (i = 0; i < 16; i++)
1249  {
1250  rnd.s6_addr[i] = (unsigned char) GNUNET_CRYPTO_random_u32 (
1252  256);
1253  local_address->address.ipv6.s6_addr[i]
1254  = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
1255  }
1256  }
1257  while ((0 == GNUNET_memcmp (&local_address->address.ipv6,
1258  &addr)) ||
1259  (0 == GNUNET_memcmp (&local_address->address.ipv6,
1260  &mask)));
1261  }
1262  break;
1263 
1264  default:
1265  GNUNET_assert (0);
1266  }
1267 }
1268 
1269 
1291 static void
1293 {
1294  struct GNUNET_HashCode key;
1295  struct ChannelState *s;
1296 
1297  /* generate fresh, unique address */
1298  do
1299  {
1300  if (NULL == state->specifics.tcp_udp.serv)
1301  setup_fresh_address (state->specifics.tcp_udp.ri.remote_address.af,
1302  state->specifics.tcp_udp.ri.remote_address.proto,
1303  &state->specifics.tcp_udp.ri.local_address);
1304  else
1305  setup_fresh_address (state->specifics.tcp_udp.serv->address.af,
1306  state->specifics.tcp_udp.serv->address.proto,
1307  &state->specifics.tcp_udp.ri.local_address);
1308  }
1309  while (NULL !=
1310  get_redirect_state (state->specifics.tcp_udp.ri.remote_address.af,
1311  state->specifics.tcp_udp.ri.remote_address.proto,
1312  &state->specifics.tcp_udp.ri.remote_address.address,
1313  state->specifics.tcp_udp.ri.remote_address.port,
1314  &state->specifics.tcp_udp.ri.local_address.address,
1315  state->specifics.tcp_udp.ri.local_address.port,
1316  &key));
1317  {
1318  char buf[INET6_ADDRSTRLEN];
1320  "Picked local address %s:%u for new connection\n",
1321  inet_ntop (state->specifics.tcp_udp.ri.local_address.af,
1322  &state->specifics.tcp_udp.ri.local_address.address,
1323  buf,
1324  sizeof(buf)),
1325  (unsigned int) state->specifics.tcp_udp.ri.local_address.port);
1326  }
1327  state->specifics.tcp_udp.state_key = key;
1330  &key, state,
1332  state->specifics.tcp_udp.heap_node
1334  state,
1335  GNUNET_TIME_absolute_get ().abs_value_us);
1337  {
1339  GNUNET_assert (state != s);
1340  s->specifics.tcp_udp.heap_node = NULL;
1344  &s->specifics.tcp_udp.
1345  state_key,
1346  s));
1347  GNUNET_free (s);
1348  }
1349 }
1350 
1351 
1360 static void
1361 send_udp_packet_via_tun (const struct SocketAddress *destination_address,
1362  const struct SocketAddress *source_address,
1363  const void *payload, size_t payload_length)
1364 {
1365  size_t len;
1366 
1368  gettext_noop ("# UDP packets sent via TUN"),
1369  1, GNUNET_NO);
1371  "Sending packet with %u bytes UDP payload via TUN\n",
1372  (unsigned int) payload_length);
1373  len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct
1375  switch (source_address->af)
1376  {
1377  case AF_INET:
1378  len += sizeof(struct GNUNET_TUN_IPv4Header);
1379  break;
1380 
1381  case AF_INET6:
1382  len += sizeof(struct GNUNET_TUN_IPv6Header);
1383  break;
1384 
1385  default:
1386  GNUNET_break (0);
1387  return;
1388  }
1389  len += sizeof(struct GNUNET_TUN_UdpHeader);
1390  len += payload_length;
1392  {
1393  GNUNET_break (0);
1394  return;
1395  }
1396  {
1397  char buf[len] GNUNET_ALIGN;
1398  struct GNUNET_MessageHeader *hdr;
1399  struct GNUNET_TUN_Layer2PacketHeader *tun;
1400 
1401  hdr = (struct GNUNET_MessageHeader *) buf;
1402  hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1403  hdr->size = htons (len);
1404  tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1405  tun->flags = htons (0);
1406  switch (source_address->af)
1407  {
1408  case AF_INET:
1409  {
1410  struct GNUNET_TUN_IPv4Header *ipv4 = (struct
1411  GNUNET_TUN_IPv4Header*) &tun[1];
1412 
1413  tun->proto = htons (ETH_P_IPV4);
1415  payload_length,
1416  IPPROTO_UDP,
1417  NULL,
1420  ipv4);
1421  }
1422  break;
1423 
1424  case AF_INET6:
1425  {
1426  struct GNUNET_TUN_IPv6Header *ipv6 = (struct
1427  GNUNET_TUN_IPv6Header*) &tun[1];
1428 
1429  tun->proto = htons (ETH_P_IPV6);
1432  IPPROTO_UDP,
1433  NULL,
1436  ipv6);
1437  }
1438  break;
1439 
1440  default:
1441  GNUNET_assert (0);
1442  break;
1443  }
1444  if (NULL != helper_handle)
1446  (const struct GNUNET_MessageHeader*) buf,
1447  GNUNET_YES,
1448  NULL, NULL);
1449  }
1450 }
1451 
1452 
1461 static int
1462 check_udp_remote (void *cls,
1463  const struct GNUNET_EXIT_UdpInternetMessage *msg)
1464 {
1465  struct ChannelState *state = cls;
1466 
1467  if (GNUNET_YES == state->is_dns)
1468  {
1469  GNUNET_break_op (0);
1470  return GNUNET_SYSERR;
1471  }
1472  return GNUNET_OK;
1473 }
1474 
1475 
1482 static void
1484  const struct GNUNET_EXIT_UdpInternetMessage *msg)
1485 {
1486  struct ChannelState *state = cls;
1487  uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
1489  const struct in_addr *v4;
1490  const struct in6_addr *v6;
1491  const void *payload;
1492  int af;
1493 
1494  if (GNUNET_SYSERR == state->is_dns)
1495  {
1496  /* channel is UDP/TCP from now on */
1497  state->is_dns = GNUNET_NO;
1498  }
1500  gettext_noop ("# Bytes received from CADET"),
1501  pkt_len, GNUNET_NO);
1503  gettext_noop (
1504  "# UDP IP-exit requests received via cadet"),
1505  1, GNUNET_NO);
1506  af = (int) ntohl (msg->af);
1507  state->specifics.tcp_udp.ri.remote_address.af = af;
1508  switch (af)
1509  {
1510  case AF_INET:
1511  if (pkt_len < sizeof(struct in_addr))
1512  {
1513  GNUNET_break_op (0);
1514  return;
1515  }
1516  if (! ipv4_exit)
1517  {
1518  GNUNET_break_op (0);
1519  return;
1520  }
1521  v4 = (const struct in_addr*) &msg[1];
1522  payload = &v4[1];
1523  pkt_len -= sizeof(struct in_addr);
1524  state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
1525  break;
1526 
1527  case AF_INET6:
1528  if (pkt_len < sizeof(struct in6_addr))
1529  {
1530  GNUNET_break_op (0);
1531  return;
1532  }
1533  if (! ipv6_exit)
1534  {
1535  GNUNET_break_op (0);
1536  return;
1537  }
1538  v6 = (const struct in6_addr*) &msg[1];
1539  payload = &v6[1];
1540  pkt_len -= sizeof(struct in6_addr);
1541  state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
1542  break;
1543 
1544  default:
1545  GNUNET_break_op (0);
1546  return;
1547  }
1548  {
1549  char buf[INET6_ADDRSTRLEN];
1551  "Received data from %s for forwarding to UDP %s:%u\n",
1552  GNUNET_i2s (&state->peer),
1553  inet_ntop (af,
1554  &state->specifics.tcp_udp.ri.remote_address.address,
1555  buf, sizeof(buf)),
1556  (unsigned int) ntohs (msg->destination_port));
1557  }
1558  state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_UDP;
1559  state->specifics.tcp_udp.ri.remote_address.port = msg->destination_port;
1560  if (NULL == state->specifics.tcp_udp.heap_node)
1562  if (0 != ntohs (msg->source_port))
1563  state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
1564  send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1565  &state->specifics.tcp_udp.ri.local_address,
1566  payload,
1567  pkt_len);
1568  GNUNET_CADET_receive_done (state->channel);
1569 }
1570 
1571 
1581 static int
1583  const struct GNUNET_EXIT_UdpServiceMessage *msg)
1584 {
1585  struct ChannelState *state = cls;
1586 
1587  if (NULL == state->specifics.tcp_udp.serv)
1588  {
1589  GNUNET_break_op (0);
1590  return GNUNET_SYSERR;
1591  }
1592  return GNUNET_OK;
1593 }
1594 
1595 
1603 static void
1605  const struct GNUNET_EXIT_UdpServiceMessage *msg)
1606 {
1607  struct ChannelState *state = cls;
1608  uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
1610 
1612  gettext_noop ("# Bytes received from CADET"),
1613  pkt_len, GNUNET_NO);
1615  gettext_noop (
1616  "# UDP service requests received via cadet"),
1617  1, GNUNET_NO);
1619  "Received data from %s for forwarding to UDP service %s on port %u\n",
1620  GNUNET_i2s (&state->peer),
1621  GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor),
1622  (unsigned int) ntohs (msg->destination_port));
1624  if (0 != ntohs (msg->source_port))
1625  state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
1626  send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1627  &state->specifics.tcp_udp.ri.local_address,
1628  &msg[1],
1629  pkt_len);
1630  GNUNET_CADET_receive_done (state->channel);
1631 }
1632 
1633 
1643 static void
1646 {
1647  struct ChannelState *state = cls;
1648  uint16_t pkt_len = ntohs (start->header.size) - sizeof(struct
1650 
1651  if (GNUNET_SYSERR == state->is_dns)
1652  {
1653  /* channel is UDP/TCP from now on */
1654  state->is_dns = GNUNET_NO;
1655  }
1657  gettext_noop (
1658  "# TCP service creation requests received via cadet"),
1659  1,
1660  GNUNET_NO);
1662  gettext_noop ("# Bytes received from CADET"),
1663  pkt_len,
1664  GNUNET_NO);
1665  GNUNET_break_op (ntohl (start->reserved) == 0);
1666  /* setup fresh connection */
1668  "Received data from %s for forwarding to TCP service %s on port %u\n",
1669  GNUNET_i2s (&state->peer),
1670  GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor),
1671  (unsigned int) ntohs (start->tcp_header.destination_port));
1673  send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1674  &state->specifics.tcp_udp.ri.local_address,
1675  &start->tcp_header,
1676  &start[1],
1677  pkt_len);
1678  GNUNET_CADET_receive_done (state->channel);
1679 }
1680 
1681 
1690 static int
1691 check_tcp_remote (void *cls,
1693 {
1694  struct ChannelState *state = cls;
1695 
1696  if (NULL == state)
1697  {
1698  GNUNET_break_op (0);
1699  return GNUNET_SYSERR;
1700  }
1701  if (GNUNET_YES == state->is_dns)
1702  {
1703  GNUNET_break_op (0);
1704  return GNUNET_SYSERR;
1705  }
1706  if ((NULL != state->specifics.tcp_udp.serv) ||
1707  (NULL != state->specifics.tcp_udp.heap_node))
1708  {
1709  GNUNET_break_op (0);
1710  return GNUNET_SYSERR;
1711  }
1712  if (start->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1713  {
1714  GNUNET_break_op (0);
1715  return GNUNET_SYSERR;
1716  }
1717  return GNUNET_OK;
1718 }
1719 
1720 
1727 static void
1730 {
1731  struct ChannelState *state = cls;
1732  uint16_t pkt_len = ntohs (start->header.size) - sizeof(struct
1734  const struct in_addr *v4;
1735  const struct in6_addr *v6;
1736  const void *payload;
1737  int af;
1738 
1739  if (GNUNET_SYSERR == state->is_dns)
1740  {
1741  /* channel is UDP/TCP from now on */
1742  state->is_dns = GNUNET_NO;
1743  }
1745  gettext_noop ("# Bytes received from CADET"),
1746  pkt_len, GNUNET_NO);
1748  gettext_noop (
1749  "# TCP IP-exit creation requests received via cadet"),
1750  1, GNUNET_NO);
1751  af = (int) ntohl (start->af);
1752  state->specifics.tcp_udp.ri.remote_address.af = af;
1753  switch (af)
1754  {
1755  case AF_INET:
1756  if (pkt_len < sizeof(struct in_addr))
1757  {
1758  GNUNET_break_op (0);
1759  return;
1760  }
1761  if (! ipv4_exit)
1762  {
1763  GNUNET_break_op (0);
1764  return;
1765  }
1766  v4 = (const struct in_addr*) &start[1];
1767  payload = &v4[1];
1768  pkt_len -= sizeof(struct in_addr);
1769  state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
1770  break;
1771 
1772  case AF_INET6:
1773  if (pkt_len < sizeof(struct in6_addr))
1774  {
1775  GNUNET_break_op (0);
1776  return;
1777  }
1778  if (! ipv6_exit)
1779  {
1780  GNUNET_break_op (0);
1781  return;
1782  }
1783  v6 = (const struct in6_addr*) &start[1];
1784  payload = &v6[1];
1785  pkt_len -= sizeof(struct in6_addr);
1786  state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
1787  break;
1788 
1789  default:
1790  GNUNET_break_op (0);
1791  return;
1792  }
1793  {
1794  char buf[INET6_ADDRSTRLEN];
1796  "Received payload from %s for existing TCP stream to %s:%u\n",
1797  GNUNET_i2s (&state->peer),
1798  inet_ntop (af,
1799  &state->specifics.tcp_udp.ri.remote_address.address,
1800  buf, sizeof(buf)),
1801  (unsigned int) ntohs (start->tcp_header.destination_port));
1802  }
1803  state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_TCP;
1804  state->specifics.tcp_udp.ri.remote_address.port = ntohs (
1805  start->tcp_header.destination_port);
1807  send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1808  &state->specifics.tcp_udp.ri.local_address,
1809  &start->tcp_header,
1810  payload,
1811  pkt_len);
1812  GNUNET_CADET_receive_done (state->channel);
1813 }
1814 
1815 
1825 static int
1826 check_tcp_data (void *cls,
1827  const struct GNUNET_EXIT_TcpDataMessage *data)
1828 {
1829  struct ChannelState *state = cls;
1830 
1831  if ((NULL == state) ||
1832  (NULL == state->specifics.tcp_udp.heap_node))
1833  {
1834  /* connection should have been up! */
1836  gettext_noop (
1837  "# TCP DATA requests dropped (no session)"),
1838  1, GNUNET_NO);
1839  GNUNET_break_op (0);
1840  return GNUNET_SYSERR;
1841  }
1842  if (data->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1843  {
1844  GNUNET_break_op (0);
1845  return GNUNET_SYSERR;
1846  }
1847  if (GNUNET_YES == state->is_dns)
1848  {
1849  GNUNET_break_op (0);
1850  return GNUNET_SYSERR;
1851  }
1852  return GNUNET_OK;
1853 }
1854 
1855 
1863 static void
1864 handle_tcp_data (void *cls,
1865  const struct GNUNET_EXIT_TcpDataMessage *data)
1866 {
1867  struct ChannelState *state = cls;
1868  uint16_t pkt_len = ntohs (data->header.size) - sizeof(struct
1870 
1872  gettext_noop ("# Bytes received from CADET"),
1873  pkt_len, GNUNET_NO);
1875  gettext_noop (
1876  "# TCP data requests received via cadet"),
1877  1, GNUNET_NO);
1878  if (GNUNET_SYSERR == state->is_dns)
1879  {
1880  /* channel is UDP/TCP from now on */
1881  state->is_dns = GNUNET_NO;
1882  }
1883 
1884  GNUNET_break_op (ntohl (data->reserved) == 0);
1885  {
1886  char buf[INET6_ADDRSTRLEN];
1888  "Received additional %u bytes of data from %s for TCP stream to %s:%u\n",
1889  pkt_len,
1890  GNUNET_i2s (&state->peer),
1891  inet_ntop (state->specifics.tcp_udp.ri.remote_address.af,
1892  &state->specifics.tcp_udp.ri.remote_address.address,
1893  buf, sizeof(buf)),
1894  (unsigned int) state->specifics.tcp_udp.ri.remote_address.port);
1895  }
1896 
1897  send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1898  &state->specifics.tcp_udp.ri.local_address,
1899  &data->tcp_header,
1900  &data[1], pkt_len);
1901  GNUNET_CADET_receive_done (state->channel);
1902 }
1903 
1904 
1914 static void
1916  struct GNUNET_TUN_IPv4Header *ipp,
1917  struct GNUNET_TUN_UdpHeader *udp)
1918 {
1920  state->specifics.tcp_udp.ri.remote_address.
1921  proto,
1922  sizeof(struct GNUNET_TUN_TcpHeader),
1923  &state->specifics.tcp_udp.ri.remote_address
1924  .address.ipv4,
1925  &state->specifics.tcp_udp.ri.local_address.
1926  address.ipv4);
1927  udp->source_port = htons (state->specifics.tcp_udp.ri.remote_address.port);
1928  udp->destination_port = htons (
1929  state->specifics.tcp_udp.ri.local_address.port);
1930  udp->len = htons (0);
1931  udp->crc = htons (0);
1932 }
1933 
1934 
1944 static void
1946  struct GNUNET_TUN_IPv6Header *ipp,
1947  struct GNUNET_TUN_UdpHeader *udp)
1948 {
1950  state->specifics.tcp_udp.ri.remote_address.
1951  proto,
1952  sizeof(struct GNUNET_TUN_TcpHeader),
1953  &state->specifics.tcp_udp.ri.remote_address
1954  .address.ipv6,
1955  &state->specifics.tcp_udp.ri.local_address.
1956  address.ipv6);
1957  udp->source_port = htons (state->specifics.tcp_udp.ri.remote_address.port);
1958  udp->destination_port = htons (
1959  state->specifics.tcp_udp.ri.local_address.port);
1960  udp->len = htons (0);
1961  udp->crc = htons (0);
1962 }
1963 
1964 
1973 static int
1975  const struct GNUNET_EXIT_IcmpInternetMessage *msg)
1976 {
1977  struct ChannelState *state = cls;
1978 
1979  if (GNUNET_YES == state->is_dns)
1980  {
1981  GNUNET_break_op (0);
1982  return GNUNET_SYSERR;
1983  }
1984  return GNUNET_OK;
1985 }
1986 
1987 
1994 static void
1996  const struct GNUNET_EXIT_IcmpInternetMessage *msg)
1997 {
1998  struct ChannelState *state = cls;
1999  uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
2001  const struct in_addr *v4;
2002  const struct in6_addr *v6;
2003  const void *payload;
2004  char buf[sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
2005  int af;
2006 
2007  if (GNUNET_SYSERR == state->is_dns)
2008  {
2009  /* channel is UDP/TCP from now on */
2010  state->is_dns = GNUNET_NO;
2011  }
2013  gettext_noop ("# Bytes received from CADET"),
2014  pkt_len, GNUNET_NO);
2016  gettext_noop (
2017  "# ICMP IP-exit requests received via cadet"),
2018  1, GNUNET_NO);
2019 
2020  af = (int) ntohl (msg->af);
2021  if ((NULL != state->specifics.tcp_udp.heap_node) &&
2022  (af != state->specifics.tcp_udp.ri.remote_address.af))
2023  {
2024  /* other peer switched AF on this channel; not allowed */
2025  GNUNET_break_op (0);
2026  return;
2027  }
2028 
2029  switch (af)
2030  {
2031  case AF_INET:
2032  if (pkt_len < sizeof(struct in_addr))
2033  {
2034  GNUNET_break_op (0);
2035  return;
2036  }
2037  if (! ipv4_exit)
2038  {
2039  GNUNET_break_op (0);
2040  return;
2041  }
2042  v4 = (const struct in_addr*) &msg[1];
2043  payload = &v4[1];
2044  pkt_len -= sizeof(struct in_addr);
2045  state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
2046  if (NULL == state->specifics.tcp_udp.heap_node)
2047  {
2048  state->specifics.tcp_udp.ri.remote_address.af = af;
2049  state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMP;
2051  }
2052  /* check that ICMP type is something we want to support
2053  and possibly make up payload! */
2054  switch (msg->icmp_header.type)
2055  {
2058  break;
2059 
2063  if (0 != pkt_len)
2064  {
2065  GNUNET_break_op (0);
2066  return;
2067  }
2068  /* make up payload */
2069  {
2070  struct GNUNET_TUN_IPv4Header *ipp = (struct
2072  struct GNUNET_TUN_UdpHeader *udp = (struct
2073  GNUNET_TUN_UdpHeader *) &ipp[1];
2074 
2075  GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2076  pkt_len = sizeof(struct GNUNET_TUN_IPv4Header) + 8;
2078  ipp,
2079  udp);
2080  payload = ipp;
2081  }
2082  break;
2083 
2084  default:
2085  GNUNET_break_op (0);
2087  gettext_noop (
2088  "# ICMPv4 packets dropped (type not allowed)"),
2089  1, GNUNET_NO);
2090  return;
2091  }
2092  /* end AF_INET */
2093  break;
2094 
2095  case AF_INET6:
2096  if (pkt_len < sizeof(struct in6_addr))
2097  {
2098  GNUNET_break_op (0);
2099  return;
2100  }
2101  if (! ipv6_exit)
2102  {
2103  GNUNET_break_op (0);
2104  return;
2105  }
2106  v6 = (const struct in6_addr*) &msg[1];
2107  payload = &v6[1];
2108  pkt_len -= sizeof(struct in6_addr);
2109  state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
2110  if (NULL == state->specifics.tcp_udp.heap_node)
2111  {
2112  state->specifics.tcp_udp.ri.remote_address.af = af;
2113  state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMPV6;
2115  }
2116  /* check that ICMP type is something we want to support
2117  and possibly make up payload! */
2118  switch (msg->icmp_header.type)
2119  {
2122  break;
2123 
2128  if (0 != pkt_len)
2129  {
2130  GNUNET_break_op (0);
2131  return;
2132  }
2133  /* make up payload */
2134  {
2135  struct GNUNET_TUN_IPv6Header *ipp = (struct
2137  struct GNUNET_TUN_UdpHeader *udp = (struct
2138  GNUNET_TUN_UdpHeader *) &ipp[1];
2139 
2140  GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2141  pkt_len = sizeof(struct GNUNET_TUN_IPv6Header) + 8;
2143  ipp,
2144  udp);
2145  payload = ipp;
2146  }
2147  break;
2148 
2149  default:
2150  GNUNET_break_op (0);
2152  gettext_noop (
2153  "# ICMPv6 packets dropped (type not allowed)"),
2154  1, GNUNET_NO);
2155  return;
2156  }
2157  /* end AF_INET6 */
2158  break;
2159 
2160  default:
2161  /* bad AF */
2162  GNUNET_break_op (0);
2163  return;
2164  }
2165 
2166  {
2167  char buf[INET6_ADDRSTRLEN];
2169  "Received ICMP data from %s for forwarding to %s\n",
2170  GNUNET_i2s (&state->peer),
2171  inet_ntop (af,
2172  &state->specifics.tcp_udp.ri.remote_address.address,
2173  buf, sizeof(buf)));
2174  }
2175  send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2176  &state->specifics.tcp_udp.ri.local_address,
2177  &msg->icmp_header,
2178  payload, pkt_len);
2179  GNUNET_CADET_receive_done (state->channel);
2180 }
2181 
2182 
2192 static uint16_t
2194  char *buf)
2195 {
2196  switch (state->specifics.tcp_udp.serv->address.af)
2197  {
2198  case AF_INET:
2199  {
2200  struct GNUNET_TUN_IPv4Header *ipv4;
2201  struct GNUNET_TUN_UdpHeader *udp;
2202 
2203  ipv4 = (struct GNUNET_TUN_IPv4Header *) buf;
2204  udp = (struct GNUNET_TUN_UdpHeader *) &ipv4[1];
2206  ipv4,
2207  udp);
2208  GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2209  return sizeof(struct GNUNET_TUN_IPv4Header) + 8;
2210  }
2211  break;
2212 
2213  case AF_INET6:
2214  {
2215  struct GNUNET_TUN_IPv6Header *ipv6;
2216  struct GNUNET_TUN_UdpHeader *udp;
2217 
2218  ipv6 = (struct GNUNET_TUN_IPv6Header *) buf;
2219  udp = (struct GNUNET_TUN_UdpHeader *) &ipv6[1];
2221  ipv6,
2222  udp);
2223  GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2224  return sizeof(struct GNUNET_TUN_IPv6Header) + 8;
2225  }
2226  break;
2227 
2228  default:
2229  GNUNET_break (0);
2230  }
2231  return 0;
2232 }
2233 
2234 
2244 static int
2246  const struct GNUNET_EXIT_IcmpServiceMessage *msg)
2247 {
2248  struct ChannelState *state = cls;
2249 
2250  if (GNUNET_YES == state->is_dns)
2251  {
2252  GNUNET_break_op (0);
2253  return GNUNET_SYSERR;
2254  }
2255  if (NULL == state->specifics.tcp_udp.serv)
2256  {
2257  GNUNET_break_op (0);
2258  return GNUNET_SYSERR;
2259  }
2260  return GNUNET_OK;
2261 }
2262 
2263 
2271 static void
2273  const struct GNUNET_EXIT_IcmpServiceMessage *msg)
2274 {
2275  struct ChannelState *state = cls;
2276  uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
2278  struct GNUNET_TUN_IcmpHeader icmp;
2279  char buf[sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
2280  const void *payload;
2281 
2283  gettext_noop ("# Bytes received from CADET"),
2284  pkt_len, GNUNET_NO);
2286  gettext_noop (
2287  "# ICMP service requests received via cadet"),
2288  1, GNUNET_NO);
2289  /* check that we got at least a valid header */
2291  "Received data from %s for forwarding to ICMP service %s\n",
2292  GNUNET_i2s (&state->peer),
2293  GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor));
2294  icmp = msg->icmp_header;
2295  payload = &msg[1];
2296  state->specifics.tcp_udp.ri.remote_address
2297  = state->specifics.tcp_udp.serv->address;
2299 
2300  /* check that ICMP type is something we want to support,
2301  perform ICMP PT if needed and possibly make up payload */
2302  switch (msg->af)
2303  {
2304  case AF_INET:
2305  switch (msg->icmp_header.type)
2306  {
2308  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2310  break;
2311 
2313  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2315  break;
2316 
2318  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2320  if (0 != pkt_len)
2321  {
2322  GNUNET_break_op (0);
2323  return;
2324  }
2325  payload = buf;
2326  pkt_len = make_up_icmp_service_payload (state, buf);
2327  break;
2328 
2330  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2332  if (0 != pkt_len)
2333  {
2334  GNUNET_break_op (0);
2335  return;
2336  }
2337  payload = buf;
2338  pkt_len = make_up_icmp_service_payload (state, buf);
2339  break;
2340 
2342  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2343  {
2345  gettext_noop (
2346  "# ICMPv4 packets dropped (impossible PT to v6)"),
2347  1, GNUNET_NO);
2348  return;
2349  }
2350  if (0 != pkt_len)
2351  {
2352  GNUNET_break_op (0);
2353  return;
2354  }
2355  payload = buf;
2356  pkt_len = make_up_icmp_service_payload (state, buf);
2357  break;
2358 
2359  default:
2360  GNUNET_break_op (0);
2362  gettext_noop (
2363  "# ICMPv4 packets dropped (type not allowed)"),
2364  1, GNUNET_NO);
2365  return;
2366  }
2367  /* end of AF_INET */
2368  break;
2369 
2370  case AF_INET6:
2371  switch (msg->icmp_header.type)
2372  {
2374  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2376  break;
2377 
2379  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2381  break;
2382 
2384  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2386  if (0 != pkt_len)
2387  {
2388  GNUNET_break_op (0);
2389  return;
2390  }
2391  payload = buf;
2392  pkt_len = make_up_icmp_service_payload (state, buf);
2393  break;
2394 
2396  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2398  if (0 != pkt_len)
2399  {
2400  GNUNET_break_op (0);
2401  return;
2402  }
2403  payload = buf;
2404  pkt_len = make_up_icmp_service_payload (state, buf);
2405  break;
2406 
2409  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2410  {
2412  gettext_noop (
2413  "# ICMPv6 packets dropped (impossible PT to v4)"),
2414  1, GNUNET_NO);
2415  return;
2416  }
2417  if (0 != pkt_len)
2418  {
2419  GNUNET_break_op (0);
2420  return;
2421  }
2422  payload = buf;
2423  pkt_len = make_up_icmp_service_payload (state, buf);
2424  break;
2425 
2426  default:
2427  GNUNET_break_op (0);
2429  gettext_noop (
2430  "# ICMPv6 packets dropped (type not allowed)"),
2431  1, GNUNET_NO);
2432  return;
2433  }
2434  /* end of AF_INET6 */
2435  break;
2436 
2437  default:
2438  GNUNET_break_op (0);
2439  return;
2440  }
2441 
2442  send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2443  &state->specifics.tcp_udp.ri.local_address,
2444  &icmp,
2445  payload,
2446  pkt_len);
2447  GNUNET_CADET_receive_done (state->channel);
2448 }
2449 
2450 
2459 static int
2461  const struct GNUNET_HashCode *key,
2462  void *value)
2463 {
2464  struct LocalService *service = value;
2465 
2468  key,
2469  service));
2471  GNUNET_free (service->name);
2472  GNUNET_free (service);
2473  return GNUNET_OK;
2474 }
2475 
2476 
2485 static void *
2487  struct GNUNET_CADET_Channel *channel,
2488  const struct GNUNET_PeerIdentity *initiator)
2489 {
2490  struct LocalService *ls = cls;
2491  struct ChannelState *s = GNUNET_new (struct ChannelState);
2492 
2493  s->peer = *initiator;
2495  gettext_noop ("# Inbound CADET channels created"),
2496  1,
2497  GNUNET_NO);
2499  "Received inbound channel from `%s'\n",
2500  GNUNET_i2s (initiator));
2501  s->channel = channel;
2502  s->specifics.tcp_udp.serv = ls;
2503  s->specifics.tcp_udp.ri.remote_address = ls->address;
2504  return s;
2505 }
2506 
2507 
2515 static void
2516 clean_channel (void *cls,
2517  const struct GNUNET_CADET_Channel *channel)
2518 {
2519  struct ChannelState *s = cls;
2520 
2522  "Channel destroyed\n");
2523  if (GNUNET_SYSERR == s->is_dns)
2524  {
2525  GNUNET_free (s);
2526  return;
2527  }
2528  if (GNUNET_YES == s->is_dns)
2529  {
2530  if (channels[s->specifics.dns.my_id] == s)
2531  channels[s->specifics.dns.my_id] = NULL;
2532  }
2533  else
2534  {
2535  if (NULL != s->specifics.tcp_udp.heap_node)
2536  {
2539  &s->specifics.tcp_udp
2540  .state_key,
2541  s));
2543  s->specifics.tcp_udp.heap_node = NULL;
2544  }
2545  }
2546  GNUNET_free (s);
2547 }
2548 
2549 
2559 static void
2561  const char *name,
2562  uint16_t destination_port,
2563  struct LocalService *service)
2564 {
2565  struct GNUNET_MQ_MessageHandler handlers[] = {
2566  GNUNET_MQ_hd_var_size (icmp_service,
2569  service),
2570  GNUNET_MQ_hd_var_size (udp_service,
2573  service),
2574  GNUNET_MQ_hd_var_size (tcp_service,
2577  service),
2578  GNUNET_MQ_hd_var_size (tcp_data,
2581  service),
2583  };
2584 
2585  struct GNUNET_HashCode cadet_port;
2586 
2587  service->name = GNUNET_strdup (name);
2589  &service->descriptor);
2591  destination_port,
2592  &cadet_port);
2594  "Opening CADET port %s for SERVICE exit %s on port %u\n",
2596  name,
2597  (unsigned int) destination_port);
2599  &cadet_port,
2601  service,
2602  NULL,
2603  &clean_channel,
2604  handlers);
2605  service->is_udp = (IPPROTO_UDP == proto);
2606  if (GNUNET_OK !=
2608  &cadet_port,
2609  service,
2611  {
2613  GNUNET_free (service->name);
2614  GNUNET_free (service);
2616  _ ("Got duplicate service records for `%s:%u'\n"),
2617  name,
2618  (unsigned int) destination_port);
2619  }
2620 }
2621 
2622 
2629 static void
2631  struct GNUNET_MQ_Envelope *env)
2632 {
2633  GNUNET_assert (NULL != s);
2635  gettext_noop (
2636  "# Messages transmitted via cadet channels"),
2637  1,
2638  GNUNET_NO);
2640  env);
2641 }
2642 
2643 
2655 static void
2657  size_t pktlen,
2658  int af,
2659  const void *destination_ip,
2660  const void *source_ip)
2661 {
2662  struct ChannelState *state;
2663  struct GNUNET_MQ_Envelope *env;
2664  struct GNUNET_EXIT_IcmpToVPNMessage *i2v;
2665  const struct GNUNET_TUN_IPv4Header *ipv4;
2666  const struct GNUNET_TUN_IPv6Header *ipv6;
2667  const struct GNUNET_TUN_UdpHeader *udp;
2668  uint16_t source_port;
2669  uint16_t destination_port;
2670  uint8_t protocol;
2671 
2672  {
2673  char sbuf[INET6_ADDRSTRLEN];
2674  char dbuf[INET6_ADDRSTRLEN];
2676  "Received ICMP packet going from %s to %s\n",
2677  inet_ntop (af,
2678  source_ip,
2679  sbuf, sizeof(sbuf)),
2680  inet_ntop (af,
2681  destination_ip,
2682  dbuf, sizeof(dbuf)));
2683  }
2684 
2685  if (pktlen < sizeof(struct GNUNET_TUN_IcmpHeader))
2686  {
2687  /* blame kernel */
2688  GNUNET_break (0);
2689  return;
2690  }
2691 
2692  /* Find out if this is an ICMP packet in response to an existing
2693  TCP/UDP packet and if so, figure out ports / protocol of the
2694  existing session from the IP data in the ICMP payload */
2695  source_port = 0;
2696  destination_port = 0;
2697  switch (af)
2698  {
2699  case AF_INET:
2700  protocol = IPPROTO_ICMP;
2701  switch (icmp->type)
2702  {
2705  break;
2706 
2710  if (pktlen <
2711  sizeof(struct GNUNET_TUN_IcmpHeader)
2712  + sizeof(struct GNUNET_TUN_IPv4Header) + 8)
2713  {
2714  /* blame kernel */
2715  GNUNET_break (0);
2716  return;
2717  }
2718  ipv4 = (const struct GNUNET_TUN_IPv4Header *) &icmp[1];
2719  protocol = ipv4->protocol;
2720  /* could be TCP or UDP, but both have the ports in the right
2721  place, so that doesn't matter here */
2722  udp = (const struct GNUNET_TUN_UdpHeader *) &ipv4[1];
2723  /* swap ports, as they are from the original message */
2724  destination_port = ntohs (udp->source_port);
2725  source_port = ntohs (udp->destination_port);
2726  /* throw away ICMP payload, won't be useful for the other side anyway */
2727  pktlen = sizeof(struct GNUNET_TUN_IcmpHeader);
2728  break;
2729 
2730  default:
2732  gettext_noop (
2733  "# ICMPv4 packets dropped (type not allowed)"),
2734  1, GNUNET_NO);
2735  return;
2736  }
2737  break;
2738 
2739  case AF_INET6:
2740  protocol = IPPROTO_ICMPV6;
2741  switch (icmp->type)
2742  {
2747  if (pktlen <
2748  sizeof(struct GNUNET_TUN_IcmpHeader)
2749  + sizeof(struct GNUNET_TUN_IPv6Header) + 8)
2750  {
2751  /* blame kernel */
2752  GNUNET_break (0);
2753  return;
2754  }
2755  ipv6 = (const struct GNUNET_TUN_IPv6Header *) &icmp[1];
2756  protocol = ipv6->next_header;
2757  /* could be TCP or UDP, but both have the ports in the right
2758  place, so that doesn't matter here */
2759  udp = (const struct GNUNET_TUN_UdpHeader *) &ipv6[1];
2760  /* swap ports, as they are from the original message */
2761  destination_port = ntohs (udp->source_port);
2762  source_port = ntohs (udp->destination_port);
2763  /* throw away ICMP payload, won't be useful for the other side anyway */
2764  pktlen = sizeof(struct GNUNET_TUN_IcmpHeader);
2765  break;
2766 
2769  break;
2770 
2771  default:
2773  gettext_noop (
2774  "# ICMPv6 packets dropped (type not allowed)"),
2775  1, GNUNET_NO);
2776  return;
2777  }
2778  break;
2779 
2780  default:
2781  GNUNET_assert (0);
2782  }
2783  switch (protocol)
2784  {
2785  case IPPROTO_ICMP:
2786  state = get_redirect_state (af,
2787  IPPROTO_ICMP,
2788  source_ip,
2789  0,
2790  destination_ip,
2791  0,
2792  NULL);
2793  break;
2794 
2795  case IPPROTO_ICMPV6:
2796  state = get_redirect_state (af,
2797  IPPROTO_ICMPV6,
2798  source_ip,
2799  0,
2800  destination_ip,
2801  0,
2802  NULL);
2803  break;
2804 
2805  case IPPROTO_UDP:
2806  state = get_redirect_state (af,
2807  IPPROTO_UDP,
2808  source_ip,
2809  source_port,
2810  destination_ip,
2811  destination_port,
2812  NULL);
2813  break;
2814 
2815  case IPPROTO_TCP:
2816  state = get_redirect_state (af,
2817  IPPROTO_TCP,
2818  source_ip,
2819  source_port,
2820  destination_ip,
2821  destination_port,
2822  NULL);
2823  break;
2824 
2825  default:
2827  gettext_noop (
2828  "# ICMP packets dropped (not allowed)"),
2829  1,
2830  GNUNET_NO);
2831  return;
2832  }
2833  if (NULL == state)
2834  {
2836  _ (
2837  "ICMP Packet dropped, have no matching connection information\n"));
2838  return;
2839  }
2840  env = GNUNET_MQ_msg_extra (i2v,
2841  pktlen - sizeof(struct GNUNET_TUN_IcmpHeader),
2843  i2v->af = htonl (af);
2844  GNUNET_memcpy (&i2v->icmp_header,
2845  icmp,
2846  pktlen);
2848  env);
2849 }
2850 
2851 
2863 static void
2865  size_t pktlen,
2866  int af,
2867  const void *destination_ip,
2868  const void *source_ip)
2869 {
2870  struct ChannelState *state;
2871  struct GNUNET_MQ_Envelope *env;
2872  struct GNUNET_EXIT_UdpReplyMessage *urm;
2873 
2874  {
2875  char sbuf[INET6_ADDRSTRLEN];
2876  char dbuf[INET6_ADDRSTRLEN];
2877 
2879  "Received UDP packet going from %s:%u to %s:%u\n",
2880  inet_ntop (af,
2881  source_ip,
2882  sbuf, sizeof(sbuf)),
2883  (unsigned int) ntohs (udp->source_port),
2884  inet_ntop (af,
2885  destination_ip,
2886  dbuf, sizeof(dbuf)),
2887  (unsigned int) ntohs (udp->destination_port));
2888  }
2889 
2890  if (pktlen < sizeof(struct GNUNET_TUN_UdpHeader))
2891  {
2892  /* blame kernel */
2893  GNUNET_break (0);
2894  return;
2895  }
2896  if (pktlen != ntohs (udp->len))
2897  {
2898  /* blame kernel */
2899  GNUNET_break (0);
2900  return;
2901  }
2902  state = get_redirect_state (af,
2903  IPPROTO_UDP,
2904  source_ip,
2905  ntohs (udp->source_port),
2906  destination_ip,
2907  ntohs (udp->destination_port),
2908  NULL);
2909  if (NULL == state)
2910  {
2912  _ (
2913  "UDP Packet dropped, have no matching connection information\n"));
2914  return;
2915  }
2916  env = GNUNET_MQ_msg_extra (urm,
2917  pktlen - sizeof(struct GNUNET_TUN_UdpHeader),
2919  urm->source_port = htons (0);
2920  urm->destination_port = htons (0);
2921  GNUNET_memcpy (&urm[1],
2922  &udp[1],
2923  pktlen - sizeof(struct GNUNET_TUN_UdpHeader));
2925  env);
2926 }
2927 
2928 
2940 static void
2942  size_t pktlen,
2943  int af,
2944  const void *destination_ip,
2945  const void *source_ip)
2946 {
2947  struct ChannelState *state;
2948  char buf[pktlen] GNUNET_ALIGN;
2949  struct GNUNET_TUN_TcpHeader *mtcp;
2950  struct GNUNET_EXIT_TcpDataMessage *tdm;
2951  struct GNUNET_MQ_Envelope *env;
2952  size_t mlen;
2953 
2954  {
2955  char sbuf[INET6_ADDRSTRLEN];
2956  char dbuf[INET6_ADDRSTRLEN];
2958  "Received TCP packet with %u bytes going from %s:%u to %s:%u\n",
2959  (unsigned int) (pktlen - sizeof(struct GNUNET_TUN_TcpHeader)),
2960  inet_ntop (af,
2961  source_ip,
2962  sbuf, sizeof(sbuf)),
2963  (unsigned int) ntohs (tcp->source_port),
2964  inet_ntop (af,
2965  destination_ip,
2966  dbuf, sizeof(dbuf)),
2967  (unsigned int) ntohs (tcp->destination_port));
2968  }
2969 
2970  if (pktlen < sizeof(struct GNUNET_TUN_TcpHeader))
2971  {
2972  /* blame kernel */
2973  GNUNET_break (0);
2974  return;
2975  }
2976  state = get_redirect_state (af,
2977  IPPROTO_TCP,
2978  source_ip,
2979  ntohs (tcp->source_port),
2980  destination_ip,
2981  ntohs (tcp->destination_port),
2982  NULL);
2983  if (NULL == state)
2984  {
2986  _ (
2987  "TCP Packet dropped, have no matching connection information\n"));
2988 
2989  return;
2990  }
2991  /* mug port numbers and crc to avoid information leakage;
2992  sender will need to lookup the correct values anyway */
2993  GNUNET_memcpy (buf, tcp, pktlen);
2994  mtcp = (struct GNUNET_TUN_TcpHeader *) buf;
2995  mtcp->source_port = 0;
2996  mtcp->destination_port = 0;
2997  mtcp->crc = 0;
2998 
2999  mlen = sizeof(struct GNUNET_EXIT_TcpDataMessage) + (pktlen - sizeof(struct
3001  if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
3002  {
3003  GNUNET_break (0);
3004  return;
3005  }
3006  env = GNUNET_MQ_msg_extra (tdm,
3007  pktlen - sizeof(struct GNUNET_TUN_TcpHeader),
3009  tdm->reserved = htonl (0);
3010  GNUNET_memcpy (&tdm->tcp_header,
3011  buf,
3012  pktlen);
3014  env);
3015 }
3016 
3017 
3024 static int
3026  const struct GNUNET_MessageHeader *message)
3027 {
3028  const struct GNUNET_TUN_Layer2PacketHeader *pkt_tun;
3029  size_t size;
3030 
3032  "Got %u-byte message of type %u from gnunet-helper-exit\n",
3033  ntohs (message->size),
3034  ntohs (message->type));
3036  gettext_noop ("# Packets received from TUN"),
3037  1, GNUNET_NO);
3038  if (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER)
3039  {
3040  GNUNET_break (0);
3041  return GNUNET_OK;
3042  }
3043  size = ntohs (message->size);
3044  if (size < sizeof(struct GNUNET_TUN_Layer2PacketHeader) + sizeof(struct
3046  {
3047  GNUNET_break (0);
3048  return GNUNET_OK;
3049  }
3051  gettext_noop ("# Bytes received from TUN"),
3052  size, GNUNET_NO);
3053  pkt_tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1];
3054  size -= sizeof(struct GNUNET_TUN_Layer2PacketHeader) + sizeof(struct
3056  switch (ntohs (pkt_tun->proto))
3057  {
3058  case ETH_P_IPV4:
3059  {
3060  const struct GNUNET_TUN_IPv4Header *pkt4;
3061 
3062  if (size < sizeof(struct GNUNET_TUN_IPv4Header))
3063  {
3064  /* Kernel to blame? */
3065  GNUNET_break (0);
3066  return GNUNET_OK;
3067  }
3068  pkt4 = (const struct GNUNET_TUN_IPv4Header *) &pkt_tun[1];
3069  if (size != ntohs (pkt4->total_length))
3070  {
3071  /* Kernel to blame? */
3072  GNUNET_break (0);
3073  return GNUNET_OK;
3074  }
3075  if (pkt4->header_length * 4 != sizeof(struct GNUNET_TUN_IPv4Header))
3076  {
3078  _ ("IPv4 packet options received. Ignored.\n"));
3079  return GNUNET_OK;
3080  }
3081 
3082  size -= sizeof(struct GNUNET_TUN_IPv4Header);
3083  switch (pkt4->protocol)
3084  {
3085  case IPPROTO_UDP:
3086  udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt4[1], size,
3087  AF_INET,
3088  &pkt4->destination_address,
3089  &pkt4->source_address);
3090  break;
3091 
3092  case IPPROTO_TCP:
3093  tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt4[1], size,
3094  AF_INET,
3095  &pkt4->destination_address,
3096  &pkt4->source_address);
3097  break;
3098 
3099  case IPPROTO_ICMP:
3100  icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt4[1], size,
3101  AF_INET,
3102  &pkt4->destination_address,
3103  &pkt4->source_address);
3104  break;
3105 
3106  default:
3108  _ (
3109  "IPv4 packet with unsupported next header %u received. Ignored.\n"),
3110  (int) pkt4->protocol);
3111  return GNUNET_OK;
3112  }
3113  }
3114  break;
3115 
3116  case ETH_P_IPV6:
3117  {
3118  const struct GNUNET_TUN_IPv6Header *pkt6;
3119 
3120  if (size < sizeof(struct GNUNET_TUN_IPv6Header))
3121  {
3122  /* Kernel to blame? */
3123  GNUNET_break (0);
3124  return GNUNET_OK;
3125  }
3126  pkt6 = (struct GNUNET_TUN_IPv6Header *) &pkt_tun[1];
3127  if (size != ntohs (pkt6->payload_length) + sizeof(struct
3129  {
3130  /* Kernel to blame? */
3131  GNUNET_break (0);
3132  return GNUNET_OK;
3133  }
3134  size -= sizeof(struct GNUNET_TUN_IPv6Header);
3135  switch (pkt6->next_header)
3136  {
3137  case IPPROTO_UDP:
3138  udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt6[1], size,
3139  AF_INET6,
3140  &pkt6->destination_address,
3141  &pkt6->source_address);
3142  break;
3143 
3144  case IPPROTO_TCP:
3145  tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt6[1], size,
3146  AF_INET6,
3147  &pkt6->destination_address,
3148  &pkt6->source_address);
3149  break;
3150 
3151  case IPPROTO_ICMPV6:
3152  icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt6[1], size,
3153  AF_INET6,
3154  &pkt6->destination_address,
3155  &pkt6->source_address);
3156  break;
3157 
3158  default:
3160  _ (
3161  "IPv6 packet with unsupported next header %d received. Ignored.\n"),
3162  pkt6->next_header);
3163  return GNUNET_OK;
3164  }
3165  }
3166  break;
3167 
3168  default:
3170  _ ("Packet from unknown protocol %u received. Ignored.\n"),
3171  ntohs (pkt_tun->proto));
3172  break;
3173  }
3174  return GNUNET_OK;
3175 }
3176 
3177 
3186 static void *
3187 new_channel (void *cls,
3188  struct GNUNET_CADET_Channel *channel,
3189  const struct GNUNET_PeerIdentity *initiator)
3190 {
3191  struct ChannelState *s = GNUNET_new (struct ChannelState);
3192 
3193  s->is_dns = GNUNET_SYSERR;
3194  s->peer = *initiator;
3196  gettext_noop ("# Inbound CADET channels created"),
3197  1,
3198  GNUNET_NO);
3200  "Received inbound channel from `%s'\n",
3201  GNUNET_i2s (initiator));
3202  s->channel = channel;
3203  return s;
3204 }
3205 
3206 
3214 static int
3215 free_iterate (void *cls,
3216  const struct GNUNET_HashCode *hash,
3217  void *value)
3218 {
3219  GNUNET_free (value);
3220  return GNUNET_YES;
3221 }
3222 
3223 
3232 static void
3233 dummy_task (void *cls)
3234 {
3235  /* just terminate */
3236 }
3237 
3238 
3244 static void
3245 cleanup (void *cls)
3246 {
3247  unsigned int i;
3248 
3250  "Exit service is shutting down now\n");
3251 
3252  if (NULL != helper_handle)
3253  {
3255  helper_handle = NULL;
3256  }
3257  if (NULL != regex4)
3258  {
3260  regex4 = NULL;
3261  }
3262  if (NULL != regex6)
3263  {
3265  regex6 = NULL;
3266  }
3267  if (NULL != services)
3268  {
3271  NULL);
3273  }
3274  if (NULL != dns_port)
3275  {
3277  dns_port = NULL;
3278  }
3279  if (NULL != cadet_port4)
3280  {
3282  cadet_port4 = NULL;
3283  }
3284  if (NULL != cadet_port6)
3285  {
3287  cadet_port6 = NULL;
3288  }
3289  if (NULL != cadet_handle)
3290  {
3292  cadet_handle = NULL;
3293  }
3294  if (NULL != connections_map)
3295  {
3297  &free_iterate,
3298  NULL);
3300  connections_map = NULL;
3301  }
3302  if (NULL != connections_heap)
3303  {
3305  connections_heap = NULL;
3306  }
3307  if (NULL != dnsstub)
3308  {
3310  dnsstub = NULL;
3311  }
3312  if (NULL != peer_key)
3313  {
3315  peer_key = NULL;
3316  }
3317  if (NULL != dht_task)
3318  {
3320  dht_task = NULL;
3321  }
3322  if (NULL != dht_put)
3323  {
3325  dht_put = NULL;
3326  }
3327  if (NULL != dht)
3328  {
3330  dht = NULL;
3331  }
3332  if (NULL != stats)
3333  {
3335  GNUNET_NO);
3336  stats = NULL;
3337  }
3338  for (i = 0; i < 8; i++)
3339  GNUNET_free (exit_argv[i]);
3340 }
3341 
3342 
3350 static void
3352  char *cpy,
3353  const char *name)
3354 {
3355  char *redirect;
3356  char *hostname;
3357  char *hostport;
3358  struct LocalService *serv;
3359  char *n;
3360  size_t slen;
3361 
3362  slen = strlen (name);
3363  GNUNET_assert (slen >= 8);
3364  n = GNUNET_strndup (name, slen - 8 /* remove .gnunet. */);
3365 
3366  for (redirect = strtok (cpy, " ;"); redirect != NULL;
3367  redirect = strtok (NULL, " ;"))
3368  {
3369  if (NULL == (hostname = strstr (redirect, ":")))
3370  {
3372  _ (
3373  "Option `%s' for domain `%s' is not formatted correctly!\n"),
3374  redirect,
3375  name);
3376  continue;
3377  }
3378  hostname[0] = '\0';
3379  hostname++;
3380  if (NULL == (hostport = strstr (hostname, ":")))
3381  {
3383  _ (
3384  "Option `%s' for domain `%s' is not formatted correctly!\n"),
3385  redirect,
3386  name);
3387  continue;
3388  }
3389  hostport[0] = '\0';
3390  hostport++;
3391 
3392  int local_port = atoi (redirect);
3393  int remote_port = atoi (hostport);
3394 
3395  if (! ((local_port > 0) && (local_port < 65536)))
3396  {
3398  _ ("`%s' is not a valid port number (for domain `%s')!"),
3399  redirect,
3400  name);
3401  continue;
3402  }
3403  if (! ((remote_port > 0) && (remote_port < 65536)))
3404  {
3406  _ ("`%s' is not a valid port number (for domain `%s')!"),
3407  hostport,
3408  name);
3409  continue;
3410  }
3411 
3412  serv = GNUNET_new (struct LocalService);
3413  serv->address.proto = proto;
3414  serv->address.port = remote_port;
3415  if (0 == strcmp ("localhost4",
3416  hostname))
3417  {
3418  const char *ip4addr = exit_argv[5];
3419 
3420  serv->address.af = AF_INET;
3421  GNUNET_assert (1 == inet_pton (AF_INET,
3422  ip4addr,
3423  &serv->address.address.ipv4));
3424  }
3425  else if (0 == strcmp ("localhost6",
3426  hostname))
3427  {
3428  const char *ip6addr = exit_argv[3];
3429 
3430  serv->address.af = AF_INET6;
3431  GNUNET_assert (1 == inet_pton (AF_INET6,
3432  ip6addr,
3433  &serv->address.address.ipv6));
3434  }
3435  else
3436  {
3437  struct addrinfo *res;
3438  int ret;
3439 
3440  ret = getaddrinfo (hostname,
3441  NULL,
3442  NULL,
3443  &res);
3444  if ((0 != ret) || (NULL == res))
3445  {
3447  _ (
3448  "No addresses found for hostname `%s' of service `%s'!\n"),
3449  hostname,
3450  n);
3451  GNUNET_free (serv);
3452  continue;
3453  }
3454 
3455  serv->address.af = res->ai_family;
3456  switch (res->ai_family)
3457  {
3458  case AF_INET:
3459  if (! ipv4_enabled)
3460  {
3462  _ (
3463  "Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
3464  n);
3465  freeaddrinfo (res);
3466  GNUNET_free (serv);
3467  continue;
3468  }
3469  serv->address.address.ipv4
3470  = ((struct sockaddr_in *) res->ai_addr)->sin_addr;
3471  break;
3472 
3473  case AF_INET6:
3474  if (! ipv6_enabled)
3475  {
3477  _ (
3478  "Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
3479  n);
3480  freeaddrinfo (res);
3481  GNUNET_free (serv);
3482  continue;
3483  }
3484  serv->address.address.ipv6
3485  = ((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
3486  break;
3487 
3488  default:
3489  freeaddrinfo (res);
3491  _ (
3492  "No IP addresses found for hostname `%s' of service `%s'!\n"),
3493  hostname,
3494  n);
3495  GNUNET_free (serv);
3496  continue;
3497  }
3498  freeaddrinfo (res);
3499  }
3501  n,
3502  local_port,
3503  serv);
3504  }
3505  GNUNET_free (n);
3506 }
3507 
3508 
3515 static void
3517  const char *section)
3518 {
3519  char *cpy;
3520 
3521  if ((strlen (section) < 8) ||
3522  (0 != strcmp (".gnunet.", section + (strlen (section) - 8))))
3523  return;
3524  if (GNUNET_OK ==
3526  section,
3527  "UDP_REDIRECTS",
3528  &cpy))
3529  {
3530  add_services (IPPROTO_UDP,
3531  cpy,
3532  section);
3533  GNUNET_free (cpy);
3534  }
3535  if (GNUNET_OK ==
3537  section,
3538  "TCP_REDIRECTS",
3539  &cpy))
3540  {
3541  add_services (IPPROTO_TCP,
3542  cpy,
3543  section);
3544  GNUNET_free (cpy);
3545  }
3546 }
3547 
3548 
3555 static void
3556 do_dht_put (void *cls);
3557 
3558 
3565 static void
3566 dht_put_cont (void *cls)
3567 {
3568  dht_put = NULL;
3569 }
3570 
3571 
3578 static void
3579 do_dht_put (void *cls)
3580 {
3582 
3584  &do_dht_put,
3585  NULL);
3587  if (GNUNET_TIME_absolute_get_remaining (expiration).rel_value_us <
3588  GNUNET_TIME_UNIT_HOURS.rel_value_us)
3589  {
3590  /* refresh advertisement */
3597  }
3598  if (NULL != dht_put)
3601  &dht_put_key,
3602  1 /* replication */,
3605  sizeof(struct GNUNET_DNS_Advertisement),
3607  expiration,
3608  &dht_put_cont,
3609  NULL);
3610 }
3611 
3612 
3617 static void
3619 {
3621  "exit",
3622  "EXIT_IPV4");
3624  "exit",
3625  "EXIT_IPV6");
3627  "exit",
3628  "ENABLE_IPV4");
3630  "exit",
3631  "ENABLE_IPV6");
3632  if ((ipv4_exit || ipv4_enabled) &&
3633  (GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET)) )
3634  {
3636  _ (
3637  "This system does not support IPv4, will disable IPv4 functions despite them being enabled in the configuration\n"));
3638  ipv4_exit = GNUNET_NO;
3640  }
3641  if ((ipv6_exit || ipv6_enabled) &&
3642  (GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET6)) )
3643  {
3645  _ (
3646  "This system does not support IPv6, will disable IPv6 functions despite them being enabled in the configuration\n"));
3647  ipv6_exit = GNUNET_NO;
3649  }
3650  if (ipv4_exit && (! ipv4_enabled))
3651  {
3653  _ (
3654  "Cannot enable IPv4 exit but disable IPv4 on TUN interface, will use ENABLE_IPv4=YES\n"));
3656  }
3657  if (ipv6_exit && (! ipv6_enabled))
3658  {
3660  _ (
3661  "Cannot enable IPv6 exit but disable IPv6 on TUN interface, will use ENABLE_IPv6=YES\n"));
3663  }
3664 }
3665 
3666 
3671 static void
3673 {
3674  struct GNUNET_MQ_MessageHandler handlers[] = {
3675  GNUNET_MQ_hd_var_size (dns_request,
3677  struct DnsResponseMessage,
3678  NULL),
3680  };
3681  char *dns_exit;
3682  struct GNUNET_HashCode port;
3683 
3684  if (GNUNET_YES !=
3686  "exit",
3687  "EXIT_DNS"))
3688  return;
3689  GNUNET_assert (NULL != (dnsstub = GNUNET_DNSSTUB_start (128)));
3690  dns_exit = NULL;
3691  /* TODO: support using multiple DNS resolvers */
3692  if ((GNUNET_OK !=
3694  "exit",
3695  "DNS_RESOLVER",
3696  &dns_exit)) ||
3697  (GNUNET_OK !=
3699  dns_exit)))
3700  {
3702  "dns",
3703  "DNS_RESOLVER",
3704  _ ("need a valid IPv4 or IPv6 address\n"));
3705  GNUNET_free (dns_exit);
3706  return;
3707  }
3708  /* open port */
3711  &port);
3713  "Opening CADET port %s for DNS exit service\n",
3714  GNUNET_h2s (&port));
3716  &port,
3717  &new_channel,
3718  NULL,
3719  NULL,
3720  &clean_channel,
3721  handlers);
3722  /* advertise exit */
3724  1);
3728  dns_advertisement.purpose.size = htonl (sizeof(struct
3730  - sizeof(struct
3734  GNUNET_CRYPTO_hash ("dns",
3735  strlen ("dns"),
3736  &dht_put_key);
3738  NULL);
3739  GNUNET_free (dns_exit);
3740 }
3741 
3742 
3748 static int
3750 {
3751  char *exit_ifname;
3752  char *tun_ifname;
3753  char *ipv6addr;
3754  char *ipv6prefix_s;
3755  char *ipv4addr;
3756  char *ipv4mask;
3757 
3758  exit_argv[0] = GNUNET_strdup ("exit-gnunet");
3759  if (GNUNET_SYSERR ==
3761  "exit",
3762  "TUN_IFNAME",
3763  &tun_ifname))
3764  {
3766  "EXIT",
3767  "TUN_IFNAME");
3768  return GNUNET_SYSERR;
3769  }
3770  exit_argv[1] = tun_ifname;
3771  if (ipv4_enabled)
3772  {
3773  if (GNUNET_SYSERR ==
3775  "exit",
3776  "EXIT_IFNAME",
3777  &exit_ifname))
3778  {
3780  "EXIT",
3781  "EXIT_IFNAME");
3782  return GNUNET_SYSERR;
3783  }
3784  exit_argv[2] = exit_ifname;
3785  }
3786  else
3787  {
3788  exit_argv[2] = GNUNET_strdup ("-");
3789  }
3790 
3791  if (GNUNET_YES == ipv6_enabled)
3792  {
3793  ipv6addr = NULL;
3794  if (((GNUNET_SYSERR ==
3796  "exit",
3797  "IPV6ADDR",
3798  &ipv6addr)) ||
3799  (1 != inet_pton (AF_INET6,
3800  ipv6addr,
3801  &exit_ipv6addr))))
3802  {
3804  "EXIT",
3805  "IPV6ADDR");
3806  GNUNET_free (ipv6addr);
3807  return GNUNET_SYSERR;
3808  }
3809  exit_argv[3] = ipv6addr;
3810  if (GNUNET_SYSERR ==
3812  "exit",
3813  "IPV6PREFIX",
3814  &ipv6prefix_s))
3815  {
3817  "EXIT",
3818  "IPV6PREFIX");
3819  return GNUNET_SYSERR;
3820  }
3821  exit_argv[4] = ipv6prefix_s;
3822  if ((GNUNET_OK !=
3824  "exit",
3825  "IPV6PREFIX",
3826  &ipv6prefix)) ||
3827  (ipv6prefix >= 127))
3828  {
3830  "EXIT",
3831  "IPV6PREFIX",
3832  _ ("Must be a number"));
3833  return GNUNET_SYSERR;
3834  }
3835  }
3836  else
3837  {
3838  /* IPv6 explicitly disabled */
3839  exit_argv[3] = GNUNET_strdup ("-");
3840  exit_argv[4] = GNUNET_strdup ("-");
3841  }
3842  if (GNUNET_YES == ipv4_enabled)
3843  {
3844  ipv4addr = NULL;
3845  if (((GNUNET_SYSERR ==
3847  "exit",
3848  "IPV4ADDR",
3849  &ipv4addr)) ||
3850  (1 != inet_pton (AF_INET,
3851  ipv4addr,
3852  &exit_ipv4addr))))
3853  {
3855  "EXIT",
3856  "IPV4ADDR");
3857  GNUNET_free (ipv4addr);
3858  return GNUNET_SYSERR;
3859  }
3860  exit_argv[5] = ipv4addr;
3861  ipv4mask = NULL;
3862  if (((GNUNET_SYSERR ==
3864  "exit",
3865  "IPV4MASK",
3866  &ipv4mask)) ||
3867  (1 != inet_pton (AF_INET,
3868  ipv4mask,
3869  &exit_ipv4mask))))
3870  {
3872  "EXIT",
3873  "IPV4MASK");
3874  GNUNET_free (ipv4mask);
3875  return GNUNET_SYSERR;
3876  }
3877  exit_argv[6] = ipv4mask;
3878  }
3879  else
3880  {
3881  /* IPv4 explicitly disabled */
3882  exit_argv[5] = GNUNET_strdup ("-");
3883  exit_argv[6] = GNUNET_strdup ("-");
3884  }
3885  exit_argv[7] = NULL;
3886  return GNUNET_OK;
3887 }
3888 
3889 
3898 static void
3899 run (void *cls,
3900  char *const *args,
3901  const char *cfgfile,
3902  const struct GNUNET_CONFIGURATION_Handle *cfg_)
3903 {
3904  struct GNUNET_MQ_MessageHandler handlers[] = {
3905  GNUNET_MQ_hd_var_size (icmp_remote,
3908  NULL),
3909  GNUNET_MQ_hd_var_size (udp_remote,
3912  NULL),
3913  GNUNET_MQ_hd_var_size (tcp_remote,
3916  NULL),
3917  GNUNET_MQ_hd_var_size (tcp_data,
3920  NULL),
3922  };
3923  struct GNUNET_HashCode port;
3924  char *policy;
3925  char *binary;
3926  char *regex;
3927  char *prefixed_regex;
3928 
3929  cfg = cfg_;
3930  if (GNUNET_OK !=
3932  "exit",
3933  "MAX_CONNECTIONS",
3934  &max_connections))
3935  max_connections = 1024;
3936  parse_ip_options ();
3937  binary = GNUNET_OS_get_suid_binary_path (cfg, "gnunet-helper-exit");
3938  if ((ipv4_exit) || (ipv6_exit))
3939  {
3940  if (GNUNET_YES !=
3942  GNUNET_YES,
3943  "gnunet-vpn - - - 169.1.3.7 255.255.255.0")) // no nat, ipv4 only
3944  {
3945  GNUNET_free (binary);
3947  _ (
3948  "`%s' is not SUID or the path is invalid, EXIT will not work\n"),
3949  "gnunet-helper-exit");
3951  NULL);
3952  global_ret = 1;
3953  return;
3954  }
3955  }
3956  if (! (ipv4_enabled || ipv6_enabled))
3957  {
3958  GNUNET_free (binary);
3960  _ ("No useful service enabled. Exiting.\n"));
3962  return;
3963  }
3964 
3966  NULL);
3967  stats = GNUNET_STATISTICS_create ("exit",
3968  cfg);
3970  if (NULL == cadet_handle)
3971  {
3972  GNUNET_free (binary);
3974  return;
3975  }
3976  advertise_dns_exit ();
3977  if (GNUNET_OK !=
3979  {
3980  GNUNET_free (binary);
3982  return;
3983  }
3984 
3986  GNUNET_NO);
3988  GNUNET_NO);
3993  NULL);
3994 
3995  /* Cadet handle acquired, now open ports and announce regular
3996  expressions matching our exit */
3997  if ((GNUNET_YES == ipv4_enabled) &&
3998  (GNUNET_YES == ipv4_exit))
3999  {
4002  &port);
4004  "Opening CADET port %s for IPv4 gateway service\n",
4005  GNUNET_h2s (&port));
4007  &port,
4008  &new_channel,
4009  NULL,
4010  NULL,
4011  &clean_channel,
4012  handlers);
4013  policy = NULL;
4014  if (GNUNET_OK !=
4016  "exit",
4017  "EXIT_RANGE_IPV4_POLICY",
4018  &policy))
4019  regex = NULL;
4020  else
4021  regex = GNUNET_TUN_ipv4policy2regex (policy);
4022  GNUNET_free (policy);
4023  if (NULL != regex)
4024  {
4025  (void) GNUNET_asprintf (&prefixed_regex,
4026  "%s%s",
4028  regex);
4030  prefixed_regex,
4033  GNUNET_free (regex);
4034  GNUNET_free (prefixed_regex);
4035  }
4036  }
4037 
4038  if ((GNUNET_YES == ipv6_enabled) && (GNUNET_YES == ipv6_exit))
4039  {
4042  &port);
4044  "Opening CADET port %s for IPv6 gateway service\n",
4045  GNUNET_h2s (&port));
4047  &port,
4048  &new_channel,
4049  NULL,
4050  NULL,
4051  &clean_channel,
4052  handlers);
4053  policy = NULL;
4054  if (GNUNET_OK !=
4056  "exit",
4057  "EXIT_RANGE_IPV6_POLICY",
4058  &policy))
4059  regex = NULL;
4060  else
4061  regex = GNUNET_TUN_ipv6policy2regex (policy);
4062  GNUNET_free (policy);
4063  if (NULL != regex)
4064  {
4065  (void) GNUNET_asprintf (&prefixed_regex,
4066  "%s%s",
4068  regex);
4070  prefixed_regex,
4073  GNUNET_free (regex);
4074  GNUNET_free (prefixed_regex);
4075  }
4076  }
4078  binary,
4079  exit_argv,
4080  &message_token,
4081  NULL,
4082  NULL);
4083  GNUNET_free (binary);
4084 }
4085 
4086 
4094 int
4095 main (int argc,
4096  char *const *argv)
4097 {
4098  static const struct GNUNET_GETOPT_CommandLineOption options[] = {
4100  };
4101 
4102  if (GNUNET_OK !=
4104  argv,
4105  &argc,
4106  &argv))
4107  return 2;
4108 
4109  return (GNUNET_OK ==
4110  GNUNET_PROGRAM_run (argc,
4111  argv,
4112  "gnunet-daemon-exit",
4113  gettext_noop (
4114  "Daemon to run to provide an IP exit node for the VPN"),
4115  options,
4116  &run,
4117  NULL)) ? global_ret : 1;
4118 }
4119 
4120 
4121 /* end of gnunet-daemon-exit.c */
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
DNS network structs.
@ GNUNET_BLOCK_TYPE_DNS
Block for storing DNS exit service advertisements.
#define GNUNET_SIGNATURE_PURPOSE_DNS_RECORD
Signature on a GNUNET_DNS_Advertisement.
format for cadet messages exchanged between VPN service and exit daemon
#define gettext_noop(String)
Definition: gettext.h:70
static char * expiration
Credential TTL.
Definition: gnunet-abd.c:96
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
static int res
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
static char * address
GNS address for this phone.
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.
static int check_dns_request(void *cls, const struct DnsResponseMessage *msg)
Check a request via cadet to perform a DNS query.
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.
static struct GNUNET_DHT_Handle * dht
Handle to the DHT.
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.
static int ipv6_enabled
Do we support IPv6 at all on the TUN interface?
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.
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.
static void clean_channel(void *cls, const struct GNUNET_CADET_Channel *channel)
Function called by cadet whenever an inbound channel is destroyed.
static struct GNUNET_REGEX_Announcement * regex4
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.
static int ipv4_enabled
Do we support IPv4 at all on the TUN interface?
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.
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 struct GNUNET_CONTAINER_MultiHashMap * services
This hashmaps saves interesting things about the configured services.
#define REGEX_MAX_PATH_LEN_IPV4
Maximum path compression length for cadet regex announcing for IPv4 address based regex.
#define DNS_ADVERTISEMENT_TIMEOUT
How long do we typically sign the DNS exit advertisement for?
static struct ChannelState * channels[UINT16_MAX+1]
Array of all open DNS requests from channels.
static unsigned long long ipv6prefix
IPv6 prefix (0..127) from configuration file.
#define REGEX_REFRESH_FREQUENCY
How frequently do we re-announce the regex for the exit?
static struct in6_addr exit_ipv6addr
IPv6 address of our TUN interface.
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.
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).
static unsigned long long max_connections
If there are at least this many connections, old ones will be removed.
static int global_ret
Return value from 'main'.
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.
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.
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
static int setup_exit_helper_args()
Initialize exit_argv.
static const struct GNUNET_CONFIGURATION_Handle * cfg
The handle to the configuration used throughout the process.
static struct GNUNET_DNS_Advertisement dns_advertisement
Advertisement message we put into the DHT to advertise us as a DNS exit.
static void cleanup(void *cls)
Function scheduled as very last function, cleans up after us.
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.
static struct GNUNET_DNSSTUB_Context * dnsstub
Handle to the DNS Stub resolver.
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 dht_put_cont(void *cls)
Function called when the DHT PUT operation is complete.
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 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.
static struct GNUNET_CONTAINER_MultiHashMap * connections_map
This hashmaps contains the mapping from peer, service-descriptor, source-port and destination-port to...
static int ipv6_exit
Are we an IPv6-exit?
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.
static void add_services(int proto, char *cpy, const char *name)
Add services to the service map.
static struct GNUNET_CONTAINER_Heap * connections_heap
Heap so we can quickly find "old" connections.
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.
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.
static struct GNUNET_DHT_PutHandle * dht_put
Handle for ongoing DHT PUT operations to advertise exit service.
#define REGEX_MAX_PATH_LEN_IPV6
Maximum path compression length for cadet regex announcing for IPv6 address based regex.
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 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.
static uint16_t make_up_icmp_service_payload(struct ChannelState *state, char *buf)
Setup ICMP payload for ICMP error messages.
static struct GNUNET_REGEX_Announcement * regex6
Handle to our regex announcement for IPv4.
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.
static struct GNUNET_CADET_Handle * cadet_handle
The handle to cadet.
static void dummy_task(void *cls)
Function scheduled as very last function if the service disabled itself because the helper is not ins...
static void * new_channel(void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *initiator)
Callback from CADET for new channels.
static void do_dht_put(void *cls)
We are running a DNS exit service, advertise it in the DHT.
static int message_token(void *cls, const struct GNUNET_MessageHeader *message)
Receive packets from the helper-process.
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.
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.
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 char * exit_argv[8]
Arguments to the exit helper.
static void read_service_conf(void *cls, const char *section)
Reads the configuration and populates #udp_services and #tcp_services.
static struct GNUNET_CADET_Port * cadet_port4
Port for IPv4 exit.
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.
static struct in_addr exit_ipv4mask
IPv4 netmask of our TUN interface.
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 struct in_addr exit_ipv4addr
IPv4 address of our TUN interface.
static void * new_service_channel(void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *initiator)
Callback from CADET for new channels.
static int free_service_record(void *cls, const struct GNUNET_HashCode *key, void *value)
Free memory associated with a service record.
static struct GNUNET_HashCode dht_put_key
Key we store the DNS advertismenet under.
static struct GNUNET_CRYPTO_EddsaPrivateKey * peer_key
Private key for this peer.
#define LOG(kind,...)
Generic logging shorthand.
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.
int main(int argc, char *const *argv)
The main function.
#define DHT_PUT_FREQUENCY
How frequently do we re-announce the DNS exit in the DHT?
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.
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 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...
static struct GNUNET_CADET_Port * dns_port
Port for DNS exit.
static struct GNUNET_HELPER_Handle * helper_handle
The handle to the helper.
static int ipv4_exit
Are we an IPv4-exit?
static int free_iterate(void *cls, const struct GNUNET_HashCode *hash, void *value)
Function that frees everything from a hashmap.
static void advertise_dns_exit()
Helper function to open the CADET port for DNS exits and to advertise the DNS exit (if applicable).
static struct GNUNET_CADET_Port * cadet_port6
Port for IPv6 exit.
static struct GNUNET_SCHEDULER_Task * dht_task
Task for doing DHT PUTs to advertise exit service.
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.
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.
static void handle_dns_request(void *cls, const struct DnsResponseMessage *msg)
Process a request via cadet to perform a DNS query.
struct GNUNET_HashCode key
The key used in the DHT.
uint32_t data
The data value.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
static char * value
Value of the record to add/remove.
static struct GNUNET_NETWORK_Handle * ls
Listen socket for STUN processing.
Definition: gnunet-nat.c:85
static uint8_t proto
Protocol to use.
Definition: gnunet-nat.c:60
enum State state
current state of profiling
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static unsigned long long payload
How much data are we currently storing in the database?
static struct GNUNET_CADET_Port * cadet_port
Listen port for incoming requests.
static char * hostname
Our hostname; we give this to all the peers we start.
static char buf[2048]
static unsigned long long remote_port
Remote host's port.
static int ipv4
Option -4: IPv4 requested.
Definition: gnunet-vpn.c:60
static int udp
Option -u: UDP requested.
Definition: gnunet-vpn.c:75
static int ipv6
Option -6: IPv6 requested.
Definition: gnunet-vpn.c:65
static int tcp
Option -t: TCP requested.
Definition: gnunet-vpn.c:70
Constants for network applications operating on top of the CADET service.
CADET service; establish channels to distant peers.
API to the DHT service.
Constants for network protocols.
API to access regex service to advertise capabilities via regex and discover respective peers using m...
API to create, modify and access statistics.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
#define GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX
Internet exit regex prefix.
#define GNUNET_APPLICATION_PORT_INTERNET_RESOLVER
Internet DNS resolution (external DNS gateway).
#define GNUNET_APPLICATION_PORT_IPV4_GATEWAY
Internet IPv4 gateway (any TCP/UDP/ICMP).
#define GNUNET_APPLICATION_PORT_IPV6_GATEWAY
Internet IPv6 gateway (any TCP/UDP/ICMP).
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:872
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:830
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:774
void GNUNET_CADET_close_port(struct GNUNET_CADET_Port *p)
Close a port opened with GNUNET_CADET_open_port.
Definition: cadet_api.c:801
struct GNUNET_MQ_Handle * GNUNET_CADET_get_mq(const struct GNUNET_CADET_Channel *channel)
Obtain the message queue for a connected peer.
Definition: cadet_api.c:1066
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition: cadet_api.c:894
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 incoming MQ-based channels.
Definition: cadet_api.c:954
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
void GNUNET_CONFIGURATION_iterate_sections(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_CONFIGURATION_SectionIterator iter, void *iter_cls)
Iterate over all sections in the configuration.
enum GNUNET_GenericReturnValue 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".
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
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's key from the file specified in the configuration.
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:197
enum GNUNET_GenericReturnValue 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:619
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
void GNUNET_DHT_put_cancel(struct GNUNET_DHT_PutHandle *ph)
Cancels a DHT PUT operation.
Definition: dht_api.c:1148
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:1039
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:1090
void GNUNET_DHT_disconnect(struct GNUNET_DHT_Handle *handle)
Shutdown connection with the DHT service.
Definition: dht_api.c:1062
@ GNUNET_DHT_RO_NONE
Default.
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:613
void GNUNET_DNSSTUB_stop(struct GNUNET_DNSSTUB_Context *ctx)
Cleanup DNSSTUB resolver.
Definition: dnsstub.c:705
struct GNUNET_DNSSTUB_Context * GNUNET_DNSSTUB_start(unsigned int num_sockets)
Start a DNS stub resolver.
Definition: dnsstub.c:586
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:526
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
void * GNUNET_CONTAINER_heap_remove_root(struct GNUNET_CONTAINER_Heap *heap)
Remove root of the heap.
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
void GNUNET_CONTAINER_heap_update_cost(struct GNUNET_CONTAINER_HeapNode *node, GNUNET_CONTAINER_HeapCostType new_cost)
Updates the cost of any node in the tree.
struct GNUNET_CONTAINER_HeapNode * GNUNET_CONTAINER_heap_insert(struct GNUNET_CONTAINER_Heap *heap, void *element, GNUNET_CONTAINER_HeapCostType cost)
Inserts a new element into the heap.
unsigned int GNUNET_CONTAINER_heap_get_size(const struct GNUNET_CONTAINER_Heap *heap)
Get the current size of the heap.
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
void GNUNET_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.
@ GNUNET_CONTAINER_HEAP_ORDER_MIN
Heap with the minimum cost at the root.
struct GNUNET_HELPER_SendHandle * GNUNET_HELPER_send(struct GNUNET_HELPER_Handle *h, const struct GNUNET_MessageHeader *msg, int can_drop, GNUNET_HELPER_Continuation cont, void *cont_cls)
Send an message to the helper.
Definition: helper.c:614
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:461
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:537
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32.
#define GNUNET_log(kind,...)
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32;.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to 'struct's.
#define GNUNET_UNUSED
gcc-ism to document unused arguments
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
void GNUNET_log_config_invalid(enum GNUNET_ErrorType kind, const char *section, const char *option, const char *required)
Log error message about invalid configuration option value.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:304
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#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:62
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
enum GNUNET_GenericReturnValue GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition: network.c:79
char * GNUNET_OS_get_suid_binary_path(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *progname)
Given the name of a helper, service or daemon binary construct the full path to the binary using the ...
enum GNUNET_GenericReturnValue GNUNET_OS_check_helper_binary(const char *binary, bool check_suid, const char *params)
Check whether an executable exists and possibly if the suid bit is set on the file.
enum GNUNET_GenericReturnValue 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,...
Definition: program.c:400
#define GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY
Type of messages containing an UDP packet from a remote host.
#define GNUNET_MESSAGE_TYPE_VPN_HELPER
Type of messages between the gnunet-vpn-helper and the daemon.
#define GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT
Type of messages containing an TCP packet of an established connection.
#define GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE
Type of messages containing an ICMP packet for a service.
#define GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START
Type of messages containing an TCP packet for the Internet.
#define GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START
Type of messages containing an TCP packet for a service.
#define GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE
Type of messages containing an UDP packet for a service.
#define GNUNET_MESSAGE_TYPE_VPN_DNS_TO_INTERNET
Type of messages containing an DNS request for a DNS exit service.
#define GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET
Type of messages containing an DNS reply from a DNS exit service.
#define GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET
Type of messages containing an ICMP packet for the Internet.
#define GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN
Type of messages containing an TCP packet of an established connection.
#define GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET
Type of messages containing an UDP packet for the Internet.
#define GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN
Type of messages containing an ICMP packet for the VPN.
void GNUNET_REGEX_announce_cancel(struct GNUNET_REGEX_Announcement *a)
Stop announcing the regex specified by the given handle.
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.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:534
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:1268
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition: scheduler.c:1303
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:944
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:1241
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
enum GNUNET_GenericReturnValue GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1222
#define GNUNET_TIME_UNIT_HOURS
One hour.
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:405
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:737
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:316
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:638
void GNUNET_TUN_initialize_ipv6_header(struct GNUNET_TUN_IPv6Header *ip, uint8_t protocol, uint16_t payload_length, const struct in6_addr *src, const struct in6_addr *dst)
Initialize an IPv6 header.
Definition: tun.c:82
void GNUNET_TUN_calculate_udp4_checksum(const struct GNUNET_TUN_IPv4Header *ip, struct GNUNET_TUN_UdpHeader *udp, const void *payload, uint16_t payload_length)
Calculate IPv4 UDP checksum.
Definition: tun.c:160
GNUNET_NETWORK_STRUCT_END void GNUNET_TUN_initialize_ipv4_header(struct GNUNET_TUN_IPv4Header *ip, uint8_t protocol, uint16_t payload_length, const struct in_addr *src, const struct in_addr *dst)
Initialize an IPv4 header.
Definition: tun.c:47
#define GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM
void GNUNET_TUN_calculate_icmp_checksum(struct GNUNET_TUN_IcmpHeader *icmp, const void *payload, uint16_t payload_length)
Calculate ICMP checksum.
Definition: tun.c:222
#define GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST
#define GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED
#define GNUNET_TUN_ICMPTYPE6_ECHO_REPLY
#define ETH_P_IPV6
Number for IPv6.
char * GNUNET_TUN_ipv4policy2regex(const char *policy)
Convert an exit policy to a regular expression.
Definition: regex.c:682
void GNUNET_TUN_compute_service_cadet_port(const struct GNUNET_HashCode *desc, uint16_t ip_port, struct GNUNET_HashCode *cadet_port)
Compute the CADET port given a service descriptor (returned from GNUNET_TUN_service_name_to_hash) and...
Definition: regex.c:791
#define ETH_P_IPV4
Number for IPv4.
#define GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED
void GNUNET_TUN_calculate_tcp6_checksum(const struct GNUNET_TUN_IPv6Header *ip, struct GNUNET_TUN_TcpHeader *tcp, const void *payload, uint16_t payload_length)
Calculate IPv6 TCP checksum.
Definition: tun.c:132
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:772
#define GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE
#define GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH
void GNUNET_TUN_calculate_tcp4_checksum(const struct GNUNET_TUN_IPv4Header *ip, struct GNUNET_TUN_TcpHeader *tcp, const void *payload, uint16_t payload_length)
Calculate IPv4 TCP checksum.
Definition: tun.c:102
#define GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE
#define GNUNET_TUN_ICMPTYPE_ECHO_REQUEST
#define GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG
#define GNUNET_TUN_ICMPTYPE_ECHO_REPLY
char * GNUNET_TUN_ipv6policy2regex(const char *policy)
Convert an exit policy to a regular expression.
Definition: regex.c:725
void GNUNET_TUN_calculate_udp6_checksum(const struct GNUNET_TUN_IPv6Header *ip, struct GNUNET_TUN_UdpHeader *udp, const void *payload, uint16_t payload_length)
Calculate IPv6 UDP checksum.
Definition: tun.c:191
static unsigned int size
Size of the "table".
Definition: peer.c:68
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
const char * name
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
struct LocalService * serv
Associated service record, or NULL for no service.
uint16_t my_id
DNS request ID that we used for forwarding.
struct GNUNET_HashCode state_key
Key this state has in the connections_map.
union ChannelState::@10 specifics
struct GNUNET_DNSSTUB_RequestSocket * rs
Socket we are using to transmit this request (must match if we receive a response).
int af
Address family used for this channel on the local TUN interface.
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
union ChannelState::@77 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
struct GNUNET_PeerIdentity peer
Who is the other end of this channel.
int is_dns
GNUNET_NO if this is a channel for TCP/UDP, GNUNET_YES if this is a channel for DNS,...
struct GNUNET_CONTAINER_HeapNode * heap_node
Heap node for this state in the connections_heap.
uint8_t protocol
IPPROTO_TCP or IPPROTO_UDP once bound.
uint16_t destination_port
Destination port used by the sender on our end; 0 for uninitialized.
uint16_t original_id
Original DNS request ID as used by the client.
struct RedirectInformation ri
Primary redirection information for this connection.
struct ChannelState::@10::@11 tcp_udp
struct ChannelState::@10::@12 dns
Message with a DNS response.
struct GNUNET_MessageHeader header
GNUnet header, of type GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET.
struct GNUNET_TUN_DnsHeader dns
DNS header.
Opaque handle to a channel.
Definition: cadet.h:116
Opaque handle to the service.
Definition: cadet_api.c:39
Opaque handle to a port.
Definition: cadet_api.c:80
Handle to a node in a heap.
Internal representation of the hash map.
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!...
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
Private ECC key encoded for transmission.
an ECC signature using EdDSA.
Connection to the DHT service.
Definition: dht_api.c:237
Handle to a PUT request.
Definition: dht_api.c:45
Handle to the stub resolver.
Definition: dnsstub.c:125
UDP socket we are using for sending DNS requests to the Internet.
Definition: dnsstub.c:46
This is the structure describing an DNS exit service.
Definition: block_dns.h:45
struct GNUNET_PeerIdentity peer
The peer providing this service.
Definition: block_dns.h:65
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does this signature expire?
Definition: block_dns.h:60
struct GNUNET_CRYPTO_EddsaSignature signature
Signature of the peer affirming that it is offering the service.
Definition: block_dns.h:49
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Beginning of signed portion of the record, signs everything until the end of the struct.
Definition: block_dns.h:55
Message send via cadet to an exit daemon to forward ICMP data to the Internet.
Definition: exit.h:237
Message send via cadet to an exit daemon to send ICMP data to a local service.
Definition: exit.h:206
Message send via cadet to the vpn service to send ICMP data to the VPN's TUN interface.
Definition: exit.h:272
struct GNUNET_TUN_IcmpHeader icmp_header
ICMP header to use.
Definition: exit.h:287
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:282
Message send via cadet between VPN and entry and an exit daemon to transmit TCP data between the VPN ...
Definition: exit.h:95
uint32_t reserved
Always 0.
Definition: exit.h:104
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:110
Message send via cadet to an exit daemon to initiate forwarding of TCP data to the Internet.
Definition: exit.h:64
Message send via cadet to an exit daemon to initiate forwarding of TCP data to a local service.
Definition: exit.h:38
Message send via cadet to an exit daemon to forward UDP data to the Internet.
Definition: exit.h:146
Message send from exit daemon back to the UDP entry point (used for both Internet and Service exit re...
Definition: exit.h:179
uint16_t source_port
Source port to use for the UDP reply (0 to use the same port as for the original request).
Definition: exit.h:189
uint16_t destination_port
Destination port to use for the UDP reply (0 to use the same port as for the original request).
Definition: exit.h:195
Message send via cadet to an exit daemon to send UDP data to a local service.
Definition: exit.h:121
Definition of a command line option.
The handle to a helper process.
Definition: helper.c:78
A 512-bit hashcode.
Message handler for a specific message type.
Header for all communications.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
The identity of the host (wraps the signing key of the peer).
struct GNUNET_CRYPTO_EddsaPublicKey public_key
Handle to store cached data about a regex announce.
Entry in list of pending tasks.
Definition: scheduler.c:136
Handle for the service.
Time for absolute times used by GNUnet, in microseconds.
uint16_t id
Unique identifier for the request/response.
Standard IPv4 header.
uint16_t total_length
Length of the packet, including this header.
uint8_t protocol
L4-protocol, for example, IPPROTO_UDP or IPPROTO_TCP.
struct in_addr source_address
Origin of the packet.
struct in_addr destination_address
Destination of the packet.
unsigned int header_length
Standard IPv6 header.
struct in6_addr source_address
Origin of the packet.
uint8_t next_header
For example, IPPROTO_UDP or IPPROTO_TCP.
struct in6_addr destination_address
Destination of the packet.
uint16_t payload_length
Length of the payload, excluding this header.
Header from Linux TUN interface.
uint16_t proto
Here we get an ETH_P_-number.
uint16_t flags
Some flags (unused).
TCP packet header.
uint16_t source_port
Source port (in NBO).
uint16_t crc
Checksum.
uint16_t destination_port
Destination port (in NBO).
UDP packet header.
uint16_t len
Number of bytes of payload.
uint16_t destination_port
Destination port (in NBO).
uint16_t source_port
Source port (in NBO).
This struct is saved into the services-hashmap to represent a service this peer is specifically offer...
int16_t is_udp
GNUNET_YES if this is a UDP service, otherwise TCP.
struct GNUNET_CADET_Port * port
Open port with CADET.
struct SocketAddress address
Remote address to use for the service.
struct GNUNET_HashCode descriptor
Descriptor for the service (CADET port).
char * name
DNS name of the service.
Information we use to track a connection (the classical 6-tuple of IP-version, protocol,...
struct SocketAddress local_address
Address information we used locally (AF and proto must match "remote_address").
struct SocketAddress remote_address
Address information for the other party (equivalent of the arguments one would give to "connect").
Information about an address.
union SocketAddress::@9 address
Remote address information.
int af
AF_INET or AF_INET6.
uint8_t proto
IPPROTO_TCP or IPPROTO_UDP;.
struct in_addr ipv4
Address, if af is AF_INET.
uint16_t port
Remote port, in host byte order!
struct in6_addr ipv6
Address, if af is AF_INET6.