aboutsummaryrefslogtreecommitdiff
path: root/src/gns/gnunet-dns2gns.c
diff options
context:
space:
mode:
authorMartin Schanzenbach <schanzen@gnunet.org>2022-02-03 22:47:03 +0100
committerMartin Schanzenbach <schanzen@gnunet.org>2022-02-03 22:47:03 +0100
commitf3eaf5dae9a14fc62109b6e7c69571a068301fed (patch)
treecec115818f7e41db3f5d6eccd1b04ed5b0b96fec /src/gns/gnunet-dns2gns.c
parentafd2cb5db220ce528b6222340b31b8a1a365c8e4 (diff)
downloadgnunet-f3eaf5dae9a14fc62109b6e7c69571a068301fed.tar.gz
gnunet-f3eaf5dae9a14fc62109b6e7c69571a068301fed.zip
GNS: Move VPN to DNS2GNS. Fixes #7171
Diffstat (limited to 'src/gns/gnunet-dns2gns.c')
-rw-r--r--src/gns/gnunet-dns2gns.c209
1 files changed, 209 insertions, 0 deletions
diff --git a/src/gns/gnunet-dns2gns.c b/src/gns/gnunet-dns2gns.c
index 06f4c9841..46659cdda 100644
--- a/src/gns/gnunet-dns2gns.c
+++ b/src/gns/gnunet-dns2gns.c
@@ -27,6 +27,7 @@
27#include <gnunet_dnsparser_lib.h> 27#include <gnunet_dnsparser_lib.h>
28#include <gnunet_gns_service.h> 28#include <gnunet_gns_service.h>
29#include <gnunet_dnsstub_lib.h> 29#include <gnunet_dnsstub_lib.h>
30#include "gnunet_vpn_service.h"
30#include "gns.h" 31#include "gns.h"
31 32
32/** 33/**
@@ -35,6 +36,46 @@
35#define TIMEOUT GNUNET_TIME_UNIT_MINUTES 36#define TIMEOUT GNUNET_TIME_UNIT_MINUTES
36 37
37/** 38/**
39 * Default timeout for VPN redirections.
40 */
41#define VPN_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 30)
42
43
44struct Request;
45
46/**
47 * Closure for #vpn_allocation_cb.
48 */
49struct VpnContext
50{
51 /**
52 * Which resolution process are we processing.
53 */
54 struct Request *request;
55
56 /**
57 * Handle to the VPN request that we were performing.
58 */
59 struct GNUNET_VPN_RedirectionRequest *vpn_request;
60
61 /**
62 * Number of records serialized in @e rd_data.
63 */
64 unsigned int rd_count;
65
66 /**
67 * Serialized records.
68 */
69 char *rd_data;
70
71 /**
72 * Number of bytes in @e rd_data.
73 */
74 ssize_t rd_data_size;
75};
76
77
78/**
38 * Data kept per request. 79 * Data kept per request.
39 */ 80 */
40struct Request 81struct Request
@@ -72,6 +113,11 @@ struct Request
72 struct GNUNET_SCHEDULER_Task *timeout_task; 113 struct GNUNET_SCHEDULER_Task *timeout_task;
73 114
74 /** 115 /**
116 * Vpn resulution context
117 */
118 struct VpnContext *vpn_ctx;
119
120 /**
75 * Original UDP request message. 121 * Original UDP request message.
76 */ 122 */
77 char *udp_msg; 123 char *udp_msg;
@@ -90,6 +136,7 @@ struct Request
90 * ID of the original request. 136 * ID of the original request.
91 */ 137 */
92 uint16_t original_request_id; 138 uint16_t original_request_id;
139
93}; 140};
94 141
95/** 142/**
@@ -109,6 +156,11 @@ static struct in6_addr address6;
109struct GNUNET_GNS_Handle *gns; 156struct GNUNET_GNS_Handle *gns;
110 157
111/** 158/**
159 * Our handle to the vpn service
160 */
161static struct GNUNET_VPN_Handle *vpn_handle;
162
163/**
112 * Stub resolver 164 * Stub resolver
113 */ 165 */
114struct GNUNET_DNSSTUB_Context *dns_stub; 166struct GNUNET_DNSSTUB_Context *dns_stub;
@@ -183,6 +235,11 @@ do_shutdown (void *cls)
183 GNUNET_GNS_disconnect (gns); 235 GNUNET_GNS_disconnect (gns);
184 gns = NULL; 236 gns = NULL;
185 } 237 }
238 if (NULL != vpn_handle)
239 {
240 GNUNET_VPN_disconnect (vpn_handle);
241 vpn_handle = NULL;
242 }
186 if (NULL != dns_stub) 243 if (NULL != dns_stub)
187 { 244 {
188 GNUNET_DNSSTUB_stop (dns_stub); 245 GNUNET_DNSSTUB_stop (dns_stub);
@@ -269,6 +326,7 @@ static void
269do_timeout (void *cls) 326do_timeout (void *cls)
270{ 327{
271 struct Request *request = cls; 328 struct Request *request = cls;
329 struct VpnContext *vpn_ctx;
272 330
273 if (NULL != request->packet) 331 if (NULL != request->packet)
274 GNUNET_DNSPARSER_free_packet (request->packet); 332 GNUNET_DNSPARSER_free_packet (request->packet);
@@ -277,6 +335,12 @@ do_timeout (void *cls)
277 if (NULL != request->dns_lookup) 335 if (NULL != request->dns_lookup)
278 GNUNET_DNSSTUB_resolve_cancel (request->dns_lookup); 336 GNUNET_DNSSTUB_resolve_cancel (request->dns_lookup);
279 GNUNET_free (request->udp_msg); 337 GNUNET_free (request->udp_msg);
338 if (NULL != (vpn_ctx = request->vpn_ctx))
339 {
340 GNUNET_VPN_cancel_request (vpn_ctx->vpn_request);
341 GNUNET_free (vpn_ctx->rd_data);
342 GNUNET_free (vpn_ctx);
343 }
280 GNUNET_free (request); 344 GNUNET_free (request);
281} 345}
282 346
@@ -321,6 +385,79 @@ dns_result_processor (void *cls,
321 send_response (request); 385 send_response (request);
322} 386}
323 387
388/**
389 * Callback invoked from the VPN service once a redirection is
390 * available. Provides the IP address that can now be used to
391 * reach the requested destination. Replaces the "VPN" record
392 * with the respective A/AAAA record and continues processing.
393 *
394 * @param cls closure
395 * @param af address family, AF_INET or AF_INET6; AF_UNSPEC on error;
396 * will match 'result_af' from the request
397 * @param address IP address (struct in_addr or struct in_addr6, depending on 'af')
398 * that the VPN allocated for the redirection;
399 * traffic to this IP will now be redirected to the
400 * specified target peer; NULL on error
401 */
402static void
403vpn_allocation_cb (void *cls,
404 int af,
405 const void *address)
406{
407 struct VpnContext *vpn_ctx = cls;
408 struct Request *request = vpn_ctx->request;
409 struct GNUNET_GNSRECORD_Data rd[vpn_ctx->rd_count];
410 unsigned int i;
411
412 vpn_ctx->vpn_request = NULL;
413 request->vpn_ctx = NULL;
414 GNUNET_assert (GNUNET_OK ==
415 GNUNET_GNSRECORD_records_deserialize (
416 (size_t) vpn_ctx->rd_data_size,
417 vpn_ctx->rd_data,
418 vpn_ctx->rd_count,
419 rd));
420 for (i = 0; i < vpn_ctx->rd_count; i++)
421 {
422 if (GNUNET_GNSRECORD_TYPE_VPN == rd[i].record_type)
423 {
424 switch (af)
425 {
426 case AF_INET:
427 rd[i].record_type = GNUNET_DNSPARSER_TYPE_A;
428 rd[i].data_size = sizeof(struct in_addr);
429 rd[i].expiration_time = GNUNET_TIME_relative_to_absolute (
430 VPN_TIMEOUT).abs_value_us;
431 rd[i].flags = 0;
432 rd[i].data = address;
433 break;
434
435 case AF_INET6:
436 rd[i].record_type = GNUNET_DNSPARSER_TYPE_AAAA;
437 rd[i].expiration_time = GNUNET_TIME_relative_to_absolute (
438 VPN_TIMEOUT).abs_value_us;
439 rd[i].flags = 0;
440 rd[i].data = address;
441 rd[i].data_size = sizeof(struct in6_addr);
442 break;
443
444 default:
445 GNUNET_assert (0);
446 }
447 break;
448 }
449 }
450 GNUNET_assert (i < vpn_ctx->rd_count);
451 if (0 == vpn_ctx->rd_count)
452 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
453 _ ("VPN returned empty result for `%s'\n"),
454 request->packet->queries[0].name);
455 send_response (request);
456 GNUNET_free (vpn_ctx->rd_data);
457 GNUNET_free (vpn_ctx);
458}
459
460
324 461
325/** 462/**
326 * Iterator called on obtained result for a GNS lookup. 463 * Iterator called on obtained result for a GNS lookup.
@@ -339,6 +476,11 @@ result_processor (void *cls,
339 struct Request *request = cls; 476 struct Request *request = cls;
340 struct GNUNET_DNSPARSER_Packet *packet; 477 struct GNUNET_DNSPARSER_Packet *packet;
341 struct GNUNET_DNSPARSER_Record rec; 478 struct GNUNET_DNSPARSER_Record rec;
479 struct VpnContext *vpn_ctx;
480 const struct GNUNET_TUN_GnsVpnRecord *vpn;
481 const char *vname;
482 struct GNUNET_HashCode vhash;
483 int af;
342 484
343 request->lookup = NULL; 485 request->lookup = NULL;
344 if (GNUNET_NO == was_gns) 486 if (GNUNET_NO == was_gns)
@@ -415,6 +557,67 @@ result_processor (void *cls,
415 packet->num_answers, 557 packet->num_answers,
416 rec); 558 rec);
417 break; 559 break;
560 case GNUNET_GNSRECORD_TYPE_VPN:
561 if ((GNUNET_DNSPARSER_TYPE_A != request->packet->queries[0].type) &&
562 (GNUNET_DNSPARSER_TYPE_AAAA != request->packet->queries[0].type))
563 break;
564 af = (GNUNET_DNSPARSER_TYPE_A == request->packet->queries[0].type) ? AF_INET :
565 AF_INET6;
566 if (sizeof(struct GNUNET_TUN_GnsVpnRecord) >
567 rd[i].data_size)
568 {
569 GNUNET_break_op (0);
570 break;
571 }
572 vpn = (const struct GNUNET_TUN_GnsVpnRecord *) rd[i].data;
573 vname = (const char *) &vpn[1];
574 if ('\0' != vname[rd[i].data_size - 1 - sizeof(struct
575 GNUNET_TUN_GnsVpnRecord)
576 ])
577 {
578 GNUNET_break_op (0);
579 break;
580 }
581 GNUNET_TUN_service_name_to_hash (vname,
582 &vhash);
583 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
584 "Attempting VPN allocation for %s-%s (AF: %d, proto %d)\n",
585 GNUNET_i2s (&vpn->peer),
586 vname,
587 (int) af,
588 (int) ntohs (vpn->proto));
589 vpn_ctx = GNUNET_new (struct VpnContext);
590 request->vpn_ctx = vpn_ctx;
591 vpn_ctx->request = request;
592 vpn_ctx->rd_data_size = GNUNET_GNSRECORD_records_get_size (rd_count,
593 rd);
594 if (vpn_ctx->rd_data_size < 0)
595 {
596 GNUNET_break_op (0);
597 GNUNET_free (vpn_ctx);
598 break;
599 }
600 vpn_ctx->rd_data = GNUNET_malloc ((size_t) vpn_ctx->rd_data_size);
601 vpn_ctx->rd_count = rd_count;
602 GNUNET_assert (vpn_ctx->rd_data_size ==
603 GNUNET_GNSRECORD_records_serialize (rd_count,
604 rd,
605 (size_t) vpn_ctx
606 ->rd_data_size,
607 vpn_ctx->rd_data));
608 vpn_ctx->vpn_request = GNUNET_VPN_redirect_to_peer (vpn_handle,
609 af,
610 ntohs (
611 vpn->proto),
612 &vpn->peer,
613 &vhash,
614 GNUNET_TIME_relative_to_absolute (
615 VPN_TIMEOUT),
616 &
617 vpn_allocation_cb,
618 vpn_ctx);
619 return;
620
418 621
419 default: 622 default:
420 /* skip */ 623 /* skip */
@@ -641,6 +844,8 @@ run (void *cls,
641 NULL); 844 NULL);
642 if (NULL == (gns = GNUNET_GNS_connect (cfg))) 845 if (NULL == (gns = GNUNET_GNS_connect (cfg)))
643 return; 846 return;
847 if (NULL == (vpn_handle = GNUNET_VPN_connect (cfg)))
848 return;
644 GNUNET_assert (NULL != (dns_stub = GNUNET_DNSSTUB_start (128))); 849 GNUNET_assert (NULL != (dns_stub = GNUNET_DNSSTUB_start (128)));
645 if (GNUNET_OK != 850 if (GNUNET_OK !=
646 GNUNET_DNSSTUB_add_dns_ip (dns_stub, 851 GNUNET_DNSSTUB_add_dns_ip (dns_stub,
@@ -649,6 +854,8 @@ run (void *cls,
649 GNUNET_DNSSTUB_stop (dns_stub); 854 GNUNET_DNSSTUB_stop (dns_stub);
650 GNUNET_GNS_disconnect (gns); 855 GNUNET_GNS_disconnect (gns);
651 gns = NULL; 856 gns = NULL;
857 GNUNET_VPN_disconnect (vpn_handle);
858 vpn_handle = NULL;
652 return; 859 return;
653 } 860 }
654 861
@@ -750,6 +957,8 @@ run (void *cls,
750 { 957 {
751 GNUNET_GNS_disconnect (gns); 958 GNUNET_GNS_disconnect (gns);
752 gns = NULL; 959 gns = NULL;
960 GNUNET_VPN_disconnect (vpn_handle);
961 vpn_handle = NULL;
753 GNUNET_DNSSTUB_stop (dns_stub); 962 GNUNET_DNSSTUB_stop (dns_stub);
754 dns_stub = NULL; 963 dns_stub = NULL;
755 return; 964 return;