GNUnet 0.26.2-114-g7c6b613e3
 
Loading...
Searching...
No Matches
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, 2026 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 "gnunet_common.h"
38#include "gnunet_pils_service.h"
39#include "platform.h"
40#include "gnunet_util_lib.h"
41#include "gnunet_protocols.h"
42#include "gnunet_applications.h"
43#include "gnunet_dht_service.h"
46#include "gnunet_signatures.h"
48#include "exit.h"
49#include "block_dns.h"
50
51
56#define REGEX_MAX_PATH_LEN_IPV4 4
57
62#define REGEX_MAX_PATH_LEN_IPV6 8
63
67#define REGEX_REFRESH_FREQUENCY GNUNET_TIME_relative_multiply ( \
68 GNUNET_TIME_UNIT_MINUTES, 30)
69
73#define DHT_PUT_FREQUENCY GNUNET_TIME_relative_multiply ( \
74 GNUNET_TIME_UNIT_MINUTES, 15)
75
79#define DNS_ADVERTISEMENT_TIMEOUT GNUNET_TIME_relative_multiply ( \
80 GNUNET_TIME_UNIT_HOURS, 3)
81
82
86#define LOG(kind, ...) \
87 GNUNET_log_from (kind, "exit", __VA_ARGS__);
88
89
94{
98 int af;
99
103 union
104 {
108 struct in_addr ipv4;
109
113 struct in6_addr ipv6;
115
119 uint8_t proto;
120
124 uint16_t port;
125};
126
127
134{
139
144
148 char *name;
149
154
158 int16_t is_udp;
159};
160
161
168{
174
181
182 /*
183 Note 1: additional information might be added here in the
184 future to support protocols that require special handling,
185 such as ftp/tftp
186
187 Note 2: we might also sometimes not match on all components
188 of the tuple, to support protocols where things do not always
189 fully map.
190 */
191};
192
193
201{
206
212
219
220 union
221 {
222 struct
223 {
228
233
238
244
245 struct
246 {
252
256 uint16_t original_id;
257
261 uint16_t my_id;
264};
265
266
270static int global_ret;
271
276
281
285static const struct GNUNET_CONFIGURATION_Handle *cfg;
286
291
295static char *exit_argv[8];
296
300static struct in6_addr exit_ipv6addr;
301
305static unsigned long long ipv6prefix;
306
310static struct in_addr exit_ipv4addr;
311
315static struct in_addr exit_ipv4mask;
316
321
326
332
337
341static unsigned long long max_connections;
342
347
351static struct ChannelState *channels[UINT16_MAX + 1];
352
357
362
366static struct GNUNET_DHT_Handle *dht;
367
372
378
383
388
393
398
403
408
412static int ipv4_exit;
413
417static int ipv6_exit;
418
422static int ipv4_enabled;
423
427static int ipv6_enabled;
428
429
431
436{
441
446
447 /* Followed by more DNS payload */
448};
449
451
452
461static void
463 const struct GNUNET_TUN_DnsHeader *dns,
464 size_t r)
465{
466 struct ChannelState *ts;
467 struct GNUNET_MQ_Envelope *env;
468 struct DnsResponseMessage *resp;
469
471 "Processing DNS result from stub resolver\n");
472 GNUNET_assert (NULL == cls);
473 if (NULL == dns)
474 return;
475 /* Handle case that this is a reply to a request from a CADET DNS channel */
476 ts = channels[dns->id];
477 if (NULL == ts)
478 return;
480 "Got a response from the stub resolver for DNS request received via CADET!\n");
481 channels[dns->id] = NULL;
482 env = GNUNET_MQ_msg_extra (resp,
483 r - sizeof(struct GNUNET_TUN_DnsHeader),
485 GNUNET_memcpy (&resp->dns,
486 dns,
487 r);
488 resp->dns.id = ts->specifics.dns.original_id;
490 env);
491}
492
493
502static int
504 const struct DnsResponseMessage *msg)
505{
506 struct ChannelState *ts = cls;
507
508 if (NULL == dnsstub)
509 {
510 GNUNET_break (0);
511 return GNUNET_SYSERR;
512 }
513 if (GNUNET_NO == ts->is_dns)
514 {
515 GNUNET_break_op (0);
516 return GNUNET_SYSERR;
517 }
518 return GNUNET_OK;
519}
520
521
528static void
530 const struct DnsResponseMessage *msg)
531{
532 struct ChannelState *ts = cls;
533 size_t mlen = ntohs (msg->header.size);
534 size_t dlen = mlen - sizeof(struct GNUNET_MessageHeader);
535 char buf[dlen] GNUNET_ALIGN;
536 struct GNUNET_TUN_DnsHeader *dns_out;
537
538 if (GNUNET_SYSERR == ts->is_dns)
539 {
540 /* channel is DNS from now on */
541 ts->is_dns = GNUNET_YES;
542 }
543 ts->specifics.dns.original_id = msg->dns.id;
544 if (channels[ts->specifics.dns.my_id] == ts)
545 channels[ts->specifics.dns.my_id] = NULL;
548 UINT16_MAX
549 + 1);
550 channels[ts->specifics.dns.my_id] = ts;
551 GNUNET_memcpy (buf,
552 &msg->dns,
553 dlen);
554 dns_out = (struct GNUNET_TUN_DnsHeader *) buf;
555 dns_out->id = ts->specifics.dns.my_id;
557 buf,
558 dlen,
560 NULL);
561 if (NULL == ts->specifics.dns.rs)
562 {
563 GNUNET_break_op (0);
564 return;
565 }
567}
568
569
577static void
579 const struct RedirectInformation *ri)
580{
581 char *off;
582
583 memset (hash,
584 0,
585 sizeof(struct GNUNET_HashCode));
586 /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
587 so we put the IP address in there (and hope for few collisions) */
588 off = (char *) hash;
589 switch (ri->remote_address.af)
590 {
591 case AF_INET:
592 GNUNET_memcpy (off,
593 &ri->remote_address.address.ipv4,
594 sizeof(struct in_addr));
595 off += sizeof(struct in_addr);
596 break;
597
598 case AF_INET6:
599 GNUNET_memcpy (off,
600 &ri->remote_address.address.ipv6,
601 sizeof(struct in6_addr));
602 off += sizeof(struct in_addr);
603 break;
604
605 default:
606 GNUNET_assert (0);
607 }
608 GNUNET_memcpy (off,
609 &ri->remote_address.port,
610 sizeof(uint16_t));
611 off += sizeof(uint16_t);
612 switch (ri->local_address.af)
613 {
614 case AF_INET:
615 GNUNET_memcpy (off,
616 &ri->local_address.address.ipv4,
617 sizeof(struct in_addr));
618 off += sizeof(struct in_addr);
619 break;
620
621 case AF_INET6:
622 GNUNET_memcpy (off,
623 &ri->local_address.address.ipv6,
624 sizeof(struct in6_addr));
625 off += sizeof(struct in_addr);
626 break;
627
628 default:
629 GNUNET_assert (0);
630 }
631 GNUNET_memcpy (off,
632 &ri->local_address.port,
633 sizeof(uint16_t));
634 off += sizeof(uint16_t);
635 GNUNET_memcpy (off,
636 &ri->remote_address.proto,
637 sizeof(uint8_t));
638 /* off += sizeof (uint8_t); */
639}
640
641
655static struct ChannelState *
657 int protocol,
658 const void *destination_ip,
659 uint16_t destination_port,
660 const void *local_ip,
661 uint16_t local_port,
663{
664 struct RedirectInformation ri;
665 struct GNUNET_HashCode key;
666 struct ChannelState *state;
667
668 if (((af == AF_INET) && (protocol == IPPROTO_ICMP)) ||
669 ((af == AF_INET6) && (protocol == IPPROTO_ICMPV6)))
670 {
671 /* ignore ports */
673 local_port = 0;
674 }
675 ri.remote_address.af = af;
676 if (af == AF_INET)
677 ri.remote_address.address.ipv4 = *((struct in_addr*) destination_ip);
678 else
679 ri.remote_address.address.ipv6 = *((struct in6_addr*) destination_ip);
680 ri.remote_address.port = destination_port;
681 ri.remote_address.proto = protocol;
682 ri.local_address.af = af;
683 if (af == AF_INET)
684 ri.local_address.address.ipv4 = *((struct in_addr*) local_ip);
685 else
686 ri.local_address.address.ipv6 = *((struct in6_addr*) local_ip);
687 ri.local_address.port = local_port;
688 ri.local_address.proto = protocol;
690 &ri);
691 if (NULL != state_key)
692 *state_key = key;
694 &key);
695 if (NULL == state)
696 return NULL;
697 /* Mark this connection as freshly used */
698 if (NULL == state_key)
699 GNUNET_CONTAINER_heap_update_cost (state->specifics.tcp_udp.heap_node,
700 GNUNET_TIME_absolute_get ().abs_value_us)
701 ;
702 return state;
703}
704
705
715static int
718{
719 struct ChannelState *state = cls;
720
721 if (NULL == state)
722 {
723 GNUNET_break_op (0);
724 return GNUNET_SYSERR;
725 }
726 if (GNUNET_YES == state->is_dns)
727 {
728 GNUNET_break_op (0);
729 return GNUNET_SYSERR;
730 }
731 if (NULL == state->specifics.tcp_udp.serv)
732 {
733 GNUNET_break_op (0);
734 return GNUNET_SYSERR;
735 }
736 if (NULL != state->specifics.tcp_udp.heap_node)
737 {
738 GNUNET_break_op (0);
739 return GNUNET_SYSERR;
740 }
741 if (start->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
742 {
743 GNUNET_break_op (0);
744 return GNUNET_SYSERR;
745 }
746 return GNUNET_OK;
747}
748
749
768static void
770 size_t payload_length,
771 int protocol,
772 const struct GNUNET_TUN_TcpHeader *tcp_header,
773 const struct SocketAddress *src_address,
774 const struct SocketAddress *dst_address,
775 struct GNUNET_TUN_IPv4Header *pkt4)
776{
777 size_t len;
778
779 len = payload_length;
780 switch (protocol)
781 {
782 case IPPROTO_UDP:
783 len += sizeof(struct GNUNET_TUN_UdpHeader);
784 break;
785
786 case IPPROTO_TCP:
787 len += sizeof(struct GNUNET_TUN_TcpHeader);
788 GNUNET_assert (NULL != tcp_header);
789 break;
790
791 default:
792 GNUNET_break (0);
793 return;
794 }
795 if (len + sizeof(struct GNUNET_TUN_IPv4Header) > UINT16_MAX)
796 {
797 GNUNET_break (0);
798 return;
799 }
800
802 protocol,
803 len,
804 &src_address->address.ipv4,
805 &dst_address->address.ipv4);
806 switch (protocol)
807 {
808 case IPPROTO_UDP:
809 {
810 struct GNUNET_TUN_UdpHeader *pkt4_udp = (struct
811 GNUNET_TUN_UdpHeader *) &pkt4[1];
812
813 pkt4_udp->source_port = htons (src_address->port);
814 pkt4_udp->destination_port = htons (dst_address->port);
815 pkt4_udp->len = htons ((uint16_t) payload_length);
817 pkt4_udp,
818 payload,
819 payload_length);
820 GNUNET_memcpy (&pkt4_udp[1],
821 payload,
822 payload_length);
823 }
824 break;
825
826 case IPPROTO_TCP:
827 {
828 struct GNUNET_TUN_TcpHeader *pkt4_tcp = (struct
830
831 *pkt4_tcp = *tcp_header;
833 "Sending TCP packet from port %u to port %u\n",
834 src_address->port,
835 dst_address->port);
836 pkt4_tcp->source_port = htons (src_address->port);
837 pkt4_tcp->destination_port = htons (dst_address->port);
839 pkt4_tcp,
840 payload,
841 payload_length);
843 payload,
844 payload_length);
845 }
846 break;
847
848 default:
849 GNUNET_assert (0);
850 }
851}
852
853
872static void
874 size_t payload_length,
875 int protocol,
876 const struct GNUNET_TUN_TcpHeader *tcp_header,
877 const struct SocketAddress *src_address,
878 const struct SocketAddress *dst_address,
880{
881 size_t len;
882
883 len = payload_length;
884 switch (protocol)
885 {
886 case IPPROTO_UDP:
887 len += sizeof(struct GNUNET_TUN_UdpHeader);
888 break;
889
890 case IPPROTO_TCP:
891 len += sizeof(struct GNUNET_TUN_TcpHeader);
892 break;
893
894 default:
895 GNUNET_break (0);
896 return;
897 }
898 if (len > UINT16_MAX)
899 {
900 GNUNET_break (0);
901 return;
902 }
903
905 protocol,
906 len,
907 &src_address->address.ipv6,
908 &dst_address->address.ipv6);
909
910 switch (protocol)
911 {
912 case IPPROTO_UDP:
913 {
914 struct GNUNET_TUN_UdpHeader *pkt6_udp = (struct
915 GNUNET_TUN_UdpHeader *) &pkt6[1];
916
917 pkt6_udp->source_port = htons (src_address->port);
918 pkt6_udp->destination_port = htons (dst_address->port);
919 pkt6_udp->len = htons ((uint16_t) payload_length);
921 pkt6_udp,
922 payload,
923 payload_length);
924 GNUNET_memcpy (&pkt6_udp[1],
925 payload,
926 payload_length);
927 }
928 break;
929
930 case IPPROTO_TCP:
931 {
932 struct GNUNET_TUN_TcpHeader *pkt6_tcp = (struct
934
935 /* GNUNET_memcpy first here as some TCP header fields are initialized this way! */
936 *pkt6_tcp = *tcp_header;
938 pkt6_tcp->destination_port = htons (dst_address->port);
940 pkt6_tcp,
941 payload,
942 payload_length);
944 payload,
945 payload_length);
946 }
947 break;
948
949 default:
950 GNUNET_assert (0);
951 break;
952 }
953}
954
955
965static void
966send_tcp_packet_via_tun (const struct SocketAddress *destination_address,
967 const struct SocketAddress *source_address,
968 const struct GNUNET_TUN_TcpHeader *tcp_header,
969 const void *payload,
970 size_t payload_length)
971{
972 size_t len;
973
975 gettext_noop ("# TCP packets sent via TUN"),
976 1,
977 GNUNET_NO);
979 "Sending packet with %u bytes TCP payload via TUN\n",
980 (unsigned int) payload_length);
981 len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct
983 switch (source_address->af)
984 {
985 case AF_INET:
986 len += sizeof(struct GNUNET_TUN_IPv4Header);
987 break;
988
989 case AF_INET6:
990 len += sizeof(struct GNUNET_TUN_IPv6Header);
991 break;
992
993 default:
994 GNUNET_break (0);
995 return;
996 }
997 len += sizeof(struct GNUNET_TUN_TcpHeader);
998 len += payload_length;
999 if (len >= GNUNET_MAX_MESSAGE_SIZE)
1000 {
1001 GNUNET_break (0);
1002 return;
1003 }
1004 {
1005 char buf[len] GNUNET_ALIGN;
1006 struct GNUNET_MessageHeader *hdr;
1008
1009 hdr = (struct GNUNET_MessageHeader *) buf;
1010 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1011 hdr->size = htons (len);
1012 tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1013 tun->flags = htons (0);
1014 switch (source_address->af)
1015 {
1016 case AF_INET:
1017 {
1019 = (struct GNUNET_TUN_IPv4Header*) &tun[1];
1020
1021 tun->proto = htons (ETH_P_IPV4);
1023 payload_length,
1024 IPPROTO_TCP,
1025 tcp_header,
1028 ipv4);
1029 }
1030 break;
1031
1032 case AF_INET6:
1033 {
1035 = (struct GNUNET_TUN_IPv6Header*) &tun[1];
1036
1037 tun->proto = htons (ETH_P_IPV6);
1040 IPPROTO_TCP,
1041 tcp_header,
1044 ipv6);
1045 }
1046 break;
1047
1048 default:
1049 GNUNET_assert (0);
1050 break;
1051 }
1052 if (NULL != helper_handle)
1054 (const struct GNUNET_MessageHeader*) buf,
1055 GNUNET_YES,
1056 NULL,
1057 NULL);
1058 }
1059}
1060
1061
1071static void
1073 const struct SocketAddress *source_address,
1074 const struct GNUNET_TUN_IcmpHeader *icmp_header,
1075 const void *payload, size_t payload_length)
1076{
1077 size_t len;
1078 struct GNUNET_TUN_IcmpHeader *icmp;
1079
1081 gettext_noop ("# ICMP packets sent via TUN"),
1082 1, GNUNET_NO);
1084 "Sending packet with %u bytes ICMP payload via TUN\n",
1085 (unsigned int) payload_length);
1086 len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct
1088 switch (destination_address->af)
1089 {
1090 case AF_INET:
1091 len += sizeof(struct GNUNET_TUN_IPv4Header);
1092 break;
1093
1094 case AF_INET6:
1095 len += sizeof(struct GNUNET_TUN_IPv6Header);
1096 break;
1097
1098 default:
1099 GNUNET_break (0);
1100 return;
1101 }
1102 len += sizeof(struct GNUNET_TUN_IcmpHeader);
1103 len += payload_length;
1104 if (len >= GNUNET_MAX_MESSAGE_SIZE)
1105 {
1106 GNUNET_break (0);
1107 return;
1108 }
1109 {
1110 char buf[len] GNUNET_ALIGN;
1111 struct GNUNET_MessageHeader *hdr;
1113
1114 hdr = (struct GNUNET_MessageHeader *) buf;
1115 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1116 hdr->size = htons (len);
1117 tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1118 tun->flags = htons (0);
1119 switch (source_address->af)
1120 {
1121 case AF_INET:
1122 {
1123 struct GNUNET_TUN_IPv4Header *ipv4 = (struct
1124 GNUNET_TUN_IPv4Header*) &tun[1];
1125
1126 tun->proto = htons (ETH_P_IPV4);
1128 IPPROTO_ICMP,
1129 sizeof(struct
1131 + payload_length,
1132 &source_address->address.ipv4,
1133 &destination_address->address.ipv4);
1134 icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv4[1];
1135 }
1136 break;
1137
1138 case AF_INET6:
1139 {
1140 struct GNUNET_TUN_IPv6Header *ipv6 = (struct
1141 GNUNET_TUN_IPv6Header*) &tun[1];
1142
1143 tun->proto = htons (ETH_P_IPV6);
1145 IPPROTO_ICMPV6,
1146 sizeof(struct
1149 &source_address->address.ipv6,
1150 &destination_address->address.ipv6);
1151 icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv6[1];
1152 }
1153 break;
1154
1155 default:
1156 GNUNET_assert (0);
1157 break;
1158 }
1159 *icmp = *icmp_header;
1160 GNUNET_memcpy (&icmp[1],
1161 payload,
1162 payload_length);
1164 payload,
1165 payload_length);
1166 if (NULL != helper_handle)
1168 (const struct GNUNET_MessageHeader*) buf,
1169 GNUNET_YES,
1170 NULL, NULL);
1171 }
1172}
1173
1174
1183static void
1185 uint8_t proto,
1186 struct SocketAddress *local_address)
1187{
1188 local_address->af = af;
1189 local_address->proto = (uint8_t) proto;
1190 /* default "local" port range is often 32768--61000,
1191 so we pick a random value in that range */
1192 if (((af == AF_INET) && (proto == IPPROTO_ICMP)) ||
1193 ((af == AF_INET6) && (proto == IPPROTO_ICMPV6)))
1194 local_address->port = 0;
1195 else
1196 local_address->port
1198 28232);
1199 switch (af)
1200 {
1201 case AF_INET:
1202 {
1203 struct in_addr addr;
1204 struct in_addr mask;
1205 struct in_addr rnd;
1206
1207 addr = exit_ipv4addr;
1208 mask = exit_ipv4mask;
1209 if (0 == ~mask.s_addr)
1210 {
1211 /* only one valid IP anyway */
1212 local_address->address.ipv4 = addr;
1213 return;
1214 }
1215 /* Given 192.168.0.1/255.255.0.0, we want a mask
1216 of '192.168.255.255', thus: */
1217 mask.s_addr = addr.s_addr | ~mask.s_addr;
1218 /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
1219 do
1220 {
1222 UINT32_MAX);
1223 local_address->address.ipv4.s_addr = (addr.s_addr | rnd.s_addr)
1224 & mask.s_addr;
1225 }
1226 while ((local_address->address.ipv4.s_addr == addr.s_addr) ||
1227 (local_address->address.ipv4.s_addr == mask.s_addr));
1228 }
1229 break;
1230
1231 case AF_INET6:
1232 {
1233 struct in6_addr addr;
1234 struct in6_addr mask;
1235 struct in6_addr rnd;
1236 int i;
1237
1238 addr = exit_ipv6addr;
1239 GNUNET_assert (ipv6prefix < 128);
1240 if (ipv6prefix == 127)
1241 {
1242 /* only one valid IP anyway */
1243 local_address->address.ipv6 = addr;
1244 return;
1245 }
1246 /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
1247 thus: */
1248 mask = addr;
1249 for (i = 127; i >= ipv6prefix; i--)
1250 mask.s6_addr[i / 8] |= (1 << (i % 8));
1251
1252 /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */
1253 do
1254 {
1255 for (i = 0; i < 16; i++)
1256 {
1257 rnd.s6_addr[i] = (unsigned char) GNUNET_CRYPTO_random_u32 (
1259 256);
1260 local_address->address.ipv6.s6_addr[i]
1261 = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
1262 }
1263 }
1264 while ((0 == GNUNET_memcmp (&local_address->address.ipv6,
1265 &addr)) ||
1266 (0 == GNUNET_memcmp (&local_address->address.ipv6,
1267 &mask)));
1268 }
1269 break;
1270
1271 default:
1272 GNUNET_assert (0);
1273 }
1274}
1275
1276
1298static void
1300{
1301 struct GNUNET_HashCode key;
1302 struct ChannelState *s;
1303
1304 /* generate fresh, unique address */
1305 do
1306 {
1307 if (NULL == state->specifics.tcp_udp.serv)
1308 setup_fresh_address (state->specifics.tcp_udp.ri.remote_address.af,
1309 state->specifics.tcp_udp.ri.remote_address.proto,
1310 &state->specifics.tcp_udp.ri.local_address);
1311 else
1312 setup_fresh_address (state->specifics.tcp_udp.serv->address.af,
1313 state->specifics.tcp_udp.serv->address.proto,
1314 &state->specifics.tcp_udp.ri.local_address);
1315 }
1316 while (NULL !=
1317 get_redirect_state (state->specifics.tcp_udp.ri.remote_address.af,
1318 state->specifics.tcp_udp.ri.remote_address.proto,
1319 &state->specifics.tcp_udp.ri.remote_address.address
1320 ,
1321 state->specifics.tcp_udp.ri.remote_address.port,
1322 &state->specifics.tcp_udp.ri.local_address.address,
1323 state->specifics.tcp_udp.ri.local_address.port,
1324 &key));
1325 {
1326 char buf[INET6_ADDRSTRLEN];
1328 "Picked local address %s:%u for new connection\n",
1329 inet_ntop (state->specifics.tcp_udp.ri.local_address.af,
1330 &state->specifics.tcp_udp.ri.local_address.address,
1331 buf,
1332 sizeof(buf)),
1333 (unsigned int) state->specifics.tcp_udp.ri.local_address.port);
1334 }
1335 state->specifics.tcp_udp.state_key = key;
1338 &key, state,
1340 state->specifics.tcp_udp.heap_node
1342 state,
1343 GNUNET_TIME_absolute_get ().abs_value_us);
1345 {
1347 GNUNET_assert (state != s);
1348 s->specifics.tcp_udp.heap_node = NULL;
1352 &s->specifics.tcp_udp.
1353 state_key,
1354 s));
1355 GNUNET_free (s);
1356 }
1357}
1358
1359
1368static void
1369send_udp_packet_via_tun (const struct SocketAddress *destination_address,
1370 const struct SocketAddress *source_address,
1371 const void *payload, size_t payload_length)
1372{
1373 size_t len;
1374
1376 gettext_noop ("# UDP packets sent via TUN"),
1377 1, GNUNET_NO);
1379 "Sending packet with %u bytes UDP payload via TUN\n",
1380 (unsigned int) payload_length);
1381 len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct
1383 switch (source_address->af)
1384 {
1385 case AF_INET:
1386 len += sizeof(struct GNUNET_TUN_IPv4Header);
1387 break;
1388
1389 case AF_INET6:
1390 len += sizeof(struct GNUNET_TUN_IPv6Header);
1391 break;
1392
1393 default:
1394 GNUNET_break (0);
1395 return;
1396 }
1397 len += sizeof(struct GNUNET_TUN_UdpHeader);
1398 len += payload_length;
1400 {
1401 GNUNET_break (0);
1402 return;
1403 }
1404 {
1405 char buf[len] GNUNET_ALIGN;
1406 struct GNUNET_MessageHeader *hdr;
1408
1409 hdr = (struct GNUNET_MessageHeader *) buf;
1410 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1411 hdr->size = htons (len);
1412 tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1413 tun->flags = htons (0);
1414 switch (source_address->af)
1415 {
1416 case AF_INET:
1417 {
1418 struct GNUNET_TUN_IPv4Header *ipv4 = (struct
1419 GNUNET_TUN_IPv4Header*) &tun[1];
1420
1421 tun->proto = htons (ETH_P_IPV4);
1423 payload_length,
1424 IPPROTO_UDP,
1425 NULL,
1428 ipv4);
1429 }
1430 break;
1431
1432 case AF_INET6:
1433 {
1434 struct GNUNET_TUN_IPv6Header *ipv6 = (struct
1435 GNUNET_TUN_IPv6Header*) &tun[1];
1436
1437 tun->proto = htons (ETH_P_IPV6);
1440 IPPROTO_UDP,
1441 NULL,
1444 ipv6);
1445 }
1446 break;
1447
1448 default:
1449 GNUNET_assert (0);
1450 break;
1451 }
1452 if (NULL != helper_handle)
1454 (const struct GNUNET_MessageHeader*) buf,
1455 GNUNET_YES,
1456 NULL, NULL);
1457 }
1458}
1459
1460
1469static int
1471 const struct GNUNET_EXIT_UdpInternetMessage *msg)
1472{
1473 struct ChannelState *state = cls;
1474
1475 if (GNUNET_YES == state->is_dns)
1476 {
1477 GNUNET_break_op (0);
1478 return GNUNET_SYSERR;
1479 }
1480 return GNUNET_OK;
1481}
1482
1483
1490static void
1492 const struct GNUNET_EXIT_UdpInternetMessage *msg)
1493{
1494 struct ChannelState *state = cls;
1495 uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
1497 const struct in_addr *v4;
1498 const struct in6_addr *v6;
1499 const void *payload;
1500 int af;
1501
1502 if (GNUNET_SYSERR == state->is_dns)
1503 {
1504 /* channel is UDP/TCP from now on */
1506 }
1508 gettext_noop ("# Bytes received from CADET"),
1509 pkt_len, GNUNET_NO);
1511 gettext_noop (
1512 "# UDP IP-exit requests received via cadet"),
1513 1, GNUNET_NO);
1514 af = (int) ntohl (msg->af);
1515 state->specifics.tcp_udp.ri.remote_address.af = af;
1516 switch (af)
1517 {
1518 case AF_INET:
1519 if (pkt_len < sizeof(struct in_addr))
1520 {
1521 GNUNET_break_op (0);
1522 return;
1523 }
1524 if (! ipv4_exit)
1525 {
1526 GNUNET_break_op (0);
1527 return;
1528 }
1529 v4 = (const struct in_addr*) &msg[1];
1530 payload = &v4[1];
1531 pkt_len -= sizeof(struct in_addr);
1532 state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
1533 break;
1534
1535 case AF_INET6:
1536 if (pkt_len < sizeof(struct in6_addr))
1537 {
1538 GNUNET_break_op (0);
1539 return;
1540 }
1541 if (! ipv6_exit)
1542 {
1543 GNUNET_break_op (0);
1544 return;
1545 }
1546 v6 = (const struct in6_addr*) &msg[1];
1547 payload = &v6[1];
1548 pkt_len -= sizeof(struct in6_addr);
1549 state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
1550 break;
1551
1552 default:
1553 GNUNET_break_op (0);
1554 return;
1555 }
1556 {
1557 char buf[INET6_ADDRSTRLEN];
1559 "Received data from %s for forwarding to UDP %s:%u\n",
1560 GNUNET_i2s (&state->peer),
1561 inet_ntop (af,
1562 &state->specifics.tcp_udp.ri.remote_address.address,
1563 buf, sizeof(buf)),
1564 (unsigned int) ntohs (msg->destination_port));
1565 }
1566 state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_UDP;
1567 state->specifics.tcp_udp.ri.remote_address.port = msg->destination_port;
1568 if (NULL == state->specifics.tcp_udp.heap_node)
1570 if (0 != ntohs (msg->source_port))
1571 state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
1572 send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1573 &state->specifics.tcp_udp.ri.local_address,
1574 payload,
1575 pkt_len);
1577}
1578
1579
1589static int
1591 const struct GNUNET_EXIT_UdpServiceMessage *msg)
1592{
1593 struct ChannelState *state = cls;
1594
1595 if (NULL == state->specifics.tcp_udp.serv)
1596 {
1597 GNUNET_break_op (0);
1598 return GNUNET_SYSERR;
1599 }
1600 return GNUNET_OK;
1601}
1602
1603
1611static void
1613 const struct GNUNET_EXIT_UdpServiceMessage *msg)
1614{
1615 struct ChannelState *state = cls;
1616 uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
1618
1620 gettext_noop ("# Bytes received from CADET"),
1621 pkt_len, GNUNET_NO);
1623 gettext_noop (
1624 "# UDP service requests received via cadet"),
1625 1, GNUNET_NO);
1627 "Received data from %s for forwarding to UDP service %s on port %u\n",
1628 GNUNET_i2s (&state->peer),
1629 GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor),
1630 (unsigned int) ntohs (msg->destination_port));
1632 if (0 != ntohs (msg->source_port))
1633 state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
1634 send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1635 &state->specifics.tcp_udp.ri.local_address,
1636 &msg[1],
1637 pkt_len);
1639}
1640
1641
1651static void
1654{
1655 struct ChannelState *state = cls;
1656 uint16_t pkt_len = ntohs (start->header.size) - sizeof(struct
1658
1659 if (GNUNET_SYSERR == state->is_dns)
1660 {
1661 /* channel is UDP/TCP from now on */
1663 }
1665 gettext_noop (
1666 "# TCP service creation requests received via cadet"),
1667 1,
1668 GNUNET_NO);
1670 gettext_noop ("# Bytes received from CADET"),
1671 pkt_len,
1672 GNUNET_NO);
1673 GNUNET_break_op (ntohl (start->reserved) == 0);
1674 /* setup fresh connection */
1676 "Received data from %s for forwarding to TCP service %s on port %u\n",
1677 GNUNET_i2s (&state->peer),
1678 GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor),
1679 (unsigned int) ntohs (start->tcp_header.destination_port));
1681 send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1682 &state->specifics.tcp_udp.ri.local_address,
1683 &start->tcp_header,
1684 &start[1],
1685 pkt_len);
1687}
1688
1689
1698static int
1701{
1702 struct ChannelState *state = cls;
1703
1704 if (NULL == state)
1705 {
1706 GNUNET_break_op (0);
1707 return GNUNET_SYSERR;
1708 }
1709 if (GNUNET_YES == state->is_dns)
1710 {
1711 GNUNET_break_op (0);
1712 return GNUNET_SYSERR;
1713 }
1714 if ((NULL != state->specifics.tcp_udp.serv) ||
1715 (NULL != state->specifics.tcp_udp.heap_node))
1716 {
1717 GNUNET_break_op (0);
1718 return GNUNET_SYSERR;
1719 }
1720 if (start->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1721 {
1722 GNUNET_break_op (0);
1723 return GNUNET_SYSERR;
1724 }
1725 return GNUNET_OK;
1726}
1727
1728
1735static void
1738{
1739 struct ChannelState *state = cls;
1740 uint16_t pkt_len = ntohs (start->header.size) - sizeof(struct
1742 const struct in_addr *v4;
1743 const struct in6_addr *v6;
1744 const void *payload;
1745 int af;
1746
1747 if (GNUNET_SYSERR == state->is_dns)
1748 {
1749 /* channel is UDP/TCP from now on */
1751 }
1753 gettext_noop ("# Bytes received from CADET"),
1754 pkt_len, GNUNET_NO);
1756 gettext_noop (
1757 "# TCP IP-exit creation requests received via cadet"),
1758 1, GNUNET_NO);
1759 af = (int) ntohl (start->af);
1760 state->specifics.tcp_udp.ri.remote_address.af = af;
1761 switch (af)
1762 {
1763 case AF_INET:
1764 if (pkt_len < sizeof(struct in_addr))
1765 {
1766 GNUNET_break_op (0);
1767 return;
1768 }
1769 if (! ipv4_exit)
1770 {
1771 GNUNET_break_op (0);
1772 return;
1773 }
1774 v4 = (const struct in_addr*) &start[1];
1775 payload = &v4[1];
1776 pkt_len -= sizeof(struct in_addr);
1777 state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
1778 break;
1779
1780 case AF_INET6:
1781 if (pkt_len < sizeof(struct in6_addr))
1782 {
1783 GNUNET_break_op (0);
1784 return;
1785 }
1786 if (! ipv6_exit)
1787 {
1788 GNUNET_break_op (0);
1789 return;
1790 }
1791 v6 = (const struct in6_addr*) &start[1];
1792 payload = &v6[1];
1793 pkt_len -= sizeof(struct in6_addr);
1794 state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
1795 break;
1796
1797 default:
1798 GNUNET_break_op (0);
1799 return;
1800 }
1801 {
1802 char buf[INET6_ADDRSTRLEN];
1804 "Received payload from %s for existing TCP stream to %s:%u\n",
1805 GNUNET_i2s (&state->peer),
1806 inet_ntop (af,
1807 &state->specifics.tcp_udp.ri.remote_address.address,
1808 buf, sizeof(buf)),
1809 (unsigned int) ntohs (start->tcp_header.destination_port));
1810 }
1811 state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_TCP;
1812 state->specifics.tcp_udp.ri.remote_address.port = ntohs (
1813 start->tcp_header.destination_port);
1815 send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1816 &state->specifics.tcp_udp.ri.local_address,
1817 &start->tcp_header,
1818 payload,
1819 pkt_len);
1821}
1822
1823
1833static int
1835 const struct GNUNET_EXIT_TcpDataMessage *data)
1836{
1837 struct ChannelState *state = cls;
1838
1839 if ((NULL == state) ||
1840 (NULL == state->specifics.tcp_udp.heap_node))
1841 {
1842 /* connection should have been up! */
1844 gettext_noop (
1845 "# TCP DATA requests dropped (no session)"),
1846 1, GNUNET_NO);
1847 GNUNET_break_op (0);
1848 return GNUNET_SYSERR;
1849 }
1850 if (data->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1851 {
1852 GNUNET_break_op (0);
1853 return GNUNET_SYSERR;
1854 }
1855 if (GNUNET_YES == state->is_dns)
1856 {
1857 GNUNET_break_op (0);
1858 return GNUNET_SYSERR;
1859 }
1860 return GNUNET_OK;
1861}
1862
1863
1871static void
1873 const struct GNUNET_EXIT_TcpDataMessage *data)
1874{
1875 struct ChannelState *state = cls;
1876 uint16_t pkt_len = ntohs (data->header.size) - sizeof(struct
1878
1880 gettext_noop ("# Bytes received from CADET"),
1881 pkt_len, GNUNET_NO);
1883 gettext_noop (
1884 "# TCP data requests received via cadet"),
1885 1, GNUNET_NO);
1886 if (GNUNET_SYSERR == state->is_dns)
1887 {
1888 /* channel is UDP/TCP from now on */
1889 state->is_dns = GNUNET_NO;
1890 }
1891
1892 GNUNET_break_op (ntohl (data->reserved) == 0);
1893 {
1894 char buf[INET6_ADDRSTRLEN];
1896 "Received additional %u bytes of data from %s for TCP stream to %s:%u\n",
1897 pkt_len,
1898 GNUNET_i2s (&state->peer),
1899 inet_ntop (state->specifics.tcp_udp.ri.remote_address.af,
1900 &state->specifics.tcp_udp.ri.remote_address.address,
1901 buf, sizeof(buf)),
1902 (unsigned int) state->specifics.tcp_udp.ri.remote_address.port);
1903 }
1904
1905 send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1906 &state->specifics.tcp_udp.ri.local_address,
1907 &data->tcp_header,
1908 &data[1], pkt_len);
1910}
1911
1912
1922static void
1924 struct GNUNET_TUN_IPv4Header *ipp,
1925 struct GNUNET_TUN_UdpHeader *udp)
1926{
1928 state->specifics.tcp_udp.ri.remote_address.
1929 proto,
1930 sizeof(struct GNUNET_TUN_TcpHeader),
1931 &state->specifics.tcp_udp.ri.remote_address
1932 .address.ipv4,
1933 &state->specifics.tcp_udp.ri.local_address.
1934 address.ipv4);
1935 udp->source_port = htons (state->specifics.tcp_udp.ri.remote_address.port);
1936 udp->destination_port = htons (
1937 state->specifics.tcp_udp.ri.local_address.port);
1938 udp->len = htons (0);
1939 udp->crc = htons (0);
1940}
1941
1942
1952static void
1954 struct GNUNET_TUN_IPv6Header *ipp,
1955 struct GNUNET_TUN_UdpHeader *udp)
1956{
1958 state->specifics.tcp_udp.ri.remote_address.
1959 proto,
1960 sizeof(struct GNUNET_TUN_TcpHeader),
1961 &state->specifics.tcp_udp.ri.remote_address
1962 .address.ipv6,
1963 &state->specifics.tcp_udp.ri.local_address.
1964 address.ipv6);
1965 udp->source_port = htons (state->specifics.tcp_udp.ri.remote_address.port);
1966 udp->destination_port = htons (
1967 state->specifics.tcp_udp.ri.local_address.port);
1968 udp->len = htons (0);
1969 udp->crc = htons (0);
1970}
1971
1972
1981static int
1984{
1985 struct ChannelState *state = cls;
1986
1987 if (GNUNET_YES == state->is_dns)
1988 {
1989 GNUNET_break_op (0);
1990 return GNUNET_SYSERR;
1991 }
1992 return GNUNET_OK;
1993}
1994
1995
2002static void
2005{
2006 struct ChannelState *state = cls;
2007 uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
2009 const struct in_addr *v4;
2010 const struct in6_addr *v6;
2011 const void *payload;
2012 char buf[sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
2013 int af;
2014
2015 if (GNUNET_SYSERR == state->is_dns)
2016 {
2017 /* channel is UDP/TCP from now on */
2019 }
2021 gettext_noop ("# Bytes received from CADET"),
2022 pkt_len, GNUNET_NO);
2024 gettext_noop (
2025 "# ICMP IP-exit requests received via cadet"),
2026 1, GNUNET_NO);
2027
2028 af = (int) ntohl (msg->af);
2029 if ((NULL != state->specifics.tcp_udp.heap_node) &&
2030 (af != state->specifics.tcp_udp.ri.remote_address.af))
2031 {
2032 /* other peer switched AF on this channel; not allowed */
2033 GNUNET_break_op (0);
2034 return;
2035 }
2036
2037 switch (af)
2038 {
2039 case AF_INET:
2040 if (pkt_len < sizeof(struct in_addr))
2041 {
2042 GNUNET_break_op (0);
2043 return;
2044 }
2045 if (! ipv4_exit)
2046 {
2047 GNUNET_break_op (0);
2048 return;
2049 }
2050 v4 = (const struct in_addr*) &msg[1];
2051 payload = &v4[1];
2052 pkt_len -= sizeof(struct in_addr);
2053 state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
2054 if (NULL == state->specifics.tcp_udp.heap_node)
2055 {
2056 state->specifics.tcp_udp.ri.remote_address.af = af;
2057 state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMP;
2059 }
2060 /* check that ICMP type is something we want to support
2061 and possibly make up payload! */
2062 switch (msg->icmp_header.type)
2063 {
2066 break;
2067
2071 if (0 != pkt_len)
2072 {
2073 GNUNET_break_op (0);
2074 return;
2075 }
2076 /* make up payload */
2077 {
2078 struct GNUNET_TUN_IPv4Header *ipp = (struct
2079 GNUNET_TUN_IPv4Header *) buf;
2080 struct GNUNET_TUN_UdpHeader *udp = (struct
2081 GNUNET_TUN_UdpHeader *) &ipp[1];
2082
2083 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2084 pkt_len = sizeof(struct GNUNET_TUN_IPv4Header) + 8;
2086 ipp,
2087 udp);
2088 payload = ipp;
2089 }
2090 break;
2091
2092 default:
2093 GNUNET_break_op (0);
2095 gettext_noop (
2096 "# ICMPv4 packets dropped (type not allowed)")
2097 ,
2098 1, GNUNET_NO);
2099 return;
2100 }
2101 /* end AF_INET */
2102 break;
2103
2104 case AF_INET6:
2105 if (pkt_len < sizeof(struct in6_addr))
2106 {
2107 GNUNET_break_op (0);
2108 return;
2109 }
2110 if (! ipv6_exit)
2111 {
2112 GNUNET_break_op (0);
2113 return;
2114 }
2115 v6 = (const struct in6_addr*) &msg[1];
2116 payload = &v6[1];
2117 pkt_len -= sizeof(struct in6_addr);
2118 state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
2119 if (NULL == state->specifics.tcp_udp.heap_node)
2120 {
2121 state->specifics.tcp_udp.ri.remote_address.af = af;
2122 state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMPV6;
2124 }
2125 /* check that ICMP type is something we want to support
2126 and possibly make up payload! */
2127 switch (msg->icmp_header.type)
2128 {
2131 break;
2132
2137 if (0 != pkt_len)
2138 {
2139 GNUNET_break_op (0);
2140 return;
2141 }
2142 /* make up payload */
2143 {
2144 struct GNUNET_TUN_IPv6Header *ipp = (struct
2145 GNUNET_TUN_IPv6Header *) buf;
2146 struct GNUNET_TUN_UdpHeader *udp = (struct
2147 GNUNET_TUN_UdpHeader *) &ipp[1];
2148
2149 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2150 pkt_len = sizeof(struct GNUNET_TUN_IPv6Header) + 8;
2152 ipp,
2153 udp);
2154 payload = ipp;
2155 }
2156 break;
2157
2158 default:
2159 GNUNET_break_op (0);
2161 gettext_noop (
2162 "# ICMPv6 packets dropped (type not allowed)")
2163 ,
2164 1, GNUNET_NO);
2165 return;
2166 }
2167 /* end AF_INET6 */
2168 break;
2169
2170 default:
2171 /* bad AF */
2172 GNUNET_break_op (0);
2173 return;
2174 }
2175
2176 {
2177 char buf_tmp[INET6_ADDRSTRLEN];
2179 "Received ICMP data from %s for forwarding to %s\n",
2180 GNUNET_i2s (&state->peer),
2181 inet_ntop (af,
2182 &state->specifics.tcp_udp.ri.remote_address.address,
2183 buf_tmp, sizeof(buf_tmp)));
2184 }
2185 send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2186 &state->specifics.tcp_udp.ri.local_address,
2187 &msg->icmp_header,
2188 payload, pkt_len);
2190}
2191
2192
2202static uint16_t
2204 char *buf)
2205{
2206 switch (state->specifics.tcp_udp.serv->address.af)
2207 {
2208 case AF_INET:
2209 {
2211 struct GNUNET_TUN_UdpHeader *udp;
2212
2213 ipv4 = (struct GNUNET_TUN_IPv4Header *) buf;
2214 udp = (struct GNUNET_TUN_UdpHeader *) &ipv4[1];
2216 ipv4,
2217 udp);
2218 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2219 return sizeof(struct GNUNET_TUN_IPv4Header) + 8;
2220 }
2221 break;
2222
2223 case AF_INET6:
2224 {
2226 struct GNUNET_TUN_UdpHeader *udp;
2227
2228 ipv6 = (struct GNUNET_TUN_IPv6Header *) buf;
2229 udp = (struct GNUNET_TUN_UdpHeader *) &ipv6[1];
2231 ipv6,
2232 udp);
2233 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2234 return sizeof(struct GNUNET_TUN_IPv6Header) + 8;
2235 }
2236 break;
2237
2238 default:
2239 GNUNET_break (0);
2240 }
2241 return 0;
2242}
2243
2244
2254static int
2256 const struct GNUNET_EXIT_IcmpServiceMessage *msg)
2257{
2258 struct ChannelState *state = cls;
2259
2260 if (GNUNET_YES == state->is_dns)
2261 {
2262 GNUNET_break_op (0);
2263 return GNUNET_SYSERR;
2264 }
2265 if (NULL == state->specifics.tcp_udp.serv)
2266 {
2267 GNUNET_break_op (0);
2268 return GNUNET_SYSERR;
2269 }
2270 return GNUNET_OK;
2271}
2272
2273
2281static void
2283 const struct GNUNET_EXIT_IcmpServiceMessage *msg)
2284{
2285 struct ChannelState *state = cls;
2286 uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
2288 struct GNUNET_TUN_IcmpHeader icmp;
2289 char buf[sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
2290 const void *payload;
2291
2293 gettext_noop ("# Bytes received from CADET"),
2294 pkt_len, GNUNET_NO);
2296 gettext_noop (
2297 "# ICMP service requests received via cadet"),
2298 1, GNUNET_NO);
2299 /* check that we got at least a valid header */
2301 "Received data from %s for forwarding to ICMP service %s\n",
2302 GNUNET_i2s (&state->peer),
2303 GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor));
2304 icmp = msg->icmp_header;
2305 payload = &msg[1];
2306 state->specifics.tcp_udp.ri.remote_address
2307 = state->specifics.tcp_udp.serv->address;
2309
2310 /* check that ICMP type is something we want to support,
2311 perform ICMP PT if needed and possibly make up payload */
2312 switch (msg->af)
2313 {
2314 case AF_INET:
2315 switch (msg->icmp_header.type)
2316 {
2318 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2320 break;
2321
2323 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2325 break;
2326
2328 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2330 if (0 != pkt_len)
2331 {
2332 GNUNET_break_op (0);
2333 return;
2334 }
2335 payload = buf;
2336 pkt_len = make_up_icmp_service_payload (state, buf);
2337 break;
2338
2340 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2342 if (0 != pkt_len)
2343 {
2344 GNUNET_break_op (0);
2345 return;
2346 }
2347 payload = buf;
2348 pkt_len = make_up_icmp_service_payload (state, buf);
2349 break;
2350
2352 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2353 {
2355 gettext_noop (
2356 "# ICMPv4 packets dropped (impossible PT to v6)"),
2357 1, GNUNET_NO);
2358 return;
2359 }
2360 if (0 != pkt_len)
2361 {
2362 GNUNET_break_op (0);
2363 return;
2364 }
2365 payload = buf;
2366 pkt_len = make_up_icmp_service_payload (state, buf);
2367 break;
2368
2369 default:
2370 GNUNET_break_op (0);
2372 gettext_noop (
2373 "# ICMPv4 packets dropped (type not allowed)")
2374 ,
2375 1, GNUNET_NO);
2376 return;
2377 }
2378 /* end of AF_INET */
2379 break;
2380
2381 case AF_INET6:
2382 switch (msg->icmp_header.type)
2383 {
2385 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2387 break;
2388
2390 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2392 break;
2393
2395 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2397 if (0 != pkt_len)
2398 {
2399 GNUNET_break_op (0);
2400 return;
2401 }
2402 payload = buf;
2403 pkt_len = make_up_icmp_service_payload (state, buf);
2404 break;
2405
2407 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2409 if (0 != pkt_len)
2410 {
2411 GNUNET_break_op (0);
2412 return;
2413 }
2414 payload = buf;
2415 pkt_len = make_up_icmp_service_payload (state, buf);
2416 break;
2417
2420 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2421 {
2423 gettext_noop (
2424 "# ICMPv6 packets dropped (impossible PT to v4)"),
2425 1, GNUNET_NO);
2426 return;
2427 }
2428 if (0 != pkt_len)
2429 {
2430 GNUNET_break_op (0);
2431 return;
2432 }
2433 payload = buf;
2434 pkt_len = make_up_icmp_service_payload (state, buf);
2435 break;
2436
2437 default:
2438 GNUNET_break_op (0);
2440 gettext_noop (
2441 "# ICMPv6 packets dropped (type not allowed)")
2442 ,
2443 1, GNUNET_NO);
2444 return;
2445 }
2446 /* end of AF_INET6 */
2447 break;
2448
2449 default:
2450 GNUNET_break_op (0);
2451 return;
2452 }
2453
2454 send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2455 &state->specifics.tcp_udp.ri.local_address,
2456 &icmp,
2457 payload,
2458 pkt_len);
2460}
2461
2462
2471static int
2473 const struct GNUNET_HashCode *key,
2474 void *value)
2475{
2476 struct LocalService *service = value;
2477
2480 key,
2481 service));
2483 GNUNET_free (service->name);
2485 return GNUNET_OK;
2486}
2487
2488
2497static void *
2499 struct GNUNET_CADET_Channel *channel,
2500 const struct GNUNET_PeerIdentity *initiator)
2501{
2502 struct LocalService *ls = cls;
2503 struct ChannelState *s = GNUNET_new (struct ChannelState);
2504
2505 s->peer = *initiator;
2507 gettext_noop ("# Inbound CADET channels created"),
2508 1,
2509 GNUNET_NO);
2511 "Received inbound channel from `%s'\n",
2512 GNUNET_i2s (initiator));
2513 s->channel = channel;
2514 s->specifics.tcp_udp.serv = ls;
2515 s->specifics.tcp_udp.ri.remote_address = ls->address;
2516 return s;
2517}
2518
2519
2527static void
2528clean_channel (void *cls,
2529 const struct GNUNET_CADET_Channel *channel)
2530{
2531 struct ChannelState *s = cls;
2532
2534 "Channel destroyed\n");
2535 if (GNUNET_SYSERR == s->is_dns)
2536 {
2537 GNUNET_free (s);
2538 return;
2539 }
2540 if (GNUNET_YES == s->is_dns)
2541 {
2542 if (channels[s->specifics.dns.my_id] == s)
2543 channels[s->specifics.dns.my_id] = NULL;
2544 }
2545 else
2546 {
2547 if (NULL != s->specifics.tcp_udp.heap_node)
2548 {
2551 &s->specifics.tcp_udp
2552 .state_key,
2553 s));
2555 s->specifics.tcp_udp.heap_node = NULL;
2556 }
2557 }
2558 GNUNET_free (s);
2559}
2560
2561
2571static void
2573 const char *name,
2574 uint16_t destination_port,
2575 struct LocalService *service)
2576{
2578 GNUNET_MQ_hd_var_size (icmp_service,
2581 service),
2582 GNUNET_MQ_hd_var_size (udp_service,
2585 service),
2586 GNUNET_MQ_hd_var_size (tcp_service,
2589 service),
2590 GNUNET_MQ_hd_var_size (tcp_data,
2593 service),
2595 };
2596
2598
2599 service->name = GNUNET_strdup (name);
2601 &service->descriptor);
2603 destination_port,
2604 &cadet_port);
2606 "Opening CADET port %s for SERVICE exit %s on port %u\n",
2608 name,
2609 (unsigned int) destination_port);
2611 &cadet_port,
2613 service,
2614 NULL,
2616 handlers);
2617 service->is_udp = (IPPROTO_UDP == proto);
2618 if (GNUNET_OK !=
2620 &cadet_port,
2621 service,
2623 {
2625 GNUNET_free (service->name);
2628 _ ("Got duplicate service records for `%s:%u'\n"),
2629 name,
2630 (unsigned int) destination_port);
2631 }
2632}
2633
2634
2641static void
2643 struct GNUNET_MQ_Envelope *env)
2644{
2645 GNUNET_assert (NULL != s);
2647 gettext_noop (
2648 "# Messages transmitted via cadet channels"),
2649 1,
2650 GNUNET_NO);
2652 env);
2653}
2654
2655
2667static void
2669 size_t pktlen,
2670 int af,
2671 const void *destination_ip,
2672 const void *source_ip)
2673{
2674 struct ChannelState *state;
2675 struct GNUNET_MQ_Envelope *env;
2676 struct GNUNET_EXIT_IcmpToVPNMessage *i2v;
2677 const struct GNUNET_TUN_IPv4Header *ipv4;
2678 const struct GNUNET_TUN_IPv6Header *ipv6;
2679 const struct GNUNET_TUN_UdpHeader *udp;
2680 uint16_t source_port;
2681 uint16_t destination_port;
2682 uint8_t protocol;
2683
2684 {
2685 char sbuf[INET6_ADDRSTRLEN];
2686 char dbuf[INET6_ADDRSTRLEN];
2688 "Received ICMP packet going from %s to %s\n",
2689 inet_ntop (af,
2690 source_ip,
2691 sbuf, sizeof(sbuf)),
2692 inet_ntop (af,
2693 destination_ip,
2694 dbuf, sizeof(dbuf)));
2695 }
2696
2697 if (pktlen < sizeof(struct GNUNET_TUN_IcmpHeader))
2698 {
2699 /* blame kernel */
2700 GNUNET_break (0);
2701 return;
2702 }
2703
2704 /* Find out if this is an ICMP packet in response to an existing
2705 TCP/UDP packet and if so, figure out ports / protocol of the
2706 existing session from the IP data in the ICMP payload */
2707 source_port = 0;
2708 destination_port = 0;
2709 switch (af)
2710 {
2711 case AF_INET:
2712 protocol = IPPROTO_ICMP;
2713 switch (icmp->type)
2714 {
2717 break;
2718
2722 if (pktlen <
2723 sizeof(struct GNUNET_TUN_IcmpHeader)
2724 + sizeof(struct GNUNET_TUN_IPv4Header) + 8)
2725 {
2726 /* blame kernel */
2727 GNUNET_break (0);
2728 return;
2729 }
2730 ipv4 = (const struct GNUNET_TUN_IPv4Header *) &icmp[1];
2731 protocol = ipv4->protocol;
2732 /* could be TCP or UDP, but both have the ports in the right
2733 place, so that doesn't matter here */
2734 udp = (const struct GNUNET_TUN_UdpHeader *) &ipv4[1];
2735 /* swap ports, as they are from the original message */
2736 destination_port = ntohs (udp->source_port);
2737 source_port = ntohs (udp->destination_port);
2738 /* throw away ICMP payload, won't be useful for the other side anyway */
2739 pktlen = sizeof(struct GNUNET_TUN_IcmpHeader);
2740 break;
2741
2742 default:
2744 gettext_noop (
2745 "# ICMPv4 packets dropped (type not allowed)")
2746 ,
2747 1, GNUNET_NO);
2748 return;
2749 }
2750 break;
2751
2752 case AF_INET6:
2753 protocol = IPPROTO_ICMPV6;
2754 switch (icmp->type)
2755 {
2760 if (pktlen <
2761 sizeof(struct GNUNET_TUN_IcmpHeader)
2762 + sizeof(struct GNUNET_TUN_IPv6Header) + 8)
2763 {
2764 /* blame kernel */
2765 GNUNET_break (0);
2766 return;
2767 }
2768 ipv6 = (const struct GNUNET_TUN_IPv6Header *) &icmp[1];
2769 protocol = ipv6->next_header;
2770 /* could be TCP or UDP, but both have the ports in the right
2771 place, so that doesn't matter here */
2772 udp = (const struct GNUNET_TUN_UdpHeader *) &ipv6[1];
2773 /* swap ports, as they are from the original message */
2774 destination_port = ntohs (udp->source_port);
2775 source_port = ntohs (udp->destination_port);
2776 /* throw away ICMP payload, won't be useful for the other side anyway */
2777 pktlen = sizeof(struct GNUNET_TUN_IcmpHeader);
2778 break;
2779
2782 break;
2783
2784 default:
2786 gettext_noop (
2787 "# ICMPv6 packets dropped (type not allowed)")
2788 ,
2789 1, GNUNET_NO);
2790 return;
2791 }
2792 break;
2793
2794 default:
2795 GNUNET_assert (0);
2796 }
2797 switch (protocol)
2798 {
2799 case IPPROTO_ICMP:
2801 IPPROTO_ICMP,
2802 source_ip,
2803 0,
2804 destination_ip,
2805 0,
2806 NULL);
2807 break;
2808
2809 case IPPROTO_ICMPV6:
2811 IPPROTO_ICMPV6,
2812 source_ip,
2813 0,
2814 destination_ip,
2815 0,
2816 NULL);
2817 break;
2818
2819 case IPPROTO_UDP:
2821 IPPROTO_UDP,
2822 source_ip,
2823 source_port,
2824 destination_ip,
2825 destination_port,
2826 NULL);
2827 break;
2828
2829 case IPPROTO_TCP:
2831 IPPROTO_TCP,
2832 source_ip,
2833 source_port,
2834 destination_ip,
2835 destination_port,
2836 NULL);
2837 break;
2838
2839 default:
2841 gettext_noop (
2842 "# ICMP packets dropped (not allowed)"),
2843 1,
2844 GNUNET_NO);
2845 return;
2846 }
2847 if (NULL == state)
2848 {
2850 _ (
2851 "ICMP Packet dropped, have no matching connection information\n"));
2852 return;
2853 }
2854 env = GNUNET_MQ_msg_extra (i2v,
2855 pktlen - sizeof(struct GNUNET_TUN_IcmpHeader),
2857 i2v->af = htonl (af);
2859 icmp,
2860 pktlen);
2862 env);
2863}
2864
2865
2877static void
2879 size_t pktlen,
2880 int af,
2881 const void *destination_ip,
2882 const void *source_ip)
2883{
2884 struct ChannelState *state;
2885 struct GNUNET_MQ_Envelope *env;
2886 struct GNUNET_EXIT_UdpReplyMessage *urm;
2887
2888 {
2889 char sbuf[INET6_ADDRSTRLEN];
2890 char dbuf[INET6_ADDRSTRLEN];
2891
2893 "Received UDP packet going from %s:%u to %s:%u\n",
2894 inet_ntop (af,
2895 source_ip,
2896 sbuf, sizeof(sbuf)),
2897 (unsigned int) ntohs (udp->source_port),
2898 inet_ntop (af,
2899 destination_ip,
2900 dbuf, sizeof(dbuf)),
2901 (unsigned int) ntohs (udp->destination_port));
2902 }
2903
2904 if (pktlen < sizeof(struct GNUNET_TUN_UdpHeader))
2905 {
2906 /* blame kernel */
2907 GNUNET_break (0);
2908 return;
2909 }
2910 if (pktlen != ntohs (udp->len))
2911 {
2912 /* blame kernel */
2913 GNUNET_break (0);
2914 return;
2915 }
2917 IPPROTO_UDP,
2918 source_ip,
2919 ntohs (udp->source_port),
2920 destination_ip,
2921 ntohs (udp->destination_port),
2922 NULL);
2923 if (NULL == state)
2924 {
2926 _ (
2927 "UDP Packet dropped, have no matching connection information\n"));
2928 return;
2929 }
2930 env = GNUNET_MQ_msg_extra (urm,
2931 pktlen - sizeof(struct GNUNET_TUN_UdpHeader),
2933 urm->source_port = htons (0);
2934 urm->destination_port = htons (0);
2935 GNUNET_memcpy (&urm[1],
2936 &udp[1],
2937 pktlen - sizeof(struct GNUNET_TUN_UdpHeader));
2939 env);
2940}
2941
2942
2954static void
2956 size_t pktlen,
2957 int af,
2958 const void *destination_ip,
2959 const void *source_ip)
2960{
2961 struct ChannelState *state;
2962 char buf[pktlen] GNUNET_ALIGN;
2963 struct GNUNET_TUN_TcpHeader *mtcp;
2964 struct GNUNET_EXIT_TcpDataMessage *tdm;
2965 struct GNUNET_MQ_Envelope *env;
2966 size_t mlen;
2967
2968 {
2969 char sbuf[INET6_ADDRSTRLEN];
2970 char dbuf[INET6_ADDRSTRLEN];
2972 "Received TCP packet with %u bytes going from %s:%u to %s:%u\n",
2973 (unsigned int) (pktlen - sizeof(struct GNUNET_TUN_TcpHeader)),
2974 inet_ntop (af,
2975 source_ip,
2976 sbuf, sizeof(sbuf)),
2977 (unsigned int) ntohs (tcp->source_port),
2978 inet_ntop (af,
2979 destination_ip,
2980 dbuf, sizeof(dbuf)),
2981 (unsigned int) ntohs (tcp->destination_port));
2982 }
2983
2984 if (pktlen < sizeof(struct GNUNET_TUN_TcpHeader))
2985 {
2986 /* blame kernel */
2987 GNUNET_break (0);
2988 return;
2989 }
2991 IPPROTO_TCP,
2992 source_ip,
2993 ntohs (tcp->source_port),
2994 destination_ip,
2995 ntohs (tcp->destination_port),
2996 NULL);
2997 if (NULL == state)
2998 {
3000 _ (
3001 "TCP Packet dropped, have no matching connection information\n"));
3002
3003 return;
3004 }
3005 /* mug port numbers and crc to avoid information leakage;
3006 sender will need to lookup the correct values anyway */
3007 GNUNET_memcpy (buf, tcp, pktlen);
3008 mtcp = (struct GNUNET_TUN_TcpHeader *) buf;
3009 mtcp->source_port = 0;
3010 mtcp->destination_port = 0;
3011 mtcp->crc = 0;
3012
3013 mlen = sizeof(struct GNUNET_EXIT_TcpDataMessage) + (pktlen - sizeof(struct
3015 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
3016 {
3017 GNUNET_break (0);
3018 return;
3019 }
3020 env = GNUNET_MQ_msg_extra (tdm,
3021 pktlen - sizeof(struct GNUNET_TUN_TcpHeader),
3023 tdm->reserved = htonl (0);
3025 buf,
3026 pktlen);
3028 env);
3029}
3030
3031
3038static int
3040 const struct GNUNET_MessageHeader *message)
3041{
3042 const struct GNUNET_TUN_Layer2PacketHeader *pkt_tun;
3043 size_t size;
3044
3046 "Got %u-byte message of type %u from gnunet-helper-exit\n",
3047 ntohs (message->size),
3048 ntohs (message->type));
3050 gettext_noop ("# Packets received from TUN"),
3051 1, GNUNET_NO);
3052 if (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER)
3053 {
3054 GNUNET_break (0);
3055 return GNUNET_OK;
3056 }
3057 size = ntohs (message->size);
3058 if (size < sizeof(struct GNUNET_TUN_Layer2PacketHeader) + sizeof(struct
3060 {
3061 GNUNET_break (0);
3062 return GNUNET_OK;
3063 }
3065 gettext_noop ("# Bytes received from TUN"),
3066 size, GNUNET_NO);
3067 pkt_tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1];
3068 size -= sizeof(struct GNUNET_TUN_Layer2PacketHeader) + sizeof(struct
3070 switch (ntohs (pkt_tun->proto))
3071 {
3072 case ETH_P_IPV4:
3073 {
3074 const struct GNUNET_TUN_IPv4Header *pkt4;
3075
3076 if (size < sizeof(struct GNUNET_TUN_IPv4Header))
3077 {
3078 /* Kernel to blame? */
3079 GNUNET_break (0);
3080 return GNUNET_OK;
3081 }
3082 pkt4 = (const struct GNUNET_TUN_IPv4Header *) &pkt_tun[1];
3083 if (size != ntohs (pkt4->total_length))
3084 {
3085 /* Kernel to blame? */
3086 GNUNET_break (0);
3087 return GNUNET_OK;
3088 }
3089 if (pkt4->header_length * 4 != sizeof(struct GNUNET_TUN_IPv4Header))
3090 {
3092 _ ("IPv4 packet options received. Ignored.\n"));
3093 return GNUNET_OK;
3094 }
3095
3096 size -= sizeof(struct GNUNET_TUN_IPv4Header);
3097 switch (pkt4->protocol)
3098 {
3099 case IPPROTO_UDP:
3100 udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt4[1], size,
3101 AF_INET,
3102 &pkt4->destination_address,
3103 &pkt4->source_address);
3104 break;
3105
3106 case IPPROTO_TCP:
3107 tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt4[1], size,
3108 AF_INET,
3109 &pkt4->destination_address,
3110 &pkt4->source_address);
3111 break;
3112
3113 case IPPROTO_ICMP:
3114 icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt4[1], size,
3115 AF_INET,
3116 &pkt4->destination_address,
3117 &pkt4->source_address);
3118 break;
3119
3120 default:
3122 _ (
3123 "IPv4 packet with unsupported next header %u received. Ignored.\n"),
3124 (int) pkt4->protocol);
3125 return GNUNET_OK;
3126 }
3127 }
3128 break;
3129
3130 case ETH_P_IPV6:
3131 {
3132 const struct GNUNET_TUN_IPv6Header *pkt6;
3133
3134 if (size < sizeof(struct GNUNET_TUN_IPv6Header))
3135 {
3136 /* Kernel to blame? */
3137 GNUNET_break (0);
3138 return GNUNET_OK;
3139 }
3140 pkt6 = (struct GNUNET_TUN_IPv6Header *) &pkt_tun[1];
3141 if (size != ntohs (pkt6->payload_length) + sizeof(struct
3143 {
3144 /* Kernel to blame? */
3145 GNUNET_break (0);
3146 return GNUNET_OK;
3147 }
3148 size -= sizeof(struct GNUNET_TUN_IPv6Header);
3149 switch (pkt6->next_header)
3150 {
3151 case IPPROTO_UDP:
3152 udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt6[1], size,
3153 AF_INET6,
3154 &pkt6->destination_address,
3155 &pkt6->source_address);
3156 break;
3157
3158 case IPPROTO_TCP:
3159 tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt6[1], size,
3160 AF_INET6,
3161 &pkt6->destination_address,
3162 &pkt6->source_address);
3163 break;
3164
3165 case IPPROTO_ICMPV6:
3166 icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt6[1], size,
3167 AF_INET6,
3168 &pkt6->destination_address,
3169 &pkt6->source_address);
3170 break;
3171
3172 default:
3174 _ (
3175 "IPv6 packet with unsupported next header %d received. Ignored.\n"),
3176 pkt6->next_header);
3177 return GNUNET_OK;
3178 }
3179 }
3180 break;
3181
3182 default:
3184 _ ("Packet from unknown protocol %u received. Ignored.\n"),
3185 ntohs (pkt_tun->proto));
3186 break;
3187 }
3188 return GNUNET_OK;
3189}
3190
3191
3200static void *
3201new_channel (void *cls,
3202 struct GNUNET_CADET_Channel *channel,
3203 const struct GNUNET_PeerIdentity *initiator)
3204{
3205 struct ChannelState *s = GNUNET_new (struct ChannelState);
3206
3207 s->is_dns = GNUNET_SYSERR;
3208 s->peer = *initiator;
3210 gettext_noop ("# Inbound CADET channels created"),
3211 1,
3212 GNUNET_NO);
3214 "Received inbound channel from `%s'\n",
3215 GNUNET_i2s (initiator));
3216 s->channel = channel;
3217 return s;
3218}
3219
3220
3228static int
3229free_iterate (void *cls,
3230 const struct GNUNET_HashCode *hash,
3231 void *value)
3232{
3234 return GNUNET_YES;
3235}
3236
3237
3246static void
3247dummy_task (void *cls)
3248{
3249 /* just terminate */
3250}
3251
3252
3258static void
3259cleanup (void *cls)
3260{
3261 unsigned int i;
3262
3264 "Exit service is shutting down now\n");
3265
3266 if (NULL != helper_handle)
3267 {
3269 helper_handle = NULL;
3270 }
3271 if (NULL != regex4)
3272 {
3274 regex4 = NULL;
3275 }
3276 if (NULL != regex6)
3277 {
3279 regex6 = NULL;
3280 }
3281 if (NULL != services)
3282 {
3285 NULL);
3287 }
3288 if (NULL != dns_port)
3289 {
3291 dns_port = NULL;
3292 }
3293 if (NULL != cadet_port4)
3294 {
3296 cadet_port4 = NULL;
3297 }
3298 if (NULL != cadet_port6)
3299 {
3301 cadet_port6 = NULL;
3302 }
3303 if (NULL != cadet_handle)
3304 {
3306 cadet_handle = NULL;
3307 }
3308 if (NULL != connections_map)
3309 {
3311 &free_iterate,
3312 NULL);
3314 connections_map = NULL;
3315 }
3316 if (NULL != connections_heap)
3317 {
3319 connections_heap = NULL;
3320 }
3321 if (NULL != dnsstub)
3322 {
3324 dnsstub = NULL;
3325 }
3326 if (NULL != sign_op)
3327 {
3329 sign_op = NULL;
3330 }
3331 if (NULL != pils)
3332 {
3334 pils = NULL;
3335 }
3336 if (NULL != dht_task)
3337 {
3339 dht_task = NULL;
3340 }
3341 if (NULL != dht_put)
3342 {
3344 dht_put = NULL;
3345 }
3346 if (NULL != dht)
3347 {
3349 dht = NULL;
3350 }
3351 if (NULL != stats)
3352 {
3354 GNUNET_NO);
3355 stats = NULL;
3356 }
3357 for (i = 0; i < 8; i++)
3359}
3360
3361
3369static void
3371 char *cpy,
3372 const char *name)
3373{
3374 char *redirect;
3375 char *hostname;
3376 char *hostport;
3377 struct LocalService *serv;
3378 char *n;
3379 size_t slen;
3380 int local_port;
3381 int remote_port;
3382
3383 slen = strlen (name);
3384 GNUNET_assert (slen >= 8);
3385 n = GNUNET_strndup (name, slen - 8 /* remove .gnunet. */);
3386
3387 for (redirect = strtok (cpy, " ;"); redirect != NULL;
3388 redirect = strtok (NULL, " ;"))
3389 {
3390 if (NULL == (hostname = strstr (redirect, ":")))
3391 {
3393 _ (
3394 "Option `%s' for domain `%s' is not formatted correctly!\n")
3395 ,
3396 redirect,
3397 name);
3398 continue;
3399 }
3400 hostname[0] = '\0';
3401 hostname++;
3402 if (NULL == (hostport = strstr (hostname, ":")))
3403 {
3405 _ (
3406 "Option `%s' for domain `%s' is not formatted correctly!\n")
3407 ,
3408 redirect,
3409 name);
3410 continue;
3411 }
3412 hostport[0] = '\0';
3413 hostport++;
3414
3415 local_port = atoi (redirect);
3416 remote_port = atoi (hostport);
3417
3418 if (! ((local_port > 0) && (local_port < 65536)))
3419 {
3421 _ ("`%s' is not a valid port number (for domain `%s')!"),
3422 redirect,
3423 name);
3424 continue;
3425 }
3426 if (! ((remote_port > 0) && (remote_port < 65536)))
3427 {
3429 _ ("`%s' is not a valid port number (for domain `%s')!"),
3430 hostport,
3431 name);
3432 continue;
3433 }
3434
3435 serv = GNUNET_new (struct LocalService);
3436 serv->address.proto = proto;
3437 serv->address.port = remote_port;
3438 if (0 == strcmp ("localhost4",
3439 hostname))
3440 {
3441 const char *ip4addr = exit_argv[5];
3442
3443 serv->address.af = AF_INET;
3444 GNUNET_assert (1 == inet_pton (AF_INET,
3445 ip4addr,
3446 &serv->address.address.ipv4));
3447 }
3448 else if (0 == strcmp ("localhost6",
3449 hostname))
3450 {
3451 const char *ip6addr = exit_argv[3];
3452
3453 serv->address.af = AF_INET6;
3454 GNUNET_assert (1 == inet_pton (AF_INET6,
3455 ip6addr,
3456 &serv->address.address.ipv6));
3457 }
3458 else
3459 {
3460 struct addrinfo *res;
3461 int ret;
3462
3463 ret = getaddrinfo (hostname,
3464 NULL,
3465 NULL,
3466 &res);
3467 if ((0 != ret) || (NULL == res))
3468 {
3470 _ (
3471 "No addresses found for hostname `%s' of service `%s'!\n")
3472 ,
3473 hostname,
3474 n);
3475 GNUNET_free (serv);
3476 continue;
3477 }
3478
3479 serv->address.af = res->ai_family;
3480 switch (res->ai_family)
3481 {
3482 case AF_INET:
3483 if (! ipv4_enabled)
3484 {
3486 _ (
3487 "Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
3488 n);
3489 freeaddrinfo (res);
3490 GNUNET_free (serv);
3491 continue;
3492 }
3493 serv->address.address.ipv4
3494 = ((struct sockaddr_in *) res->ai_addr)->sin_addr;
3495 break;
3496
3497 case AF_INET6:
3498 if (! ipv6_enabled)
3499 {
3501 _ (
3502 "Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
3503 n);
3504 freeaddrinfo (res);
3505 GNUNET_free (serv);
3506 continue;
3507 }
3508 serv->address.address.ipv6
3509 = ((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
3510 break;
3511
3512 default:
3513 freeaddrinfo (res);
3515 _ (
3516 "No IP addresses found for hostname `%s' of service `%s'!\n"),
3517 hostname,
3518 n);
3519 GNUNET_free (serv);
3520 continue;
3521 }
3522 freeaddrinfo (res);
3523 }
3525 n,
3526 local_port,
3527 serv);
3528 }
3529 GNUNET_free (n);
3530}
3531
3532
3539static void
3541 const char *section)
3542{
3543 char *cpy;
3544
3545 if ((strlen (section) < 8) ||
3546 (0 != strcmp (".gnunet.", section + (strlen (section) - 8))))
3547 return;
3548 if (GNUNET_OK ==
3550 section,
3551 "UDP_REDIRECTS",
3552 &cpy))
3553 {
3554 add_services (IPPROTO_UDP,
3555 cpy,
3556 section);
3557 GNUNET_free (cpy);
3558 }
3559 if (GNUNET_OK ==
3561 section,
3562 "TCP_REDIRECTS",
3563 &cpy))
3564 {
3565 add_services (IPPROTO_TCP,
3566 cpy,
3567 section);
3568 GNUNET_free (cpy);
3569 }
3570}
3571
3572
3579static void
3580do_dht_put (void *cls);
3581
3582
3589static void
3590dht_put_cont (void *cls)
3591{
3592 dht_put = NULL;
3593}
3594
3595
3596static void
3598 const struct GNUNET_PeerIdentity *pid,
3599 const struct GNUNET_CRYPTO_EddsaSignature *sig)
3600{
3601 GNUNET_assert (sig);
3602
3603 sign_op = NULL;
3604
3606 sizeof (dns_advertisement.signature));
3607
3608 do_dht_put (cls);
3609}
3610
3611
3618static void
3655
3656
3657static void
3659 const struct GNUNET_HELLO_Parser *parser,
3660 const struct GNUNET_HashCode *hash)
3661{
3662 const struct GNUNET_PeerIdentity *my_identity;
3663
3666
3668 my_identity, sizeof (*my_identity));
3669 dns_advertisement.purpose.size = htonl (sizeof(struct
3671 - sizeof(struct
3673 );
3676 GNUNET_CRYPTO_hash ("dns",
3677 strlen ("dns"),
3678 &dht_put_key);
3679
3680 if (NULL != sign_op)
3681 {
3683 sign_op = NULL;
3684 }
3685
3686 if (NULL != dht_task)
3688
3690 NULL);
3691}
3692
3693
3698static void
3700{
3702 "exit",
3703 "EXIT_IPV4");
3705 "exit",
3706 "EXIT_IPV6");
3708 "exit",
3709 "ENABLE_IPV4");
3711 "exit",
3712 "ENABLE_IPV6");
3713 if ((ipv4_exit || ipv4_enabled) &&
3714 (GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET)) )
3715 {
3717 _ (
3718 "This system does not support IPv4, will disable IPv4 functions despite them being enabled in the configuration\n"));
3721 }
3722 if ((ipv6_exit || ipv6_enabled) &&
3723 (GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET6)) )
3724 {
3726 _ (
3727 "This system does not support IPv6, will disable IPv6 functions despite them being enabled in the configuration\n"));
3730 }
3731 if (ipv4_exit && (! ipv4_enabled))
3732 {
3734 _ (
3735 "Cannot enable IPv4 exit but disable IPv4 on TUN interface, will use ENABLE_IPv4=YES\n"));
3737 }
3738 if (ipv6_exit && (! ipv6_enabled))
3739 {
3741 _ (
3742 "Cannot enable IPv6 exit but disable IPv6 on TUN interface, will use ENABLE_IPv6=YES\n"));
3744 }
3745}
3746
3747
3752static void
3754{
3756 GNUNET_MQ_hd_var_size (dns_request,
3758 struct DnsResponseMessage,
3759 NULL),
3761 };
3762 char *dns_exit;
3763 struct GNUNET_HashCode port;
3764
3765 if (GNUNET_YES !=
3767 "exit",
3768 "EXIT_DNS"))
3769 return;
3770 GNUNET_assert (NULL != (dnsstub = GNUNET_DNSSTUB_start (128)));
3771 dns_exit = NULL;
3772 /* TODO: support using multiple DNS resolvers */
3773 if ((GNUNET_OK !=
3775 "exit",
3776 "DNS_RESOLVER",
3777 &dns_exit)) ||
3778 (GNUNET_OK !=
3780 dns_exit)))
3781 {
3783 "dns",
3784 "DNS_RESOLVER",
3785 _ ("need a valid IPv4 or IPv6 address\n"));
3786 GNUNET_free (dns_exit);
3787 return;
3788 }
3789 /* open port */
3792 &port);
3794 "Opening CADET port %s for DNS exit service\n",
3795 GNUNET_h2s (&port));
3797 &port,
3798 &new_channel,
3799 NULL,
3800 NULL,
3802 handlers);
3803 /* advertise exit */
3804 dht = GNUNET_DHT_connect (cfg, 1);
3805 dht_task = NULL;
3807 sign_op = NULL;
3808 GNUNET_free (dns_exit);
3809}
3810
3811
3817static int
3819{
3820 char *exit_ifname;
3821 char *tun_ifname;
3822 char *ipv6addr;
3823 char *ipv6prefix_s;
3824 char *ipv4addr;
3825 char *ipv4mask;
3826
3827 exit_argv[0] = GNUNET_strdup ("exit-gnunet");
3828 if (GNUNET_SYSERR ==
3830 "exit",
3831 "TUN_IFNAME",
3832 &tun_ifname))
3833 {
3835 "EXIT",
3836 "TUN_IFNAME");
3837 return GNUNET_SYSERR;
3838 }
3839 exit_argv[1] = tun_ifname;
3840 if (ipv4_enabled)
3841 {
3842 if (GNUNET_SYSERR ==
3844 "exit",
3845 "EXIT_IFNAME",
3846 &exit_ifname))
3847 {
3849 "EXIT",
3850 "EXIT_IFNAME");
3851 return GNUNET_SYSERR;
3852 }
3853 exit_argv[2] = exit_ifname;
3854 }
3855 else
3856 {
3857 exit_argv[2] = GNUNET_strdup ("-");
3858 }
3859
3860 if (GNUNET_YES == ipv6_enabled)
3861 {
3862 ipv6addr = NULL;
3863 if (((GNUNET_SYSERR ==
3865 "exit",
3866 "IPV6ADDR",
3867 &ipv6addr)) ||
3868 (1 != inet_pton (AF_INET6,
3869 ipv6addr,
3870 &exit_ipv6addr))))
3871 {
3873 "EXIT",
3874 "IPV6ADDR");
3875 GNUNET_free (ipv6addr);
3876 return GNUNET_SYSERR;
3877 }
3878 exit_argv[3] = ipv6addr;
3879 if (GNUNET_SYSERR ==
3881 "exit",
3882 "IPV6PREFIX",
3883 &ipv6prefix_s))
3884 {
3886 "EXIT",
3887 "IPV6PREFIX");
3888 return GNUNET_SYSERR;
3889 }
3890 exit_argv[4] = ipv6prefix_s;
3891 if ((GNUNET_OK !=
3893 "exit",
3894 "IPV6PREFIX",
3895 &ipv6prefix)) ||
3896 (ipv6prefix >= 127))
3897 {
3899 "EXIT",
3900 "IPV6PREFIX",
3901 _ ("Must be a number"));
3902 return GNUNET_SYSERR;
3903 }
3904 }
3905 else
3906 {
3907 /* IPv6 explicitly disabled */
3908 exit_argv[3] = GNUNET_strdup ("-");
3909 exit_argv[4] = GNUNET_strdup ("-");
3910 }
3911 if (GNUNET_YES == ipv4_enabled)
3912 {
3913 ipv4addr = NULL;
3914 if (((GNUNET_SYSERR ==
3916 "exit",
3917 "IPV4ADDR",
3918 &ipv4addr)) ||
3919 (1 != inet_pton (AF_INET,
3920 ipv4addr,
3921 &exit_ipv4addr))))
3922 {
3924 "EXIT",
3925 "IPV4ADDR");
3926 GNUNET_free (ipv4addr);
3927 return GNUNET_SYSERR;
3928 }
3929 exit_argv[5] = ipv4addr;
3930 ipv4mask = NULL;
3931 if (((GNUNET_SYSERR ==
3933 "exit",
3934 "IPV4MASK",
3935 &ipv4mask)) ||
3936 (1 != inet_pton (AF_INET,
3937 ipv4mask,
3938 &exit_ipv4mask))))
3939 {
3941 "EXIT",
3942 "IPV4MASK");
3943 GNUNET_free (ipv4mask);
3944 return GNUNET_SYSERR;
3945 }
3946 exit_argv[6] = ipv4mask;
3947 }
3948 else
3949 {
3950 /* IPv4 explicitly disabled */
3951 exit_argv[5] = GNUNET_strdup ("-");
3952 exit_argv[6] = GNUNET_strdup ("-");
3953 }
3954 exit_argv[7] = NULL;
3955 return GNUNET_OK;
3956}
3957
3958
3967static void
3968run (void *cls,
3969 char *const *args,
3970 const char *cfgfile,
3971 const struct GNUNET_CONFIGURATION_Handle *cfg_)
3972{
3974 GNUNET_MQ_hd_var_size (icmp_remote,
3977 NULL),
3978 GNUNET_MQ_hd_var_size (udp_remote,
3981 NULL),
3982 GNUNET_MQ_hd_var_size (tcp_remote,
3985 NULL),
3986 GNUNET_MQ_hd_var_size (tcp_data,
3989 NULL),
3991 };
3992 struct GNUNET_HashCode port;
3993 char *policy;
3994 char *binary;
3995 char *regex;
3996 char *prefixed_regex;
3997
3998 cfg = cfg_;
3999 if (GNUNET_OK !=
4001 "exit",
4002 "MAX_CONNECTIONS",
4004 max_connections = 1024;
4007 cfg,
4008 "gnunet-helper-exit");
4009 if ((ipv4_exit) || (ipv6_exit))
4010 {
4011 if (GNUNET_YES !=
4013 GNUNET_YES,
4014 "gnunet-vpn - - - 169.1.3.7 255.255.255.0"))
4015 // no nat, ipv4 only
4016 {
4017 GNUNET_free (binary);
4019 _ (
4020 "`%s' is not SUID or the path is invalid, EXIT will not work\n"),
4021 "gnunet-helper-exit");
4023 NULL);
4024 global_ret = 1;
4025 return;
4026 }
4027 }
4028 if (! (ipv4_enabled || ipv6_enabled))
4029 {
4030 GNUNET_free (binary);
4032 _ ("No useful service enabled. Exiting.\n"));
4034 return;
4035 }
4036
4038 NULL);
4040 cfg);
4042 if (NULL == cadet_handle)
4043 {
4044 GNUNET_free (binary);
4046 return;
4047 }
4049 if (GNUNET_OK !=
4051 {
4052 GNUNET_free (binary);
4054 return;
4055 }
4056
4058 GNUNET_NO);
4060 GNUNET_NO);
4065 NULL);
4066
4067 /* Cadet handle acquired, now open ports and announce regular
4068 expressions matching our exit */
4069 if ((GNUNET_YES == ipv4_enabled) &&
4070 (GNUNET_YES == ipv4_exit))
4071 {
4074 &port);
4076 "Opening CADET port %s for IPv4 gateway service\n",
4077 GNUNET_h2s (&port));
4079 &port,
4080 &new_channel,
4081 NULL,
4082 NULL,
4084 handlers);
4085 policy = NULL;
4086 if (GNUNET_OK !=
4088 "exit",
4089 "EXIT_RANGE_IPV4_POLICY",
4090 &policy))
4091 regex = NULL;
4092 else
4093 regex = GNUNET_REGEX_ipv4policy2regex (policy);
4094 GNUNET_free (policy);
4095 if (NULL != regex)
4096 {
4097 (void) GNUNET_asprintf (&prefixed_regex,
4098 "%s%s",
4100 regex);
4102 prefixed_regex,
4105 GNUNET_free (regex);
4106 GNUNET_free (prefixed_regex);
4107 }
4108 }
4109
4111 {
4114 &port);
4116 "Opening CADET port %s for IPv6 gateway service\n",
4117 GNUNET_h2s (&port));
4119 &port,
4120 &new_channel,
4121 NULL,
4122 NULL,
4124 handlers);
4125 policy = NULL;
4126 if (GNUNET_OK !=
4128 "exit",
4129 "EXIT_RANGE_IPV6_POLICY",
4130 &policy))
4131 regex = NULL;
4132 else
4133 regex = GNUNET_REGEX_ipv6policy2regex (policy);
4134 GNUNET_free (policy);
4135 if (NULL != regex)
4136 {
4137 (void) GNUNET_asprintf (&prefixed_regex,
4138 "%s%s",
4140 regex);
4142 prefixed_regex,
4145 GNUNET_free (regex);
4146 GNUNET_free (prefixed_regex);
4147 }
4148 }
4150 GNUNET_NO,
4151 binary,
4152 exit_argv,
4154 NULL,
4155 NULL);
4156 GNUNET_free (binary);
4157}
4158
4159
4167int
4168main (int argc,
4169 char *const *argv)
4170{
4171 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
4173 };
4174
4175 return (GNUNET_OK ==
4177 argc,
4178 argv,
4179 "gnunet-daemon-exit",
4180 gettext_noop (
4181 "Daemon to run to provide an IP exit node for the VPN"),
4182 options,
4183 &run,
4184 NULL)) ? global_ret : 1;
4185}
4186
4187
4188/* end of gnunet-daemon-exit.c */
struct GNUNET_GETOPT_CommandLineOption options[]
Definition 002.c:5
struct GNUNET_MQ_MessageHandlers handlers[]
Definition 003.c:1
struct GNUNET_MessageHeader * msg
Definition 005.c:2
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
DNS network structs.
int main()
Program to simulate results from GCP_get_desirability_of_path() for various plausible inputs.
format for cadet messages exchanged between VPN service and exit daemon
#define gettext_noop(String)
Definition gettext.h:74
static int start
Set if we are to start default services (including ARM).
Definition gnunet-arm.c:38
static int ret
Final status code.
Definition gnunet-arm.c:93
static uint16_t port
Port number.
Definition gnunet-bcd.c:146
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 void do_initial_dht_put(void *cls, const struct GNUNET_HELLO_Parser *parser, const struct GNUNET_HashCode *hash)
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 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 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 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 * new_service_channel(void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *initiator)
Callback from CADET for new channels.
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 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 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 void * new_channel(void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *initiator)
Callback from CADET for new channels.
#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.
static void sign_dns_advertisement(void *cls, const struct GNUNET_PeerIdentity *pid, const struct GNUNET_CRYPTO_EddsaSignature *sig)
#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 struct GNUNET_PILS_Operation * sign_op
Operation for signing the dns advertisement.
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 struct GNUNET_PILS_Handle * pils
The pils service handle.
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.
static char * data
The data to insert into the dht.
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_TIME_Relative expiration
User supplied expiration value.
static char * name
Name (label) of the records to list.
static int state
The current state of the parser.
static char * res
Currently read line or NULL on EOF.
static char * value
Value of the record to add/remove.
static uint8_t proto
Protocol to use.
static struct GNUNET_NETWORK_Handle * ls
Listen socket for STUN processing.
Definition gnunet-nat.c:85
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
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 void cleanup()
Cleanup task.
static unsigned long long remote_port
Remote host's port.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
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.
commonly used definitions; globals in this file are exempt from the rule that the module name ("commo...
@ GNUNET_BLOCK_TYPE_DNS
Block for storing DNS exit service advertisements.
API to the DHT service.
struct GNUNET_PILS_Handle * GNUNET_PILS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_PILS_PidChangeCallback pid_change_cb, void *cls)
Connect to the PILS service.
Definition pils_api.c:465
void GNUNET_PILS_disconnect(struct GNUNET_PILS_Handle *handle)
Disconnect from the PILS service.
Definition pils_api.c:488
void GNUNET_PILS_cancel(struct GNUNET_PILS_Operation *op)
Cancel request.
Definition pils_api.c:623
struct GNUNET_PILS_Operation * GNUNET_PILS_sign_by_peer_identity(struct GNUNET_PILS_Handle *handle, const struct GNUNET_CRYPTO_SignaturePurpose *purpose, GNUNET_PILS_SignResultCallback cb, void *cb_cls)
Sign data with the peer id.
Definition pils_api.c:528
const struct GNUNET_PeerIdentity * GNUNET_PILS_get_identity(const struct GNUNET_PILS_Handle *handle)
Return the current peer identity of a given handle.
Definition pils_api.c:727
Constants for network protocols.
API to access regex service to advertise capabilities via regex and discover respective peers using m...
#define GNUNET_SIGNATURE_PURPOSE_DNS_RECORD
Signature on a GNUNET_DNS_Advertisement.
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).
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition cadet_api.c:897
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Indicate readiness to receive the next message on a channel.
Definition cadet_api.c:875
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition cadet_api.c:833
struct GNUNET_MQ_Handle * GNUNET_CADET_get_mq(const struct GNUNET_CADET_Channel *channel)
Obtain the message queue for a connected channel.
Definition cadet_api.c:1081
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:966
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition cadet_api.c:777
void GNUNET_CADET_close_port(struct GNUNET_CADET_Port *p)
Close a port opened with GNUNET_CADET_open_port.
Definition cadet_api.c:804
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.
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:1150
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:1087
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:1036
void GNUNET_DHT_disconnect(struct GNUNET_DHT_Handle *handle)
Shutdown connection with the DHT service.
Definition dht_api.c:1059
@ GNUNET_DHT_RO_NONE
Default.
struct GNUNET_DNSSTUB_Context * GNUNET_DNSSTUB_start(unsigned int num_sockets)
Start a DNS stub resolver.
Definition dnsstub.c:586
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_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
#define GNUNET_GETOPT_OPTION_END
Marker for the end of the list of options.
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.
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.
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.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
@ 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_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
void * GNUNET_CONTAINER_heap_remove_root(struct GNUNET_CONTAINER_Heap *heap)
Remove root of 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, bool can_drop, GNUNET_HELPER_Continuation cont, void *cont_cls)
Send an message to the helper.
Definition helper.c:639
struct GNUNET_HELPER_Handle * GNUNET_HELPER_start(const struct GNUNET_OS_ProjectData *pd, 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:484
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:562
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#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.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ 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:305
#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.
#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
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_gnunet(void)
Return default project data used by 'libgnunetutil' for GNUnet.
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.
char * GNUNET_OS_get_suid_binary_path(const struct GNUNET_OS_ProjectData *pd, 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_PROGRAM_run(const struct GNUNET_OS_ProjectData *pd, 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:407
#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.
char * GNUNET_REGEX_ipv6policy2regex(const char *policy)
Convert an exit policy to a regular expression.
Definition regex.c:725
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.
char * GNUNET_REGEX_ipv4policy2regex(const char *policy)
Convert an exit policy to a regular expression.
Definition regex.c:682
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition scheduler.c:572
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:1345
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
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:1310
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:1283
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).
#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:406
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:636
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:115
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:193
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:80
#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:255
#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.
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 tun.c:57
#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:165
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 tun.c:38
#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:135
#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
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:224
static unsigned int size
Size of the "table".
Definition peer.c:68
#define _(String)
GNU gettext support macro.
Definition platform.h:179
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::@79 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
struct ChannelState::@54::@55 tcp_udp
struct GNUNET_DNSSTUB_RequestSocket * rs
Socket we are using to transmit this request (must match if we receive a response).
struct ChannelState::@54::@56 dns
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::@54 specifics
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.
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.
an ECC signature using EdDSA.
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!...
Connection to the DHT service.
Definition dht_api.c:235
Handle to a PUT request.
Definition dht_api.c:43
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_SignaturePurpose purpose
Beginning of signed portion of the record, signs everything until the end of the struct.
Definition block_dns.h:55
struct GNUNET_CRYPTO_EddsaSignature signature
Signature of the peer affirming that it is offering the service.
Definition block_dns.h:49
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.
Context for parsing HELLOs.
Definition hello-uri.c:233
The handle to a helper process.
Definition helper.c:77
A 512-bit hashcode.
Message handler for a specific message type.
Header for all communications.
A handle for the PILS service.
Definition pils_api.c:82
The identity of the host (wraps the signing key of the peer).
Handle to store cached data about a regex announce.
Entry in list of pending tasks.
Definition scheduler.c:141
Handle for the service.
Time for absolute times used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
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.
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).
unsigned int off
Number of 32-bit words in TCP header.
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.
int af
AF_INET or AF_INET6.
union SocketAddress::@53 address
Remote address information.
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.
enum GNUNET_TIME_RounderInterval ri
Definition time.c:1251