diff options
author | Martin Schanzenbach <schanzen@gnunet.org> | 2022-02-03 22:47:03 +0100 |
---|---|---|
committer | Martin Schanzenbach <schanzen@gnunet.org> | 2022-02-03 22:47:03 +0100 |
commit | f3eaf5dae9a14fc62109b6e7c69571a068301fed (patch) | |
tree | cec115818f7e41db3f5d6eccd1b04ed5b0b96fec /src/gns/gnunet-dns2gns.c | |
parent | afd2cb5db220ce528b6222340b31b8a1a365c8e4 (diff) | |
download | gnunet-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.c | 209 |
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 | |||
44 | struct Request; | ||
45 | |||
46 | /** | ||
47 | * Closure for #vpn_allocation_cb. | ||
48 | */ | ||
49 | struct 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 | */ |
40 | struct Request | 81 | struct 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; | |||
109 | struct GNUNET_GNS_Handle *gns; | 156 | struct GNUNET_GNS_Handle *gns; |
110 | 157 | ||
111 | /** | 158 | /** |
159 | * Our handle to the vpn service | ||
160 | */ | ||
161 | static struct GNUNET_VPN_Handle *vpn_handle; | ||
162 | |||
163 | /** | ||
112 | * Stub resolver | 164 | * Stub resolver |
113 | */ | 165 | */ |
114 | struct GNUNET_DNSSTUB_Context *dns_stub; | 166 | struct 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 | |||
269 | do_timeout (void *cls) | 326 | do_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 | */ | ||
402 | static void | ||
403 | vpn_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; |