aboutsummaryrefslogtreecommitdiff
path: root/src/pt/gnunet-daemon-pt.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-01-18 22:10:08 +0000
committerChristian Grothoff <christian@grothoff.org>2012-01-18 22:10:08 +0000
commitd8cda8039015fe11760ae256c43094d046e08cac (patch)
tree18644056a4e8e26eb537a683ae343adc066fe602 /src/pt/gnunet-daemon-pt.c
parentc37fba0bd9febb11297ebca62a58935276130244 (diff)
downloadgnunet-d8cda8039015fe11760ae256c43094d046e08cac.tar.gz
gnunet-d8cda8039015fe11760ae256c43094d046e08cac.zip
-adding support for routing DNS requests via MESH to PT daemon
Diffstat (limited to 'src/pt/gnunet-daemon-pt.c')
-rw-r--r--src/pt/gnunet-daemon-pt.c548
1 files changed, 493 insertions, 55 deletions
diff --git a/src/pt/gnunet-daemon-pt.c b/src/pt/gnunet-daemon-pt.c
index 3d9128379..17ed6712d 100644
--- a/src/pt/gnunet-daemon-pt.c
+++ b/src/pt/gnunet-daemon-pt.c
@@ -27,12 +27,15 @@
27#include "gnunet_util_lib.h" 27#include "gnunet_util_lib.h"
28#include "gnunet_dns_service.h" 28#include "gnunet_dns_service.h"
29#include "gnunet_dnsparser_lib.h" 29#include "gnunet_dnsparser_lib.h"
30#include "gnunet_mesh_service.h"
31#include "gnunet_tun_lib.h"
30#include "gnunet_vpn_service.h" 32#include "gnunet_vpn_service.h"
31#include "gnunet_statistics_service.h" 33#include "gnunet_statistics_service.h"
34#include "gnunet_applications.h"
32 35
33 36
34/** 37/**
35 * After how long do we time out if we could not get an IP from VPN? 38 * After how long do we time out if we could not get an IP from VPN or MESH?
36 */ 39 */
37#define TIMEOUT GNUNET_TIME_UNIT_MINUTES 40#define TIMEOUT GNUNET_TIME_UNIT_MINUTES
38 41
@@ -75,9 +78,9 @@ enum RequestGroup
75 78
76 79
77/** 80/**
78 * Information tracked per DNS request that we are processing. 81 * Information tracked per DNS reply that we are processing.
79 */ 82 */
80struct RequestContext 83struct ReplyContext
81{ 84{
82 /** 85 /**
83 * Handle to submit the final result. 86 * Handle to submit the final result.
@@ -113,6 +116,51 @@ struct RequestContext
113 116
114 117
115/** 118/**
119 * State we keep for a request that is going out via MESH.
120 */
121struct RequestContext
122{
123 /**
124 * We keep these in a DLL.
125 */
126 struct RequestContext *next;
127
128 /**
129 * We keep these in a DLL.
130 */
131 struct RequestContext *prev;
132
133 /**
134 * Handle for interaction with DNS service.
135 */
136 struct GNUNET_DNS_RequestHandle *rh;
137
138 /**
139 * Message we're sending out via MESH, allocated at the
140 * end of this struct.
141 */
142 const struct GNUNET_MessageHeader *mesh_message;
143
144 /**
145 * Task used to abort this operation with timeout.
146 */
147 GNUNET_SCHEDULER_TaskIdentifier timeout_task;
148
149 /**
150 * ID of the original DNS request (used to match the reply).
151 */
152 uint16_t dns_id;
153
154 /**
155 * GNUNET_NO if this request is still in the transmit_queue,
156 * GNUNET_YES if we are in the receive_queue.
157 */
158 int16_t was_transmitted;
159
160};
161
162
163/**
116 * The handle to the configuration used throughout the process 164 * The handle to the configuration used throughout the process
117 */ 165 */
118static const struct GNUNET_CONFIGURATION_Handle *cfg; 166static const struct GNUNET_CONFIGURATION_Handle *cfg;
@@ -123,14 +171,54 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg;
123static struct GNUNET_VPN_Handle *vpn_handle; 171static struct GNUNET_VPN_Handle *vpn_handle;
124 172
125/** 173/**
174 * The handle to the MESH service
175 */
176static struct GNUNET_MESH_Handle *mesh_handle;
177
178/**
179 * Tunnel we use for DNS requests over MESH.
180 */
181static struct GNUNET_MESH_Tunnel *mesh_tunnel;
182
183/**
184 * Active transmission request with MESH (or NULL).
185 */
186static struct GNUNET_MESH_TransmitHandle *mesh_th;
187
188/**
189 * Head of DLL of requests to be transmitted to mesh_tunnel.
190 */
191static struct RequestContext *transmit_queue_head;
192
193/**
194 * Tail of DLL of requests to be transmitted to mesh_tunnel.
195 */
196static struct RequestContext *transmit_queue_tail;
197
198/**
199 * Head of DLL of requests waiting for a response.
200 */
201static struct RequestContext *receive_queue_head;
202
203/**
204 * Tail of DLL of requests waiting for a response.
205 */
206static struct RequestContext *receive_queue_tail;
207
208/**
126 * Statistics. 209 * Statistics.
127 */ 210 */
128static struct GNUNET_STATISTICS_Handle *stats; 211static struct GNUNET_STATISTICS_Handle *stats;
129 212
130/** 213/**
131 * The handle to DNS 214 * The handle to DNS post-resolution modifications.
132 */ 215 */
133static struct GNUNET_DNS_Handle *dns_handle; 216static struct GNUNET_DNS_Handle *dns_post_handle;
217
218/**
219 * The handle to DNS pre-resolution modifications.
220 */
221static struct GNUNET_DNS_Handle *dns_pre_handle;
134 222
135/** 223/**
136 * Are we doing IPv4-pt? 224 * Are we doing IPv4-pt?
@@ -142,6 +230,17 @@ static int ipv4_pt;
142 */ 230 */
143static int ipv6_pt; 231static int ipv6_pt;
144 232
233/**
234 * Are we tunneling DNS queries?
235 */
236static int dns_tunnel;
237
238/**
239 * Number of DNS exit peers we currently have in the mesh tunnel.
240 * Used to see if using the mesh tunnel makes any sense right now.
241 */
242static unsigned int dns_exit_available;
243
145 244
146/** 245/**
147 * We're done modifying all records in the response. Submit the reply 246 * We're done modifying all records in the response. Submit the reply
@@ -150,7 +249,7 @@ static int ipv6_pt;
150 * @param rc context to process 249 * @param rc context to process
151 */ 250 */
152static void 251static void
153finish_request (struct RequestContext *rc) 252finish_request (struct ReplyContext *rc)
154{ 253{
155 char *buf; 254 char *buf;
156 size_t buf_len; 255 size_t buf_len;
@@ -187,7 +286,7 @@ finish_request (struct RequestContext *rc)
187 * @param rc context to process 286 * @param rc context to process
188 */ 287 */
189static void 288static void
190submit_request (struct RequestContext *rc); 289submit_request (struct ReplyContext *rc);
191 290
192 291
193/** 292/**
@@ -197,7 +296,7 @@ submit_request (struct RequestContext *rc);
197 * record and then continue with 'submit_request' to look at 296 * record and then continue with 'submit_request' to look at
198 * the other records. 297 * the other records.
199 * 298 *
200 * @param cls our 'struct RequestContext' 299 * @param cls our 'struct ReplyContext'
201 * @param af address family, AF_INET or AF_INET6; AF_UNSPEC on error; 300 * @param af address family, AF_INET or AF_INET6; AF_UNSPEC on error;
202 * will match 'result_af' from the request 301 * will match 'result_af' from the request
203 * @param address IP address (struct in_addr or struct in_addr6, depending on 'af') 302 * @param address IP address (struct in_addr or struct in_addr6, depending on 'af')
@@ -210,7 +309,7 @@ vpn_allocation_callback (void *cls,
210 int af, 309 int af,
211 const void *address) 310 const void *address)
212{ 311{
213 struct RequestContext *rc = cls; 312 struct ReplyContext *rc = cls;
214 313
215 rc->rr = NULL; 314 rc->rr = NULL;
216 if (af == AF_UNSPEC) 315 if (af == AF_UNSPEC)
@@ -252,7 +351,7 @@ vpn_allocation_callback (void *cls,
252 * @param rec record to modify 351 * @param rec record to modify
253 */ 352 */
254static void 353static void
255modify_address (struct RequestContext *rc, 354modify_address (struct ReplyContext *rc,
256 struct GNUNET_DNSPARSER_Record *rec) 355 struct GNUNET_DNSPARSER_Record *rec)
257{ 356{
258 int af; 357 int af;
@@ -290,7 +389,7 @@ modify_address (struct RequestContext *rc,
290 * @param rc context to process 389 * @param rc context to process
291 */ 390 */
292static void 391static void
293submit_request (struct RequestContext *rc) 392submit_request (struct ReplyContext *rc)
294{ 393{
295 struct GNUNET_DNSPARSER_Record *ra; 394 struct GNUNET_DNSPARSER_Record *ra;
296 unsigned int ra_len; 395 unsigned int ra_len;
@@ -377,22 +476,10 @@ work_test (const struct GNUNET_DNSPARSER_Record *ra,
377 476
378 477
379/** 478/**
380 * Signature of a function that is called whenever the DNS service 479 * This function is called AFTER we got an IP address for a
381 * encounters a DNS request and needs to do something with it. The 480 * DNS request. Now, the PT daemon has the chance to substitute
382 * function has then the chance to generate or modify the response by 481 * the IP address with one from the VPN range to tunnel requests
383 * calling one of the three "GNUNET_DNS_request_*" continuations. 482 * destined for this IP address via VPN and MESH.
384 *
385 * When a request is intercepted, this function is called first to
386 * give the client a chance to do the complete address resolution;
387 * "rdata" will be NULL for this first call for a DNS request, unless
388 * some other client has already filled in a response.
389 *
390 * If multiple clients exist, all of them are called before the global
391 * DNS. The global DNS is only called if all of the clients'
392 * functions call GNUNET_DNS_request_forward. Functions that call
393 * GNUNET_DNS_request_forward will be called again before a final
394 * response is returned to the application. If any of the clients'
395 * functions call GNUNET_DNS_request_drop, the response is dropped.
396 * 483 *
397 * @param cls closure 484 * @param cls closure
398 * @param rh request handle to user for reply 485 * @param rh request handle to user for reply
@@ -400,17 +487,17 @@ work_test (const struct GNUNET_DNSPARSER_Record *ra,
400 * @param request udp payload of the DNS request 487 * @param request udp payload of the DNS request
401 */ 488 */
402static void 489static void
403dns_request_handler (void *cls, 490dns_post_request_handler (void *cls,
404 struct GNUNET_DNS_RequestHandle *rh, 491 struct GNUNET_DNS_RequestHandle *rh,
405 size_t request_length, 492 size_t request_length,
406 const char *request) 493 const char *request)
407{ 494{
408 struct GNUNET_DNSPARSER_Packet *dns; 495 struct GNUNET_DNSPARSER_Packet *dns;
409 struct RequestContext *rc; 496 struct ReplyContext *rc;
410 int work; 497 int work;
411 498
412 GNUNET_STATISTICS_update (stats, 499 GNUNET_STATISTICS_update (stats,
413 gettext_noop ("# DNS requests intercepted"), 500 gettext_noop ("# DNS replies intercepted"),
414 1, GNUNET_NO); 501 1, GNUNET_NO);
415 dns = GNUNET_DNSPARSER_parse (request, request_length); 502 dns = GNUNET_DNSPARSER_parse (request, request_length);
416 if (NULL == dns) 503 if (NULL == dns)
@@ -429,7 +516,7 @@ dns_request_handler (void *cls,
429 GNUNET_DNS_request_forward (rh); 516 GNUNET_DNS_request_forward (rh);
430 return; 517 return;
431 } 518 }
432 rc = GNUNET_malloc (sizeof (struct RequestContext)); 519 rc = GNUNET_malloc (sizeof (struct ReplyContext));
433 rc->rh = rh; 520 rc->rh = rh;
434 rc->dns = dns; 521 rc->dns = dns;
435 rc->offset = 0; 522 rc->offset = 0;
@@ -439,6 +526,292 @@ dns_request_handler (void *cls,
439 526
440 527
441/** 528/**
529 * Transmit a DNS request via MESH and move the request
530 * handle to the receive queue.
531 *
532 * @param cls NULL
533 * @param size number of bytes available in buf
534 * @param buf where to copy the message
535 * @return number of bytes written to buf
536 */
537static size_t
538transmit_dns_request_to_mesh (void *cls,
539 size_t size,
540 void *buf)
541{
542 struct RequestContext *rc;
543 size_t mlen;
544
545 mesh_th = NULL;
546 if (NULL == (rc = transmit_queue_head))
547 return 0;
548 mlen = ntohs (rc->mesh_message->size);
549 if (mlen > size)
550 {
551 mesh_th = GNUNET_MESH_notify_transmit_ready (mesh_tunnel,
552 GNUNET_NO, 0,
553 TIMEOUT,
554 NULL, mlen,
555 &transmit_dns_request_to_mesh,
556 NULL);
557 return 0;
558 }
559 GNUNET_assert (GNUNET_NO == rc->was_transmitted);
560 memcpy (buf, rc->mesh_message, mlen);
561 GNUNET_CONTAINER_DLL_remove (transmit_queue_head,
562 transmit_queue_tail,
563 rc);
564 rc->was_transmitted = GNUNET_YES;
565 GNUNET_CONTAINER_DLL_insert (receive_queue_head,
566 receive_queue_tail,
567 rc);
568 rc = transmit_queue_head;
569 if (NULL != rc)
570 mesh_th = GNUNET_MESH_notify_transmit_ready (mesh_tunnel,
571 GNUNET_NO, 0,
572 TIMEOUT,
573 NULL, ntohs (rc->mesh_message->size),
574 &transmit_dns_request_to_mesh,
575 NULL);
576 return mlen;
577}
578
579
580/**
581 * Task run if the time to answer a DNS request via MESH is over.
582 *
583 * @param cls the 'struct RequestContext' to abort
584 * @param tc scheduler context
585 */
586static void
587timeout_request (void *cls,
588 const struct GNUNET_SCHEDULER_TaskContext *tc)
589{
590 struct RequestContext *rc = cls;
591
592 if (rc->was_transmitted)
593 GNUNET_CONTAINER_DLL_remove (receive_queue_head,
594 receive_queue_tail,
595 rc);
596 else
597 GNUNET_CONTAINER_DLL_remove (transmit_queue_head,
598 transmit_queue_tail,
599 rc);
600 GNUNET_STATISTICS_update (stats,
601 gettext_noop ("# DNS requests dropped (timeout)"),
602 1, GNUNET_NO);
603 GNUNET_DNS_request_drop (rc->rh);
604 GNUNET_free (rc);
605}
606
607
608/**
609 * This function is called *before* the DNS request has been
610 * given to a "local" DNS resolver. Tunneling for DNS requests
611 * was enabled, so we now need to send the request via some MESH
612 * tunnel to a DNS EXIT for resolution.
613 *
614 * @param cls closure
615 * @param rh request handle to user for reply
616 * @param request_length number of bytes in request
617 * @param request udp payload of the DNS request
618 */
619static void
620dns_pre_request_handler (void *cls,
621 struct GNUNET_DNS_RequestHandle *rh,
622 size_t request_length,
623 const char *request)
624{
625 struct RequestContext *rc;
626 size_t mlen;
627 struct GNUNET_MessageHeader hdr;
628 struct GNUNET_TUN_DnsHeader dns;
629
630 GNUNET_STATISTICS_update (stats,
631 gettext_noop ("# DNS requests intercepted"),
632 1, GNUNET_NO);
633 if (0 == dns_exit_available)
634 {
635 GNUNET_STATISTICS_update (stats,
636 gettext_noop ("# DNS requests dropped (DNS mesh tunnel down)"),
637 1, GNUNET_NO);
638 GNUNET_DNS_request_drop (rh);
639 return;
640 }
641 if (request_length < sizeof (dns))
642 {
643 GNUNET_STATISTICS_update (stats,
644 gettext_noop ("# DNS requests dropped (malformed)"),
645 1, GNUNET_NO);
646 GNUNET_DNS_request_drop (rh);
647 return;
648 }
649 memcpy (&dns, request, sizeof (dns));
650 GNUNET_assert (NULL != mesh_tunnel);
651 mlen = sizeof (struct GNUNET_MessageHeader) + request_length;
652 rc = GNUNET_malloc (sizeof (struct RequestContext) + mlen);
653 rc->rh = rh;
654 rc->mesh_message = (const struct GNUNET_MessageHeader*) &rc[1];
655 rc->timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
656 &timeout_request,
657 rc);
658 rc->dns_id = dns.id;
659 hdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_DNS_TO_INTERNET);
660 hdr.size = htons (mlen);
661 memcpy (&rc[1], &hdr, sizeof (struct GNUNET_MessageHeader));
662 memcpy (&(((char*)&rc[1])[sizeof (struct GNUNET_MessageHeader)]),
663 request,
664 request_length);
665 GNUNET_CONTAINER_DLL_insert_tail (transmit_queue_head,
666 transmit_queue_tail,
667 rc);
668 if (NULL == mesh_th)
669 mesh_th = GNUNET_MESH_notify_transmit_ready (mesh_tunnel,
670 GNUNET_NO, 0,
671 TIMEOUT,
672 NULL, mlen,
673 &transmit_dns_request_to_mesh,
674 NULL);
675}
676
677
678/**
679 * Process a request via mesh to perform a DNS query.
680 *
681 * @param cls closure, NULL
682 * @param tunnel connection to the other end
683 * @param tunnel_ctx pointer to our 'struct TunnelState *'
684 * @param sender who sent the message
685 * @param message the actual message
686 * @param atsi performance data for the connection
687 * @return GNUNET_OK to keep the connection open,
688 * GNUNET_SYSERR to close it (signal serious error)
689 */
690static int
691receive_dns_response (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
692 void **tunnel_ctx,
693 const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
694 const struct GNUNET_MessageHeader *message,
695 const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
696{
697 struct GNUNET_TUN_DnsHeader dns;
698 size_t mlen;
699 struct RequestContext *rc;
700
701 mlen = ntohs (message->size);
702 mlen -= sizeof (struct GNUNET_MessageHeader);
703 if (mlen < sizeof (struct GNUNET_TUN_DnsHeader))
704 {
705 GNUNET_break_op (0);
706 return GNUNET_SYSERR;
707 }
708 memcpy (&dns, &message[1], sizeof (dns));
709 for (rc = receive_queue_head; NULL != rc; rc = rc->next)
710 {
711 GNUNET_assert (GNUNET_YES == rc->was_transmitted);
712 if (dns.id == rc->dns_id)
713 {
714 GNUNET_STATISTICS_update (stats,
715 gettext_noop ("# DNS replies received"),
716 1, GNUNET_NO);
717 GNUNET_DNS_request_answer (rc->rh,
718 mlen,
719 (const void*) &message[1]);
720 GNUNET_CONTAINER_DLL_remove (receive_queue_head,
721 receive_queue_tail,
722 rc);
723 GNUNET_SCHEDULER_cancel (rc->timeout_task);
724 GNUNET_free (rc);
725 return GNUNET_OK;
726 }
727 }
728 GNUNET_STATISTICS_update (stats,
729 gettext_noop ("# DNS replies dropped (too late?)"),
730 1, GNUNET_NO);
731 return GNUNET_OK;
732}
733
734
735/**
736 * The MESH DNS tunnel went down. Abort all pending DNS
737 * requests (we're unlikely to get an answer in time).
738 */
739static void
740abort_all_requests ()
741{
742 struct RequestContext *rc;
743
744 while (NULL != (rc = receive_queue_head))
745 {
746 GNUNET_STATISTICS_update (stats,
747 gettext_noop ("# DNS requests aborted (tunnel down)"),
748 1, GNUNET_NO);
749 GNUNET_CONTAINER_DLL_remove (receive_queue_head,
750 receive_queue_tail,
751 rc);
752 GNUNET_DNS_request_drop (rc->rh);
753 GNUNET_SCHEDULER_cancel (rc->timeout_task);
754 GNUNET_free (rc);
755 }
756 while (NULL != (rc = transmit_queue_head))
757 {
758 GNUNET_STATISTICS_update (stats,
759 gettext_noop ("# DNS requests aborted (tunnel down)"),
760 1, GNUNET_NO);
761 GNUNET_CONTAINER_DLL_remove (transmit_queue_head,
762 transmit_queue_tail,
763 rc);
764 GNUNET_DNS_request_drop (rc->rh);
765 GNUNET_SCHEDULER_cancel (rc->timeout_task);
766 GNUNET_free (rc);
767 }
768}
769
770
771/**
772 * Method called whenever a peer has disconnected from the tunnel.
773 *
774 * @param cls closure
775 * @param peer peer identity the tunnel stopped working with
776 */
777static void
778mesh_disconnect_handler (void *cls,
779 const struct
780 GNUNET_PeerIdentity * peer)
781{
782 GNUNET_assert (dns_exit_available > 0);
783 dns_exit_available--;
784 if (0 == dns_exit_available)
785 {
786 if (NULL != mesh_th)
787 {
788 GNUNET_MESH_notify_transmit_ready_cancel (mesh_th);
789 mesh_th = NULL;
790 }
791 abort_all_requests ();
792 }
793}
794
795
796/**
797 * Method called whenever a peer has connected to the tunnel.
798 *
799 * @param cls closure
800 * @param peer peer identity the tunnel was created to, NULL on timeout
801 * @param atsi performance data for the connection
802 */
803static void
804mesh_connect_handler (void *cls,
805 const struct GNUNET_PeerIdentity
806 * peer,
807 const struct
808 GNUNET_ATS_Information * atsi)
809{
810 dns_exit_available++;
811}
812
813
814/**
442 * Function scheduled as very last function, cleans up after us 815 * Function scheduled as very last function, cleans up after us
443 */ 816 */
444static void 817static void
@@ -452,10 +825,31 @@ cleanup (void *cls GNUNET_UNUSED,
452 GNUNET_VPN_disconnect (vpn_handle); 825 GNUNET_VPN_disconnect (vpn_handle);
453 vpn_handle = NULL; 826 vpn_handle = NULL;
454 } 827 }
455 if (dns_handle != NULL) 828 if (NULL != mesh_th)
829 {
830 GNUNET_MESH_notify_transmit_ready_cancel (mesh_th);
831 mesh_th = NULL;
832 }
833 if (NULL != mesh_tunnel)
834 {
835 GNUNET_MESH_tunnel_destroy (mesh_tunnel);
836 mesh_tunnel = NULL;
837 }
838 if (mesh_handle != NULL)
839 {
840 GNUNET_MESH_disconnect (mesh_handle);
841 mesh_handle = NULL;
842 }
843 abort_all_requests ();
844 if (dns_post_handle != NULL)
845 {
846 GNUNET_DNS_disconnect (dns_post_handle);
847 dns_post_handle = NULL;
848 }
849 if (dns_pre_handle != NULL)
456 { 850 {
457 GNUNET_DNS_disconnect (dns_handle); 851 GNUNET_DNS_disconnect (dns_pre_handle);
458 dns_handle = NULL; 852 dns_pre_handle = NULL;
459 } 853 }
460 if (stats != NULL) 854 if (stats != NULL)
461 { 855 {
@@ -482,7 +876,8 @@ run (void *cls, char *const *args GNUNET_UNUSED,
482 stats = GNUNET_STATISTICS_create ("pt", cfg); 876 stats = GNUNET_STATISTICS_create ("pt", cfg);
483 ipv4_pt = GNUNET_CONFIGURATION_get_value_yesno (cfg, "pt", "TUNNEL_IPV4"); 877 ipv4_pt = GNUNET_CONFIGURATION_get_value_yesno (cfg, "pt", "TUNNEL_IPV4");
484 ipv6_pt = GNUNET_CONFIGURATION_get_value_yesno (cfg, "pt", "TUNNEL_IPV6"); 878 ipv6_pt = GNUNET_CONFIGURATION_get_value_yesno (cfg, "pt", "TUNNEL_IPV6");
485 if (! (ipv4_pt || ipv6_pt)) 879 dns_tunnel = GNUNET_CONFIGURATION_get_value_yesno (cfg, "pt", "TUNNEL_DNS");
880 if (! (ipv4_pt || ipv6_pt || dns_tunnel))
486 { 881 {
487 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 882 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
488 _("No useful service enabled. Exiting.\n")); 883 _("No useful service enabled. Exiting.\n"));
@@ -490,26 +885,69 @@ run (void *cls, char *const *args GNUNET_UNUSED,
490 return; 885 return;
491 } 886 }
492 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls); 887 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls);
493 dns_handle 888 if (ipv4_pt || ipv6_pt)
494 = GNUNET_DNS_connect (cfg,
495 GNUNET_DNS_FLAG_POST_RESOLUTION,
496 &dns_request_handler, NULL);
497 if (NULL == dns_handle)
498 { 889 {
499 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 890 dns_post_handle
500 _("Failed to connect to %s service. Exiting.\n"), 891 = GNUNET_DNS_connect (cfg,
501 "DNS"); 892 GNUNET_DNS_FLAG_POST_RESOLUTION,
502 GNUNET_SCHEDULER_shutdown (); 893 &dns_post_request_handler, NULL);
503 return; 894 if (NULL == dns_post_handle)
895 {
896 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
897 _("Failed to connect to %s service. Exiting.\n"),
898 "DNS");
899 GNUNET_SCHEDULER_shutdown ();
900 return;
901 }
902 vpn_handle = GNUNET_VPN_connect (cfg);
903 if (NULL == vpn_handle)
904 {
905 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
906 _("Failed to connect to %s service. Exiting.\n"),
907 "VPN");
908 GNUNET_SCHEDULER_shutdown ();
909 return;
910 }
504 } 911 }
505 vpn_handle = GNUNET_VPN_connect (cfg); 912 if (dns_tunnel)
506 if (NULL == vpn_handle)
507 { 913 {
508 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 914 static struct GNUNET_MESH_MessageHandler mesh_handlers[] = {
509 _("Failed to connect to %s service. Exiting.\n"), 915 {&receive_dns_response, GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET, 0},
510 "VPN"); 916 {NULL, 0, 0}
511 GNUNET_SCHEDULER_shutdown (); 917 };
512 return; 918 static GNUNET_MESH_ApplicationType mesh_types[] = {
919 GNUNET_APPLICATION_TYPE_END
920 };
921
922 dns_pre_handle
923 = GNUNET_DNS_connect (cfg,
924 GNUNET_DNS_FLAG_PRE_RESOLUTION,
925 &dns_pre_request_handler, NULL);
926 if (NULL == dns_pre_handle)
927 {
928 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
929 _("Failed to connect to %s service. Exiting.\n"),
930 "DNS");
931 GNUNET_SCHEDULER_shutdown ();
932 return;
933 }
934 mesh_handle = GNUNET_MESH_connect (cfg, 1, NULL, NULL, NULL,
935 mesh_handlers, mesh_types);
936 if (NULL == mesh_handle)
937 {
938 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
939 _("Failed to connect to %s service. Exiting.\n"),
940 "MESH");
941 GNUNET_SCHEDULER_shutdown ();
942 return;
943 }
944 mesh_tunnel = GNUNET_MESH_tunnel_create (mesh_handle,
945 NULL,
946 &mesh_connect_handler,
947 &mesh_disconnect_handler,
948 NULL);
949 GNUNET_MESH_peer_request_connect_by_type (mesh_tunnel,
950 GNUNET_APPLICATION_TYPE_INTERNET_RESOLVER);
513 } 951 }
514} 952}
515 953