diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-01-02 09:57:25 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-01-02 09:57:25 +0000 |
commit | 2b152f749e6274ab97baa09b9d1522803c76027f (patch) | |
tree | ea5e4857b6de87cb3ad79da334c6d61e213cd54a | |
parent | a0f00b8f5726eccb6eab9bcf974c3e45ab572220 (diff) | |
download | gnunet-2b152f749e6274ab97baa09b9d1522803c76027f.tar.gz gnunet-2b152f749e6274ab97baa09b9d1522803c76027f.zip |
-using new GNUNET_HELPER_ API inside of VPN, also eliminating bugs with partial writes as part of this
-rw-r--r-- | src/vpn/Makefile.am | 3 | ||||
-rw-r--r-- | src/vpn/gnunet-daemon-exit.c | 283 | ||||
-rw-r--r-- | src/vpn/gnunet-daemon-vpn-helper.c | 691 | ||||
-rw-r--r-- | src/vpn/gnunet-daemon-vpn-helper.h | 76 | ||||
-rw-r--r-- | src/vpn/gnunet-daemon-vpn.c | 656 | ||||
-rw-r--r-- | src/vpn/gnunet-helper-vpn-api.c | 98 | ||||
-rw-r--r-- | src/vpn/gnunet-helper-vpn-api.h | 110 |
7 files changed, 780 insertions, 1137 deletions
diff --git a/src/vpn/Makefile.am b/src/vpn/Makefile.am index ecb01969b..bdfca7f2f 100644 --- a/src/vpn/Makefile.am +++ b/src/vpn/Makefile.am | |||
@@ -34,8 +34,6 @@ gnunet_helper_vpn_SOURCES = \ | |||
34 | 34 | ||
35 | gnunet_daemon_vpn_SOURCES = \ | 35 | gnunet_daemon_vpn_SOURCES = \ |
36 | gnunet-daemon-vpn.c gnunet-daemon-vpn.h \ | 36 | gnunet-daemon-vpn.c gnunet-daemon-vpn.h \ |
37 | gnunet-daemon-vpn-helper.c gnunet-daemon-vpn-helper.h \ | ||
38 | gnunet-helper-vpn-api.c gnunet-helper-vpn-api.h \ | ||
39 | gnunet-vpn-checksum.c gnunet-vpn-checksum.h | 37 | gnunet-vpn-checksum.c gnunet-vpn-checksum.h |
40 | gnunet_daemon_vpn_LDADD = \ | 38 | gnunet_daemon_vpn_LDADD = \ |
41 | $(top_builddir)/src/core/libgnunetcore.la \ | 39 | $(top_builddir)/src/core/libgnunetcore.la \ |
@@ -48,7 +46,6 @@ gnunet_daemon_vpn_LDADD = \ | |||
48 | 46 | ||
49 | gnunet_daemon_exit_SOURCES = \ | 47 | gnunet_daemon_exit_SOURCES = \ |
50 | gnunet-daemon-exit.c \ | 48 | gnunet-daemon-exit.c \ |
51 | gnunet-helper-vpn-api.c gnunet-helper-vpn-api.h \ | ||
52 | gnunet-vpn-checksum.c gnunet-vpn-checksum.h | 49 | gnunet-vpn-checksum.c gnunet-vpn-checksum.h |
53 | gnunet_daemon_exit_LDADD = \ | 50 | gnunet_daemon_exit_LDADD = \ |
54 | $(top_builddir)/src/core/libgnunetcore.la \ | 51 | $(top_builddir)/src/core/libgnunetcore.la \ |
diff --git a/src/vpn/gnunet-daemon-exit.c b/src/vpn/gnunet-daemon-exit.c index 5c450ecc6..ebe3ec61a 100644 --- a/src/vpn/gnunet-daemon-exit.c +++ b/src/vpn/gnunet-daemon-exit.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2010 Christian Grothoff | 3 | (C) 2010, 2012 Christian Grothoff |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -33,11 +33,8 @@ | |||
33 | #include <string.h> | 33 | #include <string.h> |
34 | 34 | ||
35 | #include "gnunet-vpn-packet.h" | 35 | #include "gnunet-vpn-packet.h" |
36 | #include "gnunet-helper-vpn-api.h" | ||
37 | #include "gnunet-vpn-checksum.h" | 36 | #include "gnunet-vpn-checksum.h" |
38 | 37 | ||
39 | GNUNET_SCHEDULER_TaskIdentifier shs_task; | ||
40 | |||
41 | /** | 38 | /** |
42 | * The handle to the configuration used throughout the process | 39 | * The handle to the configuration used throughout the process |
43 | */ | 40 | */ |
@@ -46,7 +43,12 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg; | |||
46 | /** | 43 | /** |
47 | * The handle to the helper | 44 | * The handle to the helper |
48 | */ | 45 | */ |
49 | struct GNUNET_VPN_HELPER_Handle *helper_handle; | 46 | static struct GNUNET_HELPER_Handle *helper_handle; |
47 | |||
48 | /** | ||
49 | * Arguments to the exit helper. | ||
50 | */ | ||
51 | static char *exit_argv[7]; | ||
50 | 52 | ||
51 | /** | 53 | /** |
52 | * Final status code. | 54 | * Final status code. |
@@ -63,8 +65,11 @@ static struct GNUNET_MESH_Handle *mesh_handle; | |||
63 | * source-port and destination-port to a struct redirect_state | 65 | * source-port and destination-port to a struct redirect_state |
64 | */ | 66 | */ |
65 | static struct GNUNET_CONTAINER_MultiHashMap *udp_connections; | 67 | static struct GNUNET_CONTAINER_MultiHashMap *udp_connections; |
68 | |||
66 | static struct GNUNET_CONTAINER_Heap *udp_connections_heap; | 69 | static struct GNUNET_CONTAINER_Heap *udp_connections_heap; |
70 | |||
67 | static struct GNUNET_CONTAINER_MultiHashMap *tcp_connections; | 71 | static struct GNUNET_CONTAINER_MultiHashMap *tcp_connections; |
72 | |||
68 | static struct GNUNET_CONTAINER_Heap *tcp_connections_heap; | 73 | static struct GNUNET_CONTAINER_Heap *tcp_connections_heap; |
69 | 74 | ||
70 | /** | 75 | /** |
@@ -136,8 +141,7 @@ struct redirect_state | |||
136 | struct GNUNET_CONTAINER_MultiHashMap *hashmap; | 141 | struct GNUNET_CONTAINER_MultiHashMap *hashmap; |
137 | GNUNET_HashCode hash; | 142 | GNUNET_HashCode hash; |
138 | 143 | ||
139 | enum | 144 | enum { SERVICE, REMOTE } type; |
140 | { SERVICE, REMOTE } type; | ||
141 | 145 | ||
142 | /** | 146 | /** |
143 | * The source-address and -port of this connection | 147 | * The source-address and -port of this connection |
@@ -146,9 +150,14 @@ struct redirect_state | |||
146 | }; | 150 | }; |
147 | 151 | ||
148 | /** | 152 | /** |
149 | * This hashmaps saves interesting things about the configured services | 153 | * This hashmaps saves interesting things about the configured UDP services |
150 | */ | 154 | */ |
151 | static struct GNUNET_CONTAINER_MultiHashMap *udp_services; | 155 | static struct GNUNET_CONTAINER_MultiHashMap *udp_services; |
156 | |||
157 | /** | ||
158 | * This hashmaps saves interesting things about the configured TCP services | ||
159 | */ | ||
160 | |||
152 | static struct GNUNET_CONTAINER_MultiHashMap *tcp_services; | 161 | static struct GNUNET_CONTAINER_MultiHashMap *tcp_services; |
153 | 162 | ||
154 | struct tunnel_notify_queue | 163 | struct tunnel_notify_queue |
@@ -166,6 +175,7 @@ struct tunnel_state | |||
166 | struct GNUNET_MESH_TransmitHandle *th; | 175 | struct GNUNET_MESH_TransmitHandle *th; |
167 | }; | 176 | }; |
168 | 177 | ||
178 | |||
169 | /** | 179 | /** |
170 | * Function that frees everything from a hashmap | 180 | * Function that frees everything from a hashmap |
171 | */ | 181 | */ |
@@ -184,17 +194,23 @@ static void | |||
184 | cleanup (void *cls GNUNET_UNUSED, | 194 | cleanup (void *cls GNUNET_UNUSED, |
185 | const struct GNUNET_SCHEDULER_TaskContext *tskctx) | 195 | const struct GNUNET_SCHEDULER_TaskContext *tskctx) |
186 | { | 196 | { |
187 | GNUNET_assert (0 != (tskctx->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)); | 197 | unsigned int i; |
188 | |||
189 | GNUNET_CONTAINER_multihashmap_iterate (udp_connections, free_iterate, NULL); | ||
190 | |||
191 | GNUNET_CONTAINER_multihashmap_iterate (tcp_connections, free_iterate, NULL); | ||
192 | 198 | ||
199 | GNUNET_assert (0 != (tskctx->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)); | ||
193 | if (mesh_handle != NULL) | 200 | if (mesh_handle != NULL) |
194 | { | 201 | { |
195 | GNUNET_MESH_disconnect (mesh_handle); | 202 | GNUNET_MESH_disconnect (mesh_handle); |
196 | mesh_handle = NULL; | 203 | mesh_handle = NULL; |
197 | } | 204 | } |
205 | if (helper_handle != NULL) | ||
206 | { | ||
207 | GNUNET_HELPER_stop (helper_handle); | ||
208 | helper_handle = NULL; | ||
209 | } | ||
210 | GNUNET_CONTAINER_multihashmap_iterate (udp_connections, &free_iterate, NULL); | ||
211 | GNUNET_CONTAINER_multihashmap_iterate (tcp_connections, &free_iterate, NULL); | ||
212 | for (i=0;i<5;i++) | ||
213 | GNUNET_free_non_null (exit_argv[i]); | ||
198 | } | 214 | } |
199 | 215 | ||
200 | static void * | 216 | static void * |
@@ -750,89 +766,7 @@ next: | |||
750 | while (proto != UDP); | 766 | while (proto != UDP); |
751 | } | 767 | } |
752 | 768 | ||
753 | /** | ||
754 | * Start the helper-process | ||
755 | * | ||
756 | * If cls != NULL it is assumed that this function is called as a result of a dying | ||
757 | * helper. cls is then taken as handle to the old helper and is cleaned up. | ||
758 | */ | ||
759 | static void | ||
760 | start_helper_and_schedule (void *cls, | ||
761 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
762 | { | ||
763 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | ||
764 | return; | ||
765 | |||
766 | if (cls != NULL) | ||
767 | cleanup_helper (cls); | ||
768 | cls = NULL; | ||
769 | |||
770 | char *ifname; | ||
771 | char *ipv6addr; | ||
772 | char *ipv6prefix; | ||
773 | char *ipv4addr; | ||
774 | char *ipv4mask; | ||
775 | |||
776 | if (GNUNET_SYSERR == | ||
777 | GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IFNAME", &ifname)) | ||
778 | { | ||
779 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
780 | "No entry 'IFNAME' in configuration!\n"); | ||
781 | exit (1); | ||
782 | } | ||
783 | |||
784 | if (GNUNET_SYSERR == | ||
785 | GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6ADDR", | ||
786 | &ipv6addr)) | ||
787 | { | ||
788 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
789 | "No entry 'IPV6ADDR' in configuration!\n"); | ||
790 | exit (1); | ||
791 | } | ||
792 | |||
793 | if (GNUNET_SYSERR == | ||
794 | GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6PREFIX", | ||
795 | &ipv6prefix)) | ||
796 | { | ||
797 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
798 | "No entry 'IPV6PREFIX' in configuration!\n"); | ||
799 | exit (1); | ||
800 | } | ||
801 | |||
802 | if (GNUNET_SYSERR == | ||
803 | GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4ADDR", | ||
804 | &ipv4addr)) | ||
805 | { | ||
806 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
807 | "No entry 'IPV4ADDR' in configuration!\n"); | ||
808 | exit (1); | ||
809 | } | ||
810 | |||
811 | if (GNUNET_SYSERR == | ||
812 | GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4MASK", | ||
813 | &ipv4mask)) | ||
814 | { | ||
815 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
816 | "No entry 'IPV4MASK' in configuration!\n"); | ||
817 | exit (1); | ||
818 | } | ||
819 | |||
820 | /* Start the helper | ||
821 | * Messages get passed to the function message_token | ||
822 | * When the helper dies, this function will be called again with the | ||
823 | * helper_handle as cls. | ||
824 | */ | ||
825 | helper_handle = | ||
826 | start_helper (ifname, ipv6addr, ipv6prefix, ipv4addr, ipv4mask, | ||
827 | "exit-gnunet", start_helper_and_schedule, message_token, | ||
828 | NULL); | ||
829 | 769 | ||
830 | GNUNET_free (ipv6addr); | ||
831 | GNUNET_free (ipv6prefix); | ||
832 | GNUNET_free (ipv4addr); | ||
833 | GNUNET_free (ipv4mask); | ||
834 | GNUNET_free (ifname); | ||
835 | } | ||
836 | 770 | ||
837 | static void | 771 | static void |
838 | prepare_ipv4_packet (size_t len, uint16_t pktlen, void *payload, | 772 | prepare_ipv4_packet (size_t len, uint16_t pktlen, void *payload, |
@@ -1068,7 +1002,6 @@ receive_tcp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1068 | * At this point it would be possible to check against some kind of ACL. | 1002 | * At this point it would be possible to check against some kind of ACL. |
1069 | */ | 1003 | */ |
1070 | 1004 | ||
1071 | char *buf; | ||
1072 | size_t len; | 1005 | size_t len; |
1073 | 1006 | ||
1074 | /* Prepare the state. | 1007 | /* Prepare the state. |
@@ -1086,50 +1019,56 @@ receive_tcp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1086 | len = | 1019 | len = |
1087 | sizeof (struct GNUNET_MessageHeader) + sizeof (struct pkt_tun) + | 1020 | sizeof (struct GNUNET_MessageHeader) + sizeof (struct pkt_tun) + |
1088 | sizeof (struct ip6_hdr) + pkt_len; | 1021 | sizeof (struct ip6_hdr) + pkt_len; |
1089 | buf = alloca (len); | ||
1090 | |||
1091 | memset (buf, 0, len); | ||
1092 | |||
1093 | switch (serv->version) | ||
1094 | { | 1022 | { |
1095 | case 4: | 1023 | char buf[len]; |
1096 | prepare_ipv4_packet (len, pkt_len, pkt, IPPROTO_TCP, &serv->v4.ip4address, | ||
1097 | tunnel, state, (struct ip_pkt *) buf); | ||
1098 | break; | ||
1099 | case 6: | ||
1100 | prepare_ipv6_packet (len, pkt_len, pkt, IPPROTO_TCP, &serv->v6.ip6address, | ||
1101 | tunnel, state, (struct ip6_pkt *) buf); | ||
1102 | |||
1103 | break; | ||
1104 | default: | ||
1105 | GNUNET_assert (0); | ||
1106 | break; | ||
1107 | } | ||
1108 | |||
1109 | hash_redirect_info (&state->hash, &state->redirect_info, | ||
1110 | serv->version == 4 ? 4 : 16); | ||
1111 | 1024 | ||
1112 | if (GNUNET_NO == | 1025 | memset (buf, 0, len); |
1113 | GNUNET_CONTAINER_multihashmap_contains (tcp_connections, &state->hash)) | 1026 | switch (serv->version) |
1114 | { | 1027 | { |
1115 | GNUNET_CONTAINER_multihashmap_put (tcp_connections, &state->hash, state, | 1028 | case 4: |
1116 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | 1029 | prepare_ipv4_packet (len, pkt_len, pkt, IPPROTO_TCP, &serv->v4.ip4address, |
1030 | tunnel, state, (struct ip_pkt *) buf); | ||
1031 | break; | ||
1032 | case 6: | ||
1033 | prepare_ipv6_packet (len, pkt_len, pkt, IPPROTO_TCP, &serv->v6.ip6address, | ||
1034 | tunnel, state, (struct ip6_pkt *) buf); | ||
1035 | |||
1036 | break; | ||
1037 | default: | ||
1038 | GNUNET_assert (0); | ||
1039 | break; | ||
1040 | } | ||
1117 | 1041 | ||
1118 | state->heap_node = | 1042 | hash_redirect_info (&state->hash, &state->redirect_info, |
1119 | GNUNET_CONTAINER_heap_insert (tcp_connections_heap, state, | 1043 | serv->version == 4 ? 4 : 16); |
1120 | GNUNET_TIME_absolute_get ().abs_value); | 1044 | |
1045 | if (GNUNET_NO == | ||
1046 | GNUNET_CONTAINER_multihashmap_contains (tcp_connections, &state->hash)) | ||
1047 | { | ||
1048 | GNUNET_CONTAINER_multihashmap_put (tcp_connections, &state->hash, state, | ||
1049 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
1050 | |||
1051 | state->heap_node = | ||
1052 | GNUNET_CONTAINER_heap_insert (tcp_connections_heap, state, | ||
1053 | GNUNET_TIME_absolute_get ().abs_value); | ||
1054 | |||
1055 | if (GNUNET_CONTAINER_heap_get_size (tcp_connections_heap) > | ||
1056 | max_tcp_connections) | ||
1057 | GNUNET_SCHEDULER_add_now (collect_connections, tcp_connections_heap); | ||
1058 | } | ||
1059 | else | ||
1060 | GNUNET_free (state); | ||
1121 | 1061 | ||
1122 | if (GNUNET_CONTAINER_heap_get_size (tcp_connections_heap) > | 1062 | /* FIXME: here, flow-control with mesh would be nice to have... */ |
1123 | max_tcp_connections) | 1063 | (void) GNUNET_HELPER_send (helper_handle, |
1124 | GNUNET_SCHEDULER_add_now (collect_connections, tcp_connections_heap); | 1064 | (const struct GNUNET_MessageHeader*) buf, |
1065 | GNUNET_YES, | ||
1066 | NULL, NULL); | ||
1125 | } | 1067 | } |
1126 | else | ||
1127 | GNUNET_free (state); | ||
1128 | |||
1129 | (void) GNUNET_DISK_file_write (helper_handle->fh_to_helper, buf, len); | ||
1130 | return GNUNET_YES; | 1068 | return GNUNET_YES; |
1131 | } | 1069 | } |
1132 | 1070 | ||
1071 | |||
1133 | static int | 1072 | static int |
1134 | receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | 1073 | receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, |
1135 | void **tunnel_ctx GNUNET_UNUSED, | 1074 | void **tunnel_ctx GNUNET_UNUSED, |
@@ -1197,7 +1136,11 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1197 | else | 1136 | else |
1198 | GNUNET_free (state); | 1137 | GNUNET_free (state); |
1199 | 1138 | ||
1200 | (void) GNUNET_DISK_file_write (helper_handle->fh_to_helper, buf, len); | 1139 | /* FIXME: here, flow-control with mesh would be nice to have... */ |
1140 | (void) GNUNET_HELPER_send (helper_handle, | ||
1141 | (const struct GNUNET_MessageHeader*) buf, | ||
1142 | GNUNET_YES, | ||
1143 | NULL, NULL); | ||
1201 | return GNUNET_YES; | 1144 | return GNUNET_YES; |
1202 | 1145 | ||
1203 | } | 1146 | } |
@@ -1271,7 +1214,10 @@ receive_udp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1271 | else | 1214 | else |
1272 | GNUNET_free (state); | 1215 | GNUNET_free (state); |
1273 | 1216 | ||
1274 | (void) GNUNET_DISK_file_write (helper_handle->fh_to_helper, buf, len); | 1217 | (void) GNUNET_HELPER_send (helper_handle, |
1218 | (const struct GNUNET_MessageHeader*) buf, | ||
1219 | GNUNET_YES, | ||
1220 | NULL, NULL); | ||
1275 | return GNUNET_YES; | 1221 | return GNUNET_YES; |
1276 | } | 1222 | } |
1277 | 1223 | ||
@@ -1374,7 +1320,10 @@ receive_udp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1374 | else | 1320 | else |
1375 | GNUNET_free (state); | 1321 | GNUNET_free (state); |
1376 | 1322 | ||
1377 | (void) GNUNET_DISK_file_write (helper_handle->fh_to_helper, buf, len); | 1323 | (void) GNUNET_HELPER_send (helper_handle, |
1324 | (const struct GNUNET_MessageHeader*) buf, | ||
1325 | GNUNET_YES, | ||
1326 | NULL, NULL); | ||
1378 | return GNUNET_YES; | 1327 | return GNUNET_YES; |
1379 | } | 1328 | } |
1380 | 1329 | ||
@@ -1430,6 +1379,7 @@ connect_to_mesh () | |||
1430 | } | 1379 | } |
1431 | 1380 | ||
1432 | 1381 | ||
1382 | |||
1433 | /** | 1383 | /** |
1434 | * @brief Main function that will be run by the scheduler. | 1384 | * @brief Main function that will be run by the scheduler. |
1435 | * | 1385 | * |
@@ -1443,10 +1393,14 @@ run (void *cls, char *const *args GNUNET_UNUSED, | |||
1443 | const char *cfgfile GNUNET_UNUSED, | 1393 | const char *cfgfile GNUNET_UNUSED, |
1444 | const struct GNUNET_CONFIGURATION_Handle *cfg_) | 1394 | const struct GNUNET_CONFIGURATION_Handle *cfg_) |
1445 | { | 1395 | { |
1446 | cfg = cfg_; | 1396 | char *ifname; |
1397 | char *ipv6addr; | ||
1398 | char *ipv6prefix; | ||
1399 | char *ipv4addr; | ||
1400 | char *ipv4mask; | ||
1447 | 1401 | ||
1402 | cfg = cfg_; | ||
1448 | connect_to_mesh (); | 1403 | connect_to_mesh (); |
1449 | |||
1450 | udp_connections = GNUNET_CONTAINER_multihashmap_create (65536); | 1404 | udp_connections = GNUNET_CONTAINER_multihashmap_create (65536); |
1451 | udp_connections_heap = | 1405 | udp_connections_heap = |
1452 | GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); | 1406 | GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); |
@@ -1455,7 +1409,6 @@ run (void *cls, char *const *args GNUNET_UNUSED, | |||
1455 | GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); | 1409 | GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); |
1456 | udp_services = GNUNET_CONTAINER_multihashmap_create (65536); | 1410 | udp_services = GNUNET_CONTAINER_multihashmap_create (65536); |
1457 | tcp_services = GNUNET_CONTAINER_multihashmap_create (65536); | 1411 | tcp_services = GNUNET_CONTAINER_multihashmap_create (65536); |
1458 | |||
1459 | if (GNUNET_OK != | 1412 | if (GNUNET_OK != |
1460 | GNUNET_CONFIGURATION_get_value_number (cfg, "exit", "MAX_UDP_CONNECTIONS", | 1413 | GNUNET_CONFIGURATION_get_value_number (cfg, "exit", "MAX_UDP_CONNECTIONS", |
1461 | &max_udp_connections)) | 1414 | &max_udp_connections)) |
@@ -1465,7 +1418,59 @@ run (void *cls, char *const *args GNUNET_UNUSED, | |||
1465 | &max_tcp_connections)) | 1418 | &max_tcp_connections)) |
1466 | max_tcp_connections = 256; | 1419 | max_tcp_connections = 256; |
1467 | GNUNET_CONFIGURATION_iterate_sections (cfg, read_service_conf, NULL); | 1420 | GNUNET_CONFIGURATION_iterate_sections (cfg, read_service_conf, NULL); |
1468 | GNUNET_SCHEDULER_add_now (start_helper_and_schedule, NULL); | 1421 | |
1422 | if (GNUNET_SYSERR == | ||
1423 | GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IFNAME", &ifname)) | ||
1424 | { | ||
1425 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1426 | "No entry 'IFNAME' in configuration!\n"); | ||
1427 | exit (1); | ||
1428 | } | ||
1429 | |||
1430 | if (GNUNET_SYSERR == | ||
1431 | GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6ADDR", | ||
1432 | &ipv6addr)) | ||
1433 | { | ||
1434 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1435 | "No entry 'IPV6ADDR' in configuration!\n"); | ||
1436 | exit (1); | ||
1437 | } | ||
1438 | |||
1439 | if (GNUNET_SYSERR == | ||
1440 | GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV6PREFIX", | ||
1441 | &ipv6prefix)) | ||
1442 | { | ||
1443 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1444 | "No entry 'IPV6PREFIX' in configuration!\n"); | ||
1445 | exit (1); | ||
1446 | } | ||
1447 | |||
1448 | if (GNUNET_SYSERR == | ||
1449 | GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4ADDR", | ||
1450 | &ipv4addr)) | ||
1451 | { | ||
1452 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1453 | "No entry 'IPV4ADDR' in configuration!\n"); | ||
1454 | exit (1); | ||
1455 | } | ||
1456 | |||
1457 | if (GNUNET_SYSERR == | ||
1458 | GNUNET_CONFIGURATION_get_value_string (cfg, "exit", "IPV4MASK", | ||
1459 | &ipv4mask)) | ||
1460 | { | ||
1461 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1462 | "No entry 'IPV4MASK' in configuration!\n"); | ||
1463 | exit (1); | ||
1464 | } | ||
1465 | exit_argv[0] = GNUNET_strdup ("exit-gnunet"); | ||
1466 | exit_argv[1] = ifname; | ||
1467 | exit_argv[2] = ipv6addr; | ||
1468 | exit_argv[3] = ipv6prefix; | ||
1469 | exit_argv[4] = ipv4addr; | ||
1470 | exit_argv[5] = ipv4mask; | ||
1471 | exit_argv[6] = NULL; | ||
1472 | helper_handle = GNUNET_HELPER_start ("gnunet-helper-vpn", exit_argv, | ||
1473 | &message_token, NULL); | ||
1469 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls); | 1474 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls); |
1470 | } | 1475 | } |
1471 | 1476 | ||
diff --git a/src/vpn/gnunet-daemon-vpn-helper.c b/src/vpn/gnunet-daemon-vpn-helper.c deleted file mode 100644 index 3bb3aa262..000000000 --- a/src/vpn/gnunet-daemon-vpn-helper.c +++ /dev/null | |||
@@ -1,691 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2010 Christian Grothoff | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file vpn/gnunet-daemon-vpn-helper.c | ||
23 | * @brief | ||
24 | * @author Philipp Toelke | ||
25 | */ | ||
26 | #include <platform.h> | ||
27 | #include <gnunet_common.h> | ||
28 | #include <gnunet_client_lib.h> | ||
29 | #include <gnunet_os_lib.h> | ||
30 | #include <gnunet_mesh_service.h> | ||
31 | #include <gnunet_protocols.h> | ||
32 | #include <gnunet_server_lib.h> | ||
33 | #include <gnunet_container_lib.h> | ||
34 | #include <block_dns.h> | ||
35 | #include <gnunet_configuration_lib.h> | ||
36 | #include <gnunet_applications.h> | ||
37 | #include <gnunet_dns_service.h> | ||
38 | |||
39 | #include "gnunet-daemon-vpn.h" | ||
40 | #include "gnunet-daemon-vpn-helper.h" | ||
41 | #include "gnunet-vpn-packet.h" | ||
42 | #include "gnunet-vpn-checksum.h" | ||
43 | #include "gnunet-helper-vpn-api.h" | ||
44 | |||
45 | struct GNUNET_VPN_HELPER_Handle *helper_handle; | ||
46 | |||
47 | extern struct GNUNET_CLIENT_TransmitHandle *dns_transmit_handle; | ||
48 | |||
49 | /** | ||
50 | * The tunnels that will be used to send tcp- and udp-packets | ||
51 | */ | ||
52 | static struct GNUNET_MESH_Tunnel *tcp_tunnel; | ||
53 | static struct GNUNET_MESH_Tunnel *udp_tunnel; | ||
54 | |||
55 | /** | ||
56 | * Start the helper-process | ||
57 | * | ||
58 | * If cls != NULL it is assumed that this function is called as a result of a dying | ||
59 | * helper. cls is then taken as handle to the old helper and is cleaned up. | ||
60 | * {{{ | ||
61 | */ | ||
62 | void | ||
63 | start_helper_and_schedule (void *cls, | ||
64 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
65 | { | ||
66 | shs_task = GNUNET_SCHEDULER_NO_TASK; | ||
67 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | ||
68 | return; | ||
69 | |||
70 | if (cls != NULL) | ||
71 | cleanup_helper (cls); | ||
72 | cls = NULL; | ||
73 | |||
74 | char *ifname; | ||
75 | char *ipv6addr; | ||
76 | char *ipv6prefix; | ||
77 | char *ipv4addr; | ||
78 | char *ipv4mask; | ||
79 | |||
80 | if (GNUNET_SYSERR == | ||
81 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IFNAME", &ifname)) | ||
82 | { | ||
83 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
84 | "No entry 'IFNAME' in configuration!\n"); | ||
85 | exit (1); | ||
86 | } | ||
87 | |||
88 | if (GNUNET_SYSERR == | ||
89 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR", &ipv6addr)) | ||
90 | { | ||
91 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
92 | "No entry 'IPV6ADDR' in configuration!\n"); | ||
93 | exit (1); | ||
94 | } | ||
95 | |||
96 | if (GNUNET_SYSERR == | ||
97 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6PREFIX", | ||
98 | &ipv6prefix)) | ||
99 | { | ||
100 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
101 | "No entry 'IPV6PREFIX' in configuration!\n"); | ||
102 | exit (1); | ||
103 | } | ||
104 | |||
105 | if (GNUNET_SYSERR == | ||
106 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4ADDR", &ipv4addr)) | ||
107 | { | ||
108 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
109 | "No entry 'IPV4ADDR' in configuration!\n"); | ||
110 | exit (1); | ||
111 | } | ||
112 | |||
113 | if (GNUNET_SYSERR == | ||
114 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4MASK", &ipv4mask)) | ||
115 | { | ||
116 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
117 | "No entry 'IPV4MASK' in configuration!\n"); | ||
118 | exit (1); | ||
119 | } | ||
120 | |||
121 | /* Start the helper | ||
122 | * Messages get passed to the function message_token | ||
123 | * When the helper dies, this function will be called again with the | ||
124 | * helper_handle as cls. | ||
125 | */ | ||
126 | helper_handle = | ||
127 | start_helper (ifname, ipv6addr, ipv6prefix, ipv4addr, ipv4mask, | ||
128 | "vpn-gnunet", start_helper_and_schedule, message_token, | ||
129 | NULL); | ||
130 | |||
131 | GNUNET_free (ipv6addr); | ||
132 | GNUNET_free (ipv6prefix); | ||
133 | GNUNET_free (ipv4addr); | ||
134 | GNUNET_free (ipv4mask); | ||
135 | GNUNET_free (ifname); | ||
136 | |||
137 | /* Tell the dns-service to rehijack the dns-port | ||
138 | * The routing-table gets flushed if an interface disappears. | ||
139 | */ | ||
140 | GNUNET_DNS_restart_hijack (dns_handle); | ||
141 | GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
142 | helper_handle->fh_to_helper, &helper_write, | ||
143 | NULL); | ||
144 | } | ||
145 | |||
146 | /*}}}*/ | ||
147 | |||
148 | static void * | ||
149 | initialize_tunnel_state (int addrlen, struct GNUNET_MESH_TransmitHandle *th) | ||
150 | { | ||
151 | struct tunnel_state *ts = GNUNET_malloc (sizeof *ts); | ||
152 | |||
153 | ts->addrlen = addrlen; | ||
154 | ts->th = th; | ||
155 | return ts; | ||
156 | } | ||
157 | |||
158 | /** | ||
159 | * Send an dns-answer-packet to the helper | ||
160 | */ | ||
161 | void | ||
162 | helper_write (void *cls GNUNET_UNUSED, | ||
163 | const struct GNUNET_SCHEDULER_TaskContext *tsdkctx) | ||
164 | { | ||
165 | if (tsdkctx->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) | ||
166 | return; | ||
167 | |||
168 | struct answer_packet_list *ans = answer_proc_head; | ||
169 | |||
170 | if (NULL == ans) | ||
171 | return; | ||
172 | |||
173 | size_t len = ntohs (ans->pkt.hdr.size); | ||
174 | |||
175 | GNUNET_assert (ans->pkt.subtype == GNUNET_DNS_ANSWER_TYPE_IP); | ||
176 | |||
177 | GNUNET_assert (20 == sizeof (struct ip_hdr)); | ||
178 | GNUNET_assert (8 == sizeof (struct udp_pkt)); | ||
179 | |||
180 | size_t data_len = len - sizeof (struct answer_packet) + 1; | ||
181 | |||
182 | void *buf; | ||
183 | size_t pkt_len; | ||
184 | |||
185 | if (ans->pkt.addrlen == 16) | ||
186 | { | ||
187 | size_t net_len = | ||
188 | sizeof (struct ip6_hdr) + sizeof (struct udp_dns) + data_len; | ||
189 | pkt_len = | ||
190 | sizeof (struct GNUNET_MessageHeader) + sizeof (struct pkt_tun) + | ||
191 | net_len; | ||
192 | |||
193 | struct ip6_udp_dns *pkt = alloca (pkt_len); | ||
194 | |||
195 | GNUNET_assert (pkt != NULL); | ||
196 | memset (pkt, 0, pkt_len); | ||
197 | |||
198 | /* set the gnunet-header */ | ||
199 | pkt->shdr.size = htons (pkt_len); | ||
200 | pkt->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
201 | |||
202 | /* set the tun-header (no flags and ethertype of IPv4) */ | ||
203 | pkt->tun.flags = 0; | ||
204 | pkt->tun.type = htons (0x86dd); | ||
205 | |||
206 | memcpy (&pkt->ip6_hdr.sadr, ans->pkt.from, 16); | ||
207 | memcpy (&pkt->ip6_hdr.dadr, ans->pkt.to, 16); | ||
208 | |||
209 | /* set the udp-header */ | ||
210 | pkt->udp_dns.udp_hdr.spt = htons (53); | ||
211 | pkt->udp_dns.udp_hdr.dpt = ans->pkt.dst_port; | ||
212 | pkt->udp_dns.udp_hdr.len = htons (net_len - sizeof (struct ip6_hdr)); | ||
213 | pkt->udp_dns.udp_hdr.crc = 0; | ||
214 | uint32_t sum = 0; | ||
215 | |||
216 | sum = calculate_checksum_update (sum, (uint16_t *) & pkt->ip6_hdr.sadr, 16); | ||
217 | sum = calculate_checksum_update (sum, (uint16_t *) & pkt->ip6_hdr.dadr, 16); | ||
218 | uint32_t tmp = (pkt->udp_dns.udp_hdr.len & 0xffff); | ||
219 | |||
220 | sum = calculate_checksum_update (sum, (uint16_t *) & tmp, 4); | ||
221 | tmp = htons (((pkt->ip6_hdr.nxthdr & 0x00ff))); | ||
222 | sum = calculate_checksum_update (sum, (uint16_t *) & tmp, 4); | ||
223 | |||
224 | sum = | ||
225 | calculate_checksum_update (sum, (uint16_t *) & pkt->udp_dns.udp_hdr, | ||
226 | ntohs (net_len - sizeof (struct ip6_hdr))); | ||
227 | pkt->udp_dns.udp_hdr.crc = calculate_checksum_end (sum); | ||
228 | |||
229 | pkt->ip6_hdr.version = 6; | ||
230 | pkt->ip6_hdr.paylgth = net_len - sizeof (struct ip6_hdr); | ||
231 | pkt->ip6_hdr.nxthdr = IPPROTO_UDP; | ||
232 | pkt->ip6_hdr.hoplmt = 0xff; | ||
233 | |||
234 | memcpy (&pkt->udp_dns.data, ans->pkt.data, data_len); | ||
235 | buf = pkt; | ||
236 | } | ||
237 | else if (ans->pkt.addrlen == 4) | ||
238 | { | ||
239 | size_t net_len = | ||
240 | sizeof (struct ip_hdr) + sizeof (struct udp_dns) + data_len; | ||
241 | pkt_len = | ||
242 | sizeof (struct GNUNET_MessageHeader) + sizeof (struct pkt_tun) + | ||
243 | net_len; | ||
244 | |||
245 | struct ip_udp_dns *pkt = alloca (pkt_len); | ||
246 | |||
247 | GNUNET_assert (pkt != NULL); | ||
248 | memset (pkt, 0, pkt_len); | ||
249 | |||
250 | /* set the gnunet-header */ | ||
251 | pkt->shdr.size = htons (pkt_len); | ||
252 | pkt->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
253 | |||
254 | /* set the tun-header (no flags and ethertype of IPv4) */ | ||
255 | pkt->tun.flags = 0; | ||
256 | pkt->tun.type = htons (0x0800); | ||
257 | |||
258 | /* set the ip-header */ | ||
259 | pkt->ip_hdr.version = 4; | ||
260 | pkt->ip_hdr.hdr_lngth = 5; | ||
261 | pkt->ip_hdr.diff_serv = 0; | ||
262 | pkt->ip_hdr.tot_lngth = htons (net_len); | ||
263 | pkt->ip_hdr.ident = 0; | ||
264 | pkt->ip_hdr.flags = 0; | ||
265 | pkt->ip_hdr.frag_off = 0; | ||
266 | pkt->ip_hdr.ttl = 255; | ||
267 | pkt->ip_hdr.proto = IPPROTO_UDP; | ||
268 | pkt->ip_hdr.chks = 0; /* Will be calculated later */ | ||
269 | |||
270 | memcpy (&pkt->ip_hdr.sadr, ans->pkt.from, 4); | ||
271 | memcpy (&pkt->ip_hdr.dadr, ans->pkt.to, 4); | ||
272 | |||
273 | pkt->ip_hdr.chks = | ||
274 | calculate_ip_checksum ((uint16_t *) & pkt->ip_hdr, 5 * 4); | ||
275 | |||
276 | /* set the udp-header */ | ||
277 | pkt->udp_dns.udp_hdr.spt = htons (53); | ||
278 | pkt->udp_dns.udp_hdr.dpt = ans->pkt.dst_port; | ||
279 | pkt->udp_dns.udp_hdr.len = htons (net_len - sizeof (struct ip_hdr)); | ||
280 | pkt->udp_dns.udp_hdr.crc = 0; /* Optional for IPv4 */ | ||
281 | |||
282 | memcpy (&pkt->udp_dns.data, ans->pkt.data, data_len); | ||
283 | buf = pkt; | ||
284 | } | ||
285 | else | ||
286 | { | ||
287 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Wrong addrlen = %d\n", | ||
288 | ans->pkt.addrlen); | ||
289 | GNUNET_assert (0); | ||
290 | return; /* convince compiler that we're done here */ | ||
291 | } | ||
292 | |||
293 | GNUNET_CONTAINER_DLL_remove (answer_proc_head, answer_proc_tail, ans); | ||
294 | GNUNET_free (ans); | ||
295 | |||
296 | if (GNUNET_DISK_file_write (helper_handle->fh_to_helper, buf, pkt_len) < 0) | ||
297 | { | ||
298 | cleanup_helper (helper_handle); | ||
299 | GNUNET_SCHEDULER_add_now (start_helper_and_schedule, NULL); | ||
300 | return; | ||
301 | } | ||
302 | |||
303 | /* if more packets are available, reschedule */ | ||
304 | if (answer_proc_head != NULL) | ||
305 | GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
306 | helper_handle->fh_to_helper, &helper_write, | ||
307 | NULL); | ||
308 | } | ||
309 | |||
310 | /** | ||
311 | * Receive packets from the helper-process | ||
312 | */ | ||
313 | void | ||
314 | message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, | ||
315 | const struct GNUNET_MessageHeader *message) | ||
316 | { | ||
317 | GNUNET_assert (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
318 | |||
319 | struct tun_pkt *pkt_tun = (struct tun_pkt *) message; | ||
320 | GNUNET_HashCode *key; | ||
321 | |||
322 | /* ethertype is ipv6 */ | ||
323 | if (ntohs (pkt_tun->tun.type) == 0x86dd) | ||
324 | { | ||
325 | struct ip6_pkt *pkt6 = (struct ip6_pkt *) message; | ||
326 | |||
327 | GNUNET_assert (pkt6->ip6_hdr.version == 6); | ||
328 | struct ip6_tcp *pkt6_tcp; | ||
329 | struct ip6_udp *pkt6_udp; | ||
330 | struct ip6_icmp *pkt6_icmp; | ||
331 | |||
332 | pkt6_udp = NULL; /* make compiler happy */ | ||
333 | switch (pkt6->ip6_hdr.nxthdr) | ||
334 | { | ||
335 | case IPPROTO_UDP: | ||
336 | pkt6_udp = (struct ip6_udp *) pkt6; | ||
337 | /* Send dns-packets to the service-dns */ | ||
338 | if (ntohs (pkt6_udp->udp_hdr.dpt) == 53) | ||
339 | { | ||
340 | /* 9 = 8 for the udp-header + 1 for the unsigned char data[1]; */ | ||
341 | GNUNET_DNS_queue_request_v6 (dns_handle, | ||
342 | &pkt6->ip6_hdr.dadr, | ||
343 | &pkt6->ip6_hdr.sadr, | ||
344 | ntohs (pkt6_udp->udp_hdr.spt), | ||
345 | ntohs (pkt6_udp->udp_hdr.len) - 8, | ||
346 | (const void*) pkt6_udp->data); | ||
347 | |||
348 | break; | ||
349 | } | ||
350 | /* fall through */ | ||
351 | case IPPROTO_TCP: | ||
352 | pkt6_tcp = (struct ip6_tcp *) pkt6; | ||
353 | |||
354 | if ((key = address6_mapping_exists (&pkt6->ip6_hdr.dadr)) != NULL) | ||
355 | { | ||
356 | struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key); | ||
357 | |||
358 | GNUNET_assert (me != NULL); | ||
359 | GNUNET_free (key); | ||
360 | |||
361 | size_t size = | ||
362 | sizeof (struct GNUNET_MESH_Tunnel *) + | ||
363 | sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + | ||
364 | ntohs (pkt6->ip6_hdr.paylgth); | ||
365 | |||
366 | struct GNUNET_MESH_Tunnel **cls = GNUNET_malloc (size); | ||
367 | struct GNUNET_MessageHeader *hdr = | ||
368 | (struct GNUNET_MessageHeader *) (cls + 1); | ||
369 | GNUNET_HashCode *hc = (GNUNET_HashCode *) (hdr + 1); | ||
370 | |||
371 | hdr->size = | ||
372 | htons (sizeof (struct GNUNET_MessageHeader) + | ||
373 | sizeof (GNUNET_HashCode) + ntohs (pkt6->ip6_hdr.paylgth)); | ||
374 | |||
375 | GNUNET_MESH_ApplicationType app_type = 0; /* fix compiler uninitialized warning... */ | ||
376 | |||
377 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "me->addrlen is %d\n", | ||
378 | me->addrlen); | ||
379 | if (me->addrlen == 0) | ||
380 | { | ||
381 | /* This is a mapping to a gnunet-service */ | ||
382 | memcpy (hc, &me->desc.service_descriptor, sizeof (GNUNET_HashCode)); | ||
383 | |||
384 | if (IPPROTO_UDP == pkt6->ip6_hdr.nxthdr && | ||
385 | (me->desc.service_type & htonl (GNUNET_DNS_SERVICE_TYPE_UDP)) && | ||
386 | (port_in_ports (me->desc.ports, pkt6_udp->udp_hdr.dpt) || | ||
387 | testBit (me->additional_ports, ntohs (pkt6_udp->udp_hdr.dpt)))) | ||
388 | { | ||
389 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP); | ||
390 | |||
391 | memcpy (hc + 1, &pkt6_udp->udp_hdr, ntohs (pkt6_udp->udp_hdr.len)); | ||
392 | |||
393 | } | ||
394 | else if (IPPROTO_TCP == pkt6->ip6_hdr.nxthdr && | ||
395 | (me->desc.service_type & htonl (GNUNET_DNS_SERVICE_TYPE_TCP)) | ||
396 | && (port_in_ports (me->desc.ports, pkt6_tcp->tcp_hdr.dpt))) | ||
397 | { | ||
398 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP); | ||
399 | |||
400 | memcpy (hc + 1, &pkt6_tcp->tcp_hdr, ntohs (pkt6->ip6_hdr.paylgth)); | ||
401 | |||
402 | } | ||
403 | else | ||
404 | { | ||
405 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "pip: %d\n", | ||
406 | port_in_ports (me->desc.ports, pkt6_tcp->tcp_hdr.dpt)); | ||
407 | GNUNET_assert (0); | ||
408 | } | ||
409 | if (me->tunnel == NULL && NULL != cls) | ||
410 | { | ||
411 | *cls = | ||
412 | GNUNET_MESH_tunnel_create (mesh_handle, | ||
413 | initialize_tunnel_state (16, NULL), | ||
414 | &send_pkt_to_peer, NULL, cls); | ||
415 | |||
416 | GNUNET_MESH_peer_request_connect_add (*cls, | ||
417 | (struct GNUNET_PeerIdentity *) | ||
418 | &me->desc.peer); | ||
419 | me->tunnel = *cls; | ||
420 | } | ||
421 | else if (NULL != cls) | ||
422 | { | ||
423 | *cls = me->tunnel; | ||
424 | send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL); | ||
425 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
426 | "Queued to send IPv6 to peer %x, type %d\n", | ||
427 | *((unsigned int *) &me->desc.peer), ntohs (hdr->type)); | ||
428 | } | ||
429 | } | ||
430 | else | ||
431 | { | ||
432 | /* This is a mapping to a "real" address */ | ||
433 | struct remote_addr *s = (struct remote_addr *) hc; | ||
434 | |||
435 | s->addrlen = me->addrlen; | ||
436 | memcpy (s->addr, me->addr, me->addrlen); | ||
437 | s->proto = pkt6->ip6_hdr.nxthdr; | ||
438 | if (s->proto == IPPROTO_UDP) | ||
439 | { | ||
440 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP); | ||
441 | memcpy (hc + 1, &pkt6_udp->udp_hdr, ntohs (pkt6_udp->udp_hdr.len)); | ||
442 | app_type = GNUNET_APPLICATION_TYPE_INTERNET_UDP_GATEWAY; | ||
443 | if (NULL != udp_tunnel) | ||
444 | me->tunnel = udp_tunnel; | ||
445 | } | ||
446 | else if (s->proto == IPPROTO_TCP) | ||
447 | { | ||
448 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP); | ||
449 | memcpy (hc + 1, &pkt6_tcp->tcp_hdr, ntohs (pkt6->ip6_hdr.paylgth)); | ||
450 | app_type = GNUNET_APPLICATION_TYPE_INTERNET_TCP_GATEWAY; | ||
451 | if (NULL != tcp_tunnel) | ||
452 | me->tunnel = tcp_tunnel; | ||
453 | } | ||
454 | else | ||
455 | { | ||
456 | GNUNET_assert (0); | ||
457 | } | ||
458 | if (me->tunnel == NULL && NULL != cls) | ||
459 | { | ||
460 | *cls = | ||
461 | GNUNET_MESH_tunnel_create (mesh_handle, | ||
462 | initialize_tunnel_state (16, NULL), | ||
463 | &send_pkt_to_peer, NULL, cls); | ||
464 | |||
465 | GNUNET_MESH_peer_request_connect_by_type (*cls, app_type); | ||
466 | me->tunnel = *cls; | ||
467 | if (GNUNET_APPLICATION_TYPE_INTERNET_UDP_GATEWAY == app_type) | ||
468 | udp_tunnel = *cls; | ||
469 | else if (GNUNET_APPLICATION_TYPE_INTERNET_TCP_GATEWAY == app_type) | ||
470 | tcp_tunnel = *cls; | ||
471 | } | ||
472 | else if (NULL != cls) | ||
473 | { | ||
474 | *cls = me->tunnel; | ||
475 | send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL); | ||
476 | } | ||
477 | } | ||
478 | } | ||
479 | else | ||
480 | { | ||
481 | char pbuf[INET6_ADDRSTRLEN]; | ||
482 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
483 | "Packet to %s, which has no mapping\n", | ||
484 | inet_ntop (AF_INET6, | ||
485 | &pkt6->ip6_hdr.dadr, | ||
486 | pbuf, | ||
487 | sizeof (pbuf))); | ||
488 | } | ||
489 | break; | ||
490 | case 0x3a: | ||
491 | /* ICMPv6 */ | ||
492 | pkt6_icmp = (struct ip6_icmp *) pkt6; | ||
493 | /* If this packet is an icmp-echo-request and a mapping exists, answer */ | ||
494 | if (pkt6_icmp->icmp_hdr.type == 0x80 && | ||
495 | (key = address6_mapping_exists (&pkt6->ip6_hdr.dadr)) != NULL) | ||
496 | { | ||
497 | GNUNET_free (key); | ||
498 | pkt6_icmp = GNUNET_malloc (ntohs (pkt6->shdr.size)); | ||
499 | memcpy (pkt6_icmp, pkt6, ntohs (pkt6->shdr.size)); | ||
500 | GNUNET_SCHEDULER_add_now (&send_icmp6_response, pkt6_icmp); | ||
501 | } | ||
502 | break; | ||
503 | } | ||
504 | } | ||
505 | /* ethertype is ipv4 */ | ||
506 | else if (ntohs (pkt_tun->tun.type) == 0x0800) | ||
507 | { | ||
508 | struct ip_pkt *pkt = (struct ip_pkt *) message; | ||
509 | struct ip_udp *udp = (struct ip_udp *) message; | ||
510 | struct ip_tcp *pkt_tcp; | ||
511 | struct ip_udp *pkt_udp; | ||
512 | struct ip_icmp *pkt_icmp; | ||
513 | |||
514 | GNUNET_assert (pkt->ip_hdr.version == 4); | ||
515 | |||
516 | /* Send dns-packets to the service-dns */ | ||
517 | if (pkt->ip_hdr.proto == IPPROTO_UDP && ntohs (udp->udp_hdr.dpt) == 53) | ||
518 | { | ||
519 | GNUNET_DNS_queue_request_v4 (dns_handle, | ||
520 | &pkt->ip_hdr.dadr, | ||
521 | &pkt->ip_hdr.sadr, | ||
522 | ntohs (udp->udp_hdr.spt), | ||
523 | ntohs (udp->udp_hdr.len) - 8, | ||
524 | (const void*) udp->data); | ||
525 | } | ||
526 | else | ||
527 | { | ||
528 | uint32_t dadr = pkt->ip_hdr.dadr.s_addr; | ||
529 | unsigned char *c = (unsigned char *) &dadr; | ||
530 | |||
531 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Packet to %d.%d.%d.%d, proto %x\n", | ||
532 | c[0], c[1], c[2], c[3], pkt->ip_hdr.proto); | ||
533 | switch (pkt->ip_hdr.proto) | ||
534 | { | ||
535 | case IPPROTO_TCP: | ||
536 | case IPPROTO_UDP: | ||
537 | pkt_tcp = (struct ip_tcp *) pkt; | ||
538 | pkt_udp = (struct ip_udp *) pkt; | ||
539 | |||
540 | if ((key = address4_mapping_exists (dadr)) != NULL) | ||
541 | { | ||
542 | struct map_entry *me = | ||
543 | GNUNET_CONTAINER_multihashmap_get (hashmap, key); | ||
544 | GNUNET_assert (me != NULL); | ||
545 | GNUNET_free (key); | ||
546 | |||
547 | size_t size = | ||
548 | sizeof (struct GNUNET_MESH_Tunnel *) + | ||
549 | sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + | ||
550 | ntohs (pkt->ip_hdr.tot_lngth) - 4 * pkt->ip_hdr.hdr_lngth; | ||
551 | |||
552 | struct GNUNET_MESH_Tunnel **cls = GNUNET_malloc (size); | ||
553 | struct GNUNET_MessageHeader *hdr = | ||
554 | (struct GNUNET_MessageHeader *) (cls + 1); | ||
555 | GNUNET_HashCode *hc = (GNUNET_HashCode *) (hdr + 1); | ||
556 | |||
557 | hdr->size = | ||
558 | htons (sizeof (struct GNUNET_MessageHeader) + | ||
559 | sizeof (GNUNET_HashCode) + ntohs (pkt->ip_hdr.tot_lngth) - | ||
560 | 4 * pkt->ip_hdr.hdr_lngth); | ||
561 | |||
562 | GNUNET_MESH_ApplicationType app_type = 0; /* make compiler happy */ | ||
563 | |||
564 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "me->addrlen is %d\n", | ||
565 | me->addrlen); | ||
566 | if (me->addrlen == 0) | ||
567 | { | ||
568 | /* This is a mapping to a gnunet-service */ | ||
569 | memcpy (hc, &me->desc.service_descriptor, sizeof (GNUNET_HashCode)); | ||
570 | |||
571 | if ((IPPROTO_UDP == pkt->ip_hdr.proto) && | ||
572 | (me->desc.service_type & htonl (GNUNET_DNS_SERVICE_TYPE_UDP)) && | ||
573 | (port_in_ports (me->desc.ports, pkt_udp->udp_hdr.dpt) || | ||
574 | testBit (me->additional_ports, ntohs (pkt_udp->udp_hdr.dpt)))) | ||
575 | { | ||
576 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP); | ||
577 | |||
578 | memcpy (hc + 1, &pkt_udp->udp_hdr, ntohs (pkt_udp->udp_hdr.len)); | ||
579 | |||
580 | } | ||
581 | else if ((IPPROTO_TCP == pkt->ip_hdr.proto) && | ||
582 | (me-> | ||
583 | desc.service_type & htonl (GNUNET_DNS_SERVICE_TYPE_TCP)) | ||
584 | && (port_in_ports (me->desc.ports, pkt_tcp->tcp_hdr.dpt))) | ||
585 | { | ||
586 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP); | ||
587 | |||
588 | memcpy (hc + 1, &pkt_tcp->tcp_hdr, | ||
589 | ntohs (pkt->ip_hdr.tot_lngth) - | ||
590 | 4 * pkt->ip_hdr.hdr_lngth); | ||
591 | |||
592 | } | ||
593 | if (me->tunnel == NULL && NULL != cls) | ||
594 | { | ||
595 | *cls = | ||
596 | GNUNET_MESH_tunnel_create (mesh_handle, | ||
597 | initialize_tunnel_state (4, NULL), | ||
598 | send_pkt_to_peer, NULL, cls); | ||
599 | GNUNET_MESH_peer_request_connect_add (*cls, | ||
600 | (struct GNUNET_PeerIdentity | ||
601 | *) &me->desc.peer); | ||
602 | me->tunnel = *cls; | ||
603 | } | ||
604 | else if (NULL != cls) | ||
605 | { | ||
606 | *cls = me->tunnel; | ||
607 | send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL); | ||
608 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
609 | "Queued to send IPv4 to peer %x, type %d\n", | ||
610 | *((unsigned int *) &me->desc.peer), | ||
611 | ntohs (hdr->type)); | ||
612 | } | ||
613 | } | ||
614 | else | ||
615 | { | ||
616 | /* This is a mapping to a "real" address */ | ||
617 | struct remote_addr *s = (struct remote_addr *) hc; | ||
618 | |||
619 | s->addrlen = me->addrlen; | ||
620 | memcpy (s->addr, me->addr, me->addrlen); | ||
621 | s->proto = pkt->ip_hdr.proto; | ||
622 | if (s->proto == IPPROTO_UDP) | ||
623 | { | ||
624 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP); | ||
625 | memcpy (hc + 1, &pkt_udp->udp_hdr, ntohs (pkt_udp->udp_hdr.len)); | ||
626 | app_type = GNUNET_APPLICATION_TYPE_INTERNET_UDP_GATEWAY; | ||
627 | } | ||
628 | else if (s->proto == IPPROTO_TCP) | ||
629 | { | ||
630 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP); | ||
631 | memcpy (hc + 1, &pkt_tcp->tcp_hdr, | ||
632 | ntohs (pkt->ip_hdr.tot_lngth) - | ||
633 | 4 * pkt->ip_hdr.hdr_lngth); | ||
634 | app_type = GNUNET_APPLICATION_TYPE_INTERNET_TCP_GATEWAY; | ||
635 | } | ||
636 | else | ||
637 | GNUNET_assert (0); | ||
638 | if (me->tunnel == NULL && NULL != cls) | ||
639 | { | ||
640 | *cls = | ||
641 | GNUNET_MESH_tunnel_create (mesh_handle, | ||
642 | initialize_tunnel_state (4, NULL), | ||
643 | send_pkt_to_peer, NULL, cls); | ||
644 | |||
645 | GNUNET_MESH_peer_request_connect_by_type (*cls, app_type); | ||
646 | me->tunnel = *cls; | ||
647 | } | ||
648 | else if (NULL != cls) | ||
649 | { | ||
650 | *cls = me->tunnel; | ||
651 | send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL); | ||
652 | } | ||
653 | } | ||
654 | } | ||
655 | else | ||
656 | { | ||
657 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
658 | "Packet to %x which has no mapping\n", dadr); | ||
659 | } | ||
660 | break; | ||
661 | case 0x01: | ||
662 | /* ICMP */ | ||
663 | pkt_icmp = (struct ip_icmp *) pkt; | ||
664 | if (pkt_icmp->icmp_hdr.type == 0x8 && | ||
665 | (key = address4_mapping_exists (dadr)) != NULL) | ||
666 | { | ||
667 | GNUNET_free (key); | ||
668 | pkt_icmp = GNUNET_malloc (ntohs (pkt->shdr.size)); | ||
669 | memcpy (pkt_icmp, pkt, ntohs (pkt->shdr.size)); | ||
670 | GNUNET_SCHEDULER_add_now (&send_icmp4_response, pkt_icmp); | ||
671 | } | ||
672 | break; | ||
673 | } | ||
674 | } | ||
675 | } | ||
676 | } | ||
677 | |||
678 | void | ||
679 | write_to_helper (void *buf, size_t len) | ||
680 | { | ||
681 | (void) GNUNET_DISK_file_write (helper_handle->fh_to_helper, buf, len); | ||
682 | } | ||
683 | |||
684 | void | ||
685 | schedule_helper_write (struct GNUNET_TIME_Relative time, void *cls) | ||
686 | { | ||
687 | if (GNUNET_SCHEDULER_NO_TASK != shs_task) | ||
688 | return; | ||
689 | GNUNET_SCHEDULER_add_write_file (time, helper_handle->fh_to_helper, | ||
690 | &helper_write, cls); | ||
691 | } | ||
diff --git a/src/vpn/gnunet-daemon-vpn-helper.h b/src/vpn/gnunet-daemon-vpn-helper.h deleted file mode 100644 index 7329e45ff..000000000 --- a/src/vpn/gnunet-daemon-vpn-helper.h +++ /dev/null | |||
@@ -1,76 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2010 Christian Grothoff | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file vpn/gnunet-daemon-vpn-helper.h | ||
23 | * @brief | ||
24 | * @author Philipp Toelke | ||
25 | */ | ||
26 | #ifndef GNUNET_DAEMON_VPN_HELPER_H | ||
27 | #define GNUNET_DAEMON_VPN_HELPER_H | ||
28 | |||
29 | #include "gnunet-helper-vpn-api.h" | ||
30 | |||
31 | /** | ||
32 | * Handle to the helper. contains filedescriptors and such | ||
33 | */ | ||
34 | extern struct GNUNET_VPN_HELPER_Handle *helper_handle; | ||
35 | |||
36 | extern GNUNET_SCHEDULER_TaskIdentifier shs_task; | ||
37 | |||
38 | /** | ||
39 | * Start the helper-process | ||
40 | */ | ||
41 | void | ||
42 | start_helper_and_schedule (void *cls, | ||
43 | const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
44 | |||
45 | /** | ||
46 | * Restart the helper-process | ||
47 | */ | ||
48 | void | ||
49 | restart_helper (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tskctx); | ||
50 | |||
51 | /** | ||
52 | * Read from the helper-process | ||
53 | */ | ||
54 | void | ||
55 | helper_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tsdkctx); | ||
56 | |||
57 | /** | ||
58 | * Send an dns-answer-packet to the helper | ||
59 | */ | ||
60 | void | ||
61 | helper_write (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tsdkctx); | ||
62 | |||
63 | /** | ||
64 | * Receive packets from the helper-process | ||
65 | */ | ||
66 | void | ||
67 | message_token (void *cls, void *client, | ||
68 | const struct GNUNET_MessageHeader *message); | ||
69 | |||
70 | void | ||
71 | write_to_helper (void *buf, size_t len); | ||
72 | |||
73 | void | ||
74 | schedule_helper_write (struct GNUNET_TIME_Relative, void *cls); | ||
75 | |||
76 | #endif /* end of include guard: GNUNET-DAEMON-VPN-HELPER_H */ | ||
diff --git a/src/vpn/gnunet-daemon-vpn.c b/src/vpn/gnunet-daemon-vpn.c index 7d303ecd5..35db8af7b 100644 --- a/src/vpn/gnunet-daemon-vpn.c +++ b/src/vpn/gnunet-daemon-vpn.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include "gnunet_container_lib.h" | 35 | #include "gnunet_container_lib.h" |
36 | #include "gnunet_constants.h" | 36 | #include "gnunet_constants.h" |
37 | #include <block_dns.h> | 37 | #include <block_dns.h> |
38 | #include "gnunet-daemon-vpn-helper.h" | ||
39 | #include "gnunet_dns_service.h" | 38 | #include "gnunet_dns_service.h" |
40 | #include "gnunet-daemon-vpn.h" | 39 | #include "gnunet-daemon-vpn.h" |
41 | #include "gnunet-vpn-checksum.h" | 40 | #include "gnunet-vpn-checksum.h" |
@@ -45,6 +44,16 @@ struct GNUNET_MESH_Handle *mesh_handle; | |||
45 | struct GNUNET_CONTAINER_MultiHashMap *hashmap; | 44 | struct GNUNET_CONTAINER_MultiHashMap *hashmap; |
46 | static struct GNUNET_CONTAINER_Heap *heap; | 45 | static struct GNUNET_CONTAINER_Heap *heap; |
47 | 46 | ||
47 | /** | ||
48 | * The handle to the helper | ||
49 | */ | ||
50 | static struct GNUNET_HELPER_Handle *helper_handle; | ||
51 | |||
52 | /** | ||
53 | * Arguments to the exit helper. | ||
54 | */ | ||
55 | static char *vpn_argv[7]; | ||
56 | |||
48 | struct GNUNET_DNS_Handle *dns_handle; | 57 | struct GNUNET_DNS_Handle *dns_handle; |
49 | 58 | ||
50 | struct answer_packet_list *answer_proc_head; | 59 | struct answer_packet_list *answer_proc_head; |
@@ -82,6 +91,14 @@ GNUNET_SCHEDULER_TaskIdentifier shs_task; | |||
82 | 91 | ||
83 | 92 | ||
84 | /** | 93 | /** |
94 | * The tunnels that will be used to send tcp- and udp-packets | ||
95 | */ | ||
96 | static struct GNUNET_MESH_Tunnel *tcp_tunnel; | ||
97 | static struct GNUNET_MESH_Tunnel *udp_tunnel; | ||
98 | |||
99 | |||
100 | |||
101 | /** | ||
85 | * Sets a bit active in a bitArray. | 102 | * Sets a bit active in a bitArray. |
86 | * | 103 | * |
87 | * @param bitArray memory area to set the bit in | 104 | * @param bitArray memory area to set the bit in |
@@ -129,11 +146,9 @@ static void | |||
129 | cleanup (void *cls GNUNET_UNUSED, | 146 | cleanup (void *cls GNUNET_UNUSED, |
130 | const struct GNUNET_SCHEDULER_TaskContext *tskctx) | 147 | const struct GNUNET_SCHEDULER_TaskContext *tskctx) |
131 | { | 148 | { |
132 | GNUNET_assert (0 != (tskctx->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)); | 149 | unsigned int i; |
133 | |||
134 | /* stop the helper */ | ||
135 | cleanup_helper (helper_handle); | ||
136 | 150 | ||
151 | GNUNET_assert (0 != (tskctx->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)); | ||
137 | /* close the connection to the service-dns */ | 152 | /* close the connection to the service-dns */ |
138 | GNUNET_DNS_disconnect (dns_handle); | 153 | GNUNET_DNS_disconnect (dns_handle); |
139 | if (mesh_handle != NULL) | 154 | if (mesh_handle != NULL) |
@@ -141,6 +156,11 @@ cleanup (void *cls GNUNET_UNUSED, | |||
141 | GNUNET_MESH_disconnect (mesh_handle); | 156 | GNUNET_MESH_disconnect (mesh_handle); |
142 | mesh_handle = NULL; | 157 | mesh_handle = NULL; |
143 | } | 158 | } |
159 | if (helper_handle != NULL) | ||
160 | { | ||
161 | GNUNET_HELPER_stop (helper_handle); | ||
162 | helper_handle = NULL; | ||
163 | } | ||
144 | if (GNUNET_SCHEDULER_NO_TASK != shs_task) | 164 | if (GNUNET_SCHEDULER_NO_TASK != shs_task) |
145 | { | 165 | { |
146 | GNUNET_SCHEDULER_cancel (shs_task); | 166 | GNUNET_SCHEDULER_cancel (shs_task); |
@@ -151,6 +171,8 @@ cleanup (void *cls GNUNET_UNUSED, | |||
151 | GNUNET_SCHEDULER_cancel (conn_task); | 171 | GNUNET_SCHEDULER_cancel (conn_task); |
152 | conn_task = GNUNET_SCHEDULER_NO_TASK; | 172 | conn_task = GNUNET_SCHEDULER_NO_TASK; |
153 | } | 173 | } |
174 | for (i=0;i<5;i++) | ||
175 | GNUNET_free_non_null (vpn_argv[i]); | ||
154 | } | 176 | } |
155 | 177 | ||
156 | /*}}}*/ | 178 | /*}}}*/ |
@@ -210,6 +232,532 @@ address4_mapping_exists (uint32_t addr) | |||
210 | } | 232 | } |
211 | } | 233 | } |
212 | 234 | ||
235 | |||
236 | static void * | ||
237 | initialize_tunnel_state (int addrlen, struct GNUNET_MESH_TransmitHandle *th) | ||
238 | { | ||
239 | struct tunnel_state *ts = GNUNET_malloc (sizeof *ts); | ||
240 | |||
241 | ts->addrlen = addrlen; | ||
242 | ts->th = th; | ||
243 | return ts; | ||
244 | } | ||
245 | |||
246 | /** | ||
247 | * Send an dns-answer-packet to the helper | ||
248 | */ | ||
249 | void | ||
250 | helper_write (void *cls GNUNET_UNUSED, | ||
251 | int status) | ||
252 | { | ||
253 | struct answer_packet_list *ans = answer_proc_head; | ||
254 | |||
255 | if (NULL == ans) | ||
256 | return; | ||
257 | if (GNUNET_SYSERR == status) | ||
258 | return; | ||
259 | |||
260 | size_t len = ntohs (ans->pkt.hdr.size); | ||
261 | |||
262 | GNUNET_assert (ans->pkt.subtype == GNUNET_DNS_ANSWER_TYPE_IP); | ||
263 | |||
264 | GNUNET_assert (20 == sizeof (struct ip_hdr)); | ||
265 | GNUNET_assert (8 == sizeof (struct udp_pkt)); | ||
266 | |||
267 | size_t data_len = len - sizeof (struct answer_packet) + 1; | ||
268 | |||
269 | size_t pkt_len; | ||
270 | |||
271 | if (ans->pkt.addrlen == 16) | ||
272 | { | ||
273 | size_t net_len = | ||
274 | sizeof (struct ip6_hdr) + sizeof (struct udp_dns) + data_len; | ||
275 | pkt_len = | ||
276 | sizeof (struct GNUNET_MessageHeader) + sizeof (struct pkt_tun) + | ||
277 | net_len; | ||
278 | |||
279 | struct ip6_udp_dns *pkt = alloca (pkt_len); | ||
280 | |||
281 | GNUNET_assert (pkt != NULL); | ||
282 | memset (pkt, 0, pkt_len); | ||
283 | |||
284 | /* set the gnunet-header */ | ||
285 | pkt->shdr.size = htons (pkt_len); | ||
286 | pkt->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
287 | |||
288 | /* set the tun-header (no flags and ethertype of IPv4) */ | ||
289 | pkt->tun.flags = 0; | ||
290 | pkt->tun.type = htons (0x86dd); | ||
291 | |||
292 | memcpy (&pkt->ip6_hdr.sadr, ans->pkt.from, 16); | ||
293 | memcpy (&pkt->ip6_hdr.dadr, ans->pkt.to, 16); | ||
294 | |||
295 | /* set the udp-header */ | ||
296 | pkt->udp_dns.udp_hdr.spt = htons (53); | ||
297 | pkt->udp_dns.udp_hdr.dpt = ans->pkt.dst_port; | ||
298 | pkt->udp_dns.udp_hdr.len = htons (net_len - sizeof (struct ip6_hdr)); | ||
299 | pkt->udp_dns.udp_hdr.crc = 0; | ||
300 | uint32_t sum = 0; | ||
301 | |||
302 | sum = calculate_checksum_update (sum, (uint16_t *) & pkt->ip6_hdr.sadr, 16); | ||
303 | sum = calculate_checksum_update (sum, (uint16_t *) & pkt->ip6_hdr.dadr, 16); | ||
304 | uint32_t tmp = (pkt->udp_dns.udp_hdr.len & 0xffff); | ||
305 | |||
306 | sum = calculate_checksum_update (sum, (uint16_t *) & tmp, 4); | ||
307 | tmp = htons (((pkt->ip6_hdr.nxthdr & 0x00ff))); | ||
308 | sum = calculate_checksum_update (sum, (uint16_t *) & tmp, 4); | ||
309 | |||
310 | sum = | ||
311 | calculate_checksum_update (sum, (uint16_t *) & pkt->udp_dns.udp_hdr, | ||
312 | ntohs (net_len - sizeof (struct ip6_hdr))); | ||
313 | pkt->udp_dns.udp_hdr.crc = calculate_checksum_end (sum); | ||
314 | |||
315 | pkt->ip6_hdr.version = 6; | ||
316 | pkt->ip6_hdr.paylgth = net_len - sizeof (struct ip6_hdr); | ||
317 | pkt->ip6_hdr.nxthdr = IPPROTO_UDP; | ||
318 | pkt->ip6_hdr.hoplmt = 0xff; | ||
319 | |||
320 | memcpy (&pkt->udp_dns.data, ans->pkt.data, data_len); | ||
321 | (void) GNUNET_HELPER_send (helper_handle, | ||
322 | &pkt->shdr, | ||
323 | GNUNET_YES, | ||
324 | &helper_write, NULL); | ||
325 | } | ||
326 | else if (ans->pkt.addrlen == 4) | ||
327 | { | ||
328 | size_t net_len = | ||
329 | sizeof (struct ip_hdr) + sizeof (struct udp_dns) + data_len; | ||
330 | pkt_len = | ||
331 | sizeof (struct GNUNET_MessageHeader) + sizeof (struct pkt_tun) + | ||
332 | net_len; | ||
333 | |||
334 | struct ip_udp_dns *pkt = alloca (pkt_len); | ||
335 | |||
336 | GNUNET_assert (pkt != NULL); | ||
337 | memset (pkt, 0, pkt_len); | ||
338 | |||
339 | /* set the gnunet-header */ | ||
340 | pkt->shdr.size = htons (pkt_len); | ||
341 | pkt->shdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
342 | |||
343 | /* set the tun-header (no flags and ethertype of IPv4) */ | ||
344 | pkt->tun.flags = 0; | ||
345 | pkt->tun.type = htons (0x0800); | ||
346 | |||
347 | /* set the ip-header */ | ||
348 | pkt->ip_hdr.version = 4; | ||
349 | pkt->ip_hdr.hdr_lngth = 5; | ||
350 | pkt->ip_hdr.diff_serv = 0; | ||
351 | pkt->ip_hdr.tot_lngth = htons (net_len); | ||
352 | pkt->ip_hdr.ident = 0; | ||
353 | pkt->ip_hdr.flags = 0; | ||
354 | pkt->ip_hdr.frag_off = 0; | ||
355 | pkt->ip_hdr.ttl = 255; | ||
356 | pkt->ip_hdr.proto = IPPROTO_UDP; | ||
357 | pkt->ip_hdr.chks = 0; /* Will be calculated later */ | ||
358 | |||
359 | memcpy (&pkt->ip_hdr.sadr, ans->pkt.from, 4); | ||
360 | memcpy (&pkt->ip_hdr.dadr, ans->pkt.to, 4); | ||
361 | |||
362 | pkt->ip_hdr.chks = | ||
363 | calculate_ip_checksum ((uint16_t *) & pkt->ip_hdr, 5 * 4); | ||
364 | |||
365 | /* set the udp-header */ | ||
366 | pkt->udp_dns.udp_hdr.spt = htons (53); | ||
367 | pkt->udp_dns.udp_hdr.dpt = ans->pkt.dst_port; | ||
368 | pkt->udp_dns.udp_hdr.len = htons (net_len - sizeof (struct ip_hdr)); | ||
369 | pkt->udp_dns.udp_hdr.crc = 0; /* Optional for IPv4 */ | ||
370 | |||
371 | memcpy (&pkt->udp_dns.data, ans->pkt.data, data_len); | ||
372 | (void) GNUNET_HELPER_send (helper_handle, | ||
373 | &pkt->shdr, | ||
374 | GNUNET_YES, | ||
375 | &helper_write, NULL); | ||
376 | |||
377 | } | ||
378 | else | ||
379 | { | ||
380 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Wrong addrlen = %d\n", | ||
381 | ans->pkt.addrlen); | ||
382 | GNUNET_assert (0); | ||
383 | return; /* convince compiler that we're done here */ | ||
384 | } | ||
385 | |||
386 | GNUNET_CONTAINER_DLL_remove (answer_proc_head, answer_proc_tail, ans); | ||
387 | GNUNET_free (ans); | ||
388 | |||
389 | } | ||
390 | |||
391 | /** | ||
392 | * Receive packets from the helper-process | ||
393 | */ | ||
394 | void | ||
395 | message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED, | ||
396 | const struct GNUNET_MessageHeader *message) | ||
397 | { | ||
398 | GNUNET_assert (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
399 | |||
400 | struct tun_pkt *pkt_tun = (struct tun_pkt *) message; | ||
401 | GNUNET_HashCode *key; | ||
402 | |||
403 | /* ethertype is ipv6 */ | ||
404 | if (ntohs (pkt_tun->tun.type) == 0x86dd) | ||
405 | { | ||
406 | struct ip6_pkt *pkt6 = (struct ip6_pkt *) message; | ||
407 | |||
408 | GNUNET_assert (pkt6->ip6_hdr.version == 6); | ||
409 | struct ip6_tcp *pkt6_tcp; | ||
410 | struct ip6_udp *pkt6_udp; | ||
411 | struct ip6_icmp *pkt6_icmp; | ||
412 | |||
413 | pkt6_udp = NULL; /* make compiler happy */ | ||
414 | switch (pkt6->ip6_hdr.nxthdr) | ||
415 | { | ||
416 | case IPPROTO_UDP: | ||
417 | pkt6_udp = (struct ip6_udp *) pkt6; | ||
418 | /* Send dns-packets to the service-dns */ | ||
419 | if (ntohs (pkt6_udp->udp_hdr.dpt) == 53) | ||
420 | { | ||
421 | /* 9 = 8 for the udp-header + 1 for the unsigned char data[1]; */ | ||
422 | GNUNET_DNS_queue_request_v6 (dns_handle, | ||
423 | &pkt6->ip6_hdr.dadr, | ||
424 | &pkt6->ip6_hdr.sadr, | ||
425 | ntohs (pkt6_udp->udp_hdr.spt), | ||
426 | ntohs (pkt6_udp->udp_hdr.len) - 8, | ||
427 | (const void*) pkt6_udp->data); | ||
428 | |||
429 | break; | ||
430 | } | ||
431 | /* fall through */ | ||
432 | case IPPROTO_TCP: | ||
433 | pkt6_tcp = (struct ip6_tcp *) pkt6; | ||
434 | |||
435 | if ((key = address6_mapping_exists (&pkt6->ip6_hdr.dadr)) != NULL) | ||
436 | { | ||
437 | struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key); | ||
438 | |||
439 | GNUNET_assert (me != NULL); | ||
440 | GNUNET_free (key); | ||
441 | |||
442 | size_t size = | ||
443 | sizeof (struct GNUNET_MESH_Tunnel *) + | ||
444 | sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + | ||
445 | ntohs (pkt6->ip6_hdr.paylgth); | ||
446 | |||
447 | struct GNUNET_MESH_Tunnel **cls = GNUNET_malloc (size); | ||
448 | struct GNUNET_MessageHeader *hdr = | ||
449 | (struct GNUNET_MessageHeader *) (cls + 1); | ||
450 | GNUNET_HashCode *hc = (GNUNET_HashCode *) (hdr + 1); | ||
451 | |||
452 | hdr->size = | ||
453 | htons (sizeof (struct GNUNET_MessageHeader) + | ||
454 | sizeof (GNUNET_HashCode) + ntohs (pkt6->ip6_hdr.paylgth)); | ||
455 | |||
456 | GNUNET_MESH_ApplicationType app_type = 0; /* fix compiler uninitialized warning... */ | ||
457 | |||
458 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "me->addrlen is %d\n", | ||
459 | me->addrlen); | ||
460 | if (me->addrlen == 0) | ||
461 | { | ||
462 | /* This is a mapping to a gnunet-service */ | ||
463 | memcpy (hc, &me->desc.service_descriptor, sizeof (GNUNET_HashCode)); | ||
464 | |||
465 | if (IPPROTO_UDP == pkt6->ip6_hdr.nxthdr && | ||
466 | (me->desc.service_type & htonl (GNUNET_DNS_SERVICE_TYPE_UDP)) && | ||
467 | (port_in_ports (me->desc.ports, pkt6_udp->udp_hdr.dpt) || | ||
468 | testBit (me->additional_ports, ntohs (pkt6_udp->udp_hdr.dpt)))) | ||
469 | { | ||
470 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP); | ||
471 | |||
472 | memcpy (hc + 1, &pkt6_udp->udp_hdr, ntohs (pkt6_udp->udp_hdr.len)); | ||
473 | |||
474 | } | ||
475 | else if (IPPROTO_TCP == pkt6->ip6_hdr.nxthdr && | ||
476 | (me->desc.service_type & htonl (GNUNET_DNS_SERVICE_TYPE_TCP)) | ||
477 | && (port_in_ports (me->desc.ports, pkt6_tcp->tcp_hdr.dpt))) | ||
478 | { | ||
479 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP); | ||
480 | |||
481 | memcpy (hc + 1, &pkt6_tcp->tcp_hdr, ntohs (pkt6->ip6_hdr.paylgth)); | ||
482 | |||
483 | } | ||
484 | else | ||
485 | { | ||
486 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "pip: %d\n", | ||
487 | port_in_ports (me->desc.ports, pkt6_tcp->tcp_hdr.dpt)); | ||
488 | GNUNET_assert (0); | ||
489 | } | ||
490 | if (me->tunnel == NULL && NULL != cls) | ||
491 | { | ||
492 | *cls = | ||
493 | GNUNET_MESH_tunnel_create (mesh_handle, | ||
494 | initialize_tunnel_state (16, NULL), | ||
495 | &send_pkt_to_peer, NULL, cls); | ||
496 | |||
497 | GNUNET_MESH_peer_request_connect_add (*cls, | ||
498 | (struct GNUNET_PeerIdentity *) | ||
499 | &me->desc.peer); | ||
500 | me->tunnel = *cls; | ||
501 | } | ||
502 | else if (NULL != cls) | ||
503 | { | ||
504 | *cls = me->tunnel; | ||
505 | send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL); | ||
506 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
507 | "Queued to send IPv6 to peer %x, type %d\n", | ||
508 | *((unsigned int *) &me->desc.peer), ntohs (hdr->type)); | ||
509 | } | ||
510 | } | ||
511 | else | ||
512 | { | ||
513 | /* This is a mapping to a "real" address */ | ||
514 | struct remote_addr *s = (struct remote_addr *) hc; | ||
515 | |||
516 | s->addrlen = me->addrlen; | ||
517 | memcpy (s->addr, me->addr, me->addrlen); | ||
518 | s->proto = pkt6->ip6_hdr.nxthdr; | ||
519 | if (s->proto == IPPROTO_UDP) | ||
520 | { | ||
521 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP); | ||
522 | memcpy (hc + 1, &pkt6_udp->udp_hdr, ntohs (pkt6_udp->udp_hdr.len)); | ||
523 | app_type = GNUNET_APPLICATION_TYPE_INTERNET_UDP_GATEWAY; | ||
524 | if (NULL != udp_tunnel) | ||
525 | me->tunnel = udp_tunnel; | ||
526 | } | ||
527 | else if (s->proto == IPPROTO_TCP) | ||
528 | { | ||
529 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP); | ||
530 | memcpy (hc + 1, &pkt6_tcp->tcp_hdr, ntohs (pkt6->ip6_hdr.paylgth)); | ||
531 | app_type = GNUNET_APPLICATION_TYPE_INTERNET_TCP_GATEWAY; | ||
532 | if (NULL != tcp_tunnel) | ||
533 | me->tunnel = tcp_tunnel; | ||
534 | } | ||
535 | else | ||
536 | { | ||
537 | GNUNET_assert (0); | ||
538 | } | ||
539 | if (me->tunnel == NULL && NULL != cls) | ||
540 | { | ||
541 | *cls = | ||
542 | GNUNET_MESH_tunnel_create (mesh_handle, | ||
543 | initialize_tunnel_state (16, NULL), | ||
544 | &send_pkt_to_peer, NULL, cls); | ||
545 | |||
546 | GNUNET_MESH_peer_request_connect_by_type (*cls, app_type); | ||
547 | me->tunnel = *cls; | ||
548 | if (GNUNET_APPLICATION_TYPE_INTERNET_UDP_GATEWAY == app_type) | ||
549 | udp_tunnel = *cls; | ||
550 | else if (GNUNET_APPLICATION_TYPE_INTERNET_TCP_GATEWAY == app_type) | ||
551 | tcp_tunnel = *cls; | ||
552 | } | ||
553 | else if (NULL != cls) | ||
554 | { | ||
555 | *cls = me->tunnel; | ||
556 | send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL); | ||
557 | } | ||
558 | } | ||
559 | } | ||
560 | else | ||
561 | { | ||
562 | char pbuf[INET6_ADDRSTRLEN]; | ||
563 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
564 | "Packet to %s, which has no mapping\n", | ||
565 | inet_ntop (AF_INET6, | ||
566 | &pkt6->ip6_hdr.dadr, | ||
567 | pbuf, | ||
568 | sizeof (pbuf))); | ||
569 | } | ||
570 | break; | ||
571 | case 0x3a: | ||
572 | /* ICMPv6 */ | ||
573 | pkt6_icmp = (struct ip6_icmp *) pkt6; | ||
574 | /* If this packet is an icmp-echo-request and a mapping exists, answer */ | ||
575 | if (pkt6_icmp->icmp_hdr.type == 0x80 && | ||
576 | (key = address6_mapping_exists (&pkt6->ip6_hdr.dadr)) != NULL) | ||
577 | { | ||
578 | GNUNET_free (key); | ||
579 | pkt6_icmp = GNUNET_malloc (ntohs (pkt6->shdr.size)); | ||
580 | memcpy (pkt6_icmp, pkt6, ntohs (pkt6->shdr.size)); | ||
581 | GNUNET_SCHEDULER_add_now (&send_icmp6_response, pkt6_icmp); | ||
582 | } | ||
583 | break; | ||
584 | } | ||
585 | } | ||
586 | /* ethertype is ipv4 */ | ||
587 | else if (ntohs (pkt_tun->tun.type) == 0x0800) | ||
588 | { | ||
589 | struct ip_pkt *pkt = (struct ip_pkt *) message; | ||
590 | struct ip_udp *udp = (struct ip_udp *) message; | ||
591 | struct ip_tcp *pkt_tcp; | ||
592 | struct ip_udp *pkt_udp; | ||
593 | struct ip_icmp *pkt_icmp; | ||
594 | |||
595 | GNUNET_assert (pkt->ip_hdr.version == 4); | ||
596 | |||
597 | /* Send dns-packets to the service-dns */ | ||
598 | if (pkt->ip_hdr.proto == IPPROTO_UDP && ntohs (udp->udp_hdr.dpt) == 53) | ||
599 | { | ||
600 | GNUNET_DNS_queue_request_v4 (dns_handle, | ||
601 | &pkt->ip_hdr.dadr, | ||
602 | &pkt->ip_hdr.sadr, | ||
603 | ntohs (udp->udp_hdr.spt), | ||
604 | ntohs (udp->udp_hdr.len) - 8, | ||
605 | (const void*) udp->data); | ||
606 | } | ||
607 | else | ||
608 | { | ||
609 | uint32_t dadr = pkt->ip_hdr.dadr.s_addr; | ||
610 | unsigned char *c = (unsigned char *) &dadr; | ||
611 | |||
612 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Packet to %d.%d.%d.%d, proto %x\n", | ||
613 | c[0], c[1], c[2], c[3], pkt->ip_hdr.proto); | ||
614 | switch (pkt->ip_hdr.proto) | ||
615 | { | ||
616 | case IPPROTO_TCP: | ||
617 | case IPPROTO_UDP: | ||
618 | pkt_tcp = (struct ip_tcp *) pkt; | ||
619 | pkt_udp = (struct ip_udp *) pkt; | ||
620 | |||
621 | if ((key = address4_mapping_exists (dadr)) != NULL) | ||
622 | { | ||
623 | struct map_entry *me = | ||
624 | GNUNET_CONTAINER_multihashmap_get (hashmap, key); | ||
625 | GNUNET_assert (me != NULL); | ||
626 | GNUNET_free (key); | ||
627 | |||
628 | size_t size = | ||
629 | sizeof (struct GNUNET_MESH_Tunnel *) + | ||
630 | sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + | ||
631 | ntohs (pkt->ip_hdr.tot_lngth) - 4 * pkt->ip_hdr.hdr_lngth; | ||
632 | |||
633 | struct GNUNET_MESH_Tunnel **cls = GNUNET_malloc (size); | ||
634 | struct GNUNET_MessageHeader *hdr = | ||
635 | (struct GNUNET_MessageHeader *) (cls + 1); | ||
636 | GNUNET_HashCode *hc = (GNUNET_HashCode *) (hdr + 1); | ||
637 | |||
638 | hdr->size = | ||
639 | htons (sizeof (struct GNUNET_MessageHeader) + | ||
640 | sizeof (GNUNET_HashCode) + ntohs (pkt->ip_hdr.tot_lngth) - | ||
641 | 4 * pkt->ip_hdr.hdr_lngth); | ||
642 | |||
643 | GNUNET_MESH_ApplicationType app_type = 0; /* make compiler happy */ | ||
644 | |||
645 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "me->addrlen is %d\n", | ||
646 | me->addrlen); | ||
647 | if (me->addrlen == 0) | ||
648 | { | ||
649 | /* This is a mapping to a gnunet-service */ | ||
650 | memcpy (hc, &me->desc.service_descriptor, sizeof (GNUNET_HashCode)); | ||
651 | |||
652 | if ((IPPROTO_UDP == pkt->ip_hdr.proto) && | ||
653 | (me->desc.service_type & htonl (GNUNET_DNS_SERVICE_TYPE_UDP)) && | ||
654 | (port_in_ports (me->desc.ports, pkt_udp->udp_hdr.dpt) || | ||
655 | testBit (me->additional_ports, ntohs (pkt_udp->udp_hdr.dpt)))) | ||
656 | { | ||
657 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_UDP); | ||
658 | |||
659 | memcpy (hc + 1, &pkt_udp->udp_hdr, ntohs (pkt_udp->udp_hdr.len)); | ||
660 | |||
661 | } | ||
662 | else if ((IPPROTO_TCP == pkt->ip_hdr.proto) && | ||
663 | (me-> | ||
664 | desc.service_type & htonl (GNUNET_DNS_SERVICE_TYPE_TCP)) | ||
665 | && (port_in_ports (me->desc.ports, pkt_tcp->tcp_hdr.dpt))) | ||
666 | { | ||
667 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_SERVICE_TCP); | ||
668 | |||
669 | memcpy (hc + 1, &pkt_tcp->tcp_hdr, | ||
670 | ntohs (pkt->ip_hdr.tot_lngth) - | ||
671 | 4 * pkt->ip_hdr.hdr_lngth); | ||
672 | |||
673 | } | ||
674 | if (me->tunnel == NULL && NULL != cls) | ||
675 | { | ||
676 | *cls = | ||
677 | GNUNET_MESH_tunnel_create (mesh_handle, | ||
678 | initialize_tunnel_state (4, NULL), | ||
679 | send_pkt_to_peer, NULL, cls); | ||
680 | GNUNET_MESH_peer_request_connect_add (*cls, | ||
681 | (struct GNUNET_PeerIdentity | ||
682 | *) &me->desc.peer); | ||
683 | me->tunnel = *cls; | ||
684 | } | ||
685 | else if (NULL != cls) | ||
686 | { | ||
687 | *cls = me->tunnel; | ||
688 | send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL); | ||
689 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
690 | "Queued to send IPv4 to peer %x, type %d\n", | ||
691 | *((unsigned int *) &me->desc.peer), | ||
692 | ntohs (hdr->type)); | ||
693 | } | ||
694 | } | ||
695 | else | ||
696 | { | ||
697 | /* This is a mapping to a "real" address */ | ||
698 | struct remote_addr *s = (struct remote_addr *) hc; | ||
699 | |||
700 | s->addrlen = me->addrlen; | ||
701 | memcpy (s->addr, me->addr, me->addrlen); | ||
702 | s->proto = pkt->ip_hdr.proto; | ||
703 | if (s->proto == IPPROTO_UDP) | ||
704 | { | ||
705 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP); | ||
706 | memcpy (hc + 1, &pkt_udp->udp_hdr, ntohs (pkt_udp->udp_hdr.len)); | ||
707 | app_type = GNUNET_APPLICATION_TYPE_INTERNET_UDP_GATEWAY; | ||
708 | } | ||
709 | else if (s->proto == IPPROTO_TCP) | ||
710 | { | ||
711 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP); | ||
712 | memcpy (hc + 1, &pkt_tcp->tcp_hdr, | ||
713 | ntohs (pkt->ip_hdr.tot_lngth) - | ||
714 | 4 * pkt->ip_hdr.hdr_lngth); | ||
715 | app_type = GNUNET_APPLICATION_TYPE_INTERNET_TCP_GATEWAY; | ||
716 | } | ||
717 | else | ||
718 | GNUNET_assert (0); | ||
719 | if (me->tunnel == NULL && NULL != cls) | ||
720 | { | ||
721 | *cls = | ||
722 | GNUNET_MESH_tunnel_create (mesh_handle, | ||
723 | initialize_tunnel_state (4, NULL), | ||
724 | send_pkt_to_peer, NULL, cls); | ||
725 | |||
726 | GNUNET_MESH_peer_request_connect_by_type (*cls, app_type); | ||
727 | me->tunnel = *cls; | ||
728 | } | ||
729 | else if (NULL != cls) | ||
730 | { | ||
731 | *cls = me->tunnel; | ||
732 | send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL); | ||
733 | } | ||
734 | } | ||
735 | } | ||
736 | else | ||
737 | { | ||
738 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
739 | "Packet to %x which has no mapping\n", dadr); | ||
740 | } | ||
741 | break; | ||
742 | case 0x01: | ||
743 | /* ICMP */ | ||
744 | pkt_icmp = (struct ip_icmp *) pkt; | ||
745 | if (pkt_icmp->icmp_hdr.type == 0x8 && | ||
746 | (key = address4_mapping_exists (dadr)) != NULL) | ||
747 | { | ||
748 | GNUNET_free (key); | ||
749 | pkt_icmp = GNUNET_malloc (ntohs (pkt->shdr.size)); | ||
750 | memcpy (pkt_icmp, pkt, ntohs (pkt->shdr.size)); | ||
751 | GNUNET_SCHEDULER_add_now (&send_icmp4_response, pkt_icmp); | ||
752 | } | ||
753 | break; | ||
754 | } | ||
755 | } | ||
756 | } | ||
757 | } | ||
758 | |||
759 | |||
760 | |||
213 | static void | 761 | static void |
214 | collect_mappings (void *cls GNUNET_UNUSED, | 762 | collect_mappings (void *cls GNUNET_UNUSED, |
215 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 763 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
@@ -269,8 +817,10 @@ send_icmp4_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
269 | memcpy (response + 1, request + 1, | 817 | memcpy (response + 1, request + 1, |
270 | ntohs (request->shdr.size) - sizeof (struct ip_icmp)); | 818 | ntohs (request->shdr.size) - sizeof (struct ip_icmp)); |
271 | 819 | ||
272 | write_to_helper (response, ntohs (response->shdr.size)); | 820 | (void) GNUNET_HELPER_send (helper_handle, |
273 | 821 | &response->shdr, | |
822 | GNUNET_YES, | ||
823 | NULL, NULL); | ||
274 | GNUNET_free (request); | 824 | GNUNET_free (request); |
275 | } | 825 | } |
276 | 826 | ||
@@ -310,8 +860,10 @@ send_icmp6_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
310 | memcpy (response + 1, request + 1, | 860 | memcpy (response + 1, request + 1, |
311 | ntohs (request->shdr.size) - sizeof (struct ip6_icmp)); | 861 | ntohs (request->shdr.size) - sizeof (struct ip6_icmp)); |
312 | 862 | ||
313 | write_to_helper (response, ntohs (response->shdr.size)); | 863 | (void) GNUNET_HELPER_send (helper_handle, |
314 | 864 | &response->shdr, | |
865 | GNUNET_YES, | ||
866 | NULL, NULL); | ||
315 | GNUNET_free (request); | 867 | GNUNET_free (request); |
316 | } | 868 | } |
317 | 869 | ||
@@ -824,9 +1376,6 @@ process_answer (void *cls, | |||
824 | GNUNET_CONTAINER_DLL_insert_after (answer_proc_head, answer_proc_tail, | 1376 | GNUNET_CONTAINER_DLL_insert_after (answer_proc_head, answer_proc_tail, |
825 | answer_proc_tail, list); | 1377 | answer_proc_tail, list); |
826 | 1378 | ||
827 | schedule_helper_write (GNUNET_TIME_UNIT_FOREVER_REL, NULL); | ||
828 | |||
829 | return; | ||
830 | } | 1379 | } |
831 | 1380 | ||
832 | 1381 | ||
@@ -939,8 +1488,11 @@ receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
939 | calculate_checksum_update (sum, (uint16_t *) & pkt6->udp_hdr, | 1488 | calculate_checksum_update (sum, (uint16_t *) & pkt6->udp_hdr, |
940 | ntohs (pkt->len)); | 1489 | ntohs (pkt->len)); |
941 | pkt6->udp_hdr.crc = calculate_checksum_end (sum); | 1490 | pkt6->udp_hdr.crc = calculate_checksum_end (sum); |
942 | 1491 | ||
943 | write_to_helper (pkt6, size); | 1492 | (void) GNUNET_HELPER_send (helper_handle, |
1493 | &pkt6->shdr, | ||
1494 | GNUNET_YES, | ||
1495 | NULL, NULL); | ||
944 | } | 1496 | } |
945 | else | 1497 | else |
946 | { | 1498 | { |
@@ -1011,7 +1563,10 @@ receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1011 | pkt4->ip_hdr.chks = | 1563 | pkt4->ip_hdr.chks = |
1012 | calculate_ip_checksum ((uint16_t *) & pkt4->ip_hdr, 5 * 4); | 1564 | calculate_ip_checksum ((uint16_t *) & pkt4->ip_hdr, 5 * 4); |
1013 | 1565 | ||
1014 | write_to_helper (pkt4, size); | 1566 | (void) GNUNET_HELPER_send (helper_handle, |
1567 | &pkt4->shdr, | ||
1568 | GNUNET_YES, | ||
1569 | NULL, NULL); | ||
1015 | } | 1570 | } |
1016 | 1571 | ||
1017 | return GNUNET_OK; | 1572 | return GNUNET_OK; |
@@ -1113,7 +1668,10 @@ receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1113 | ntohs (pkt6->ip6_hdr.paylgth)); | 1668 | ntohs (pkt6->ip6_hdr.paylgth)); |
1114 | pkt6->tcp_hdr.crc = calculate_checksum_end (sum); | 1669 | pkt6->tcp_hdr.crc = calculate_checksum_end (sum); |
1115 | 1670 | ||
1116 | write_to_helper (pkt6, size); | 1671 | (void) GNUNET_HELPER_send (helper_handle, |
1672 | &pkt6->shdr, | ||
1673 | GNUNET_YES, | ||
1674 | NULL, NULL); | ||
1117 | } | 1675 | } |
1118 | else | 1676 | else |
1119 | { | 1677 | { |
@@ -1194,7 +1752,11 @@ receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1194 | pkt4->ip_hdr.chks = | 1752 | pkt4->ip_hdr.chks = |
1195 | calculate_ip_checksum ((uint16_t *) & pkt4->ip_hdr, 5 * 4); | 1753 | calculate_ip_checksum ((uint16_t *) & pkt4->ip_hdr, 5 * 4); |
1196 | 1754 | ||
1197 | write_to_helper (pkt4, size); | 1755 | (void) GNUNET_HELPER_send (helper_handle, |
1756 | &pkt4->shdr, | ||
1757 | GNUNET_YES, | ||
1758 | NULL, NULL); | ||
1759 | |||
1198 | } | 1760 | } |
1199 | 1761 | ||
1200 | return GNUNET_OK; | 1762 | return GNUNET_OK; |
@@ -1237,10 +1799,14 @@ run (void *cls, char *const *args GNUNET_UNUSED, | |||
1237 | {receive_tcp_back, GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP_BACK, 0}, | 1799 | {receive_tcp_back, GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP_BACK, 0}, |
1238 | {NULL, 0, 0} | 1800 | {NULL, 0, 0} |
1239 | }; | 1801 | }; |
1240 | |||
1241 | static const GNUNET_MESH_ApplicationType types[] = { | 1802 | static const GNUNET_MESH_ApplicationType types[] = { |
1242 | GNUNET_APPLICATION_TYPE_END | 1803 | GNUNET_APPLICATION_TYPE_END |
1243 | }; | 1804 | }; |
1805 | char *ifname; | ||
1806 | char *ipv6addr; | ||
1807 | char *ipv6prefix; | ||
1808 | char *ipv4addr; | ||
1809 | char *ipv4mask; | ||
1244 | 1810 | ||
1245 | mesh_handle = | 1811 | mesh_handle = |
1246 | GNUNET_MESH_connect (cfg_, 42, NULL, new_tunnel, cleaner, handlers, | 1812 | GNUNET_MESH_connect (cfg_, 42, NULL, new_tunnel, cleaner, handlers, |
@@ -1254,8 +1820,58 @@ run (void *cls, char *const *args GNUNET_UNUSED, | |||
1254 | dns_handle = GNUNET_DNS_connect (cfg, | 1820 | dns_handle = GNUNET_DNS_connect (cfg, |
1255 | &process_answer, | 1821 | &process_answer, |
1256 | NULL); | 1822 | NULL); |
1257 | shs_task = | 1823 | if (GNUNET_SYSERR == |
1258 | GNUNET_SCHEDULER_add_after (conn_task, start_helper_and_schedule, NULL); | 1824 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IFNAME", &ifname)) |
1825 | { | ||
1826 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1827 | "No entry 'IFNAME' in configuration!\n"); | ||
1828 | exit (1); | ||
1829 | } | ||
1830 | |||
1831 | if (GNUNET_SYSERR == | ||
1832 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR", &ipv6addr)) | ||
1833 | { | ||
1834 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1835 | "No entry 'IPV6ADDR' in configuration!\n"); | ||
1836 | exit (1); | ||
1837 | } | ||
1838 | |||
1839 | if (GNUNET_SYSERR == | ||
1840 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6PREFIX", | ||
1841 | &ipv6prefix)) | ||
1842 | { | ||
1843 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1844 | "No entry 'IPV6PREFIX' in configuration!\n"); | ||
1845 | exit (1); | ||
1846 | } | ||
1847 | |||
1848 | if (GNUNET_SYSERR == | ||
1849 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4ADDR", &ipv4addr)) | ||
1850 | { | ||
1851 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1852 | "No entry 'IPV4ADDR' in configuration!\n"); | ||
1853 | exit (1); | ||
1854 | } | ||
1855 | |||
1856 | if (GNUNET_SYSERR == | ||
1857 | GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4MASK", &ipv4mask)) | ||
1858 | { | ||
1859 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1860 | "No entry 'IPV4MASK' in configuration!\n"); | ||
1861 | exit (1); | ||
1862 | } | ||
1863 | |||
1864 | vpn_argv[0] = GNUNET_strdup ("vpn-gnunet"); | ||
1865 | vpn_argv[1] = ifname; | ||
1866 | vpn_argv[2] = ipv6addr; | ||
1867 | vpn_argv[3] = ipv6prefix; | ||
1868 | vpn_argv[4] = ipv4addr; | ||
1869 | vpn_argv[5] = ipv4mask; | ||
1870 | vpn_argv[6] = NULL; | ||
1871 | |||
1872 | helper_handle = GNUNET_HELPER_start ("gnunet-helper-vpn", vpn_argv, | ||
1873 | &message_token, NULL); | ||
1874 | GNUNET_DNS_restart_hijack (dns_handle); | ||
1259 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls); | 1875 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls); |
1260 | } | 1876 | } |
1261 | 1877 | ||
diff --git a/src/vpn/gnunet-helper-vpn-api.c b/src/vpn/gnunet-helper-vpn-api.c index 379e75765..d2b5673d0 100644 --- a/src/vpn/gnunet-helper-vpn-api.c +++ b/src/vpn/gnunet-helper-vpn-api.c | |||
@@ -32,71 +32,6 @@ | |||
32 | 32 | ||
33 | #include "gnunet-helper-vpn-api.h" | 33 | #include "gnunet-helper-vpn-api.h" |
34 | 34 | ||
35 | static void | ||
36 | stop_helper (struct GNUNET_VPN_HELPER_Handle *handle) | ||
37 | { | ||
38 | if (NULL == handle->helper_proc) | ||
39 | return; | ||
40 | GNUNET_OS_process_kill (handle->helper_proc, SIGKILL); | ||
41 | GNUNET_OS_process_wait (handle->helper_proc); | ||
42 | GNUNET_OS_process_close (handle->helper_proc); | ||
43 | handle->helper_proc = NULL; | ||
44 | |||
45 | GNUNET_DISK_pipe_close (handle->helper_in); | ||
46 | GNUNET_DISK_pipe_close (handle->helper_out); | ||
47 | |||
48 | GNUNET_SERVER_mst_destroy (handle->mst); | ||
49 | } | ||
50 | |||
51 | extern GNUNET_SCHEDULER_TaskIdentifier shs_task; | ||
52 | |||
53 | /** | ||
54 | * Read from the helper-process | ||
55 | */ | ||
56 | static void | ||
57 | helper_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tsdkctx) | ||
58 | { | ||
59 | struct GNUNET_VPN_HELPER_Handle *handle = cls; | ||
60 | |||
61 | /* no message can be bigger then 64k */ | ||
62 | char buf[65535]; | ||
63 | |||
64 | if (tsdkctx->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) | ||
65 | return; | ||
66 | |||
67 | int t = GNUNET_DISK_file_read (handle->fh_from_helper, &buf, 65535); | ||
68 | |||
69 | /* On read-error, restart the helper */ | ||
70 | if (t <= 0) | ||
71 | { | ||
72 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
73 | "Read error for header from vpn-helper: %m\n"); | ||
74 | stop_helper (handle); | ||
75 | |||
76 | /* Restart the helper */ | ||
77 | shs_task = | ||
78 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, | ||
79 | handle->restart_task, handle); | ||
80 | return; | ||
81 | } | ||
82 | |||
83 | if (GNUNET_SYSERR == | ||
84 | GNUNET_SERVER_mst_receive (handle->mst, handle->client, buf, t, 0, 0)) | ||
85 | { | ||
86 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "SYSERR from mst\n"); | ||
87 | stop_helper (handle); | ||
88 | |||
89 | /* Restart the helper */ | ||
90 | shs_task = | ||
91 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, | ||
92 | handle->restart_task, handle); | ||
93 | return; | ||
94 | |||
95 | } | ||
96 | |||
97 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
98 | handle->fh_from_helper, &helper_read, handle); | ||
99 | } | ||
100 | 35 | ||
101 | void | 36 | void |
102 | cleanup_helper (struct GNUNET_VPN_HELPER_Handle *handle) | 37 | cleanup_helper (struct GNUNET_VPN_HELPER_Handle *handle) |
@@ -111,37 +46,4 @@ start_helper (const char *ifname, const char *ipv6addr, const char *ipv6prefix, | |||
111 | const char *process_name, GNUNET_SCHEDULER_Task restart_task, | 46 | const char *process_name, GNUNET_SCHEDULER_Task restart_task, |
112 | GNUNET_SERVER_MessageTokenizerCallback cb, void *cb_cls) | 47 | GNUNET_SERVER_MessageTokenizerCallback cb, void *cb_cls) |
113 | { | 48 | { |
114 | struct GNUNET_VPN_HELPER_Handle *handle = | ||
115 | GNUNET_malloc (sizeof (struct GNUNET_VPN_HELPER_Handle)); | ||
116 | |||
117 | handle->helper_in = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO); | ||
118 | handle->helper_out = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_NO, GNUNET_YES); | ||
119 | |||
120 | handle->restart_task = restart_task; | ||
121 | 49 | ||
122 | if (handle->helper_in == NULL || handle->helper_out == NULL) | ||
123 | { | ||
124 | GNUNET_free (handle); | ||
125 | return NULL; | ||
126 | } | ||
127 | |||
128 | handle->helper_proc = | ||
129 | GNUNET_OS_start_process (handle->helper_in, handle->helper_out, | ||
130 | "gnunet-helper-vpn", process_name, ifname, | ||
131 | ipv6addr, ipv6prefix, ipv4addr, ipv4mask, NULL); | ||
132 | |||
133 | handle->fh_from_helper = | ||
134 | GNUNET_DISK_pipe_handle (handle->helper_out, GNUNET_DISK_PIPE_END_READ); | ||
135 | handle->fh_to_helper = | ||
136 | GNUNET_DISK_pipe_handle (handle->helper_in, GNUNET_DISK_PIPE_END_WRITE); | ||
137 | |||
138 | GNUNET_DISK_pipe_close_end (handle->helper_out, GNUNET_DISK_PIPE_END_WRITE); | ||
139 | GNUNET_DISK_pipe_close_end (handle->helper_in, GNUNET_DISK_PIPE_END_READ); | ||
140 | |||
141 | handle->mst = GNUNET_SERVER_mst_create (cb, cb_cls); | ||
142 | |||
143 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
144 | handle->fh_from_helper, &helper_read, handle); | ||
145 | |||
146 | return handle; | ||
147 | } | ||
diff --git a/src/vpn/gnunet-helper-vpn-api.h b/src/vpn/gnunet-helper-vpn-api.h deleted file mode 100644 index 964beb23c..000000000 --- a/src/vpn/gnunet-helper-vpn-api.h +++ /dev/null | |||
@@ -1,110 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2010 Christian Grothoff | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file vpn/gnunet-helper-vpn-api.h | ||
23 | * @brief exposes the API (the convenience-functions) of dealing with the | ||
24 | * helper-vpn | ||
25 | * @author Philipp Toelke | ||
26 | */ | ||
27 | #ifndef GNUNET_HELPER_VPN_API_H | ||
28 | #define GNUNET_HELPER_VPN_API_H | ||
29 | |||
30 | /** | ||
31 | * The handle to a helper. | ||
32 | * sometimes a few entries may be made opaque. | ||
33 | */ | ||
34 | struct GNUNET_VPN_HELPER_Handle | ||
35 | { | ||
36 | /** | ||
37 | * PipeHandle to receive data from the helper | ||
38 | */ | ||
39 | struct GNUNET_DISK_PipeHandle *helper_in; | ||
40 | |||
41 | /** | ||
42 | * PipeHandle to send data to the helper | ||
43 | */ | ||
44 | struct GNUNET_DISK_PipeHandle *helper_out; | ||
45 | |||
46 | /** | ||
47 | * FileHandle to receive data from the helper | ||
48 | */ | ||
49 | const struct GNUNET_DISK_FileHandle *fh_from_helper; | ||
50 | |||
51 | /** | ||
52 | * FileHandle to send data to the helper | ||
53 | */ | ||
54 | const struct GNUNET_DISK_FileHandle *fh_to_helper; | ||
55 | |||
56 | /** | ||
57 | * The process id of the helper | ||
58 | */ | ||
59 | struct GNUNET_OS_Process *helper_proc; | ||
60 | |||
61 | /** | ||
62 | * The Message-Tokenizer that tokenizes the messages comming from the helper | ||
63 | */ | ||
64 | struct GNUNET_SERVER_MessageStreamTokenizer *mst; | ||
65 | |||
66 | /** | ||
67 | * The client-identifier passed to the mst-callback | ||
68 | */ | ||
69 | void *client; | ||
70 | |||
71 | /** | ||
72 | * The name of the interface | ||
73 | */ | ||
74 | char *ifname; | ||
75 | |||
76 | /** | ||
77 | * The task called when the helper dies. | ||
78 | * Will be called with the handle as cls | ||
79 | */ | ||
80 | GNUNET_SCHEDULER_Task restart_task; | ||
81 | }; | ||
82 | |||
83 | /** | ||
84 | * @brief Starts a helper and begins reading from it | ||
85 | * | ||
86 | * @param ifname The name of the new interface | ||
87 | * @param ipv6addr The IPv6 address of the new interface | ||
88 | * @param ipv6prefix The IPv6 prefix length of the new IP | ||
89 | * @param ipv4addr The IPv4 address of the new interface | ||
90 | * @param ipv4mask The associated netmask | ||
91 | * @param process_name How the helper should appear in process-listings | ||
92 | * @param restart_task The task called when the helper dies. Will be called with the handle as cls | ||
93 | * @param cb A callback for messages from the helper | ||
94 | * @param cb_cls Closure for the callback | ||
95 | * | ||
96 | * @return A pointer to the new Handle, NULL on error | ||
97 | */ | ||
98 | struct GNUNET_VPN_HELPER_Handle * | ||
99 | start_helper (const char *ifname, const char *ipv6addr, const char *ipv6prefix, | ||
100 | const char *ipv4addr, const char *ipv4mask, | ||
101 | const char *process_name, GNUNET_SCHEDULER_Task restart_task, | ||
102 | GNUNET_SERVER_MessageTokenizerCallback cb, void *cb_cls); | ||
103 | |||
104 | /** | ||
105 | * @brief Kills the helper, closes the pipe and free()s the handle | ||
106 | */ | ||
107 | void | ||
108 | cleanup_helper (struct GNUNET_VPN_HELPER_Handle *); | ||
109 | |||
110 | #endif /* end of include guard: GNUNET_HELPER_VPN_API_H */ | ||