diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-01-18 20:43:25 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-01-18 20:43:25 +0000 |
commit | c37fba0bd9febb11297ebca62a58935276130244 (patch) | |
tree | 45cf17c2f0f4ffd0daa2b77181f8cc63a3445ffa /src/dns | |
parent | 6b2fb63de633b086a91e7733ca0dd5591198c20c (diff) | |
download | gnunet-c37fba0bd9febb11297ebca62a58935276130244.tar.gz gnunet-c37fba0bd9febb11297ebca62a58935276130244.zip |
-adding DNS exit-from-mesh functionality to gnunet-service-dns
Diffstat (limited to 'src/dns')
-rw-r--r-- | src/dns/Makefile.am | 1 | ||||
-rw-r--r-- | src/dns/dns.conf.in | 25 | ||||
-rw-r--r-- | src/dns/dns.h | 2 | ||||
-rw-r--r-- | src/dns/gnunet-service-dns.c | 325 |
4 files changed, 344 insertions, 9 deletions
diff --git a/src/dns/Makefile.am b/src/dns/Makefile.am index d8c2cd1c1..a9b1d652e 100644 --- a/src/dns/Makefile.am +++ b/src/dns/Makefile.am | |||
@@ -74,6 +74,7 @@ gnunet_service_dns_SOURCES = \ | |||
74 | gnunet-service-dns.c | 74 | gnunet-service-dns.c |
75 | gnunet_service_dns_LDADD = \ | 75 | gnunet_service_dns_LDADD = \ |
76 | $(top_builddir)/src/tun/libgnunettun.la \ | 76 | $(top_builddir)/src/tun/libgnunettun.la \ |
77 | $(top_builddir)/src/mesh/libgnunetmesh.la \ | ||
77 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 78 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
78 | $(top_builddir)/src/util/libgnunetutil.la \ | 79 | $(top_builddir)/src/util/libgnunetutil.la \ |
79 | $(GN_LIBINTL) | 80 | $(GN_LIBINTL) |
diff --git a/src/dns/dns.conf.in b/src/dns/dns.conf.in index a99f7fec3..d2c67958a 100644 --- a/src/dns/dns.conf.in +++ b/src/dns/dns.conf.in | |||
@@ -1,17 +1,34 @@ | |||
1 | [dns] | 1 | [dns] |
2 | AUTOSTART = YES | 2 | AUTOSTART = YES |
3 | @UNIXONLY@ PORT = 0 | ||
4 | HOSTNAME = localhost | 3 | HOSTNAME = localhost |
5 | HOME = $SERVICEHOME | 4 | HOME = $SERVICEHOME |
6 | CONFIG = $DEFAULTCONFIG | 5 | CONFIG = $DEFAULTCONFIG |
7 | BINARY = gnunet-service-dns | 6 | BINARY = gnunet-service-dns |
8 | UNIXPATH = /tmp/gnunet-service-dns.sock | 7 | UNIXPATH = /tmp/gnunet-service-dns.sock |
8 | |||
9 | # Access to this service can compromise all DNS queries in this | ||
10 | # system. Thus access should be restricted to the same UID. | ||
11 | # (see https://gnunet.org/gnunet-access-control-model) | ||
9 | UNIX_MATCH_UID = YES | 12 | UNIX_MATCH_UID = YES |
10 | UNIX_MATCH_GID = YES | 13 | UNIX_MATCH_GID = YES |
14 | |||
15 | # As there is no sufficiently restrictive access control for TCP, | ||
16 | # we never use it, even if @UNIXONLY@ is not set (just to be safe) | ||
17 | @UNIXONLY@ PORT = 0 | ||
18 | |||
19 | # This option should be set to YES to allow the DNS service to | ||
20 | # perform lookups against the locally configured DNS resolver. | ||
21 | # (set to "NO" if no normal ISP is locally available and thus | ||
22 | # requests for normal ".com"/".org"/etc. must be routed via | ||
23 | # the GNUnet VPN (the GNUNET PT daemon then needs to be configured | ||
24 | # to intercept and route DNS queries via mesh). | ||
11 | PROVIDE_EXIT = YES | 25 | PROVIDE_EXIT = YES |
26 | |||
27 | # Name of the virtual interface we use to intercept DNS traffic. | ||
12 | IFNAME = gnunet-dns | 28 | IFNAME = gnunet-dns |
13 | 29 | ||
14 | # Use RFC 3849-style documentation IPv6 address (RFC 4773 might provide an alternative in the future) | 30 | # Use RFC 3849-style documentation IPv6 address (RFC 4773 might provide an alternative in the future) |
31 | # FIXME: or just default to a site-local address scope as we do for VPN!? | ||
15 | IPV6ADDR = 2001:DB8::1 | 32 | IPV6ADDR = 2001:DB8::1 |
16 | IPV6PREFIX = 126 | 33 | IPV6PREFIX = 126 |
17 | 34 | ||
@@ -19,3 +36,9 @@ IPV6PREFIX = 126 | |||
19 | IPV4ADDR = 169.254.1.1 | 36 | IPV4ADDR = 169.254.1.1 |
20 | IPV4MASK = 255.255.0.0 | 37 | IPV4MASK = 255.255.0.0 |
21 | 38 | ||
39 | # Enable GNUnet-wide DNS-EXIT service by setting this value to the IP address (IPv4 or IPv6) | ||
40 | # of a DNS resolver to use. Only works if "PROVIDE_EXIT" is also set to YES. Must absolutely | ||
41 | # NOT be an address of any of GNUnet's virtual tunnel interfaces. Use a well-known | ||
42 | # public DNS resolver or your ISP's resolver from /etc/resolv.conf. | ||
43 | # DNS_EXIT = 8.8.8.8 | ||
44 | |||
diff --git a/src/dns/dns.h b/src/dns/dns.h index 29a9f937b..2b0ad0376 100644 --- a/src/dns/dns.h +++ b/src/dns/dns.h | |||
@@ -19,7 +19,7 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @file dns/dns_new.h | 22 | * @file dns/dns.h |
23 | * @brief IPC messages between DNS API and DNS service | 23 | * @brief IPC messages between DNS API and DNS service |
24 | * @author Christian Grothoff | 24 | * @author Christian Grothoff |
25 | */ | 25 | */ |
diff --git a/src/dns/gnunet-service-dns.c b/src/dns/gnunet-service-dns.c index 690b4887e..9f3a64334 100644 --- a/src/dns/gnunet-service-dns.c +++ b/src/dns/gnunet-service-dns.c | |||
@@ -25,11 +25,13 @@ | |||
25 | */ | 25 | */ |
26 | #include "platform.h" | 26 | #include "platform.h" |
27 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
28 | #include "gnunet_applications.h" | ||
28 | #include "gnunet_constants.h" | 29 | #include "gnunet_constants.h" |
29 | #include "gnunet_protocols.h" | 30 | #include "gnunet_protocols.h" |
30 | #include "gnunet_signatures.h" | 31 | #include "gnunet_signatures.h" |
31 | #include "dns.h" | 32 | #include "dns.h" |
32 | #include "gnunet_dns_service.h" | 33 | #include "gnunet_dns_service.h" |
34 | #include "gnunet_mesh_service.h" | ||
33 | #include "gnunet_statistics_service.h" | 35 | #include "gnunet_statistics_service.h" |
34 | #include "gnunet_tun_lib.h" | 36 | #include "gnunet_tun_lib.h" |
35 | 37 | ||
@@ -162,6 +164,55 @@ struct RequestRecord | |||
162 | }; | 164 | }; |
163 | 165 | ||
164 | 166 | ||
167 | |||
168 | /** | ||
169 | * State we keep for each DNS tunnel that terminates at this node. | ||
170 | */ | ||
171 | struct TunnelState | ||
172 | { | ||
173 | |||
174 | /** | ||
175 | * Associated MESH tunnel. | ||
176 | */ | ||
177 | struct GNUNET_MESH_Tunnel *tunnel; | ||
178 | |||
179 | /** | ||
180 | * Active request for sending a reply. | ||
181 | */ | ||
182 | struct GNUNET_MESH_TransmitHandle *th; | ||
183 | |||
184 | /** | ||
185 | * DNS reply ready for transmission. | ||
186 | */ | ||
187 | char *reply; | ||
188 | |||
189 | /** | ||
190 | * Address we sent the DNS request to. | ||
191 | */ | ||
192 | struct sockaddr_storage addr; | ||
193 | |||
194 | /** | ||
195 | * Number of bytes in 'addr'. | ||
196 | */ | ||
197 | socklen_t addrlen; | ||
198 | |||
199 | /** | ||
200 | * Number of bytes in 'reply'. | ||
201 | */ | ||
202 | size_t reply_length; | ||
203 | |||
204 | /** | ||
205 | * Original DNS request ID as used by the client. | ||
206 | */ | ||
207 | uint16_t original_id; | ||
208 | |||
209 | /** | ||
210 | * DNS request ID that we used for forwarding. | ||
211 | */ | ||
212 | uint16_t my_id; | ||
213 | }; | ||
214 | |||
215 | |||
165 | /** | 216 | /** |
166 | * The IPv4 UDP-Socket through which DNS-Resolves will be sent if they are not to be | 217 | * The IPv4 UDP-Socket through which DNS-Resolves will be sent if they are not to be |
167 | * sent through gnunet. The port of this socket will not be hijacked. | 218 | * sent through gnunet. The port of this socket will not be hijacked. |
@@ -231,10 +282,27 @@ static struct GNUNET_SERVER_NotificationContext *nc; | |||
231 | static struct RequestRecord requests[UINT16_MAX + 1]; | 282 | static struct RequestRecord requests[UINT16_MAX + 1]; |
232 | 283 | ||
233 | /** | 284 | /** |
285 | * Array of all open requests from tunnels. | ||
286 | */ | ||
287 | static struct TunnelState *tunnels[UINT16_MAX + 1]; | ||
288 | |||
289 | /** | ||
234 | * Generator for unique request IDs. | 290 | * Generator for unique request IDs. |
235 | */ | 291 | */ |
236 | static uint64_t request_id_gen; | 292 | static uint64_t request_id_gen; |
237 | 293 | ||
294 | /** | ||
295 | * IP address to use for the DNS server if we are a DNS exit service | ||
296 | * (for VPN via mesh); otherwise NULL. | ||
297 | */ | ||
298 | static char *dns_exit; | ||
299 | |||
300 | /** | ||
301 | * Handle to the MESH service (for receiving DNS queries), or NULL | ||
302 | * if we are not a DNS exit. | ||
303 | */ | ||
304 | static struct GNUNET_MESH_Handle *mesh; | ||
305 | |||
238 | 306 | ||
239 | /** | 307 | /** |
240 | * We're done processing a DNS request, free associated memory. | 308 | * We're done processing a DNS request, free associated memory. |
@@ -298,6 +366,11 @@ cleanup_task (void *cls GNUNET_UNUSED, | |||
298 | GNUNET_STATISTICS_destroy (stats, GNUNET_YES); | 366 | GNUNET_STATISTICS_destroy (stats, GNUNET_YES); |
299 | stats = NULL; | 367 | stats = NULL; |
300 | } | 368 | } |
369 | if (NULL != dns_exit) | ||
370 | { | ||
371 | GNUNET_free (dns_exit); | ||
372 | dns_exit = NULL; | ||
373 | } | ||
301 | } | 374 | } |
302 | 375 | ||
303 | 376 | ||
@@ -657,6 +730,52 @@ client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) | |||
657 | 730 | ||
658 | 731 | ||
659 | /** | 732 | /** |
733 | * We got a reply from DNS for a request of a MESH tunnel. Send it | ||
734 | * via the tunnel (after changing the request ID back). | ||
735 | * | ||
736 | * @param cls the 'struct TunnelState' | ||
737 | * @param size number of bytes available in buf | ||
738 | * @param buf where to copy the reply | ||
739 | * @return number of bytes written to buf | ||
740 | */ | ||
741 | static size_t | ||
742 | transmit_reply_to_mesh (void *cls, | ||
743 | size_t size, | ||
744 | void *buf) | ||
745 | { | ||
746 | struct TunnelState *ts = cls; | ||
747 | size_t off; | ||
748 | size_t ret; | ||
749 | char *cbuf = buf; | ||
750 | struct GNUNET_MessageHeader hdr; | ||
751 | struct GNUNET_TUN_DnsHeader dns; | ||
752 | |||
753 | ts->th = NULL; | ||
754 | GNUNET_assert (ts->reply != NULL); | ||
755 | if (size == 0) | ||
756 | return 0; | ||
757 | ret = sizeof (struct GNUNET_MessageHeader) + ts->reply_length; | ||
758 | GNUNET_assert (ret <= size); | ||
759 | hdr.size = htons (ret); | ||
760 | hdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET); | ||
761 | memcpy (&dns, ts->reply, sizeof (dns)); | ||
762 | dns.id = ts->original_id; | ||
763 | off = 0; | ||
764 | memcpy (&cbuf[off], &hdr, sizeof (hdr)); | ||
765 | off += sizeof (hdr); | ||
766 | memcpy (&cbuf[off], &dns, sizeof (dns)); | ||
767 | off += sizeof (dns); | ||
768 | memcpy (&cbuf[off], &ts->reply[sizeof (dns)], ts->reply_length - sizeof (dns)); | ||
769 | off += ts->reply_length - sizeof (dns); | ||
770 | GNUNET_free (ts->reply); | ||
771 | ts->reply = NULL; | ||
772 | ts->reply_length = 0; | ||
773 | GNUNET_assert (ret == off); | ||
774 | return ret; | ||
775 | } | ||
776 | |||
777 | |||
778 | /** | ||
660 | * Read a DNS response from the (unhindered) UDP-Socket | 779 | * Read a DNS response from the (unhindered) UDP-Socket |
661 | * | 780 | * |
662 | * @param cls socket to read from | 781 | * @param cls socket to read from |
@@ -673,6 +792,7 @@ read_response (void *cls, | |||
673 | struct GNUNET_TUN_DnsHeader *dns; | 792 | struct GNUNET_TUN_DnsHeader *dns; |
674 | socklen_t addrlen; | 793 | socklen_t addrlen; |
675 | struct RequestRecord *rr; | 794 | struct RequestRecord *rr; |
795 | struct TunnelState *ts; | ||
676 | ssize_t r; | 796 | ssize_t r; |
677 | int len; | 797 | int len; |
678 | 798 | ||
@@ -728,19 +848,48 @@ read_response (void *cls, | |||
728 | return; | 848 | return; |
729 | } | 849 | } |
730 | dns = (struct GNUNET_TUN_DnsHeader *) buf; | 850 | dns = (struct GNUNET_TUN_DnsHeader *) buf; |
851 | /* Handle case that this is a reply to a request from a MESH DNS tunnel */ | ||
852 | ts = tunnels[dns->id]; | ||
853 | if ( (NULL == ts) || | ||
854 | (addrlen != ts->addrlen) || | ||
855 | (0 != memcmp (&ts->addr, | ||
856 | addr, | ||
857 | addrlen)) ) | ||
858 | ts = NULL; /* DNS responder address missmatch */ | ||
859 | if (NULL != ts) | ||
860 | { | ||
861 | tunnels[dns->id] = NULL; | ||
862 | GNUNET_free_non_null (ts->reply); | ||
863 | ts->reply = GNUNET_malloc (r); | ||
864 | ts->reply_length = r; | ||
865 | memcpy (ts->reply, dns, r); | ||
866 | if (ts->th != NULL) | ||
867 | GNUNET_MESH_notify_transmit_ready_cancel (ts->th); | ||
868 | ts->th = GNUNET_MESH_notify_transmit_ready (ts->tunnel, | ||
869 | GNUNET_NO, 0, | ||
870 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
871 | NULL, | ||
872 | sizeof (struct GNUNET_MessageHeader) + r, | ||
873 | &transmit_reply_to_mesh, | ||
874 | ts); | ||
875 | } | ||
876 | /* Handle case that this is a reply to a local request (intercepted from TUN interface) */ | ||
731 | rr = &requests[dns->id]; | 877 | rr = &requests[dns->id]; |
732 | if (rr->phase != RP_INTERNET_DNS) | 878 | if (rr->phase != RP_INTERNET_DNS) |
733 | { | 879 | { |
734 | /* unexpected / bogus reply */ | 880 | if (NULL == ts) |
735 | GNUNET_STATISTICS_update (stats, | 881 | { |
736 | gettext_noop ("# External DNS response discarded (no matching request)"), | 882 | /* unexpected / bogus reply */ |
737 | 1, GNUNET_NO); | 883 | GNUNET_STATISTICS_update (stats, |
884 | gettext_noop ("# External DNS response discarded (no matching request)"), | ||
885 | 1, GNUNET_NO); | ||
886 | } | ||
738 | return; | 887 | return; |
739 | } | 888 | } |
740 | GNUNET_free_non_null (rr->payload); | 889 | GNUNET_free_non_null (rr->payload); |
741 | rr->payload = GNUNET_malloc (len); | 890 | rr->payload = GNUNET_malloc (r); |
742 | memcpy (rr->payload, buf, len); | 891 | memcpy (rr->payload, buf, r); |
743 | rr->payload_length = len; | 892 | rr->payload_length = r; |
744 | next_phase (rr); | 893 | next_phase (rr); |
745 | } | 894 | } |
746 | } | 895 | } |
@@ -1123,6 +1272,147 @@ process_helper_messages (void *cls GNUNET_UNUSED, void *client, | |||
1123 | 1272 | ||
1124 | 1273 | ||
1125 | /** | 1274 | /** |
1275 | * Process a request via mesh to perform a DNS query. | ||
1276 | * | ||
1277 | * @param cls closure, NULL | ||
1278 | * @param tunnel connection to the other end | ||
1279 | * @param tunnel_ctx pointer to our 'struct TunnelState *' | ||
1280 | * @param sender who sent the message | ||
1281 | * @param message the actual message | ||
1282 | * @param atsi performance data for the connection | ||
1283 | * @return GNUNET_OK to keep the connection open, | ||
1284 | * GNUNET_SYSERR to close it (signal serious error) | ||
1285 | */ | ||
1286 | static int | ||
1287 | receive_dns_request (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | ||
1288 | void **tunnel_ctx, | ||
1289 | const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED, | ||
1290 | const struct GNUNET_MessageHeader *message, | ||
1291 | const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) | ||
1292 | { | ||
1293 | struct TunnelState *ts = *tunnel_ctx; | ||
1294 | const struct GNUNET_TUN_DnsHeader *dns; | ||
1295 | size_t mlen = ntohs (message->size); | ||
1296 | size_t dlen = mlen - sizeof (struct GNUNET_MessageHeader); | ||
1297 | char buf[dlen]; | ||
1298 | struct GNUNET_TUN_DnsHeader *dout; | ||
1299 | struct sockaddr_in v4; | ||
1300 | struct sockaddr_in6 v6; | ||
1301 | struct sockaddr *so; | ||
1302 | socklen_t salen; | ||
1303 | struct GNUNET_NETWORK_Handle *dnsout; | ||
1304 | |||
1305 | if (dlen < sizeof (struct GNUNET_TUN_DnsHeader)) | ||
1306 | { | ||
1307 | GNUNET_break_op (0); | ||
1308 | return GNUNET_SYSERR; | ||
1309 | } | ||
1310 | dns = (const struct GNUNET_TUN_DnsHeader *) &message[1]; | ||
1311 | ts->original_id = dns->id; | ||
1312 | if (tunnels[ts->my_id] == ts) | ||
1313 | tunnels[ts->my_id] = NULL; | ||
1314 | ts->my_id = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, | ||
1315 | 65536); | ||
1316 | tunnels[ts->my_id] = ts; | ||
1317 | memcpy (buf, dns, dlen); | ||
1318 | dout = (struct GNUNET_TUN_DnsHeader*) buf; | ||
1319 | dout->id = ts->my_id; | ||
1320 | |||
1321 | memset (&v4, 0, sizeof (v4)); | ||
1322 | memset (&v6, 0, sizeof (v6)); | ||
1323 | dnsout = NULL; | ||
1324 | if (1 == inet_pton (AF_INET, dns_exit, &v4.sin_addr)) | ||
1325 | { | ||
1326 | salen = sizeof (v4); | ||
1327 | v4.sin_family = AF_INET; | ||
1328 | v4.sin_port = htons (53); | ||
1329 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
1330 | v4.sin_len = (u_char) salen; | ||
1331 | #endif | ||
1332 | so = (struct sockaddr *) &v4; | ||
1333 | dnsout = dnsout4; | ||
1334 | } | ||
1335 | if (1 == inet_pton (AF_INET6, dns_exit, &v6.sin6_addr)) | ||
1336 | { | ||
1337 | salen = sizeof (v6); | ||
1338 | v6.sin6_family = AF_INET6; | ||
1339 | v6.sin6_port = htons (53); | ||
1340 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
1341 | v6.sin6_len = (u_char) salen; | ||
1342 | #endif | ||
1343 | so = (struct sockaddr *) &v6; | ||
1344 | dnsout = dnsout6; | ||
1345 | } | ||
1346 | if (NULL == dnsout) | ||
1347 | { | ||
1348 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1349 | _("Configured DNS exit `%s' is not working / valid.\n"), | ||
1350 | dns_exit); | ||
1351 | return GNUNET_SYSERR; | ||
1352 | } | ||
1353 | memcpy (&ts->addr, | ||
1354 | so, | ||
1355 | salen); | ||
1356 | ts->addrlen = salen; | ||
1357 | GNUNET_NETWORK_socket_sendto (dnsout, | ||
1358 | buf, dlen, so, salen); | ||
1359 | return GNUNET_OK; | ||
1360 | } | ||
1361 | |||
1362 | |||
1363 | /** | ||
1364 | * Callback from GNUNET_MESH for new tunnels. | ||
1365 | * | ||
1366 | * @param cls closure | ||
1367 | * @param tunnel new handle to the tunnel | ||
1368 | * @param initiator peer that started the tunnel | ||
1369 | * @param atsi performance information for the tunnel | ||
1370 | * @return initial tunnel context for the tunnel | ||
1371 | */ | ||
1372 | static void * | ||
1373 | accept_dns_tunnel (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | ||
1374 | const struct GNUNET_PeerIdentity *initiator GNUNET_UNUSED, | ||
1375 | const struct GNUNET_ATS_Information *ats GNUNET_UNUSED) | ||
1376 | { | ||
1377 | struct TunnelState *ts = GNUNET_malloc (sizeof (struct TunnelState)); | ||
1378 | |||
1379 | GNUNET_STATISTICS_update (stats, | ||
1380 | gettext_noop ("# Inbound MESH tunnels created"), | ||
1381 | 1, GNUNET_NO); | ||
1382 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1383 | "Received inbound tunnel from `%s'\n", | ||
1384 | GNUNET_i2s (initiator)); | ||
1385 | ts->tunnel = tunnel; | ||
1386 | return ts; | ||
1387 | } | ||
1388 | |||
1389 | |||
1390 | /** | ||
1391 | * Function called by mesh whenever an inbound tunnel is destroyed. | ||
1392 | * Should clean up any associated state. | ||
1393 | * | ||
1394 | * @param cls closure (set from GNUNET_MESH_connect) | ||
1395 | * @param tunnel connection to the other end (henceforth invalid) | ||
1396 | * @param tunnel_ctx place where local state associated | ||
1397 | * with the tunnel is stored | ||
1398 | */ | ||
1399 | static void | ||
1400 | destroy_dns_tunnel (void *cls GNUNET_UNUSED, | ||
1401 | const struct GNUNET_MESH_Tunnel *tunnel, | ||
1402 | void *tunnel_ctx) | ||
1403 | { | ||
1404 | struct TunnelState *ts = tunnel_ctx; | ||
1405 | |||
1406 | if (tunnels[ts->my_id] == ts) | ||
1407 | tunnels[ts->my_id] = NULL; | ||
1408 | if (NULL != ts->th) | ||
1409 | GNUNET_MESH_notify_transmit_ready_cancel (ts->th); | ||
1410 | GNUNET_free_non_null (ts->reply); | ||
1411 | GNUNET_free (ts); | ||
1412 | } | ||
1413 | |||
1414 | |||
1415 | /** | ||
1126 | * @param cls closure | 1416 | * @param cls closure |
1127 | * @param server the initialized server | 1417 | * @param server the initialized server |
1128 | * @param cfg_ configuration to use | 1418 | * @param cfg_ configuration to use |
@@ -1150,6 +1440,9 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
1150 | nc = GNUNET_SERVER_notification_context_create (server, 1); | 1440 | nc = GNUNET_SERVER_notification_context_create (server, 1); |
1151 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup_task, | 1441 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup_task, |
1152 | cls); | 1442 | cls); |
1443 | (void) GNUNET_CONFIGURATION_get_value_string (cfg, "dns", | ||
1444 | "DNS_EXIT", | ||
1445 | &dns_exit); | ||
1153 | if (GNUNET_YES == | 1446 | if (GNUNET_YES == |
1154 | GNUNET_CONFIGURATION_get_value_yesno (cfg_, "dns", "PROVIDE_EXIT")) | 1447 | GNUNET_CONFIGURATION_get_value_yesno (cfg_, "dns", "PROVIDE_EXIT")) |
1155 | { | 1448 | { |
@@ -1220,6 +1513,24 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
1220 | (unsigned int) dnsoutport); | 1513 | (unsigned int) dnsoutport); |
1221 | helper_argv[6] = GNUNET_strdup (port_s); | 1514 | helper_argv[6] = GNUNET_strdup (port_s); |
1222 | helper_argv[7] = NULL; | 1515 | helper_argv[7] = NULL; |
1516 | |||
1517 | if (NULL != dns_exit) | ||
1518 | { | ||
1519 | static struct GNUNET_MESH_MessageHandler mesh_handlers[] = { | ||
1520 | {&receive_dns_request, GNUNET_MESSAGE_TYPE_VPN_DNS_TO_INTERNET, 0}, | ||
1521 | {NULL, 0, 0} | ||
1522 | }; | ||
1523 | static GNUNET_MESH_ApplicationType mesh_types[] = { | ||
1524 | GNUNET_APPLICATION_TYPE_INTERNET_RESOLVER, | ||
1525 | GNUNET_APPLICATION_TYPE_END | ||
1526 | }; | ||
1527 | mesh = GNUNET_MESH_connect (cfg, | ||
1528 | 1, NULL, | ||
1529 | &accept_dns_tunnel, | ||
1530 | &destroy_dns_tunnel, | ||
1531 | mesh_handlers, | ||
1532 | mesh_types); | ||
1533 | } | ||
1223 | hijacker = GNUNET_HELPER_start ("gnunet-helper-dns", | 1534 | hijacker = GNUNET_HELPER_start ("gnunet-helper-dns", |
1224 | helper_argv, | 1535 | helper_argv, |
1225 | &process_helper_messages, | 1536 | &process_helper_messages, |