GNUnet 0.28.0-dev.3-7-g31e20e2e6
 
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;
547 UINT16_MAX
548 + 1);
549 channels[ts->specifics.dns.my_id] = ts;
550 GNUNET_memcpy (buf,
551 &msg->dns,
552 dlen);
553 dns_out = (struct GNUNET_TUN_DnsHeader *) buf;
554 dns_out->id = ts->specifics.dns.my_id;
556 buf,
557 dlen,
559 NULL);
560 if (NULL == ts->specifics.dns.rs)
561 {
562 GNUNET_break_op (0);
563 return;
564 }
566}
567
568
576static void
578 const struct RedirectInformation *ri)
579{
580 char *off;
581
582 memset (hash,
583 0,
584 sizeof(struct GNUNET_HashCode));
585 /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
586 so we put the IP address in there (and hope for few collisions) */
587 off = (char *) hash;
588 switch (ri->remote_address.af)
589 {
590 case AF_INET:
591 GNUNET_memcpy (off,
592 &ri->remote_address.address.ipv4,
593 sizeof(struct in_addr));
594 off += sizeof(struct in_addr);
595 break;
596
597 case AF_INET6:
598 GNUNET_memcpy (off,
599 &ri->remote_address.address.ipv6,
600 sizeof(struct in6_addr));
601 off += sizeof(struct in_addr);
602 break;
603
604 default:
605 GNUNET_assert (0);
606 }
607 GNUNET_memcpy (off,
608 &ri->remote_address.port,
609 sizeof(uint16_t));
610 off += sizeof(uint16_t);
611 switch (ri->local_address.af)
612 {
613 case AF_INET:
614 GNUNET_memcpy (off,
615 &ri->local_address.address.ipv4,
616 sizeof(struct in_addr));
617 off += sizeof(struct in_addr);
618 break;
619
620 case AF_INET6:
621 GNUNET_memcpy (off,
622 &ri->local_address.address.ipv6,
623 sizeof(struct in6_addr));
624 off += sizeof(struct in_addr);
625 break;
626
627 default:
628 GNUNET_assert (0);
629 }
630 GNUNET_memcpy (off,
631 &ri->local_address.port,
632 sizeof(uint16_t));
633 off += sizeof(uint16_t);
634 GNUNET_memcpy (off,
635 &ri->remote_address.proto,
636 sizeof(uint8_t));
637 /* off += sizeof (uint8_t); */
638}
639
640
654static struct ChannelState *
656 int protocol,
657 const void *destination_ip,
658 uint16_t destination_port,
659 const void *local_ip,
660 uint16_t local_port,
662{
663 struct RedirectInformation ri;
664 struct GNUNET_HashCode key;
665 struct ChannelState *state;
666
667 if (((af == AF_INET) && (protocol == IPPROTO_ICMP)) ||
668 ((af == AF_INET6) && (protocol == IPPROTO_ICMPV6)))
669 {
670 /* ignore ports */
672 local_port = 0;
673 }
674 ri.remote_address.af = af;
675 if (af == AF_INET)
676 ri.remote_address.address.ipv4 = *((struct in_addr*) destination_ip);
677 else
678 ri.remote_address.address.ipv6 = *((struct in6_addr*) destination_ip);
679 ri.remote_address.port = destination_port;
680 ri.remote_address.proto = protocol;
681 ri.local_address.af = af;
682 if (af == AF_INET)
683 ri.local_address.address.ipv4 = *((struct in_addr*) local_ip);
684 else
685 ri.local_address.address.ipv6 = *((struct in6_addr*) local_ip);
686 ri.local_address.port = local_port;
687 ri.local_address.proto = protocol;
689 &ri);
690 if (NULL != state_key)
691 *state_key = key;
693 &key);
694 if (NULL == state)
695 return NULL;
696 /* Mark this connection as freshly used */
697 if (NULL == state_key)
698 GNUNET_CONTAINER_heap_update_cost (state->specifics.tcp_udp.heap_node,
699 GNUNET_TIME_absolute_get ().abs_value_us)
700 ;
701 return state;
702}
703
704
714static int
717{
718 struct ChannelState *state = cls;
719
720 if (NULL == state)
721 {
722 GNUNET_break_op (0);
723 return GNUNET_SYSERR;
724 }
725 if (GNUNET_YES == state->is_dns)
726 {
727 GNUNET_break_op (0);
728 return GNUNET_SYSERR;
729 }
730 if (NULL == state->specifics.tcp_udp.serv)
731 {
732 GNUNET_break_op (0);
733 return GNUNET_SYSERR;
734 }
735 if (NULL != state->specifics.tcp_udp.heap_node)
736 {
737 GNUNET_break_op (0);
738 return GNUNET_SYSERR;
739 }
740 if (start->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
741 {
742 GNUNET_break_op (0);
743 return GNUNET_SYSERR;
744 }
745 return GNUNET_OK;
746}
747
748
767static void
769 size_t payload_length,
770 int protocol,
771 const struct GNUNET_TUN_TcpHeader *tcp_header,
772 const struct SocketAddress *src_address,
773 const struct SocketAddress *dst_address,
774 struct GNUNET_TUN_IPv4Header *pkt4)
775{
776 size_t len;
777
778 len = payload_length;
779 switch (protocol)
780 {
781 case IPPROTO_UDP:
782 len += sizeof(struct GNUNET_TUN_UdpHeader);
783 break;
784
785 case IPPROTO_TCP:
786 len += sizeof(struct GNUNET_TUN_TcpHeader);
787 GNUNET_assert (NULL != tcp_header);
788 break;
789
790 default:
791 GNUNET_break (0);
792 return;
793 }
794 if (len + sizeof(struct GNUNET_TUN_IPv4Header) > UINT16_MAX)
795 {
796 GNUNET_break (0);
797 return;
798 }
799
801 protocol,
802 len,
803 &src_address->address.ipv4,
804 &dst_address->address.ipv4);
805 switch (protocol)
806 {
807 case IPPROTO_UDP:
808 {
809 struct GNUNET_TUN_UdpHeader *pkt4_udp = (struct
810 GNUNET_TUN_UdpHeader *) &pkt4[1];
811
812 pkt4_udp->source_port = htons (src_address->port);
813 pkt4_udp->destination_port = htons (dst_address->port);
814 pkt4_udp->len = htons ((uint16_t) payload_length);
816 pkt4_udp,
817 payload,
818 payload_length);
819 GNUNET_memcpy (&pkt4_udp[1],
820 payload,
821 payload_length);
822 }
823 break;
824
825 case IPPROTO_TCP:
826 {
827 struct GNUNET_TUN_TcpHeader *pkt4_tcp = (struct
829
830 *pkt4_tcp = *tcp_header;
832 "Sending TCP packet from port %u to port %u\n",
833 src_address->port,
834 dst_address->port);
835 pkt4_tcp->source_port = htons (src_address->port);
836 pkt4_tcp->destination_port = htons (dst_address->port);
838 pkt4_tcp,
839 payload,
840 payload_length);
842 payload,
843 payload_length);
844 }
845 break;
846
847 default:
848 GNUNET_assert (0);
849 }
850}
851
852
871static void
873 size_t payload_length,
874 int protocol,
875 const struct GNUNET_TUN_TcpHeader *tcp_header,
876 const struct SocketAddress *src_address,
877 const struct SocketAddress *dst_address,
879{
880 size_t len;
881
882 len = payload_length;
883 switch (protocol)
884 {
885 case IPPROTO_UDP:
886 len += sizeof(struct GNUNET_TUN_UdpHeader);
887 break;
888
889 case IPPROTO_TCP:
890 len += sizeof(struct GNUNET_TUN_TcpHeader);
891 break;
892
893 default:
894 GNUNET_break (0);
895 return;
896 }
897 if (len > UINT16_MAX)
898 {
899 GNUNET_break (0);
900 return;
901 }
902
904 protocol,
905 len,
906 &src_address->address.ipv6,
907 &dst_address->address.ipv6);
908
909 switch (protocol)
910 {
911 case IPPROTO_UDP:
912 {
913 struct GNUNET_TUN_UdpHeader *pkt6_udp = (struct
914 GNUNET_TUN_UdpHeader *) &pkt6[1];
915
916 pkt6_udp->source_port = htons (src_address->port);
917 pkt6_udp->destination_port = htons (dst_address->port);
918 pkt6_udp->len = htons ((uint16_t) payload_length);
920 pkt6_udp,
921 payload,
922 payload_length);
923 GNUNET_memcpy (&pkt6_udp[1],
924 payload,
925 payload_length);
926 }
927 break;
928
929 case IPPROTO_TCP:
930 {
931 struct GNUNET_TUN_TcpHeader *pkt6_tcp = (struct
933
934 /* GNUNET_memcpy first here as some TCP header fields are initialized this way! */
935 *pkt6_tcp = *tcp_header;
937 pkt6_tcp->destination_port = htons (dst_address->port);
939 pkt6_tcp,
940 payload,
941 payload_length);
943 payload,
944 payload_length);
945 }
946 break;
947
948 default:
949 GNUNET_assert (0);
950 break;
951 }
952}
953
954
964static void
965send_tcp_packet_via_tun (const struct SocketAddress *destination_address,
966 const struct SocketAddress *source_address,
967 const struct GNUNET_TUN_TcpHeader *tcp_header,
968 const void *payload,
969 size_t payload_length)
970{
971 size_t len;
972
974 gettext_noop ("# TCP packets sent via TUN"),
975 1,
976 GNUNET_NO);
978 "Sending packet with %u bytes TCP payload via TUN\n",
979 (unsigned int) payload_length);
980 len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct
982 switch (source_address->af)
983 {
984 case AF_INET:
985 len += sizeof(struct GNUNET_TUN_IPv4Header);
986 break;
987
988 case AF_INET6:
989 len += sizeof(struct GNUNET_TUN_IPv6Header);
990 break;
991
992 default:
993 GNUNET_break (0);
994 return;
995 }
996 len += sizeof(struct GNUNET_TUN_TcpHeader);
997 len += payload_length;
998 if (len >= GNUNET_MAX_MESSAGE_SIZE)
999 {
1000 GNUNET_break (0);
1001 return;
1002 }
1003 {
1004 char buf[len] GNUNET_ALIGN;
1005 struct GNUNET_MessageHeader *hdr;
1007
1008 hdr = (struct GNUNET_MessageHeader *) buf;
1009 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1010 hdr->size = htons (len);
1011 tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1012 tun->flags = htons (0);
1013 switch (source_address->af)
1014 {
1015 case AF_INET:
1016 {
1018 = (struct GNUNET_TUN_IPv4Header*) &tun[1];
1019
1020 tun->proto = htons (ETH_P_IPV4);
1022 payload_length,
1023 IPPROTO_TCP,
1024 tcp_header,
1027 ipv4);
1028 }
1029 break;
1030
1031 case AF_INET6:
1032 {
1034 = (struct GNUNET_TUN_IPv6Header*) &tun[1];
1035
1036 tun->proto = htons (ETH_P_IPV6);
1039 IPPROTO_TCP,
1040 tcp_header,
1043 ipv6);
1044 }
1045 break;
1046
1047 default:
1048 GNUNET_assert (0);
1049 break;
1050 }
1051 if (NULL != helper_handle)
1053 (const struct GNUNET_MessageHeader*) buf,
1054 GNUNET_YES,
1055 NULL,
1056 NULL);
1057 }
1058}
1059
1060
1070static void
1072 const struct SocketAddress *source_address,
1073 const struct GNUNET_TUN_IcmpHeader *icmp_header,
1074 const void *payload, size_t payload_length)
1075{
1076 size_t len;
1077 struct GNUNET_TUN_IcmpHeader *icmp;
1078
1080 gettext_noop ("# ICMP packets sent via TUN"),
1081 1, GNUNET_NO);
1083 "Sending packet with %u bytes ICMP payload via TUN\n",
1084 (unsigned int) payload_length);
1085 len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct
1087 switch (destination_address->af)
1088 {
1089 case AF_INET:
1090 len += sizeof(struct GNUNET_TUN_IPv4Header);
1091 break;
1092
1093 case AF_INET6:
1094 len += sizeof(struct GNUNET_TUN_IPv6Header);
1095 break;
1096
1097 default:
1098 GNUNET_break (0);
1099 return;
1100 }
1101 len += sizeof(struct GNUNET_TUN_IcmpHeader);
1102 len += payload_length;
1103 if (len >= GNUNET_MAX_MESSAGE_SIZE)
1104 {
1105 GNUNET_break (0);
1106 return;
1107 }
1108 {
1109 char buf[len] GNUNET_ALIGN;
1110 struct GNUNET_MessageHeader *hdr;
1112
1113 hdr = (struct GNUNET_MessageHeader *) buf;
1114 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1115 hdr->size = htons (len);
1116 tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1117 tun->flags = htons (0);
1118 switch (source_address->af)
1119 {
1120 case AF_INET:
1121 {
1122 struct GNUNET_TUN_IPv4Header *ipv4 = (struct
1123 GNUNET_TUN_IPv4Header*) &tun[1];
1124
1125 tun->proto = htons (ETH_P_IPV4);
1127 IPPROTO_ICMP,
1128 sizeof(struct
1130 + payload_length,
1131 &source_address->address.ipv4,
1132 &destination_address->address.ipv4);
1133 icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv4[1];
1134 }
1135 break;
1136
1137 case AF_INET6:
1138 {
1139 struct GNUNET_TUN_IPv6Header *ipv6 = (struct
1140 GNUNET_TUN_IPv6Header*) &tun[1];
1141
1142 tun->proto = htons (ETH_P_IPV6);
1144 IPPROTO_ICMPV6,
1145 sizeof(struct
1148 &source_address->address.ipv6,
1149 &destination_address->address.ipv6);
1150 icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv6[1];
1151 }
1152 break;
1153
1154 default:
1155 GNUNET_assert (0);
1156 break;
1157 }
1158 *icmp = *icmp_header;
1159 GNUNET_memcpy (&icmp[1],
1160 payload,
1161 payload_length);
1163 payload,
1164 payload_length);
1165 if (NULL != helper_handle)
1167 (const struct GNUNET_MessageHeader*) buf,
1168 GNUNET_YES,
1169 NULL, NULL);
1170 }
1171}
1172
1173
1182static void
1184 uint8_t proto,
1185 struct SocketAddress *local_address)
1186{
1187 local_address->af = af;
1188 local_address->proto = (uint8_t) proto;
1189 /* default "local" port range is often 32768--61000,
1190 so we pick a random value in that range */
1191 if (((af == AF_INET) && (proto == IPPROTO_ICMP)) ||
1192 ((af == AF_INET6) && (proto == IPPROTO_ICMPV6)))
1193 local_address->port = 0;
1194 else
1195 local_address->port
1196 = (uint16_t) 32768 + GNUNET_CRYPTO_random_u32 (28232);
1197 switch (af)
1198 {
1199 case AF_INET:
1200 {
1201 struct in_addr addr;
1202 struct in_addr mask;
1203 struct in_addr rnd;
1204
1205 addr = exit_ipv4addr;
1206 mask = exit_ipv4mask;
1207 if (0 == ~mask.s_addr)
1208 {
1209 /* only one valid IP anyway */
1210 local_address->address.ipv4 = addr;
1211 return;
1212 }
1213 /* Given 192.168.0.1/255.255.0.0, we want a mask
1214 of '192.168.255.255', thus: */
1215 mask.s_addr = addr.s_addr | ~mask.s_addr;
1216 /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
1217 do
1218 {
1219 rnd.s_addr = GNUNET_CRYPTO_random_u32 (UINT32_MAX);
1220 local_address->address.ipv4.s_addr = (addr.s_addr | rnd.s_addr)
1221 & mask.s_addr;
1222 }
1223 while ((local_address->address.ipv4.s_addr == addr.s_addr) ||
1224 (local_address->address.ipv4.s_addr == mask.s_addr));
1225 }
1226 break;
1227
1228 case AF_INET6:
1229 {
1230 struct in6_addr addr;
1231 struct in6_addr mask;
1232 struct in6_addr rnd;
1233 int i;
1234
1235 addr = exit_ipv6addr;
1236 GNUNET_assert (ipv6prefix < 128);
1237 if (ipv6prefix == 127)
1238 {
1239 /* only one valid IP anyway */
1240 local_address->address.ipv6 = addr;
1241 return;
1242 }
1243 /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
1244 thus: */
1245 mask = addr;
1246 for (i = 127; i >= ipv6prefix; i--)
1247 mask.s6_addr[i / 8] |= (1 << (i % 8));
1248
1249 /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */
1250 do
1251 {
1252 for (i = 0; i < 16; i++)
1253 {
1254 rnd.s6_addr[i] = (unsigned char) GNUNET_CRYPTO_random_u32 (
1255 256);
1256 local_address->address.ipv6.s6_addr[i]
1257 = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
1258 }
1259 }
1260 while ((0 == GNUNET_memcmp (&local_address->address.ipv6,
1261 &addr)) ||
1262 (0 == GNUNET_memcmp (&local_address->address.ipv6,
1263 &mask)));
1264 }
1265 break;
1266
1267 default:
1268 GNUNET_assert (0);
1269 }
1270}
1271
1272
1294static void
1296{
1297 struct GNUNET_HashCode key;
1298 struct ChannelState *s;
1299
1300 /* generate fresh, unique address */
1301 do
1302 {
1303 if (NULL == state->specifics.tcp_udp.serv)
1304 setup_fresh_address (state->specifics.tcp_udp.ri.remote_address.af,
1305 state->specifics.tcp_udp.ri.remote_address.proto,
1306 &state->specifics.tcp_udp.ri.local_address);
1307 else
1308 setup_fresh_address (state->specifics.tcp_udp.serv->address.af,
1309 state->specifics.tcp_udp.serv->address.proto,
1310 &state->specifics.tcp_udp.ri.local_address);
1311 }
1312 while (NULL !=
1313 get_redirect_state (state->specifics.tcp_udp.ri.remote_address.af,
1314 state->specifics.tcp_udp.ri.remote_address.proto,
1315 &state->specifics.tcp_udp.ri.remote_address.address
1316 ,
1317 state->specifics.tcp_udp.ri.remote_address.port,
1318 &state->specifics.tcp_udp.ri.local_address.address,
1319 state->specifics.tcp_udp.ri.local_address.port,
1320 &key));
1321 {
1322 char buf[INET6_ADDRSTRLEN];
1324 "Picked local address %s:%u for new connection\n",
1325 inet_ntop (state->specifics.tcp_udp.ri.local_address.af,
1326 &state->specifics.tcp_udp.ri.local_address.address,
1327 buf,
1328 sizeof(buf)),
1329 (unsigned int) state->specifics.tcp_udp.ri.local_address.port);
1330 }
1331 state->specifics.tcp_udp.state_key = key;
1334 &key, state,
1336 state->specifics.tcp_udp.heap_node
1338 state,
1339 GNUNET_TIME_absolute_get ().abs_value_us);
1341 {
1343 GNUNET_assert (state != s);
1344 s->specifics.tcp_udp.heap_node = NULL;
1348 &s->specifics.tcp_udp.
1349 state_key,
1350 s));
1351 GNUNET_free (s);
1352 }
1353}
1354
1355
1364static void
1365send_udp_packet_via_tun (const struct SocketAddress *destination_address,
1366 const struct SocketAddress *source_address,
1367 const void *payload, size_t payload_length)
1368{
1369 size_t len;
1370
1372 gettext_noop ("# UDP packets sent via TUN"),
1373 1, GNUNET_NO);
1375 "Sending packet with %u bytes UDP payload via TUN\n",
1376 (unsigned int) payload_length);
1377 len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct
1379 switch (source_address->af)
1380 {
1381 case AF_INET:
1382 len += sizeof(struct GNUNET_TUN_IPv4Header);
1383 break;
1384
1385 case AF_INET6:
1386 len += sizeof(struct GNUNET_TUN_IPv6Header);
1387 break;
1388
1389 default:
1390 GNUNET_break (0);
1391 return;
1392 }
1393 len += sizeof(struct GNUNET_TUN_UdpHeader);
1394 len += payload_length;
1396 {
1397 GNUNET_break (0);
1398 return;
1399 }
1400 {
1401 char buf[len] GNUNET_ALIGN;
1402 struct GNUNET_MessageHeader *hdr;
1404
1405 hdr = (struct GNUNET_MessageHeader *) buf;
1406 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1407 hdr->size = htons (len);
1408 tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1409 tun->flags = htons (0);
1410 switch (source_address->af)
1411 {
1412 case AF_INET:
1413 {
1414 struct GNUNET_TUN_IPv4Header *ipv4 = (struct
1415 GNUNET_TUN_IPv4Header*) &tun[1];
1416
1417 tun->proto = htons (ETH_P_IPV4);
1419 payload_length,
1420 IPPROTO_UDP,
1421 NULL,
1424 ipv4);
1425 }
1426 break;
1427
1428 case AF_INET6:
1429 {
1430 struct GNUNET_TUN_IPv6Header *ipv6 = (struct
1431 GNUNET_TUN_IPv6Header*) &tun[1];
1432
1433 tun->proto = htons (ETH_P_IPV6);
1436 IPPROTO_UDP,
1437 NULL,
1440 ipv6);
1441 }
1442 break;
1443
1444 default:
1445 GNUNET_assert (0);
1446 break;
1447 }
1448 if (NULL != helper_handle)
1450 (const struct GNUNET_MessageHeader*) buf,
1451 GNUNET_YES,
1452 NULL, NULL);
1453 }
1454}
1455
1456
1465static int
1467 const struct GNUNET_EXIT_UdpInternetMessage *msg)
1468{
1469 struct ChannelState *state = cls;
1470
1471 if (GNUNET_YES == state->is_dns)
1472 {
1473 GNUNET_break_op (0);
1474 return GNUNET_SYSERR;
1475 }
1476 return GNUNET_OK;
1477}
1478
1479
1486static void
1488 const struct GNUNET_EXIT_UdpInternetMessage *msg)
1489{
1490 struct ChannelState *state = cls;
1491 uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
1493 const struct in_addr *v4;
1494 const struct in6_addr *v6;
1495 const void *payload;
1496 int af;
1497
1498 if (GNUNET_SYSERR == state->is_dns)
1499 {
1500 /* channel is UDP/TCP from now on */
1502 }
1504 gettext_noop ("# Bytes received from CADET"),
1505 pkt_len, GNUNET_NO);
1507 gettext_noop (
1508 "# UDP IP-exit requests received via cadet"),
1509 1, GNUNET_NO);
1510 af = (int) ntohl (msg->af);
1511 state->specifics.tcp_udp.ri.remote_address.af = af;
1512 switch (af)
1513 {
1514 case AF_INET:
1515 if (pkt_len < sizeof(struct in_addr))
1516 {
1517 GNUNET_break_op (0);
1518 return;
1519 }
1520 if (! ipv4_exit)
1521 {
1522 GNUNET_break_op (0);
1523 return;
1524 }
1525 v4 = (const struct in_addr*) &msg[1];
1526 payload = &v4[1];
1527 pkt_len -= sizeof(struct in_addr);
1528 state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
1529 break;
1530
1531 case AF_INET6:
1532 if (pkt_len < sizeof(struct in6_addr))
1533 {
1534 GNUNET_break_op (0);
1535 return;
1536 }
1537 if (! ipv6_exit)
1538 {
1539 GNUNET_break_op (0);
1540 return;
1541 }
1542 v6 = (const struct in6_addr*) &msg[1];
1543 payload = &v6[1];
1544 pkt_len -= sizeof(struct in6_addr);
1545 state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
1546 break;
1547
1548 default:
1549 GNUNET_break_op (0);
1550 return;
1551 }
1552 {
1553 char buf[INET6_ADDRSTRLEN];
1555 "Received data from %s for forwarding to UDP %s:%u\n",
1556 GNUNET_i2s (&state->peer),
1557 inet_ntop (af,
1558 &state->specifics.tcp_udp.ri.remote_address.address,
1559 buf, sizeof(buf)),
1560 (unsigned int) ntohs (msg->destination_port));
1561 }
1562 state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_UDP;
1563 state->specifics.tcp_udp.ri.remote_address.port = msg->destination_port;
1564 if (NULL == state->specifics.tcp_udp.heap_node)
1566 if (0 != ntohs (msg->source_port))
1567 state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
1568 send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1569 &state->specifics.tcp_udp.ri.local_address,
1570 payload,
1571 pkt_len);
1573}
1574
1575
1585static int
1587 const struct GNUNET_EXIT_UdpServiceMessage *msg)
1588{
1589 struct ChannelState *state = cls;
1590
1591 if (NULL == state->specifics.tcp_udp.serv)
1592 {
1593 GNUNET_break_op (0);
1594 return GNUNET_SYSERR;
1595 }
1596 return GNUNET_OK;
1597}
1598
1599
1607static void
1609 const struct GNUNET_EXIT_UdpServiceMessage *msg)
1610{
1611 struct ChannelState *state = cls;
1612 uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
1614
1616 gettext_noop ("# Bytes received from CADET"),
1617 pkt_len, GNUNET_NO);
1619 gettext_noop (
1620 "# UDP service requests received via cadet"),
1621 1, GNUNET_NO);
1623 "Received data from %s for forwarding to UDP service %s on port %u\n",
1624 GNUNET_i2s (&state->peer),
1625 GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor),
1626 (unsigned int) ntohs (msg->destination_port));
1628 if (0 != ntohs (msg->source_port))
1629 state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
1630 send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1631 &state->specifics.tcp_udp.ri.local_address,
1632 &msg[1],
1633 pkt_len);
1635}
1636
1637
1647static void
1650{
1651 struct ChannelState *state = cls;
1652 uint16_t pkt_len = ntohs (start->header.size) - sizeof(struct
1654
1655 if (GNUNET_SYSERR == state->is_dns)
1656 {
1657 /* channel is UDP/TCP from now on */
1659 }
1661 gettext_noop (
1662 "# TCP service creation requests received via cadet"),
1663 1,
1664 GNUNET_NO);
1666 gettext_noop ("# Bytes received from CADET"),
1667 pkt_len,
1668 GNUNET_NO);
1669 GNUNET_break_op (ntohl (start->reserved) == 0);
1670 /* setup fresh connection */
1672 "Received data from %s for forwarding to TCP service %s on port %u\n",
1673 GNUNET_i2s (&state->peer),
1674 GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor),
1675 (unsigned int) ntohs (start->tcp_header.destination_port));
1677 send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1678 &state->specifics.tcp_udp.ri.local_address,
1679 &start->tcp_header,
1680 &start[1],
1681 pkt_len);
1683}
1684
1685
1694static int
1697{
1698 struct ChannelState *state = cls;
1699
1700 if (NULL == state)
1701 {
1702 GNUNET_break_op (0);
1703 return GNUNET_SYSERR;
1704 }
1705 if (GNUNET_YES == state->is_dns)
1706 {
1707 GNUNET_break_op (0);
1708 return GNUNET_SYSERR;
1709 }
1710 if ((NULL != state->specifics.tcp_udp.serv) ||
1711 (NULL != state->specifics.tcp_udp.heap_node))
1712 {
1713 GNUNET_break_op (0);
1714 return GNUNET_SYSERR;
1715 }
1716 if (start->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1717 {
1718 GNUNET_break_op (0);
1719 return GNUNET_SYSERR;
1720 }
1721 return GNUNET_OK;
1722}
1723
1724
1731static void
1734{
1735 struct ChannelState *state = cls;
1736 uint16_t pkt_len = ntohs (start->header.size) - sizeof(struct
1738 const struct in_addr *v4;
1739 const struct in6_addr *v6;
1740 const void *payload;
1741 int af;
1742
1743 if (GNUNET_SYSERR == state->is_dns)
1744 {
1745 /* channel is UDP/TCP from now on */
1747 }
1749 gettext_noop ("# Bytes received from CADET"),
1750 pkt_len, GNUNET_NO);
1752 gettext_noop (
1753 "# TCP IP-exit creation requests received via cadet"),
1754 1, GNUNET_NO);
1755 af = (int) ntohl (start->af);
1756 state->specifics.tcp_udp.ri.remote_address.af = af;
1757 switch (af)
1758 {
1759 case AF_INET:
1760 if (pkt_len < sizeof(struct in_addr))
1761 {
1762 GNUNET_break_op (0);
1763 return;
1764 }
1765 if (! ipv4_exit)
1766 {
1767 GNUNET_break_op (0);
1768 return;
1769 }
1770 v4 = (const struct in_addr*) &start[1];
1771 payload = &v4[1];
1772 pkt_len -= sizeof(struct in_addr);
1773 state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
1774 break;
1775
1776 case AF_INET6:
1777 if (pkt_len < sizeof(struct in6_addr))
1778 {
1779 GNUNET_break_op (0);
1780 return;
1781 }
1782 if (! ipv6_exit)
1783 {
1784 GNUNET_break_op (0);
1785 return;
1786 }
1787 v6 = (const struct in6_addr*) &start[1];
1788 payload = &v6[1];
1789 pkt_len -= sizeof(struct in6_addr);
1790 state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
1791 break;
1792
1793 default:
1794 GNUNET_break_op (0);
1795 return;
1796 }
1797 {
1798 char buf[INET6_ADDRSTRLEN];
1800 "Received payload from %s for existing TCP stream to %s:%u\n",
1801 GNUNET_i2s (&state->peer),
1802 inet_ntop (af,
1803 &state->specifics.tcp_udp.ri.remote_address.address,
1804 buf, sizeof(buf)),
1805 (unsigned int) ntohs (start->tcp_header.destination_port));
1806 }
1807 state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_TCP;
1808 state->specifics.tcp_udp.ri.remote_address.port = ntohs (
1809 start->tcp_header.destination_port);
1811 send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1812 &state->specifics.tcp_udp.ri.local_address,
1813 &start->tcp_header,
1814 payload,
1815 pkt_len);
1817}
1818
1819
1829static int
1831 const struct GNUNET_EXIT_TcpDataMessage *data)
1832{
1833 struct ChannelState *state = cls;
1834
1835 if ((NULL == state) ||
1836 (NULL == state->specifics.tcp_udp.heap_node))
1837 {
1838 /* connection should have been up! */
1840 gettext_noop (
1841 "# TCP DATA requests dropped (no session)"),
1842 1, GNUNET_NO);
1843 GNUNET_break_op (0);
1844 return GNUNET_SYSERR;
1845 }
1846 if (data->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1847 {
1848 GNUNET_break_op (0);
1849 return GNUNET_SYSERR;
1850 }
1851 if (GNUNET_YES == state->is_dns)
1852 {
1853 GNUNET_break_op (0);
1854 return GNUNET_SYSERR;
1855 }
1856 return GNUNET_OK;
1857}
1858
1859
1867static void
1869 const struct GNUNET_EXIT_TcpDataMessage *data)
1870{
1871 struct ChannelState *state = cls;
1872 uint16_t pkt_len = ntohs (data->header.size) - sizeof(struct
1874
1876 gettext_noop ("# Bytes received from CADET"),
1877 pkt_len, GNUNET_NO);
1879 gettext_noop (
1880 "# TCP data requests received via cadet"),
1881 1, GNUNET_NO);
1882 if (GNUNET_SYSERR == state->is_dns)
1883 {
1884 /* channel is UDP/TCP from now on */
1885 state->is_dns = GNUNET_NO;
1886 }
1887
1888 GNUNET_break_op (ntohl (data->reserved) == 0);
1889 {
1890 char buf[INET6_ADDRSTRLEN];
1892 "Received additional %u bytes of data from %s for TCP stream to %s:%u\n",
1893 pkt_len,
1894 GNUNET_i2s (&state->peer),
1895 inet_ntop (state->specifics.tcp_udp.ri.remote_address.af,
1896 &state->specifics.tcp_udp.ri.remote_address.address,
1897 buf, sizeof(buf)),
1898 (unsigned int) state->specifics.tcp_udp.ri.remote_address.port);
1899 }
1900
1901 send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1902 &state->specifics.tcp_udp.ri.local_address,
1903 &data->tcp_header,
1904 &data[1], pkt_len);
1906}
1907
1908
1918static void
1920 struct GNUNET_TUN_IPv4Header *ipp,
1921 struct GNUNET_TUN_UdpHeader *udp)
1922{
1924 state->specifics.tcp_udp.ri.remote_address.
1925 proto,
1926 sizeof(struct GNUNET_TUN_TcpHeader),
1927 &state->specifics.tcp_udp.ri.remote_address
1928 .address.ipv4,
1929 &state->specifics.tcp_udp.ri.local_address.
1930 address.ipv4);
1931 udp->source_port = htons (state->specifics.tcp_udp.ri.remote_address.port);
1932 udp->destination_port = htons (
1933 state->specifics.tcp_udp.ri.local_address.port);
1934 udp->len = htons (0);
1935 udp->crc = htons (0);
1936}
1937
1938
1948static void
1950 struct GNUNET_TUN_IPv6Header *ipp,
1951 struct GNUNET_TUN_UdpHeader *udp)
1952{
1954 state->specifics.tcp_udp.ri.remote_address.
1955 proto,
1956 sizeof(struct GNUNET_TUN_TcpHeader),
1957 &state->specifics.tcp_udp.ri.remote_address
1958 .address.ipv6,
1959 &state->specifics.tcp_udp.ri.local_address.
1960 address.ipv6);
1961 udp->source_port = htons (state->specifics.tcp_udp.ri.remote_address.port);
1962 udp->destination_port = htons (
1963 state->specifics.tcp_udp.ri.local_address.port);
1964 udp->len = htons (0);
1965 udp->crc = htons (0);
1966}
1967
1968
1977static int
1980{
1981 struct ChannelState *state = cls;
1982
1983 if (GNUNET_YES == state->is_dns)
1984 {
1985 GNUNET_break_op (0);
1986 return GNUNET_SYSERR;
1987 }
1988 return GNUNET_OK;
1989}
1990
1991
1998static void
2001{
2002 struct ChannelState *state = cls;
2003 uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
2005 const struct in_addr *v4;
2006 const struct in6_addr *v6;
2007 const void *payload;
2008 char buf[sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
2009 int af;
2010
2011 if (GNUNET_SYSERR == state->is_dns)
2012 {
2013 /* channel is UDP/TCP from now on */
2015 }
2017 gettext_noop ("# Bytes received from CADET"),
2018 pkt_len, GNUNET_NO);
2020 gettext_noop (
2021 "# ICMP IP-exit requests received via cadet"),
2022 1, GNUNET_NO);
2023
2024 af = (int) ntohl (msg->af);
2025 if ((NULL != state->specifics.tcp_udp.heap_node) &&
2026 (af != state->specifics.tcp_udp.ri.remote_address.af))
2027 {
2028 /* other peer switched AF on this channel; not allowed */
2029 GNUNET_break_op (0);
2030 return;
2031 }
2032
2033 switch (af)
2034 {
2035 case AF_INET:
2036 if (pkt_len < sizeof(struct in_addr))
2037 {
2038 GNUNET_break_op (0);
2039 return;
2040 }
2041 if (! ipv4_exit)
2042 {
2043 GNUNET_break_op (0);
2044 return;
2045 }
2046 v4 = (const struct in_addr*) &msg[1];
2047 payload = &v4[1];
2048 pkt_len -= sizeof(struct in_addr);
2049 state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
2050 if (NULL == state->specifics.tcp_udp.heap_node)
2051 {
2052 state->specifics.tcp_udp.ri.remote_address.af = af;
2053 state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMP;
2055 }
2056 /* check that ICMP type is something we want to support
2057 and possibly make up payload! */
2058 switch (msg->icmp_header.type)
2059 {
2062 break;
2063
2067 if (0 != pkt_len)
2068 {
2069 GNUNET_break_op (0);
2070 return;
2071 }
2072 /* make up payload */
2073 {
2074 struct GNUNET_TUN_IPv4Header *ipp = (struct
2075 GNUNET_TUN_IPv4Header *) buf;
2076 struct GNUNET_TUN_UdpHeader *udp = (struct
2077 GNUNET_TUN_UdpHeader *) &ipp[1];
2078
2079 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2080 pkt_len = sizeof(struct GNUNET_TUN_IPv4Header) + 8;
2082 ipp,
2083 udp);
2084 payload = ipp;
2085 }
2086 break;
2087
2088 default:
2089 GNUNET_break_op (0);
2091 gettext_noop (
2092 "# ICMPv4 packets dropped (type not allowed)")
2093 ,
2094 1, GNUNET_NO);
2095 return;
2096 }
2097 /* end AF_INET */
2098 break;
2099
2100 case AF_INET6:
2101 if (pkt_len < sizeof(struct in6_addr))
2102 {
2103 GNUNET_break_op (0);
2104 return;
2105 }
2106 if (! ipv6_exit)
2107 {
2108 GNUNET_break_op (0);
2109 return;
2110 }
2111 v6 = (const struct in6_addr*) &msg[1];
2112 payload = &v6[1];
2113 pkt_len -= sizeof(struct in6_addr);
2114 state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
2115 if (NULL == state->specifics.tcp_udp.heap_node)
2116 {
2117 state->specifics.tcp_udp.ri.remote_address.af = af;
2118 state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMPV6;
2120 }
2121 /* check that ICMP type is something we want to support
2122 and possibly make up payload! */
2123 switch (msg->icmp_header.type)
2124 {
2127 break;
2128
2133 if (0 != pkt_len)
2134 {
2135 GNUNET_break_op (0);
2136 return;
2137 }
2138 /* make up payload */
2139 {
2140 struct GNUNET_TUN_IPv6Header *ipp = (struct
2141 GNUNET_TUN_IPv6Header *) buf;
2142 struct GNUNET_TUN_UdpHeader *udp = (struct
2143 GNUNET_TUN_UdpHeader *) &ipp[1];
2144
2145 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2146 pkt_len = sizeof(struct GNUNET_TUN_IPv6Header) + 8;
2148 ipp,
2149 udp);
2150 payload = ipp;
2151 }
2152 break;
2153
2154 default:
2155 GNUNET_break_op (0);
2157 gettext_noop (
2158 "# ICMPv6 packets dropped (type not allowed)")
2159 ,
2160 1, GNUNET_NO);
2161 return;
2162 }
2163 /* end AF_INET6 */
2164 break;
2165
2166 default:
2167 /* bad AF */
2168 GNUNET_break_op (0);
2169 return;
2170 }
2171
2172 {
2173 char buf_tmp[INET6_ADDRSTRLEN];
2175 "Received ICMP data from %s for forwarding to %s\n",
2176 GNUNET_i2s (&state->peer),
2177 inet_ntop (af,
2178 &state->specifics.tcp_udp.ri.remote_address.address,
2179 buf_tmp, sizeof(buf_tmp)));
2180 }
2181 send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2182 &state->specifics.tcp_udp.ri.local_address,
2183 &msg->icmp_header,
2184 payload, pkt_len);
2186}
2187
2188
2198static uint16_t
2200 char *buf)
2201{
2202 switch (state->specifics.tcp_udp.serv->address.af)
2203 {
2204 case AF_INET:
2205 {
2207 struct GNUNET_TUN_UdpHeader *udp;
2208
2209 ipv4 = (struct GNUNET_TUN_IPv4Header *) buf;
2210 udp = (struct GNUNET_TUN_UdpHeader *) &ipv4[1];
2212 ipv4,
2213 udp);
2214 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2215 return sizeof(struct GNUNET_TUN_IPv4Header) + 8;
2216 }
2217 break;
2218
2219 case AF_INET6:
2220 {
2222 struct GNUNET_TUN_UdpHeader *udp;
2223
2224 ipv6 = (struct GNUNET_TUN_IPv6Header *) buf;
2225 udp = (struct GNUNET_TUN_UdpHeader *) &ipv6[1];
2227 ipv6,
2228 udp);
2229 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2230 return sizeof(struct GNUNET_TUN_IPv6Header) + 8;
2231 }
2232 break;
2233
2234 default:
2235 GNUNET_break (0);
2236 }
2237 return 0;
2238}
2239
2240
2250static int
2252 const struct GNUNET_EXIT_IcmpServiceMessage *msg)
2253{
2254 struct ChannelState *state = cls;
2255
2256 if (GNUNET_YES == state->is_dns)
2257 {
2258 GNUNET_break_op (0);
2259 return GNUNET_SYSERR;
2260 }
2261 if (NULL == state->specifics.tcp_udp.serv)
2262 {
2263 GNUNET_break_op (0);
2264 return GNUNET_SYSERR;
2265 }
2266 return GNUNET_OK;
2267}
2268
2269
2277static void
2279 const struct GNUNET_EXIT_IcmpServiceMessage *msg)
2280{
2281 struct ChannelState *state = cls;
2282 uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
2284 struct GNUNET_TUN_IcmpHeader icmp;
2285 char buf[sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
2286 const void *payload;
2287
2289 gettext_noop ("# Bytes received from CADET"),
2290 pkt_len, GNUNET_NO);
2292 gettext_noop (
2293 "# ICMP service requests received via cadet"),
2294 1, GNUNET_NO);
2295 /* check that we got at least a valid header */
2297 "Received data from %s for forwarding to ICMP service %s\n",
2298 GNUNET_i2s (&state->peer),
2299 GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor));
2300 icmp = msg->icmp_header;
2301 payload = &msg[1];
2302 state->specifics.tcp_udp.ri.remote_address
2303 = state->specifics.tcp_udp.serv->address;
2305
2306 /* check that ICMP type is something we want to support,
2307 perform ICMP PT if needed and possibly make up payload */
2308 switch (msg->af)
2309 {
2310 case AF_INET:
2311 switch (msg->icmp_header.type)
2312 {
2314 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2316 break;
2317
2319 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2321 break;
2322
2324 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2326 if (0 != pkt_len)
2327 {
2328 GNUNET_break_op (0);
2329 return;
2330 }
2331 payload = buf;
2332 pkt_len = make_up_icmp_service_payload (state, buf);
2333 break;
2334
2336 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2338 if (0 != pkt_len)
2339 {
2340 GNUNET_break_op (0);
2341 return;
2342 }
2343 payload = buf;
2344 pkt_len = make_up_icmp_service_payload (state, buf);
2345 break;
2346
2348 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2349 {
2351 gettext_noop (
2352 "# ICMPv4 packets dropped (impossible PT to v6)"),
2353 1, GNUNET_NO);
2354 return;
2355 }
2356 if (0 != pkt_len)
2357 {
2358 GNUNET_break_op (0);
2359 return;
2360 }
2361 payload = buf;
2362 pkt_len = make_up_icmp_service_payload (state, buf);
2363 break;
2364
2365 default:
2366 GNUNET_break_op (0);
2368 gettext_noop (
2369 "# ICMPv4 packets dropped (type not allowed)")
2370 ,
2371 1, GNUNET_NO);
2372 return;
2373 }
2374 /* end of AF_INET */
2375 break;
2376
2377 case AF_INET6:
2378 switch (msg->icmp_header.type)
2379 {
2381 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2383 break;
2384
2386 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2388 break;
2389
2391 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2393 if (0 != pkt_len)
2394 {
2395 GNUNET_break_op (0);
2396 return;
2397 }
2398 payload = buf;
2399 pkt_len = make_up_icmp_service_payload (state, buf);
2400 break;
2401
2403 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2405 if (0 != pkt_len)
2406 {
2407 GNUNET_break_op (0);
2408 return;
2409 }
2410 payload = buf;
2411 pkt_len = make_up_icmp_service_payload (state, buf);
2412 break;
2413
2416 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2417 {
2419 gettext_noop (
2420 "# ICMPv6 packets dropped (impossible PT to v4)"),
2421 1, GNUNET_NO);
2422 return;
2423 }
2424 if (0 != pkt_len)
2425 {
2426 GNUNET_break_op (0);
2427 return;
2428 }
2429 payload = buf;
2430 pkt_len = make_up_icmp_service_payload (state, buf);
2431 break;
2432
2433 default:
2434 GNUNET_break_op (0);
2436 gettext_noop (
2437 "# ICMPv6 packets dropped (type not allowed)")
2438 ,
2439 1, GNUNET_NO);
2440 return;
2441 }
2442 /* end of AF_INET6 */
2443 break;
2444
2445 default:
2446 GNUNET_break_op (0);
2447 return;
2448 }
2449
2450 send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2451 &state->specifics.tcp_udp.ri.local_address,
2452 &icmp,
2453 payload,
2454 pkt_len);
2456}
2457
2458
2467static int
2469 const struct GNUNET_HashCode *key,
2470 void *value)
2471{
2472 struct LocalService *service = value;
2473
2476 key,
2477 service));
2479 GNUNET_free (service->name);
2481 return GNUNET_OK;
2482}
2483
2484
2493static void *
2495 struct GNUNET_CADET_Channel *channel,
2496 const struct GNUNET_PeerIdentity *initiator)
2497{
2498 struct LocalService *ls = cls;
2499 struct ChannelState *s = GNUNET_new (struct ChannelState);
2500
2501 s->peer = *initiator;
2503 gettext_noop ("# Inbound CADET channels created"),
2504 1,
2505 GNUNET_NO);
2507 "Received inbound channel from `%s'\n",
2508 GNUNET_i2s (initiator));
2509 s->channel = channel;
2510 s->specifics.tcp_udp.serv = ls;
2511 s->specifics.tcp_udp.ri.remote_address = ls->address;
2512 return s;
2513}
2514
2515
2523static void
2524clean_channel (void *cls,
2525 const struct GNUNET_CADET_Channel *channel)
2526{
2527 struct ChannelState *s = cls;
2528
2530 "Channel destroyed\n");
2531 if (GNUNET_SYSERR == s->is_dns)
2532 {
2533 GNUNET_free (s);
2534 return;
2535 }
2536 if (GNUNET_YES == s->is_dns)
2537 {
2538 if (channels[s->specifics.dns.my_id] == s)
2539 channels[s->specifics.dns.my_id] = NULL;
2540 }
2541 else
2542 {
2543 if (NULL != s->specifics.tcp_udp.heap_node)
2544 {
2547 &s->specifics.tcp_udp
2548 .state_key,
2549 s));
2551 s->specifics.tcp_udp.heap_node = NULL;
2552 }
2553 }
2554 GNUNET_free (s);
2555}
2556
2557
2567static void
2569 const char *name,
2570 uint16_t destination_port,
2571 struct LocalService *service)
2572{
2574 GNUNET_MQ_hd_var_size (icmp_service,
2577 service),
2578 GNUNET_MQ_hd_var_size (udp_service,
2581 service),
2582 GNUNET_MQ_hd_var_size (tcp_service,
2585 service),
2586 GNUNET_MQ_hd_var_size (tcp_data,
2589 service),
2591 };
2592
2594
2595 service->name = GNUNET_strdup (name);
2597 &service->descriptor);
2599 destination_port,
2600 &cadet_port);
2602 "Opening CADET port %s for SERVICE exit %s on port %u\n",
2604 name,
2605 (unsigned int) destination_port);
2607 &cadet_port,
2609 service,
2610 NULL,
2612 handlers);
2613 service->is_udp = (IPPROTO_UDP == proto);
2614 if (GNUNET_OK !=
2616 &cadet_port,
2617 service,
2619 {
2621 GNUNET_free (service->name);
2624 _ ("Got duplicate service records for `%s:%u'\n"),
2625 name,
2626 (unsigned int) destination_port);
2627 }
2628}
2629
2630
2637static void
2639 struct GNUNET_MQ_Envelope *env)
2640{
2641 GNUNET_assert (NULL != s);
2643 gettext_noop (
2644 "# Messages transmitted via cadet channels"),
2645 1,
2646 GNUNET_NO);
2648 env);
2649}
2650
2651
2663static void
2665 size_t pktlen,
2666 int af,
2667 const void *destination_ip,
2668 const void *source_ip)
2669{
2670 struct ChannelState *state;
2671 struct GNUNET_MQ_Envelope *env;
2672 struct GNUNET_EXIT_IcmpToVPNMessage *i2v;
2673 const struct GNUNET_TUN_IPv4Header *ipv4;
2674 const struct GNUNET_TUN_IPv6Header *ipv6;
2675 const struct GNUNET_TUN_UdpHeader *udp;
2676 uint16_t source_port;
2677 uint16_t destination_port;
2678 uint8_t protocol;
2679
2680 {
2681 char sbuf[INET6_ADDRSTRLEN];
2682 char dbuf[INET6_ADDRSTRLEN];
2684 "Received ICMP packet going from %s to %s\n",
2685 inet_ntop (af,
2686 source_ip,
2687 sbuf, sizeof(sbuf)),
2688 inet_ntop (af,
2689 destination_ip,
2690 dbuf, sizeof(dbuf)));
2691 }
2692
2693 if (pktlen < sizeof(struct GNUNET_TUN_IcmpHeader))
2694 {
2695 /* blame kernel */
2696 GNUNET_break (0);
2697 return;
2698 }
2699
2700 /* Find out if this is an ICMP packet in response to an existing
2701 TCP/UDP packet and if so, figure out ports / protocol of the
2702 existing session from the IP data in the ICMP payload */
2703 source_port = 0;
2704 destination_port = 0;
2705 switch (af)
2706 {
2707 case AF_INET:
2708 protocol = IPPROTO_ICMP;
2709 switch (icmp->type)
2710 {
2713 break;
2714
2718 if (pktlen <
2719 sizeof(struct GNUNET_TUN_IcmpHeader)
2720 + sizeof(struct GNUNET_TUN_IPv4Header) + 8)
2721 {
2722 /* blame kernel */
2723 GNUNET_break (0);
2724 return;
2725 }
2726 ipv4 = (const struct GNUNET_TUN_IPv4Header *) &icmp[1];
2727 protocol = ipv4->protocol;
2728 /* could be TCP or UDP, but both have the ports in the right
2729 place, so that doesn't matter here */
2730 udp = (const struct GNUNET_TUN_UdpHeader *) &ipv4[1];
2731 /* swap ports, as they are from the original message */
2732 destination_port = ntohs (udp->source_port);
2733 source_port = ntohs (udp->destination_port);
2734 /* throw away ICMP payload, won't be useful for the other side anyway */
2735 pktlen = sizeof(struct GNUNET_TUN_IcmpHeader);
2736 break;
2737
2738 default:
2740 gettext_noop (
2741 "# ICMPv4 packets dropped (type not allowed)")
2742 ,
2743 1, GNUNET_NO);
2744 return;
2745 }
2746 break;
2747
2748 case AF_INET6:
2749 protocol = IPPROTO_ICMPV6;
2750 switch (icmp->type)
2751 {
2756 if (pktlen <
2757 sizeof(struct GNUNET_TUN_IcmpHeader)
2758 + sizeof(struct GNUNET_TUN_IPv6Header) + 8)
2759 {
2760 /* blame kernel */
2761 GNUNET_break (0);
2762 return;
2763 }
2764 ipv6 = (const struct GNUNET_TUN_IPv6Header *) &icmp[1];
2765 protocol = ipv6->next_header;
2766 /* could be TCP or UDP, but both have the ports in the right
2767 place, so that doesn't matter here */
2768 udp = (const struct GNUNET_TUN_UdpHeader *) &ipv6[1];
2769 /* swap ports, as they are from the original message */
2770 destination_port = ntohs (udp->source_port);
2771 source_port = ntohs (udp->destination_port);
2772 /* throw away ICMP payload, won't be useful for the other side anyway */
2773 pktlen = sizeof(struct GNUNET_TUN_IcmpHeader);
2774 break;
2775
2778 break;
2779
2780 default:
2782 gettext_noop (
2783 "# ICMPv6 packets dropped (type not allowed)")
2784 ,
2785 1, GNUNET_NO);
2786 return;
2787 }
2788 break;
2789
2790 default:
2791 GNUNET_assert (0);
2792 }
2793 switch (protocol)
2794 {
2795 case IPPROTO_ICMP:
2797 IPPROTO_ICMP,
2798 source_ip,
2799 0,
2800 destination_ip,
2801 0,
2802 NULL);
2803 break;
2804
2805 case IPPROTO_ICMPV6:
2807 IPPROTO_ICMPV6,
2808 source_ip,
2809 0,
2810 destination_ip,
2811 0,
2812 NULL);
2813 break;
2814
2815 case IPPROTO_UDP:
2817 IPPROTO_UDP,
2818 source_ip,
2819 source_port,
2820 destination_ip,
2821 destination_port,
2822 NULL);
2823 break;
2824
2825 case IPPROTO_TCP:
2827 IPPROTO_TCP,
2828 source_ip,
2829 source_port,
2830 destination_ip,
2831 destination_port,
2832 NULL);
2833 break;
2834
2835 default:
2837 gettext_noop (
2838 "# ICMP packets dropped (not allowed)"),
2839 1,
2840 GNUNET_NO);
2841 return;
2842 }
2843 if (NULL == state)
2844 {
2846 _ (
2847 "ICMP Packet dropped, have no matching connection information\n"));
2848 return;
2849 }
2850 env = GNUNET_MQ_msg_extra (i2v,
2851 pktlen - sizeof(struct GNUNET_TUN_IcmpHeader),
2853 i2v->af = htonl (af);
2855 icmp,
2856 pktlen);
2858 env);
2859}
2860
2861
2873static void
2875 size_t pktlen,
2876 int af,
2877 const void *destination_ip,
2878 const void *source_ip)
2879{
2880 struct ChannelState *state;
2881 struct GNUNET_MQ_Envelope *env;
2882 struct GNUNET_EXIT_UdpReplyMessage *urm;
2883
2884 {
2885 char sbuf[INET6_ADDRSTRLEN];
2886 char dbuf[INET6_ADDRSTRLEN];
2887
2889 "Received UDP packet going from %s:%u to %s:%u\n",
2890 inet_ntop (af,
2891 source_ip,
2892 sbuf, sizeof(sbuf)),
2893 (unsigned int) ntohs (udp->source_port),
2894 inet_ntop (af,
2895 destination_ip,
2896 dbuf, sizeof(dbuf)),
2897 (unsigned int) ntohs (udp->destination_port));
2898 }
2899
2900 if (pktlen < sizeof(struct GNUNET_TUN_UdpHeader))
2901 {
2902 /* blame kernel */
2903 GNUNET_break (0);
2904 return;
2905 }
2906 if (pktlen != ntohs (udp->len))
2907 {
2908 /* blame kernel */
2909 GNUNET_break (0);
2910 return;
2911 }
2913 IPPROTO_UDP,
2914 source_ip,
2915 ntohs (udp->source_port),
2916 destination_ip,
2917 ntohs (udp->destination_port),
2918 NULL);
2919 if (NULL == state)
2920 {
2922 _ (
2923 "UDP Packet dropped, have no matching connection information\n"));
2924 return;
2925 }
2926 env = GNUNET_MQ_msg_extra (urm,
2927 pktlen - sizeof(struct GNUNET_TUN_UdpHeader),
2929 urm->source_port = htons (0);
2930 urm->destination_port = htons (0);
2931 GNUNET_memcpy (&urm[1],
2932 &udp[1],
2933 pktlen - sizeof(struct GNUNET_TUN_UdpHeader));
2935 env);
2936}
2937
2938
2950static void
2952 size_t pktlen,
2953 int af,
2954 const void *destination_ip,
2955 const void *source_ip)
2956{
2957 struct ChannelState *state;
2958 char buf[pktlen] GNUNET_ALIGN;
2959 struct GNUNET_TUN_TcpHeader *mtcp;
2960 struct GNUNET_EXIT_TcpDataMessage *tdm;
2961 struct GNUNET_MQ_Envelope *env;
2962 size_t mlen;
2963
2964 {
2965 char sbuf[INET6_ADDRSTRLEN];
2966 char dbuf[INET6_ADDRSTRLEN];
2968 "Received TCP packet with %u bytes going from %s:%u to %s:%u\n",
2969 (unsigned int) (pktlen - sizeof(struct GNUNET_TUN_TcpHeader)),
2970 inet_ntop (af,
2971 source_ip,
2972 sbuf, sizeof(sbuf)),
2973 (unsigned int) ntohs (tcp->source_port),
2974 inet_ntop (af,
2975 destination_ip,
2976 dbuf, sizeof(dbuf)),
2977 (unsigned int) ntohs (tcp->destination_port));
2978 }
2979
2980 if (pktlen < sizeof(struct GNUNET_TUN_TcpHeader))
2981 {
2982 /* blame kernel */
2983 GNUNET_break (0);
2984 return;
2985 }
2987 IPPROTO_TCP,
2988 source_ip,
2989 ntohs (tcp->source_port),
2990 destination_ip,
2991 ntohs (tcp->destination_port),
2992 NULL);
2993 if (NULL == state)
2994 {
2996 _ (
2997 "TCP Packet dropped, have no matching connection information\n"));
2998
2999 return;
3000 }
3001 /* mug port numbers and crc to avoid information leakage;
3002 sender will need to lookup the correct values anyway */
3003 GNUNET_memcpy (buf, tcp, pktlen);
3004 mtcp = (struct GNUNET_TUN_TcpHeader *) buf;
3005 mtcp->source_port = 0;
3006 mtcp->destination_port = 0;
3007 mtcp->crc = 0;
3008
3009 mlen = sizeof(struct GNUNET_EXIT_TcpDataMessage) + (pktlen - sizeof(struct
3011 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
3012 {
3013 GNUNET_break (0);
3014 return;
3015 }
3016 env = GNUNET_MQ_msg_extra (tdm,
3017 pktlen - sizeof(struct GNUNET_TUN_TcpHeader),
3019 tdm->reserved = htonl (0);
3021 buf,
3022 pktlen);
3024 env);
3025}
3026
3027
3034static int
3036 const struct GNUNET_MessageHeader *message)
3037{
3038 const struct GNUNET_TUN_Layer2PacketHeader *pkt_tun;
3039 size_t size;
3040
3042 "Got %u-byte message of type %u from gnunet-helper-exit\n",
3043 ntohs (message->size),
3044 ntohs (message->type));
3046 gettext_noop ("# Packets received from TUN"),
3047 1, GNUNET_NO);
3048 if (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER)
3049 {
3050 GNUNET_break (0);
3051 return GNUNET_OK;
3052 }
3053 size = ntohs (message->size);
3054 if (size < sizeof(struct GNUNET_TUN_Layer2PacketHeader) + sizeof(struct
3056 {
3057 GNUNET_break (0);
3058 return GNUNET_OK;
3059 }
3061 gettext_noop ("# Bytes received from TUN"),
3062 size, GNUNET_NO);
3063 pkt_tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1];
3064 size -= sizeof(struct GNUNET_TUN_Layer2PacketHeader) + sizeof(struct
3066 switch (ntohs (pkt_tun->proto))
3067 {
3068 case ETH_P_IPV4:
3069 {
3070 const struct GNUNET_TUN_IPv4Header *pkt4;
3071
3072 if (size < sizeof(struct GNUNET_TUN_IPv4Header))
3073 {
3074 /* Kernel to blame? */
3075 GNUNET_break (0);
3076 return GNUNET_OK;
3077 }
3078 pkt4 = (const struct GNUNET_TUN_IPv4Header *) &pkt_tun[1];
3079 if (size != ntohs (pkt4->total_length))
3080 {
3081 /* Kernel to blame? */
3082 GNUNET_break (0);
3083 return GNUNET_OK;
3084 }
3085 if (pkt4->header_length * 4 != sizeof(struct GNUNET_TUN_IPv4Header))
3086 {
3088 _ ("IPv4 packet options received. Ignored.\n"));
3089 return GNUNET_OK;
3090 }
3091
3092 size -= sizeof(struct GNUNET_TUN_IPv4Header);
3093 switch (pkt4->protocol)
3094 {
3095 case IPPROTO_UDP:
3096 udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt4[1], size,
3097 AF_INET,
3098 &pkt4->destination_address,
3099 &pkt4->source_address);
3100 break;
3101
3102 case IPPROTO_TCP:
3103 tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt4[1], size,
3104 AF_INET,
3105 &pkt4->destination_address,
3106 &pkt4->source_address);
3107 break;
3108
3109 case IPPROTO_ICMP:
3110 icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt4[1], size,
3111 AF_INET,
3112 &pkt4->destination_address,
3113 &pkt4->source_address);
3114 break;
3115
3116 default:
3118 _ (
3119 "IPv4 packet with unsupported next header %u received. Ignored.\n"),
3120 (int) pkt4->protocol);
3121 return GNUNET_OK;
3122 }
3123 }
3124 break;
3125
3126 case ETH_P_IPV6:
3127 {
3128 const struct GNUNET_TUN_IPv6Header *pkt6;
3129
3130 if (size < sizeof(struct GNUNET_TUN_IPv6Header))
3131 {
3132 /* Kernel to blame? */
3133 GNUNET_break (0);
3134 return GNUNET_OK;
3135 }
3136 pkt6 = (struct GNUNET_TUN_IPv6Header *) &pkt_tun[1];
3137 if (size != ntohs (pkt6->payload_length) + sizeof(struct
3139 {
3140 /* Kernel to blame? */
3141 GNUNET_break (0);
3142 return GNUNET_OK;
3143 }
3144 size -= sizeof(struct GNUNET_TUN_IPv6Header);
3145 switch (pkt6->next_header)
3146 {
3147 case IPPROTO_UDP:
3148 udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt6[1], size,
3149 AF_INET6,
3150 &pkt6->destination_address,
3151 &pkt6->source_address);
3152 break;
3153
3154 case IPPROTO_TCP:
3155 tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt6[1], size,
3156 AF_INET6,
3157 &pkt6->destination_address,
3158 &pkt6->source_address);
3159 break;
3160
3161 case IPPROTO_ICMPV6:
3162 icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt6[1], size,
3163 AF_INET6,
3164 &pkt6->destination_address,
3165 &pkt6->source_address);
3166 break;
3167
3168 default:
3170 _ (
3171 "IPv6 packet with unsupported next header %d received. Ignored.\n"),
3172 pkt6->next_header);
3173 return GNUNET_OK;
3174 }
3175 }
3176 break;
3177
3178 default:
3180 _ ("Packet from unknown protocol %u received. Ignored.\n"),
3181 ntohs (pkt_tun->proto));
3182 break;
3183 }
3184 return GNUNET_OK;
3185}
3186
3187
3196static void *
3197new_channel (void *cls,
3198 struct GNUNET_CADET_Channel *channel,
3199 const struct GNUNET_PeerIdentity *initiator)
3200{
3201 struct ChannelState *s = GNUNET_new (struct ChannelState);
3202
3203 s->is_dns = GNUNET_SYSERR;
3204 s->peer = *initiator;
3206 gettext_noop ("# Inbound CADET channels created"),
3207 1,
3208 GNUNET_NO);
3210 "Received inbound channel from `%s'\n",
3211 GNUNET_i2s (initiator));
3212 s->channel = channel;
3213 return s;
3214}
3215
3216
3224static int
3225free_iterate (void *cls,
3226 const struct GNUNET_HashCode *hash,
3227 void *value)
3228{
3230 return GNUNET_YES;
3231}
3232
3233
3242static void
3243dummy_task (void *cls)
3244{
3245 /* just terminate */
3246}
3247
3248
3254static void
3255cleanup (void *cls)
3256{
3257 unsigned int i;
3258
3260 "Exit service is shutting down now\n");
3261
3262 if (NULL != helper_handle)
3263 {
3265 helper_handle = NULL;
3266 }
3267 if (NULL != regex4)
3268 {
3270 regex4 = NULL;
3271 }
3272 if (NULL != regex6)
3273 {
3275 regex6 = NULL;
3276 }
3277 if (NULL != services)
3278 {
3281 NULL);
3283 }
3284 if (NULL != dns_port)
3285 {
3287 dns_port = NULL;
3288 }
3289 if (NULL != cadet_port4)
3290 {
3292 cadet_port4 = NULL;
3293 }
3294 if (NULL != cadet_port6)
3295 {
3297 cadet_port6 = NULL;
3298 }
3299 if (NULL != cadet_handle)
3300 {
3302 cadet_handle = NULL;
3303 }
3304 if (NULL != connections_map)
3305 {
3307 &free_iterate,
3308 NULL);
3310 connections_map = NULL;
3311 }
3312 if (NULL != connections_heap)
3313 {
3315 connections_heap = NULL;
3316 }
3317 if (NULL != dnsstub)
3318 {
3320 dnsstub = NULL;
3321 }
3322 if (NULL != sign_op)
3323 {
3325 sign_op = NULL;
3326 }
3327 if (NULL != pils)
3328 {
3330 pils = NULL;
3331 }
3332 if (NULL != dht_task)
3333 {
3335 dht_task = NULL;
3336 }
3337 if (NULL != dht_put)
3338 {
3340 dht_put = NULL;
3341 }
3342 if (NULL != dht)
3343 {
3345 dht = NULL;
3346 }
3347 if (NULL != stats)
3348 {
3350 GNUNET_NO);
3351 stats = NULL;
3352 }
3353 for (i = 0; i < 8; i++)
3355}
3356
3357
3365static void
3367 char *cpy,
3368 const char *name)
3369{
3370 char *redirect;
3371 char *hostname;
3372 char *hostport;
3373 struct LocalService *serv;
3374 char *n;
3375 size_t slen;
3376 int local_port;
3377 int remote_port;
3378
3379 slen = strlen (name);
3380 GNUNET_assert (slen >= 8);
3381 n = GNUNET_strndup (name, slen - 8 /* remove .gnunet. */);
3382
3383 for (redirect = strtok (cpy, " ;"); redirect != NULL;
3384 redirect = strtok (NULL, " ;"))
3385 {
3386 if (NULL == (hostname = strstr (redirect, ":")))
3387 {
3389 _ (
3390 "Option `%s' for domain `%s' is not formatted correctly!\n")
3391 ,
3392 redirect,
3393 name);
3394 continue;
3395 }
3396 hostname[0] = '\0';
3397 hostname++;
3398 if (NULL == (hostport = strstr (hostname, ":")))
3399 {
3401 _ (
3402 "Option `%s' for domain `%s' is not formatted correctly!\n")
3403 ,
3404 redirect,
3405 name);
3406 continue;
3407 }
3408 hostport[0] = '\0';
3409 hostport++;
3410
3411 local_port = atoi (redirect);
3412 remote_port = atoi (hostport);
3413
3414 if (! ((local_port > 0) && (local_port < 65536)))
3415 {
3417 _ ("`%s' is not a valid port number (for domain `%s')!"),
3418 redirect,
3419 name);
3420 continue;
3421 }
3422 if (! ((remote_port > 0) && (remote_port < 65536)))
3423 {
3425 _ ("`%s' is not a valid port number (for domain `%s')!"),
3426 hostport,
3427 name);
3428 continue;
3429 }
3430
3431 serv = GNUNET_new (struct LocalService);
3432 serv->address.proto = proto;
3433 serv->address.port = remote_port;
3434 if (0 == strcmp ("localhost4",
3435 hostname))
3436 {
3437 const char *ip4addr = exit_argv[5];
3438
3439 serv->address.af = AF_INET;
3440 GNUNET_assert (1 == inet_pton (AF_INET,
3441 ip4addr,
3442 &serv->address.address.ipv4));
3443 }
3444 else if (0 == strcmp ("localhost6",
3445 hostname))
3446 {
3447 const char *ip6addr = exit_argv[3];
3448
3449 serv->address.af = AF_INET6;
3450 GNUNET_assert (1 == inet_pton (AF_INET6,
3451 ip6addr,
3452 &serv->address.address.ipv6));
3453 }
3454 else
3455 {
3456 struct addrinfo *res;
3457 int ret;
3458
3459 ret = getaddrinfo (hostname,
3460 NULL,
3461 NULL,
3462 &res);
3463 if ((0 != ret) || (NULL == res))
3464 {
3466 _ (
3467 "No addresses found for hostname `%s' of service `%s'!\n")
3468 ,
3469 hostname,
3470 n);
3471 GNUNET_free (serv);
3472 continue;
3473 }
3474
3475 serv->address.af = res->ai_family;
3476 switch (res->ai_family)
3477 {
3478 case AF_INET:
3479 if (! ipv4_enabled)
3480 {
3482 _ (
3483 "Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
3484 n);
3485 freeaddrinfo (res);
3486 GNUNET_free (serv);
3487 continue;
3488 }
3489 serv->address.address.ipv4
3490 = ((struct sockaddr_in *) res->ai_addr)->sin_addr;
3491 break;
3492
3493 case AF_INET6:
3494 if (! ipv6_enabled)
3495 {
3497 _ (
3498 "Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
3499 n);
3500 freeaddrinfo (res);
3501 GNUNET_free (serv);
3502 continue;
3503 }
3504 serv->address.address.ipv6
3505 = ((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
3506 break;
3507
3508 default:
3509 freeaddrinfo (res);
3511 _ (
3512 "No IP addresses found for hostname `%s' of service `%s'!\n"),
3513 hostname,
3514 n);
3515 GNUNET_free (serv);
3516 continue;
3517 }
3518 freeaddrinfo (res);
3519 }
3521 n,
3522 local_port,
3523 serv);
3524 }
3525 GNUNET_free (n);
3526}
3527
3528
3535static void
3537 const char *section)
3538{
3539 char *cpy;
3540
3541 if ((strlen (section) < 8) ||
3542 (0 != strcmp (".gnunet.", section + (strlen (section) - 8))))
3543 return;
3544 if (GNUNET_OK ==
3546 section,
3547 "UDP_REDIRECTS",
3548 &cpy))
3549 {
3550 add_services (IPPROTO_UDP,
3551 cpy,
3552 section);
3553 GNUNET_free (cpy);
3554 }
3555 if (GNUNET_OK ==
3557 section,
3558 "TCP_REDIRECTS",
3559 &cpy))
3560 {
3561 add_services (IPPROTO_TCP,
3562 cpy,
3563 section);
3564 GNUNET_free (cpy);
3565 }
3566}
3567
3568
3575static void
3576do_dht_put (void *cls);
3577
3578
3585static void
3586dht_put_cont (void *cls)
3587{
3588 dht_put = NULL;
3589}
3590
3591
3592static void
3594 const struct GNUNET_PeerIdentity *pid,
3595 const struct GNUNET_CRYPTO_EddsaSignature *sig)
3596{
3597 GNUNET_assert (sig);
3598
3599 sign_op = NULL;
3600
3602 sizeof (dns_advertisement.signature));
3603
3604 do_dht_put (cls);
3605}
3606
3607
3614static void
3651
3652
3653static void
3655 const struct GNUNET_HELLO_Parser *parser,
3656 const struct GNUNET_HashCode *hash)
3657{
3658 const struct GNUNET_PeerIdentity *my_identity;
3659
3662
3664 my_identity, sizeof (*my_identity));
3665 dns_advertisement.purpose.size = htonl (sizeof(struct
3667 - sizeof(struct
3669 );
3672 GNUNET_CRYPTO_hash ("dns",
3673 strlen ("dns"),
3674 &dht_put_key);
3675
3676 if (NULL != sign_op)
3677 {
3679 sign_op = NULL;
3680 }
3681
3682 if (NULL != dht_task)
3684
3686 NULL);
3687}
3688
3689
3694static void
3696{
3698 "exit",
3699 "EXIT_IPV4");
3701 "exit",
3702 "EXIT_IPV6");
3704 "exit",
3705 "ENABLE_IPV4");
3707 "exit",
3708 "ENABLE_IPV6");
3709 if ((ipv4_exit || ipv4_enabled) &&
3710 (GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET)) )
3711 {
3713 _ (
3714 "This system does not support IPv4, will disable IPv4 functions despite them being enabled in the configuration\n"));
3717 }
3718 if ((ipv6_exit || ipv6_enabled) &&
3719 (GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET6)) )
3720 {
3722 _ (
3723 "This system does not support IPv6, will disable IPv6 functions despite them being enabled in the configuration\n"));
3726 }
3727 if (ipv4_exit && (! ipv4_enabled))
3728 {
3730 _ (
3731 "Cannot enable IPv4 exit but disable IPv4 on TUN interface, will use ENABLE_IPv4=YES\n"));
3733 }
3734 if (ipv6_exit && (! ipv6_enabled))
3735 {
3737 _ (
3738 "Cannot enable IPv6 exit but disable IPv6 on TUN interface, will use ENABLE_IPv6=YES\n"));
3740 }
3741}
3742
3743
3748static void
3750{
3752 GNUNET_MQ_hd_var_size (dns_request,
3754 struct DnsResponseMessage,
3755 NULL),
3757 };
3758 char *dns_exit;
3759 struct GNUNET_HashCode port;
3760
3761 if (GNUNET_YES !=
3763 "exit",
3764 "EXIT_DNS"))
3765 return;
3766 GNUNET_assert (NULL != (dnsstub = GNUNET_DNSSTUB_start (128)));
3767 dns_exit = NULL;
3768 /* TODO: support using multiple DNS resolvers */
3769 if ((GNUNET_OK !=
3771 "exit",
3772 "DNS_RESOLVER",
3773 &dns_exit)) ||
3774 (GNUNET_OK !=
3776 dns_exit)))
3777 {
3779 "dns",
3780 "DNS_RESOLVER",
3781 _ ("need a valid IPv4 or IPv6 address\n"));
3782 GNUNET_free (dns_exit);
3783 return;
3784 }
3785 /* open port */
3788 &port);
3790 "Opening CADET port %s for DNS exit service\n",
3791 GNUNET_h2s (&port));
3793 &port,
3794 &new_channel,
3795 NULL,
3796 NULL,
3798 handlers);
3799 /* advertise exit */
3800 dht = GNUNET_DHT_connect (cfg, 1);
3801 dht_task = NULL;
3803 sign_op = NULL;
3804 GNUNET_free (dns_exit);
3805}
3806
3807
3813static int
3815{
3816 char *exit_ifname;
3817 char *tun_ifname;
3818 char *ipv6addr;
3819 char *ipv6prefix_s;
3820 char *ipv4addr;
3821 char *ipv4mask;
3822
3823 exit_argv[0] = GNUNET_strdup ("exit-gnunet");
3824 if (GNUNET_SYSERR ==
3826 "exit",
3827 "TUN_IFNAME",
3828 &tun_ifname))
3829 {
3831 "EXIT",
3832 "TUN_IFNAME");
3833 return GNUNET_SYSERR;
3834 }
3835 exit_argv[1] = tun_ifname;
3836 if (ipv4_enabled)
3837 {
3838 if (GNUNET_SYSERR ==
3840 "exit",
3841 "EXIT_IFNAME",
3842 &exit_ifname))
3843 {
3845 "EXIT",
3846 "EXIT_IFNAME");
3847 return GNUNET_SYSERR;
3848 }
3849 exit_argv[2] = exit_ifname;
3850 }
3851 else
3852 {
3853 exit_argv[2] = GNUNET_strdup ("-");
3854 }
3855
3856 if (GNUNET_YES == ipv6_enabled)
3857 {
3858 ipv6addr = NULL;
3859 if (((GNUNET_SYSERR ==
3861 "exit",
3862 "IPV6ADDR",
3863 &ipv6addr)) ||
3864 (1 != inet_pton (AF_INET6,
3865 ipv6addr,
3866 &exit_ipv6addr))))
3867 {
3869 "EXIT",
3870 "IPV6ADDR");
3871 GNUNET_free (ipv6addr);
3872 return GNUNET_SYSERR;
3873 }
3874 exit_argv[3] = ipv6addr;
3875 if (GNUNET_SYSERR ==
3877 "exit",
3878 "IPV6PREFIX",
3879 &ipv6prefix_s))
3880 {
3882 "EXIT",
3883 "IPV6PREFIX");
3884 return GNUNET_SYSERR;
3885 }
3886 exit_argv[4] = ipv6prefix_s;
3887 if ((GNUNET_OK !=
3889 "exit",
3890 "IPV6PREFIX",
3891 &ipv6prefix)) ||
3892 (ipv6prefix >= 127))
3893 {
3895 "EXIT",
3896 "IPV6PREFIX",
3897 _ ("Must be a number"));
3898 return GNUNET_SYSERR;
3899 }
3900 }
3901 else
3902 {
3903 /* IPv6 explicitly disabled */
3904 exit_argv[3] = GNUNET_strdup ("-");
3905 exit_argv[4] = GNUNET_strdup ("-");
3906 }
3907 if (GNUNET_YES == ipv4_enabled)
3908 {
3909 ipv4addr = NULL;
3910 if (((GNUNET_SYSERR ==
3912 "exit",
3913 "IPV4ADDR",
3914 &ipv4addr)) ||
3915 (1 != inet_pton (AF_INET,
3916 ipv4addr,
3917 &exit_ipv4addr))))
3918 {
3920 "EXIT",
3921 "IPV4ADDR");
3922 GNUNET_free (ipv4addr);
3923 return GNUNET_SYSERR;
3924 }
3925 exit_argv[5] = ipv4addr;
3926 ipv4mask = NULL;
3927 if (((GNUNET_SYSERR ==
3929 "exit",
3930 "IPV4MASK",
3931 &ipv4mask)) ||
3932 (1 != inet_pton (AF_INET,
3933 ipv4mask,
3934 &exit_ipv4mask))))
3935 {
3937 "EXIT",
3938 "IPV4MASK");
3939 GNUNET_free (ipv4mask);
3940 return GNUNET_SYSERR;
3941 }
3942 exit_argv[6] = ipv4mask;
3943 }
3944 else
3945 {
3946 /* IPv4 explicitly disabled */
3947 exit_argv[5] = GNUNET_strdup ("-");
3948 exit_argv[6] = GNUNET_strdup ("-");
3949 }
3950 exit_argv[7] = NULL;
3951 return GNUNET_OK;
3952}
3953
3954
3963static void
3964run (void *cls,
3965 char *const *args,
3966 const char *cfgfile,
3967 const struct GNUNET_CONFIGURATION_Handle *cfg_)
3968{
3970 GNUNET_MQ_hd_var_size (icmp_remote,
3973 NULL),
3974 GNUNET_MQ_hd_var_size (udp_remote,
3977 NULL),
3978 GNUNET_MQ_hd_var_size (tcp_remote,
3981 NULL),
3982 GNUNET_MQ_hd_var_size (tcp_data,
3985 NULL),
3987 };
3988 struct GNUNET_HashCode port;
3989 char *policy;
3990 char *binary;
3991 char *regex;
3992 char *prefixed_regex;
3993
3994 cfg = cfg_;
3995 if (GNUNET_OK !=
3997 "exit",
3998 "MAX_CONNECTIONS",
4000 max_connections = 1024;
4004 cfg,
4005 "gnunet-helper-exit");
4006 if ((ipv4_exit) || (ipv6_exit))
4007 {
4008 if (GNUNET_YES !=
4010 GNUNET_YES,
4011 "gnunet-vpn - - - 169.1.3.7 255.255.255.0"))
4012 // no nat, ipv4 only
4013 {
4014 GNUNET_free (binary);
4016 _ (
4017 "`%s' is not SUID or the path is invalid, EXIT will not work\n"),
4018 "gnunet-helper-exit");
4020 NULL);
4021 global_ret = 1;
4022 return;
4023 }
4024 }
4025 if (! (ipv4_enabled || ipv6_enabled))
4026 {
4027 GNUNET_free (binary);
4029 _ ("No useful service enabled. Exiting.\n"));
4031 return;
4032 }
4033
4035 NULL);
4037 cfg);
4039 if (NULL == cadet_handle)
4040 {
4041 GNUNET_free (binary);
4043 return;
4044 }
4046 if (GNUNET_OK !=
4048 {
4049 GNUNET_free (binary);
4051 return;
4052 }
4053
4055 GNUNET_NO);
4057 GNUNET_NO);
4062 NULL);
4063
4064 /* Cadet handle acquired, now open ports and announce regular
4065 expressions matching our exit */
4066 if ((GNUNET_YES == ipv4_enabled) &&
4067 (GNUNET_YES == ipv4_exit))
4068 {
4071 &port);
4073 "Opening CADET port %s for IPv4 gateway service\n",
4074 GNUNET_h2s (&port));
4076 &port,
4077 &new_channel,
4078 NULL,
4079 NULL,
4081 handlers);
4082 policy = NULL;
4083 if (GNUNET_OK !=
4085 "exit",
4086 "EXIT_RANGE_IPV4_POLICY",
4087 &policy))
4088 regex = NULL;
4089 else
4090 regex = GNUNET_REGEX_ipv4policy2regex (policy);
4091 GNUNET_free (policy);
4092 if (NULL != regex)
4093 {
4094 (void) GNUNET_asprintf (&prefixed_regex,
4095 "%s%s",
4097 regex);
4099 prefixed_regex,
4102 GNUNET_free (regex);
4103 GNUNET_free (prefixed_regex);
4104 }
4105 }
4106
4108 {
4111 &port);
4113 "Opening CADET port %s for IPv6 gateway service\n",
4114 GNUNET_h2s (&port));
4116 &port,
4117 &new_channel,
4118 NULL,
4119 NULL,
4121 handlers);
4122 policy = NULL;
4123 if (GNUNET_OK !=
4125 "exit",
4126 "EXIT_RANGE_IPV6_POLICY",
4127 &policy))
4128 regex = NULL;
4129 else
4130 regex = GNUNET_REGEX_ipv6policy2regex (policy);
4131 GNUNET_free (policy);
4132 if (NULL != regex)
4133 {
4134 (void) GNUNET_asprintf (&prefixed_regex,
4135 "%s%s",
4137 regex);
4139 prefixed_regex,
4142 GNUNET_free (regex);
4143 GNUNET_free (prefixed_regex);
4144 }
4145 }
4147 GNUNET_NO,
4148 binary,
4149 exit_argv,
4151 NULL,
4152 NULL);
4153 GNUNET_free (binary);
4154}
4155
4156
4164int
4165main (int argc,
4166 char *const *argv)
4167{
4168 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
4170 };
4171
4172 return (GNUNET_OK ==
4174 argc,
4175 argv,
4176 "gnunet-daemon-exit",
4177 gettext_noop (
4178 "Daemon to run to provide an IP exit node for the VPN"),
4179 options,
4180 &run,
4181 NULL)) ? global_ret : 1;
4182}
4183
4184
4185/* 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.
char * GNUNET_CONFIGURATION_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_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(uint32_t i)
Produce a random value.
void GNUNET_DHT_put_cancel(struct GNUNET_DHT_PutHandle *ph)
Cancels a DHT PUT operation.
Definition dht_api.c:1149
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:1086
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:1058
@ GNUNET_DHT_RO_NONE
Default.
struct GNUNET_DNSSTUB_Context * GNUNET_DNSSTUB_start(unsigned int num_sockets)
Start a DNS stub resolver.
Definition dnsstub.c:585
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:612
void GNUNET_DNSSTUB_stop(struct GNUNET_DNSSTUB_Context *ctx)
Cleanup DNSSTUB resolver.
Definition dnsstub.c:704
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:525
#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:40
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.
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:406
#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 ...
union ChannelState::@78 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
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.
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