aboutsummaryrefslogtreecommitdiff
path: root/src/exit
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-01-25 15:22:18 +0000
committerChristian Grothoff <christian@grothoff.org>2013-01-25 15:22:18 +0000
commit43d558efd13a3245e65efd0acdc9c4ba59cd2bee (patch)
tree469de47f10a4aba6742b360b8622708d60587659 /src/exit
parent07ab625068b62afc532a78534018f6579697a307 (diff)
downloadgnunet-43d558efd13a3245e65efd0acdc9c4ba59cd2bee.tar.gz
gnunet-43d558efd13a3245e65efd0acdc9c4ba59cd2bee.zip
add DNS exit for mesh to gnunet-daemon-exit
Diffstat (limited to 'src/exit')
-rw-r--r--src/exit/Makefile.am1
-rw-r--r--src/exit/exit.conf12
-rw-r--r--src/exit/gnunet-daemon-exit.c704
3 files changed, 538 insertions, 179 deletions
diff --git a/src/exit/Makefile.am b/src/exit/Makefile.am
index 2da59f14a..be3a66a34 100644
--- a/src/exit/Makefile.am
+++ b/src/exit/Makefile.am
@@ -36,6 +36,7 @@ gnunet_helper_exit_SOURCES = \
36gnunet_daemon_exit_SOURCES = \ 36gnunet_daemon_exit_SOURCES = \
37 gnunet-daemon-exit.c exit.h 37 gnunet-daemon-exit.c exit.h
38gnunet_daemon_exit_LDADD = \ 38gnunet_daemon_exit_LDADD = \
39 $(top_builddir)/src/dns/libgnunetdnsstub.la \
39 $(top_builddir)/src/core/libgnunetcore.la \ 40 $(top_builddir)/src/core/libgnunetcore.la \
40 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 41 $(top_builddir)/src/statistics/libgnunetstatistics.la \
41 $(top_builddir)/src/tun/libgnunettun.la \ 42 $(top_builddir)/src/tun/libgnunettun.la \
diff --git a/src/exit/exit.conf b/src/exit/exit.conf
index f8f0764f7..aadcee47f 100644
--- a/src/exit/exit.conf
+++ b/src/exit/exit.conf
@@ -43,6 +43,18 @@ EXIT_IPV4 = NO
43# Set this to YES to allow exiting this system via IPv6 to the Internet 43# Set this to YES to allow exiting this system via IPv6 to the Internet
44EXIT_IPV6 = NO 44EXIT_IPV6 = NO
45 45
46# This option should be set to YES to allow the DNS service to
47# perform lookups against the locally configured DNS resolver.
48# (set to "NO" if no normal ISP is locally available and thus
49# requests for normal ".com"/".org"/etc. must be routed via
50# the GNUnet VPN (the GNUNET PT daemon then needs to be configured
51# to intercept and route DNS queries via mesh).
52# Set this to YES to allow using this system for DNS queries.
53EXIT_DNS = NO
54
55# Set this to an IPv4 or IPv6 address of a DNS resolver to use for DNS queries
56DNS_RESOLVER = 8.8.8.8
57
46# For IPv4-services offered by this peer, we need to at least enable IPv4 58# For IPv4-services offered by this peer, we need to at least enable IPv4
47ENABLE_IPV4 = YES 59ENABLE_IPV4 = YES
48 60
diff --git a/src/exit/gnunet-daemon-exit.c b/src/exit/gnunet-daemon-exit.c
index 5f60ea4cd..92f38665b 100644
--- a/src/exit/gnunet-daemon-exit.c
+++ b/src/exit/gnunet-daemon-exit.c
@@ -39,6 +39,8 @@
39#include "gnunet_protocols.h" 39#include "gnunet_protocols.h"
40#include "gnunet_applications.h" 40#include "gnunet_applications.h"
41#include "gnunet_mesh_service.h" 41#include "gnunet_mesh_service.h"
42#include "gnunet_dnsparser_lib.h"
43#include "gnunet_dnsstub_lib.h"
42#include "gnunet_statistics_service.h" 44#include "gnunet_statistics_service.h"
43#include "gnunet_constants.h" 45#include "gnunet_constants.h"
44#include "gnunet_tun_lib.h" 46#include "gnunet_tun_lib.h"
@@ -59,6 +61,14 @@
59 61
60 62
61/** 63/**
64 * Generic logging shorthand
65 */
66#define LOG(kind, ...) \
67 GNUNET_log_from (kind, "exit", __VA_ARGS__);
68
69
70
71/**
62 * Information about an address. 72 * Information about an address.
63 */ 73 */
64struct SocketAddress 74struct SocketAddress
@@ -196,39 +206,85 @@ struct TunnelState
196 struct GNUNET_MESH_Tunnel *tunnel; 206 struct GNUNET_MESH_Tunnel *tunnel;
197 207
198 /** 208 /**
199 * Heap node for this state in the connections_heap. 209 * Active tunnel transmission request (or NULL).
200 */ 210 */
201 struct GNUNET_CONTAINER_HeapNode *heap_node; 211 struct GNUNET_MESH_TransmitHandle *th;
202 212
203 /** 213 /**
204 * Key this state has in the connections_map. 214 * GNUNET_NO if this is a tunnel for TCP/UDP,
215 * GNUNET_YES if this is a tunnel for DNS,
216 * GNUNET_SYSERR if the tunnel is not yet initialized.
205 */ 217 */
206 struct GNUNET_HashCode state_key; 218 int is_dns;
207 219
208 /** 220 union
209 * Associated service record, or NULL for no service. 221 {
210 */ 222 struct
211 struct LocalService *serv; 223 {
212 224
213 /** 225 /**
214 * Head of DLL of messages for this tunnel. 226 * Heap node for this state in the connections_heap.
215 */ 227 */
216 struct TunnelMessageQueue *head; 228 struct GNUNET_CONTAINER_HeapNode *heap_node;
229
230 /**
231 * Key this state has in the connections_map.
232 */
233 struct GNUNET_HashCode state_key;
234
235 /**
236 * Associated service record, or NULL for no service.
237 */
238 struct LocalService *serv;
239
240 /**
241 * Head of DLL of messages for this tunnel.
242 */
243 struct TunnelMessageQueue *head;
244
245 /**
246 * Tail of DLL of messages for this tunnel.
247 */
248 struct TunnelMessageQueue *tail;
249
250 /**
251 * Primary redirection information for this connection.
252 */
253 struct RedirectInformation ri;
254 } tcp_udp;
217 255
218 /** 256 struct
219 * Tail of DLL of messages for this tunnel. 257 {
220 */
221 struct TunnelMessageQueue *tail;
222 258
223 /** 259 /**
224 * Active tunnel transmission request (or NULL). 260 * DNS reply ready for transmission.
225 */ 261 */
226 struct GNUNET_MESH_TransmitHandle *th; 262 char *reply;
263
264 /**
265 * Socket we are using to transmit this request (must match if we receive
266 * a response).
267 */
268 struct GNUNET_DNSSTUB_RequestSocket *rs;
269
270 /**
271 * Number of bytes in 'reply'.
272 */
273 size_t reply_length;
274
275 /**
276 * Original DNS request ID as used by the client.
277 */
278 uint16_t original_id;
279
280 /**
281 * DNS request ID that we used for forwarding.
282 */
283 uint16_t my_id;
284
285 } dns;
227 286
228 /** 287 } specifics;
229 * Primary redirection information for this connection.
230 */
231 struct RedirectInformation ri;
232 288
233}; 289};
234 290
@@ -273,7 +329,6 @@ static struct in_addr exit_ipv4addr;
273 */ 329 */
274static struct in_addr exit_ipv4mask; 330static struct in_addr exit_ipv4mask;
275 331
276
277/** 332/**
278 * Statistics. 333 * Statistics.
279 */ 334 */
@@ -311,6 +366,16 @@ static struct GNUNET_CONTAINER_MultiHashMap *udp_services;
311static struct GNUNET_CONTAINER_MultiHashMap *tcp_services; 366static struct GNUNET_CONTAINER_MultiHashMap *tcp_services;
312 367
313/** 368/**
369 * Array of all open DNS requests from tunnels.
370 */
371static struct TunnelState *tunnels[UINT16_MAX + 1];
372
373/**
374 * Handle to the DNS Stub resolver.
375 */
376static struct GNUNET_DNSSTUB_Context *dnsstub;
377
378/**
314 * Are we an IPv4-exit? 379 * Are we an IPv4-exit?
315 */ 380 */
316static int ipv4_exit; 381static int ipv4_exit;
@@ -332,6 +397,160 @@ static int ipv6_enabled;
332 397
333 398
334/** 399/**
400 * We got a reply from DNS for a request of a MESH tunnel. Send it
401 * via the tunnel (after changing the request ID back).
402 *
403 * @param cls the 'struct TunnelState'
404 * @param size number of bytes available in buf
405 * @param buf where to copy the reply
406 * @return number of bytes written to buf
407 */
408static size_t
409transmit_reply_to_mesh (void *cls,
410 size_t size,
411 void *buf)
412{
413 struct TunnelState *ts = cls;
414 size_t off;
415 size_t ret;
416 char *cbuf = buf;
417 struct GNUNET_MessageHeader hdr;
418 struct GNUNET_TUN_DnsHeader dns;
419
420 GNUNET_assert (GNUNET_YES == ts->is_dns);
421 ts->th = NULL;
422 GNUNET_assert (ts->specifics.dns.reply != NULL);
423 if (size == 0)
424 return 0;
425 ret = sizeof (struct GNUNET_MessageHeader) + ts->specifics.dns.reply_length;
426 GNUNET_assert (ret <= size);
427 hdr.size = htons (ret);
428 hdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET);
429 memcpy (&dns, ts->specifics.dns.reply, sizeof (dns));
430 dns.id = ts->specifics.dns.original_id;
431 off = 0;
432 memcpy (&cbuf[off], &hdr, sizeof (hdr));
433 off += sizeof (hdr);
434 memcpy (&cbuf[off], &dns, sizeof (dns));
435 off += sizeof (dns);
436 memcpy (&cbuf[off], &ts->specifics.dns.reply[sizeof (dns)], ts->specifics.dns.reply_length - sizeof (dns));
437 off += ts->specifics.dns.reply_length - sizeof (dns);
438 GNUNET_free (ts->specifics.dns.reply);
439 ts->specifics.dns.reply = NULL;
440 ts->specifics.dns.reply_length = 0;
441 GNUNET_assert (ret == off);
442 return ret;
443}
444
445
446/**
447 * Callback called from DNSSTUB resolver when a resolution
448 * succeeded.
449 *
450 * @param cls NULL
451 * @param rs the socket that received the response
452 * @param dns the response itself
453 * @param r number of bytes in dns
454 */
455static void
456process_dns_result (void *cls,
457 struct GNUNET_DNSSTUB_RequestSocket *rs,
458 const struct GNUNET_TUN_DnsHeader *dns,
459 size_t r)
460{
461 struct TunnelState *ts;
462
463 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
464 "Processing DNS result from stub resolver\n");
465 GNUNET_assert (NULL == cls);
466 /* Handle case that this is a reply to a request from a MESH DNS tunnel */
467 ts = tunnels[dns->id];
468 if ( (NULL == ts) ||
469 (ts->specifics.dns.rs != rs) )
470 return;
471 LOG (GNUNET_ERROR_TYPE_DEBUG,
472 "Got a response from the stub resolver for DNS request received via MESH!\n");
473 tunnels[dns->id] = NULL;
474 GNUNET_free_non_null (ts->specifics.dns.reply);
475 ts->specifics.dns.reply = GNUNET_malloc (r);
476 ts->specifics.dns.reply_length = r;
477 memcpy (ts->specifics.dns.reply, dns, r);
478 if (NULL != ts->th)
479 GNUNET_MESH_notify_transmit_ready_cancel (ts->th);
480 ts->th = GNUNET_MESH_notify_transmit_ready (ts->tunnel,
481 GNUNET_NO,
482 GNUNET_TIME_UNIT_FOREVER_REL,
483 NULL,
484 sizeof (struct GNUNET_MessageHeader) + r,
485 &transmit_reply_to_mesh,
486 ts);
487}
488
489
490/**
491 * Process a request via mesh to perform a DNS query.
492 *
493 * @param cls closure, NULL
494 * @param tunnel connection to the other end
495 * @param tunnel_ctx pointer to our 'struct TunnelState *'
496 * @param sender who sent the message
497 * @param message the actual message
498 * @param atsi performance data for the connection
499 * @return GNUNET_OK to keep the connection open,
500 * GNUNET_SYSERR to close it (signal serious error)
501 */
502static int
503receive_dns_request (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
504 void **tunnel_ctx,
505 const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
506 const struct GNUNET_MessageHeader *message,
507 const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
508{
509 struct TunnelState *ts = *tunnel_ctx;
510 const struct GNUNET_TUN_DnsHeader *dns;
511 size_t mlen = ntohs (message->size);
512 size_t dlen = mlen - sizeof (struct GNUNET_MessageHeader);
513 char buf[dlen] GNUNET_ALIGN;
514 struct GNUNET_TUN_DnsHeader *dout;
515
516 if (NULL == dnsstub)
517 return GNUNET_SYSERR;
518 if (GNUNET_NO == ts->is_dns)
519 {
520 GNUNET_break_op (0);
521 return GNUNET_SYSERR;
522 }
523 if (GNUNET_SYSERR == ts->is_dns)
524 {
525 /* tunnel is DNS from now on */
526 ts->is_dns = GNUNET_YES;
527 }
528 if (dlen < sizeof (struct GNUNET_TUN_DnsHeader))
529 {
530 GNUNET_break_op (0);
531 return GNUNET_SYSERR;
532 }
533 dns = (const struct GNUNET_TUN_DnsHeader *) &message[1];
534 ts->specifics.dns.original_id = dns->id;
535 if (tunnels[ts->specifics.dns.my_id] == ts)
536 tunnels[ts->specifics.dns.my_id] = NULL;
537 ts->specifics.dns.my_id = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
538 UINT16_MAX + 1);
539 tunnels[ts->specifics.dns.my_id] = ts;
540 memcpy (buf, dns, dlen);
541 dout = (struct GNUNET_TUN_DnsHeader *) buf;
542 dout->id = ts->specifics.dns.my_id;
543 ts->specifics.dns.rs = GNUNET_DNSSTUB_resolve2 (dnsstub,
544 buf, dlen,
545 &process_dns_result,
546 NULL);
547 if (NULL == ts->specifics.dns.rs)
548 return GNUNET_SYSERR;
549 return GNUNET_OK;
550}
551
552
553/**
335 * Given IP information about a connection, calculate the respective 554 * Given IP information about a connection, calculate the respective
336 * hash we would use for the 'connections_map'. 555 * hash we would use for the 'connections_map'.
337 * 556 *
@@ -439,7 +658,7 @@ get_redirect_state (int af,
439 /* Mark this connection as freshly used */ 658 /* Mark this connection as freshly used */
440 if (NULL == state_key) 659 if (NULL == state_key)
441 GNUNET_CONTAINER_heap_update_cost (connections_heap, 660 GNUNET_CONTAINER_heap_update_cost (connections_heap,
442 state->heap_node, 661 state->specifics.tcp_udp.heap_node,
443 GNUNET_TIME_absolute_get ().abs_value); 662 GNUNET_TIME_absolute_get ().abs_value);
444 return state; 663 return state;
445} 664}
@@ -542,7 +761,7 @@ send_to_peer_notify_callback (void *cls, size_t size, void *buf)
542 struct TunnelMessageQueue *tnq; 761 struct TunnelMessageQueue *tnq;
543 762
544 s->th = NULL; 763 s->th = NULL;
545 tnq = s->head; 764 tnq = s->specifics.tcp_udp.head;
546 if (NULL == tnq) 765 if (NULL == tnq)
547 return 0; 766 return 0;
548 if (0 == size) 767 if (0 == size)
@@ -559,11 +778,11 @@ send_to_peer_notify_callback (void *cls, size_t size, void *buf)
559 GNUNET_assert (size >= tnq->len); 778 GNUNET_assert (size >= tnq->len);
560 memcpy (buf, tnq->payload, tnq->len); 779 memcpy (buf, tnq->payload, tnq->len);
561 size = tnq->len; 780 size = tnq->len;
562 GNUNET_CONTAINER_DLL_remove (s->head, 781 GNUNET_CONTAINER_DLL_remove (s->specifics.tcp_udp.head,
563 s->tail, 782 s->specifics.tcp_udp.tail,
564 tnq); 783 tnq);
565 GNUNET_free (tnq); 784 GNUNET_free (tnq);
566 if (NULL != (tnq = s->head)) 785 if (NULL != (tnq = s->specifics.tcp_udp.head))
567 s->th = GNUNET_MESH_notify_transmit_ready (tunnel, 786 s->th = GNUNET_MESH_notify_transmit_ready (tunnel,
568 GNUNET_NO /* corking */, 787 GNUNET_NO /* corking */,
569 GNUNET_TIME_UNIT_FOREVER_REL, 788 GNUNET_TIME_UNIT_FOREVER_REL,
@@ -592,7 +811,7 @@ send_packet_to_mesh_tunnel (struct GNUNET_MESH_Tunnel *mesh_tunnel,
592 811
593 s = GNUNET_MESH_tunnel_get_data (mesh_tunnel); 812 s = GNUNET_MESH_tunnel_get_data (mesh_tunnel);
594 GNUNET_assert (NULL != s); 813 GNUNET_assert (NULL != s);
595 GNUNET_CONTAINER_DLL_insert_tail (s->head, s->tail, tnq); 814 GNUNET_CONTAINER_DLL_insert_tail (s->specifics.tcp_udp.head, s->specifics.tcp_udp.tail, tnq);
596 if (NULL == s->th) 815 if (NULL == s->th)
597 s->th = GNUNET_MESH_notify_transmit_ready (mesh_tunnel, 816 s->th = GNUNET_MESH_notify_transmit_ready (mesh_tunnel,
598 GNUNET_NO /* cork */, 817 GNUNET_NO /* cork */,
@@ -1220,7 +1439,7 @@ setup_fresh_address (int af,
1220 * cleaning up 'old' states. 1439 * cleaning up 'old' states.
1221 * 1440 *
1222 * @param state skeleton state to setup a record for; should 1441 * @param state skeleton state to setup a record for; should
1223 * 'state->ri.remote_address' filled in so that 1442 * 'state->specifics.tcp_udp.ri.remote_address' filled in so that
1224 * this code can determine which AF/protocol is 1443 * this code can determine which AF/protocol is
1225 * going to be used (the 'tunnel' should also 1444 * going to be used (the 'tunnel' should also
1226 * already be set); after calling this function, 1445 * already be set); after calling this function,
@@ -1237,47 +1456,47 @@ setup_state_record (struct TunnelState *state)
1237 /* generate fresh, unique address */ 1456 /* generate fresh, unique address */
1238 do 1457 do
1239 { 1458 {
1240 if (NULL == state->serv) 1459 if (NULL == state->specifics.tcp_udp.serv)
1241 setup_fresh_address (state->ri.remote_address.af, 1460 setup_fresh_address (state->specifics.tcp_udp.ri.remote_address.af,
1242 state->ri.remote_address.proto, 1461 state->specifics.tcp_udp.ri.remote_address.proto,
1243 &state->ri.local_address); 1462 &state->specifics.tcp_udp.ri.local_address);
1244 else 1463 else
1245 setup_fresh_address (state->serv->address.af, 1464 setup_fresh_address (state->specifics.tcp_udp.serv->address.af,
1246 state->serv->address.proto, 1465 state->specifics.tcp_udp.serv->address.proto,
1247 &state->ri.local_address); 1466 &state->specifics.tcp_udp.ri.local_address);
1248 } while (NULL != get_redirect_state (state->ri.remote_address.af, 1467 } while (NULL != get_redirect_state (state->specifics.tcp_udp.ri.remote_address.af,
1249 state->ri.remote_address.proto, 1468 state->specifics.tcp_udp.ri.remote_address.proto,
1250 &state->ri.remote_address.address, 1469 &state->specifics.tcp_udp.ri.remote_address.address,
1251 state->ri.remote_address.port, 1470 state->specifics.tcp_udp.ri.remote_address.port,
1252 &state->ri.local_address.address, 1471 &state->specifics.tcp_udp.ri.local_address.address,
1253 state->ri.local_address.port, 1472 state->specifics.tcp_udp.ri.local_address.port,
1254 &key)); 1473 &key));
1255 { 1474 {
1256 char buf[INET6_ADDRSTRLEN]; 1475 char buf[INET6_ADDRSTRLEN];
1257 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1476 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1258 "Picked local address %s:%u for new connection\n", 1477 "Picked local address %s:%u for new connection\n",
1259 inet_ntop (state->ri.local_address.af, 1478 inet_ntop (state->specifics.tcp_udp.ri.local_address.af,
1260 &state->ri.local_address.address, 1479 &state->specifics.tcp_udp.ri.local_address.address,
1261 buf, sizeof (buf)), 1480 buf, sizeof (buf)),
1262 (unsigned int) state->ri.local_address.port); 1481 (unsigned int) state->specifics.tcp_udp.ri.local_address.port);
1263 } 1482 }
1264 state->state_key = key; 1483 state->specifics.tcp_udp.state_key = key;
1265 GNUNET_assert (GNUNET_OK == 1484 GNUNET_assert (GNUNET_OK ==
1266 GNUNET_CONTAINER_multihashmap_put (connections_map, 1485 GNUNET_CONTAINER_multihashmap_put (connections_map,
1267 &key, state, 1486 &key, state,
1268 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 1487 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1269 state->heap_node = GNUNET_CONTAINER_heap_insert (connections_heap, 1488 state->specifics.tcp_udp.heap_node = GNUNET_CONTAINER_heap_insert (connections_heap,
1270 state, 1489 state,
1271 GNUNET_TIME_absolute_get ().abs_value); 1490 GNUNET_TIME_absolute_get ().abs_value);
1272 while (GNUNET_CONTAINER_heap_get_size (connections_heap) > max_connections) 1491 while (GNUNET_CONTAINER_heap_get_size (connections_heap) > max_connections)
1273 { 1492 {
1274 s = GNUNET_CONTAINER_heap_remove_root (connections_heap); 1493 s = GNUNET_CONTAINER_heap_remove_root (connections_heap);
1275 GNUNET_assert (state != s); 1494 GNUNET_assert (state != s);
1276 s->heap_node = NULL; 1495 s->specifics.tcp_udp.heap_node = NULL;
1277 GNUNET_MESH_tunnel_destroy (s->tunnel); 1496 GNUNET_MESH_tunnel_destroy (s->tunnel);
1278 GNUNET_assert (GNUNET_OK == 1497 GNUNET_assert (GNUNET_OK ==
1279 GNUNET_CONTAINER_multihashmap_remove (connections_map, 1498 GNUNET_CONTAINER_multihashmap_remove (connections_map,
1280 &s->state_key, 1499 &s->specifics.tcp_udp.state_key,
1281 s)); 1500 s));
1282 GNUNET_free (s); 1501 GNUNET_free (s);
1283 } 1502 }
@@ -1548,10 +1767,11 @@ send_tcp_packet_via_tun (const struct SocketAddress *destination_address,
1548 GNUNET_assert (0); 1767 GNUNET_assert (0);
1549 break; 1768 break;
1550 } 1769 }
1551 (void) GNUNET_HELPER_send (helper_handle, 1770 if (NULL != helper_handle)
1552 (const struct GNUNET_MessageHeader*) buf, 1771 (void) GNUNET_HELPER_send (helper_handle,
1553 GNUNET_YES, 1772 (const struct GNUNET_MessageHeader*) buf,
1554 NULL, NULL); 1773 GNUNET_YES,
1774 NULL, NULL);
1555 } 1775 }
1556} 1776}
1557 1777
@@ -1580,6 +1800,16 @@ receive_tcp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1580 const struct GNUNET_EXIT_TcpServiceStartMessage *start; 1800 const struct GNUNET_EXIT_TcpServiceStartMessage *start;
1581 uint16_t pkt_len = ntohs (message->size); 1801 uint16_t pkt_len = ntohs (message->size);
1582 1802
1803 if (GNUNET_YES == state->is_dns)
1804 {
1805 GNUNET_break_op (0);
1806 return GNUNET_SYSERR;
1807 }
1808 if (GNUNET_SYSERR == state->is_dns)
1809 {
1810 /* tunnel is UDP/TCP from now on */
1811 state->is_dns = GNUNET_NO;
1812 }
1583 GNUNET_STATISTICS_update (stats, 1813 GNUNET_STATISTICS_update (stats,
1584 gettext_noop ("# TCP service creation requests received via mesh"), 1814 gettext_noop ("# TCP service creation requests received via mesh"),
1585 1, GNUNET_NO); 1815 1, GNUNET_NO);
@@ -1595,8 +1825,8 @@ receive_tcp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1595 start = (const struct GNUNET_EXIT_TcpServiceStartMessage*) message; 1825 start = (const struct GNUNET_EXIT_TcpServiceStartMessage*) message;
1596 pkt_len -= sizeof (struct GNUNET_EXIT_TcpServiceStartMessage); 1826 pkt_len -= sizeof (struct GNUNET_EXIT_TcpServiceStartMessage);
1597 if ( (NULL == state) || 1827 if ( (NULL == state) ||
1598 (NULL != state->serv) || 1828 (NULL != state->specifics.tcp_udp.serv) ||
1599 (NULL != state->heap_node) ) 1829 (NULL != state->specifics.tcp_udp.heap_node) )
1600 { 1830 {
1601 GNUNET_break_op (0); 1831 GNUNET_break_op (0);
1602 return GNUNET_SYSERR; 1832 return GNUNET_SYSERR;
@@ -1613,8 +1843,8 @@ receive_tcp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1613 GNUNET_i2s (sender), 1843 GNUNET_i2s (sender),
1614 GNUNET_h2s (&start->service_descriptor), 1844 GNUNET_h2s (&start->service_descriptor),
1615 (unsigned int) ntohs (start->tcp_header.destination_port)); 1845 (unsigned int) ntohs (start->tcp_header.destination_port));
1616 if (NULL == (state->serv = find_service (tcp_services, &start->service_descriptor, 1846 if (NULL == (state->specifics.tcp_udp.serv = find_service (tcp_services, &start->service_descriptor,
1617 ntohs (start->tcp_header.destination_port)))) 1847 ntohs (start->tcp_header.destination_port))))
1618 { 1848 {
1619 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1849 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1620 _("No service found for %s on port %d!\n"), 1850 _("No service found for %s on port %d!\n"),
@@ -1625,10 +1855,10 @@ receive_tcp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1625 1, GNUNET_NO); 1855 1, GNUNET_NO);
1626 return GNUNET_SYSERR; 1856 return GNUNET_SYSERR;
1627 } 1857 }
1628 state->ri.remote_address = state->serv->address; 1858 state->specifics.tcp_udp.ri.remote_address = state->specifics.tcp_udp.serv->address;
1629 setup_state_record (state); 1859 setup_state_record (state);
1630 send_tcp_packet_via_tun (&state->ri.remote_address, 1860 send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1631 &state->ri.local_address, 1861 &state->specifics.tcp_udp.ri.local_address,
1632 &start->tcp_header, 1862 &start->tcp_header,
1633 &start[1], pkt_len); 1863 &start[1], pkt_len);
1634 return GNUNET_YES; 1864 return GNUNET_YES;
@@ -1662,6 +1892,16 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1662 const void *payload; 1892 const void *payload;
1663 int af; 1893 int af;
1664 1894
1895 if (GNUNET_YES == state->is_dns)
1896 {
1897 GNUNET_break_op (0);
1898 return GNUNET_SYSERR;
1899 }
1900 if (GNUNET_SYSERR == state->is_dns)
1901 {
1902 /* tunnel is UDP/TCP from now on */
1903 state->is_dns = GNUNET_NO;
1904 }
1665 GNUNET_STATISTICS_update (stats, 1905 GNUNET_STATISTICS_update (stats,
1666 gettext_noop ("# Bytes received from MESH"), 1906 gettext_noop ("# Bytes received from MESH"),
1667 pkt_len, GNUNET_NO); 1907 pkt_len, GNUNET_NO);
@@ -1676,8 +1916,8 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1676 start = (const struct GNUNET_EXIT_TcpInternetStartMessage*) message; 1916 start = (const struct GNUNET_EXIT_TcpInternetStartMessage*) message;
1677 pkt_len -= sizeof (struct GNUNET_EXIT_TcpInternetStartMessage); 1917 pkt_len -= sizeof (struct GNUNET_EXIT_TcpInternetStartMessage);
1678 if ( (NULL == state) || 1918 if ( (NULL == state) ||
1679 (NULL != state->serv) || 1919 (NULL != state->specifics.tcp_udp.serv) ||
1680 (NULL != state->heap_node) ) 1920 (NULL != state->specifics.tcp_udp.heap_node) )
1681 { 1921 {
1682 GNUNET_break_op (0); 1922 GNUNET_break_op (0);
1683 return GNUNET_SYSERR; 1923 return GNUNET_SYSERR;
@@ -1688,7 +1928,7 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1688 return GNUNET_SYSERR; 1928 return GNUNET_SYSERR;
1689 } 1929 }
1690 af = (int) ntohl (start->af); 1930 af = (int) ntohl (start->af);
1691 state->ri.remote_address.af = af; 1931 state->specifics.tcp_udp.ri.remote_address.af = af;
1692 switch (af) 1932 switch (af)
1693 { 1933 {
1694 case AF_INET: 1934 case AF_INET:
@@ -1705,7 +1945,7 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1705 v4 = (const struct in_addr*) &start[1]; 1945 v4 = (const struct in_addr*) &start[1];
1706 payload = &v4[1]; 1946 payload = &v4[1];
1707 pkt_len -= sizeof (struct in_addr); 1947 pkt_len -= sizeof (struct in_addr);
1708 state->ri.remote_address.address.ipv4 = *v4; 1948 state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
1709 break; 1949 break;
1710 case AF_INET6: 1950 case AF_INET6:
1711 if (pkt_len < sizeof (struct in6_addr)) 1951 if (pkt_len < sizeof (struct in6_addr))
@@ -1721,7 +1961,7 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1721 v6 = (const struct in6_addr*) &start[1]; 1961 v6 = (const struct in6_addr*) &start[1];
1722 payload = &v6[1]; 1962 payload = &v6[1];
1723 pkt_len -= sizeof (struct in6_addr); 1963 pkt_len -= sizeof (struct in6_addr);
1724 state->ri.remote_address.address.ipv6 = *v6; 1964 state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
1725 break; 1965 break;
1726 default: 1966 default:
1727 GNUNET_break_op (0); 1967 GNUNET_break_op (0);
@@ -1733,15 +1973,15 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1733 "Received data from %s for starting TCP stream to %s:%u\n", 1973 "Received data from %s for starting TCP stream to %s:%u\n",
1734 GNUNET_i2s (sender), 1974 GNUNET_i2s (sender),
1735 inet_ntop (af, 1975 inet_ntop (af,
1736 &state->ri.remote_address.address, 1976 &state->specifics.tcp_udp.ri.remote_address.address,
1737 buf, sizeof (buf)), 1977 buf, sizeof (buf)),
1738 (unsigned int) ntohs (start->tcp_header.destination_port)); 1978 (unsigned int) ntohs (start->tcp_header.destination_port));
1739 } 1979 }
1740 state->ri.remote_address.proto = IPPROTO_TCP; 1980 state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_TCP;
1741 state->ri.remote_address.port = ntohs (start->tcp_header.destination_port); 1981 state->specifics.tcp_udp.ri.remote_address.port = ntohs (start->tcp_header.destination_port);
1742 setup_state_record (state); 1982 setup_state_record (state);
1743 send_tcp_packet_via_tun (&state->ri.remote_address, 1983 send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1744 &state->ri.local_address, 1984 &state->specifics.tcp_udp.ri.local_address,
1745 &start->tcp_header, 1985 &start->tcp_header,
1746 payload, pkt_len); 1986 payload, pkt_len);
1747 return GNUNET_YES; 1987 return GNUNET_YES;
@@ -1772,6 +2012,16 @@ receive_tcp_data (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1772 const struct GNUNET_EXIT_TcpDataMessage *data; 2012 const struct GNUNET_EXIT_TcpDataMessage *data;
1773 uint16_t pkt_len = ntohs (message->size); 2013 uint16_t pkt_len = ntohs (message->size);
1774 2014
2015 if (GNUNET_YES == state->is_dns)
2016 {
2017 GNUNET_break_op (0);
2018 return GNUNET_SYSERR;
2019 }
2020 if (GNUNET_SYSERR == state->is_dns)
2021 {
2022 /* tunnel is UDP/TCP from now on */
2023 state->is_dns = GNUNET_NO;
2024 }
1775 GNUNET_STATISTICS_update (stats, 2025 GNUNET_STATISTICS_update (stats,
1776 gettext_noop ("# Bytes received from MESH"), 2026 gettext_noop ("# Bytes received from MESH"),
1777 pkt_len, GNUNET_NO); 2027 pkt_len, GNUNET_NO);
@@ -1786,7 +2036,7 @@ receive_tcp_data (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1786 data = (const struct GNUNET_EXIT_TcpDataMessage*) message; 2036 data = (const struct GNUNET_EXIT_TcpDataMessage*) message;
1787 pkt_len -= sizeof (struct GNUNET_EXIT_TcpDataMessage); 2037 pkt_len -= sizeof (struct GNUNET_EXIT_TcpDataMessage);
1788 if ( (NULL == state) || 2038 if ( (NULL == state) ||
1789 (NULL == state->heap_node) ) 2039 (NULL == state->specifics.tcp_udp.heap_node) )
1790 { 2040 {
1791 /* connection should have been up! */ 2041 /* connection should have been up! */
1792 GNUNET_STATISTICS_update (stats, 2042 GNUNET_STATISTICS_update (stats,
@@ -1807,14 +2057,14 @@ receive_tcp_data (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
1807 "Received additional %u bytes of data from %s for TCP stream to %s:%u\n", 2057 "Received additional %u bytes of data from %s for TCP stream to %s:%u\n",
1808 pkt_len, 2058 pkt_len,
1809 GNUNET_i2s (sender), 2059 GNUNET_i2s (sender),
1810 inet_ntop (state->ri.remote_address.af, 2060 inet_ntop (state->specifics.tcp_udp.ri.remote_address.af,
1811 &state->ri.remote_address.address, 2061 &state->specifics.tcp_udp.ri.remote_address.address,
1812 buf, sizeof (buf)), 2062 buf, sizeof (buf)),
1813 (unsigned int) state->ri.remote_address.port); 2063 (unsigned int) state->specifics.tcp_udp.ri.remote_address.port);
1814 } 2064 }
1815 2065
1816 send_tcp_packet_via_tun (&state->ri.remote_address, 2066 send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1817 &state->ri.local_address, 2067 &state->specifics.tcp_udp.ri.local_address,
1818 &data->tcp_header, 2068 &data->tcp_header,
1819 &data[1], pkt_len); 2069 &data[1], pkt_len);
1820 return GNUNET_YES; 2070 return GNUNET_YES;
@@ -1914,10 +2164,11 @@ send_icmp_packet_via_tun (const struct SocketAddress *destination_address,
1914 GNUNET_TUN_calculate_icmp_checksum (icmp, 2164 GNUNET_TUN_calculate_icmp_checksum (icmp,
1915 payload, 2165 payload,
1916 payload_length); 2166 payload_length);
1917 (void) GNUNET_HELPER_send (helper_handle, 2167 if (NULL != helper_handle)
1918 (const struct GNUNET_MessageHeader*) buf, 2168 (void) GNUNET_HELPER_send (helper_handle,
1919 GNUNET_YES, 2169 (const struct GNUNET_MessageHeader*) buf,
1920 NULL, NULL); 2170 GNUNET_YES,
2171 NULL, NULL);
1921 } 2172 }
1922} 2173}
1923 2174
@@ -1937,12 +2188,12 @@ make_up_icmpv4_payload (struct TunnelState *state,
1937 struct GNUNET_TUN_UdpHeader *udp) 2188 struct GNUNET_TUN_UdpHeader *udp)
1938{ 2189{
1939 GNUNET_TUN_initialize_ipv4_header (ipp, 2190 GNUNET_TUN_initialize_ipv4_header (ipp,
1940 state->ri.remote_address.proto, 2191 state->specifics.tcp_udp.ri.remote_address.proto,
1941 sizeof (struct GNUNET_TUN_TcpHeader), 2192 sizeof (struct GNUNET_TUN_TcpHeader),
1942 &state->ri.remote_address.address.ipv4, 2193 &state->specifics.tcp_udp.ri.remote_address.address.ipv4,
1943 &state->ri.local_address.address.ipv4); 2194 &state->specifics.tcp_udp.ri.local_address.address.ipv4);
1944 udp->source_port = htons (state->ri.remote_address.port); 2195 udp->source_port = htons (state->specifics.tcp_udp.ri.remote_address.port);
1945 udp->destination_port = htons (state->ri.local_address.port); 2196 udp->destination_port = htons (state->specifics.tcp_udp.ri.local_address.port);
1946 udp->len = htons (0); 2197 udp->len = htons (0);
1947 udp->crc = htons (0); 2198 udp->crc = htons (0);
1948} 2199}
@@ -1963,12 +2214,12 @@ make_up_icmpv6_payload (struct TunnelState *state,
1963 struct GNUNET_TUN_UdpHeader *udp) 2214 struct GNUNET_TUN_UdpHeader *udp)
1964{ 2215{
1965 GNUNET_TUN_initialize_ipv6_header (ipp, 2216 GNUNET_TUN_initialize_ipv6_header (ipp,
1966 state->ri.remote_address.proto, 2217 state->specifics.tcp_udp.ri.remote_address.proto,
1967 sizeof (struct GNUNET_TUN_TcpHeader), 2218 sizeof (struct GNUNET_TUN_TcpHeader),
1968 &state->ri.remote_address.address.ipv6, 2219 &state->specifics.tcp_udp.ri.remote_address.address.ipv6,
1969 &state->ri.local_address.address.ipv6); 2220 &state->specifics.tcp_udp.ri.local_address.address.ipv6);
1970 udp->source_port = htons (state->ri.remote_address.port); 2221 udp->source_port = htons (state->specifics.tcp_udp.ri.remote_address.port);
1971 udp->destination_port = htons (state->ri.local_address.port); 2222 udp->destination_port = htons (state->specifics.tcp_udp.ri.local_address.port);
1972 udp->len = htons (0); 2223 udp->len = htons (0);
1973 udp->crc = htons (0); 2224 udp->crc = htons (0);
1974} 2225}
@@ -2002,6 +2253,16 @@ receive_icmp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
2002 char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN; 2253 char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
2003 int af; 2254 int af;
2004 2255
2256 if (GNUNET_YES == state->is_dns)
2257 {
2258 GNUNET_break_op (0);
2259 return GNUNET_SYSERR;
2260 }
2261 if (GNUNET_SYSERR == state->is_dns)
2262 {
2263 /* tunnel is UDP/TCP from now on */
2264 state->is_dns = GNUNET_NO;
2265 }
2005 GNUNET_STATISTICS_update (stats, 2266 GNUNET_STATISTICS_update (stats,
2006 gettext_noop ("# Bytes received from MESH"), 2267 gettext_noop ("# Bytes received from MESH"),
2007 pkt_len, GNUNET_NO); 2268 pkt_len, GNUNET_NO);
@@ -2017,8 +2278,8 @@ receive_icmp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
2017 pkt_len -= sizeof (struct GNUNET_EXIT_IcmpInternetMessage); 2278 pkt_len -= sizeof (struct GNUNET_EXIT_IcmpInternetMessage);
2018 2279
2019 af = (int) ntohl (msg->af); 2280 af = (int) ntohl (msg->af);
2020 if ( (NULL != state->heap_node) && 2281 if ( (NULL != state->specifics.tcp_udp.heap_node) &&
2021 (af != state->ri.remote_address.af) ) 2282 (af != state->specifics.tcp_udp.ri.remote_address.af) )
2022 { 2283 {
2023 /* other peer switched AF on this tunnel; not allowed */ 2284 /* other peer switched AF on this tunnel; not allowed */
2024 GNUNET_break_op (0); 2285 GNUNET_break_op (0);
@@ -2041,11 +2302,11 @@ receive_icmp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
2041 v4 = (const struct in_addr*) &msg[1]; 2302 v4 = (const struct in_addr*) &msg[1];
2042 payload = &v4[1]; 2303 payload = &v4[1];
2043 pkt_len -= sizeof (struct in_addr); 2304 pkt_len -= sizeof (struct in_addr);
2044 state->ri.remote_address.address.ipv4 = *v4; 2305 state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
2045 if (NULL == state->heap_node) 2306 if (NULL == state->specifics.tcp_udp.heap_node)
2046 { 2307 {
2047 state->ri.remote_address.af = af; 2308 state->specifics.tcp_udp.ri.remote_address.af = af;
2048 state->ri.remote_address.proto = IPPROTO_ICMP; 2309 state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMP;
2049 setup_state_record (state); 2310 setup_state_record (state);
2050 } 2311 }
2051 /* check that ICMP type is something we want to support 2312 /* check that ICMP type is something we want to support
@@ -2099,11 +2360,11 @@ receive_icmp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
2099 v6 = (const struct in6_addr*) &msg[1]; 2360 v6 = (const struct in6_addr*) &msg[1];
2100 payload = &v6[1]; 2361 payload = &v6[1];
2101 pkt_len -= sizeof (struct in6_addr); 2362 pkt_len -= sizeof (struct in6_addr);
2102 state->ri.remote_address.address.ipv6 = *v6; 2363 state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
2103 if (NULL == state->heap_node) 2364 if (NULL == state->specifics.tcp_udp.heap_node)
2104 { 2365 {
2105 state->ri.remote_address.af = af; 2366 state->specifics.tcp_udp.ri.remote_address.af = af;
2106 state->ri.remote_address.proto = IPPROTO_ICMPV6; 2367 state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMPV6;
2107 setup_state_record (state); 2368 setup_state_record (state);
2108 } 2369 }
2109 /* check that ICMP type is something we want to support 2370 /* check that ICMP type is something we want to support
@@ -2156,11 +2417,11 @@ receive_icmp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
2156 "Received ICMP data from %s for forwarding to %s\n", 2417 "Received ICMP data from %s for forwarding to %s\n",
2157 GNUNET_i2s (sender), 2418 GNUNET_i2s (sender),
2158 inet_ntop (af, 2419 inet_ntop (af,
2159 &state->ri.remote_address.address, 2420 &state->specifics.tcp_udp.ri.remote_address.address,
2160 buf, sizeof (buf))); 2421 buf, sizeof (buf)));
2161 } 2422 }
2162 send_icmp_packet_via_tun (&state->ri.remote_address, 2423 send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2163 &state->ri.local_address, 2424 &state->specifics.tcp_udp.ri.local_address,
2164 &msg->icmp_header, 2425 &msg->icmp_header,
2165 payload, pkt_len); 2426 payload, pkt_len);
2166 return GNUNET_YES; 2427 return GNUNET_YES;
@@ -2180,7 +2441,7 @@ static uint16_t
2180make_up_icmp_service_payload (struct TunnelState *state, 2441make_up_icmp_service_payload (struct TunnelState *state,
2181 char *buf) 2442 char *buf)
2182{ 2443{
2183 switch (state->serv->address.af) 2444 switch (state->specifics.tcp_udp.serv->address.af)
2184 { 2445 {
2185 case AF_INET: 2446 case AF_INET:
2186 { 2447 {
@@ -2244,6 +2505,16 @@ receive_icmp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel
2244 char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN; 2505 char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
2245 const void *payload; 2506 const void *payload;
2246 2507
2508 if (GNUNET_YES == state->is_dns)
2509 {
2510 GNUNET_break_op (0);
2511 return GNUNET_SYSERR;
2512 }
2513 if (GNUNET_SYSERR == state->is_dns)
2514 {
2515 /* tunnel is UDP/TCP from now on */
2516 state->is_dns = GNUNET_NO;
2517 }
2247 GNUNET_STATISTICS_update (stats, 2518 GNUNET_STATISTICS_update (stats,
2248 gettext_noop ("# Bytes received from MESH"), 2519 gettext_noop ("# Bytes received from MESH"),
2249 pkt_len, GNUNET_NO); 2520 pkt_len, GNUNET_NO);
@@ -2262,7 +2533,7 @@ receive_icmp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel
2262 "Received data from %s for forwarding to ICMP service %s\n", 2533 "Received data from %s for forwarding to ICMP service %s\n",
2263 GNUNET_i2s (sender), 2534 GNUNET_i2s (sender),
2264 GNUNET_h2s (&msg->service_descriptor)); 2535 GNUNET_h2s (&msg->service_descriptor));
2265 if (NULL == state->serv) 2536 if (NULL == state->specifics.tcp_udp.serv)
2266 { 2537 {
2267 /* first packet to service must not be ICMP (cannot determine service!) */ 2538 /* first packet to service must not be ICMP (cannot determine service!) */
2268 GNUNET_break_op (0); 2539 GNUNET_break_op (0);
@@ -2270,7 +2541,7 @@ receive_icmp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel
2270 } 2541 }
2271 icmp = msg->icmp_header; 2542 icmp = msg->icmp_header;
2272 payload = &msg[1]; 2543 payload = &msg[1];
2273 state->ri.remote_address = state->serv->address; 2544 state->specifics.tcp_udp.ri.remote_address = state->specifics.tcp_udp.serv->address;
2274 setup_state_record (state); 2545 setup_state_record (state);
2275 2546
2276 /* check that ICMP type is something we want to support, 2547 /* check that ICMP type is something we want to support,
@@ -2281,15 +2552,15 @@ receive_icmp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel
2281 switch (msg->icmp_header.type) 2552 switch (msg->icmp_header.type)
2282 { 2553 {
2283 case GNUNET_TUN_ICMPTYPE_ECHO_REPLY: 2554 case GNUNET_TUN_ICMPTYPE_ECHO_REPLY:
2284 if (state->serv->address.af == AF_INET6) 2555 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2285 icmp.type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY; 2556 icmp.type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY;
2286 break; 2557 break;
2287 case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST: 2558 case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST:
2288 if (state->serv->address.af == AF_INET6) 2559 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2289 icmp.type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST; 2560 icmp.type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST;
2290 break; 2561 break;
2291 case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE: 2562 case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE:
2292 if (state->serv->address.af == AF_INET6) 2563 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2293 icmp.type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE; 2564 icmp.type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE;
2294 if (0 != pkt_len) 2565 if (0 != pkt_len)
2295 { 2566 {
@@ -2300,7 +2571,7 @@ receive_icmp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel
2300 pkt_len = make_up_icmp_service_payload (state, buf); 2571 pkt_len = make_up_icmp_service_payload (state, buf);
2301 break; 2572 break;
2302 case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: 2573 case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED:
2303 if (state->serv->address.af == AF_INET6) 2574 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2304 icmp.type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED; 2575 icmp.type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED;
2305 if (0 != pkt_len) 2576 if (0 != pkt_len)
2306 { 2577 {
@@ -2311,7 +2582,7 @@ receive_icmp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel
2311 pkt_len = make_up_icmp_service_payload (state, buf); 2582 pkt_len = make_up_icmp_service_payload (state, buf);
2312 break; 2583 break;
2313 case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH: 2584 case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH:
2314 if (state->serv->address.af == AF_INET6) 2585 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2315 { 2586 {
2316 GNUNET_STATISTICS_update (stats, 2587 GNUNET_STATISTICS_update (stats,
2317 gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"), 2588 gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"),
@@ -2339,15 +2610,15 @@ receive_icmp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel
2339 switch (msg->icmp_header.type) 2610 switch (msg->icmp_header.type)
2340 { 2611 {
2341 case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY: 2612 case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY:
2342 if (state->serv->address.af == AF_INET) 2613 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2343 icmp.type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY; 2614 icmp.type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY;
2344 break; 2615 break;
2345 case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST: 2616 case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
2346 if (state->serv->address.af == AF_INET) 2617 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2347 icmp.type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST; 2618 icmp.type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST;
2348 break; 2619 break;
2349 case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE: 2620 case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
2350 if (state->serv->address.af == AF_INET) 2621 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2351 icmp.type = GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE; 2622 icmp.type = GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE;
2352 if (0 != pkt_len) 2623 if (0 != pkt_len)
2353 { 2624 {
@@ -2358,7 +2629,7 @@ receive_icmp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel
2358 pkt_len = make_up_icmp_service_payload (state, buf); 2629 pkt_len = make_up_icmp_service_payload (state, buf);
2359 break; 2630 break;
2360 case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED: 2631 case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
2361 if (state->serv->address.af == AF_INET) 2632 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2362 icmp.type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED; 2633 icmp.type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED;
2363 if (0 != pkt_len) 2634 if (0 != pkt_len)
2364 { 2635 {
@@ -2370,7 +2641,7 @@ receive_icmp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel
2370 break; 2641 break;
2371 case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG: 2642 case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
2372 case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM: 2643 case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM:
2373 if (state->serv->address.af == AF_INET) 2644 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2374 { 2645 {
2375 GNUNET_STATISTICS_update (stats, 2646 GNUNET_STATISTICS_update (stats,
2376 gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"), 2647 gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"),
@@ -2399,8 +2670,8 @@ receive_icmp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel
2399 return GNUNET_SYSERR; 2670 return GNUNET_SYSERR;
2400 } 2671 }
2401 2672
2402 send_icmp_packet_via_tun (&state->ri.remote_address, 2673 send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2403 &state->ri.local_address, 2674 &state->specifics.tcp_udp.ri.local_address,
2404 &icmp, 2675 &icmp,
2405 payload, pkt_len); 2676 payload, pkt_len);
2406 return GNUNET_YES; 2677 return GNUNET_YES;
@@ -2490,10 +2761,11 @@ send_udp_packet_via_tun (const struct SocketAddress *destination_address,
2490 GNUNET_assert (0); 2761 GNUNET_assert (0);
2491 break; 2762 break;
2492 } 2763 }
2493 (void) GNUNET_HELPER_send (helper_handle, 2764 if (NULL != helper_handle)
2494 (const struct GNUNET_MessageHeader*) buf, 2765 (void) GNUNET_HELPER_send (helper_handle,
2495 GNUNET_YES, 2766 (const struct GNUNET_MessageHeader*) buf,
2496 NULL, NULL); 2767 GNUNET_YES,
2768 NULL, NULL);
2497 } 2769 }
2498} 2770}
2499 2771
@@ -2525,6 +2797,16 @@ receive_udp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
2525 const void *payload; 2797 const void *payload;
2526 int af; 2798 int af;
2527 2799
2800 if (GNUNET_YES == state->is_dns)
2801 {
2802 GNUNET_break_op (0);
2803 return GNUNET_SYSERR;
2804 }
2805 if (GNUNET_SYSERR == state->is_dns)
2806 {
2807 /* tunnel is UDP/TCP from now on */
2808 state->is_dns = GNUNET_NO;
2809 }
2528 GNUNET_STATISTICS_update (stats, 2810 GNUNET_STATISTICS_update (stats,
2529 gettext_noop ("# Bytes received from MESH"), 2811 gettext_noop ("# Bytes received from MESH"),
2530 pkt_len, GNUNET_NO); 2812 pkt_len, GNUNET_NO);
@@ -2539,7 +2821,7 @@ receive_udp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
2539 msg = (const struct GNUNET_EXIT_UdpInternetMessage*) message; 2821 msg = (const struct GNUNET_EXIT_UdpInternetMessage*) message;
2540 pkt_len -= sizeof (struct GNUNET_EXIT_UdpInternetMessage); 2822 pkt_len -= sizeof (struct GNUNET_EXIT_UdpInternetMessage);
2541 af = (int) ntohl (msg->af); 2823 af = (int) ntohl (msg->af);
2542 state->ri.remote_address.af = af; 2824 state->specifics.tcp_udp.ri.remote_address.af = af;
2543 switch (af) 2825 switch (af)
2544 { 2826 {
2545 case AF_INET: 2827 case AF_INET:
@@ -2556,7 +2838,7 @@ receive_udp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
2556 v4 = (const struct in_addr*) &msg[1]; 2838 v4 = (const struct in_addr*) &msg[1];
2557 payload = &v4[1]; 2839 payload = &v4[1];
2558 pkt_len -= sizeof (struct in_addr); 2840 pkt_len -= sizeof (struct in_addr);
2559 state->ri.remote_address.address.ipv4 = *v4; 2841 state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
2560 break; 2842 break;
2561 case AF_INET6: 2843 case AF_INET6:
2562 if (pkt_len < sizeof (struct in6_addr)) 2844 if (pkt_len < sizeof (struct in6_addr))
@@ -2572,7 +2854,7 @@ receive_udp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
2572 v6 = (const struct in6_addr*) &msg[1]; 2854 v6 = (const struct in6_addr*) &msg[1];
2573 payload = &v6[1]; 2855 payload = &v6[1];
2574 pkt_len -= sizeof (struct in6_addr); 2856 pkt_len -= sizeof (struct in6_addr);
2575 state->ri.remote_address.address.ipv6 = *v6; 2857 state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
2576 break; 2858 break;
2577 default: 2859 default:
2578 GNUNET_break_op (0); 2860 GNUNET_break_op (0);
@@ -2584,18 +2866,18 @@ receive_udp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
2584 "Received data from %s for forwarding to UDP %s:%u\n", 2866 "Received data from %s for forwarding to UDP %s:%u\n",
2585 GNUNET_i2s (sender), 2867 GNUNET_i2s (sender),
2586 inet_ntop (af, 2868 inet_ntop (af,
2587 &state->ri.remote_address.address, 2869 &state->specifics.tcp_udp.ri.remote_address.address,
2588 buf, sizeof (buf)), 2870 buf, sizeof (buf)),
2589 (unsigned int) ntohs (msg->destination_port)); 2871 (unsigned int) ntohs (msg->destination_port));
2590 } 2872 }
2591 state->ri.remote_address.proto = IPPROTO_UDP; 2873 state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_UDP;
2592 state->ri.remote_address.port = msg->destination_port; 2874 state->specifics.tcp_udp.ri.remote_address.port = msg->destination_port;
2593 if (NULL == state->heap_node) 2875 if (NULL == state->specifics.tcp_udp.heap_node)
2594 setup_state_record (state); 2876 setup_state_record (state);
2595 if (0 != ntohs (msg->source_port)) 2877 if (0 != ntohs (msg->source_port))
2596 state->ri.local_address.port = msg->source_port; 2878 state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
2597 send_udp_packet_via_tun (&state->ri.remote_address, 2879 send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2598 &state->ri.local_address, 2880 &state->specifics.tcp_udp.ri.local_address,
2599 payload, pkt_len); 2881 payload, pkt_len);
2600 return GNUNET_YES; 2882 return GNUNET_YES;
2601} 2883}
@@ -2625,6 +2907,16 @@ receive_udp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
2625 const struct GNUNET_EXIT_UdpServiceMessage *msg; 2907 const struct GNUNET_EXIT_UdpServiceMessage *msg;
2626 uint16_t pkt_len = ntohs (message->size); 2908 uint16_t pkt_len = ntohs (message->size);
2627 2909
2910 if (GNUNET_YES == state->is_dns)
2911 {
2912 GNUNET_break_op (0);
2913 return GNUNET_SYSERR;
2914 }
2915 if (GNUNET_SYSERR == state->is_dns)
2916 {
2917 /* tunnel is UDP/TCP from now on */
2918 state->is_dns = GNUNET_NO;
2919 }
2628 GNUNET_STATISTICS_update (stats, 2920 GNUNET_STATISTICS_update (stats,
2629 gettext_noop ("# Bytes received from MESH"), 2921 gettext_noop ("# Bytes received from MESH"),
2630 pkt_len, GNUNET_NO); 2922 pkt_len, GNUNET_NO);
@@ -2639,13 +2931,13 @@ receive_udp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
2639 } 2931 }
2640 msg = (const struct GNUNET_EXIT_UdpServiceMessage*) message; 2932 msg = (const struct GNUNET_EXIT_UdpServiceMessage*) message;
2641 pkt_len -= sizeof (struct GNUNET_EXIT_UdpServiceMessage); 2933 pkt_len -= sizeof (struct GNUNET_EXIT_UdpServiceMessage);
2642 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2934 LOG (GNUNET_ERROR_TYPE_DEBUG,
2643 "Received data from %s for forwarding to UDP service %s on port %u\n", 2935 "Received data from %s for forwarding to UDP service %s on port %u\n",
2644 GNUNET_i2s (sender), 2936 GNUNET_i2s (sender),
2645 GNUNET_h2s (&msg->service_descriptor), 2937 GNUNET_h2s (&msg->service_descriptor),
2646 (unsigned int) ntohs (msg->destination_port)); 2938 (unsigned int) ntohs (msg->destination_port));
2647 if (NULL == (state->serv = find_service (udp_services, &msg->service_descriptor, 2939 if (NULL == (state->specifics.tcp_udp.serv = find_service (udp_services, &msg->service_descriptor,
2648 ntohs (msg->destination_port)))) 2940 ntohs (msg->destination_port))))
2649 { 2941 {
2650 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 2942 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2651 _("No service found for %s on port %d!\n"), 2943 _("No service found for %s on port %d!\n"),
@@ -2656,12 +2948,12 @@ receive_udp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
2656 1, GNUNET_NO); 2948 1, GNUNET_NO);
2657 return GNUNET_SYSERR; 2949 return GNUNET_SYSERR;
2658 } 2950 }
2659 state->ri.remote_address = state->serv->address; 2951 state->specifics.tcp_udp.ri.remote_address = state->specifics.tcp_udp.serv->address;
2660 setup_state_record (state); 2952 setup_state_record (state);
2661 if (0 != ntohs (msg->source_port)) 2953 if (0 != ntohs (msg->source_port))
2662 state->ri.local_address.port = msg->source_port; 2954 state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
2663 send_udp_packet_via_tun (&state->ri.remote_address, 2955 send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2664 &state->ri.local_address, 2956 &state->specifics.tcp_udp.ri.local_address,
2665 &msg[1], pkt_len); 2957 &msg[1], pkt_len);
2666 return GNUNET_YES; 2958 return GNUNET_YES;
2667} 2959}
@@ -2683,6 +2975,7 @@ new_tunnel (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
2683{ 2975{
2684 struct TunnelState *s = GNUNET_malloc (sizeof (struct TunnelState)); 2976 struct TunnelState *s = GNUNET_malloc (sizeof (struct TunnelState));
2685 2977
2978 s->is_dns = GNUNET_SYSERR;
2686 GNUNET_STATISTICS_update (stats, 2979 GNUNET_STATISTICS_update (stats,
2687 gettext_noop ("# Inbound MESH tunnels created"), 2980 gettext_noop ("# Inbound MESH tunnels created"),
2688 1, GNUNET_NO); 2981 1, GNUNET_NO);
@@ -2710,23 +3003,37 @@ clean_tunnel (void *cls GNUNET_UNUSED, const struct GNUNET_MESH_Tunnel *tunnel,
2710 struct TunnelState *s = tunnel_ctx; 3003 struct TunnelState *s = tunnel_ctx;
2711 struct TunnelMessageQueue *tnq; 3004 struct TunnelMessageQueue *tnq;
2712 3005
2713 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3006 LOG (GNUNET_ERROR_TYPE_DEBUG,
2714 "Tunnel destroyed\n"); 3007 "Tunnel destroyed\n");
2715 while (NULL != (tnq = s->head)) 3008 if (GNUNET_SYSERR == s->is_dns)
2716 { 3009 {
2717 GNUNET_CONTAINER_DLL_remove (s->head, 3010 GNUNET_free (s);
2718 s->tail, 3011 return;
2719 tnq);
2720 GNUNET_free (tnq);
2721 } 3012 }
2722 if (s->heap_node != NULL) 3013 if (GNUNET_YES == s->is_dns)
2723 { 3014 {
2724 GNUNET_assert (GNUNET_YES == 3015 if (tunnels[s->specifics.dns.my_id] == s)
2725 GNUNET_CONTAINER_multihashmap_remove (connections_map, 3016 tunnels[s->specifics.dns.my_id] = NULL;
2726 &s->state_key, 3017 GNUNET_free_non_null (s->specifics.dns.reply);
2727 s)); 3018 }
2728 GNUNET_CONTAINER_heap_remove_node (s->heap_node); 3019 else
2729 s->heap_node = NULL; 3020 {
3021 while (NULL != (tnq = s->specifics.tcp_udp.head))
3022 {
3023 GNUNET_CONTAINER_DLL_remove (s->specifics.tcp_udp.head,
3024 s->specifics.tcp_udp.tail,
3025 tnq);
3026 GNUNET_free (tnq);
3027 }
3028 if (NULL != s->specifics.tcp_udp.heap_node)
3029 {
3030 GNUNET_assert (GNUNET_YES ==
3031 GNUNET_CONTAINER_multihashmap_remove (connections_map,
3032 &s->specifics.tcp_udp.state_key,
3033 s));
3034 GNUNET_CONTAINER_heap_remove_node (s->specifics.tcp_udp.heap_node);
3035 s->specifics.tcp_udp.heap_node = NULL;
3036 }
2730 } 3037 }
2731 if (NULL != s->th) 3038 if (NULL != s->th)
2732 { 3039 {
@@ -2764,6 +3071,7 @@ cleanup (void *cls GNUNET_UNUSED,
2764 3071
2765 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3072 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2766 "Exit service is shutting down now\n"); 3073 "Exit service is shutting down now\n");
3074
2767 if (helper_handle != NULL) 3075 if (helper_handle != NULL)
2768 { 3076 {
2769 GNUNET_HELPER_stop (helper_handle); 3077 GNUNET_HELPER_stop (helper_handle);
@@ -2797,6 +3105,11 @@ cleanup (void *cls GNUNET_UNUSED,
2797 GNUNET_CONTAINER_multihashmap_destroy (udp_services); 3105 GNUNET_CONTAINER_multihashmap_destroy (udp_services);
2798 udp_services = NULL; 3106 udp_services = NULL;
2799 } 3107 }
3108 if (NULL != dnsstub)
3109 {
3110 GNUNET_DNSSTUB_stop (dnsstub);
3111 dnsstub = NULL;
3112 }
2800 if (stats != NULL) 3113 if (stats != NULL)
2801 { 3114 {
2802 GNUNET_STATISTICS_destroy (stats, GNUNET_NO); 3115 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
@@ -2998,12 +3311,14 @@ run (void *cls, char *const *args GNUNET_UNUSED,
2998 {&receive_tcp_service, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START, 0}, 3311 {&receive_tcp_service, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START, 0},
2999 {&receive_tcp_remote, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START, 0}, 3312 {&receive_tcp_remote, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START, 0},
3000 {&receive_tcp_data, GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT, 0}, 3313 {&receive_tcp_data, GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT, 0},
3314 {&receive_dns_request, GNUNET_MESSAGE_TYPE_VPN_DNS_TO_INTERNET, 0},
3001 {NULL, 0, 0} 3315 {NULL, 0, 0}
3002 }; 3316 };
3003 3317
3004 static GNUNET_MESH_ApplicationType apptypes[] = { 3318 static GNUNET_MESH_ApplicationType apptypes[] = {
3005 GNUNET_APPLICATION_TYPE_END, 3319 GNUNET_APPLICATION_TYPE_END,
3006 GNUNET_APPLICATION_TYPE_END, 3320 GNUNET_APPLICATION_TYPE_END,
3321 GNUNET_APPLICATION_TYPE_END,
3007 GNUNET_APPLICATION_TYPE_END 3322 GNUNET_APPLICATION_TYPE_END
3008 }; 3323 };
3009 unsigned int app_idx; 3324 unsigned int app_idx;
@@ -3016,25 +3331,31 @@ run (void *cls, char *const *args GNUNET_UNUSED,
3016 char *binary; 3331 char *binary;
3017 char *regex; 3332 char *regex;
3018 char *prefixed_regex; 3333 char *prefixed_regex;
3334 struct in_addr dns_exit4;
3335 struct in6_addr dns_exit6;
3336 char *dns_exit;
3019 3337
3020 binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-exit");
3021 if (GNUNET_YES !=
3022 GNUNET_OS_check_helper_binary (binary))
3023 {
3024 GNUNET_free (binary);
3025 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3026 _("`%s' must be installed SUID, refusing to run\n"),
3027 "gnunet-helper-exit");
3028 global_ret = 1;
3029 return;
3030 }
3031 GNUNET_free (binary);
3032 cfg = cfg_; 3338 cfg = cfg_;
3033 stats = GNUNET_STATISTICS_create ("exit", cfg);
3034 ipv4_exit = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "EXIT_IPV4"); 3339 ipv4_exit = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "EXIT_IPV4");
3035 ipv6_exit = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "EXIT_IPV6"); 3340 ipv6_exit = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "EXIT_IPV6");
3036 ipv4_enabled = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_IPV4"); 3341 ipv4_enabled = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_IPV4");
3037 ipv6_enabled = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_IPV6"); 3342 ipv6_enabled = GNUNET_CONFIGURATION_get_value_yesno (cfg, "exit", "ENABLE_IPV6");
3343 if ( (ipv4_exit) || (ipv6_exit) )
3344 {
3345 binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-exit");
3346 if (GNUNET_YES !=
3347 GNUNET_OS_check_helper_binary (binary))
3348 {
3349 GNUNET_free (binary);
3350 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3351 _("`%s' must be installed SUID, refusing to run\n"),
3352 "gnunet-helper-exit");
3353 global_ret = 1;
3354 return;
3355 }
3356 GNUNET_free (binary);
3357 }
3358 stats = GNUNET_STATISTICS_create ("exit", cfg);
3038 3359
3039 if ( (ipv4_exit || ipv4_enabled) && 3360 if ( (ipv4_exit || ipv4_enabled) &&
3040 GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET)) 3361 GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET))
@@ -3071,6 +3392,26 @@ run (void *cls, char *const *args GNUNET_UNUSED,
3071 GNUNET_SCHEDULER_shutdown (); 3392 GNUNET_SCHEDULER_shutdown ();
3072 return; 3393 return;
3073 } 3394 }
3395
3396 dns_exit = NULL;
3397 if ( (GNUNET_YES ==
3398 GNUNET_CONFIGURATION_get_value_yesno (cfg_, "exit", "ENABLE_DNS")) &&
3399 ( (GNUNET_OK !=
3400 GNUNET_CONFIGURATION_get_value_string (cfg, "exit",
3401 "DNS_RESOLVER",
3402 &dns_exit)) ||
3403 ( (1 != inet_pton (AF_INET, dns_exit, &dns_exit4)) &&
3404 (1 != inet_pton (AF_INET6, dns_exit, &dns_exit6)) ) ) )
3405 {
3406 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "dns", "DNS_RESOLVER",
3407 _("need a valid IPv4 or IPv6 address\n"));
3408 GNUNET_free_non_null (dns_exit);
3409 dns_exit = NULL;
3410 }
3411 if (NULL != dns_exit)
3412 dnsstub = GNUNET_DNSSTUB_start (dns_exit);
3413
3414
3074 app_idx = 0; 3415 app_idx = 0;
3075 if (GNUNET_YES == ipv4_exit) 3416 if (GNUNET_YES == ipv4_exit)
3076 { 3417 {
@@ -3082,6 +3423,11 @@ run (void *cls, char *const *args GNUNET_UNUSED,
3082 apptypes[app_idx] = GNUNET_APPLICATION_TYPE_IPV6_GATEWAY; 3423 apptypes[app_idx] = GNUNET_APPLICATION_TYPE_IPV6_GATEWAY;
3083 app_idx++; 3424 app_idx++;
3084 } 3425 }
3426 if (NULL != dns_exit)
3427 {
3428 apptypes[app_idx] = GNUNET_APPLICATION_TYPE_INTERNET_RESOLVER;
3429 app_idx++;
3430 }
3085 3431
3086 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls); 3432 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls);
3087 3433
@@ -3242,12 +3588,12 @@ run (void *cls, char *const *args GNUNET_UNUSED,
3242 GNUNET_free (regex); 3588 GNUNET_free (regex);
3243 GNUNET_free (prefixed_regex); 3589 GNUNET_free (prefixed_regex);
3244 } 3590 }
3245 3591 if ((ipv4_exit) || (ipv6_exit))
3246 helper_handle = GNUNET_HELPER_start (GNUNET_NO, 3592 helper_handle = GNUNET_HELPER_start (GNUNET_NO,
3247 "gnunet-helper-exit", 3593 "gnunet-helper-exit",
3248 exit_argv, 3594 exit_argv,
3249 &message_token, 3595 &message_token,
3250 NULL, NULL); 3596 NULL, NULL);
3251} 3597}
3252 3598
3253 3599