GNUnet 0.21.0
gnunet-daemon-pt.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2010, 2012, 2017 Christian Grothoff
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
25#include "platform.h"
26#include "gnunet_util_lib.h"
27#include "gnunet_dns_service.h"
29#include "gnunet_dht_service.h"
30#include "gnunet_vpn_service.h"
32#include "gnunet_applications.h"
33#include "block_dns.h"
34
35
39#define TIMEOUT GNUNET_TIME_UNIT_MINUTES
40
48#define MAX_DNS_SIZE (8 * 1024)
49
53#define MAX_OPEN_TUNNELS 4
54
55
60{
65
70
75
79 END = 3
80};
81
82
87{
92
97
102
107
111 unsigned int offset;
112
117};
118
119
126{
131
136
142
147
152
157
162
166 unsigned int num_transmitted;
167
171 unsigned int num_answered;
172
176 /* unsigned */ int idle;
177};
178
179
184{
189
194
199
204
209
214
218 uint16_t mlen;
219
223 uint16_t dns_id;
224};
225
226
232static struct CadetExit *exit_head;
233
237static struct CadetExit *exit_tail;
238
242static const struct GNUNET_CONFIGURATION_Handle *cfg;
243
248
253
258
263
268
272static struct GNUNET_DHT_Handle *dht;
273
278
282static int ipv4_pt;
283
287static int ipv6_pt;
288
292static int dns_channel;
293
299static unsigned int dns_exit_available;
300
301
305static void
306try_open_exit (void);
307
308
318static uint32_t
320{
321 uint32_t dropped;
322 uint32_t drop_percent;
323 uint32_t good_percent;
324
326 dropped = exit->num_transmitted - exit->num_answered;
327 if (exit->num_transmitted > 0)
328 drop_percent = (uint32_t) ((100LL * dropped) / exit->num_transmitted);
329 else
330 drop_percent = 50; /* no data */
331 if ((exit->num_transmitted > 20) &&
332 (drop_percent > 25))
333 return 0; /* statistically significant, and > 25% loss, die */
334 good_percent = 100 - drop_percent;
335 GNUNET_assert (0 != good_percent);
336 if (UINT32_MAX / good_percent / good_percent < exit->num_transmitted)
337 return UINT32_MAX; /* formula below would overflow */
338 return 1 + good_percent * good_percent * exit->num_transmitted;
339}
340
341
353static struct CadetExit *
355{
356 struct CadetExit *pos;
357 uint64_t total_transmitted;
358 uint64_t selected_offset;
359 uint32_t channel_weight;
360
361 total_transmitted = 0;
362 for (pos = exit_head; NULL != pos; pos = pos->next)
363 {
364 if (NULL == pos->cadet_channel)
365 break;
366 channel_weight = get_channel_weight (pos);
367 total_transmitted += channel_weight;
368 /* double weight for idle channels */
369 if (0 != pos->idle)
370 total_transmitted += channel_weight;
371 }
372 if (0 == total_transmitted)
373 {
374 /* no channels available, or only a very bad one... */
375 return exit_head;
376 }
378 total_transmitted);
379 total_transmitted = 0;
380 for (pos = exit_head; NULL != pos; pos = pos->next)
381 {
382 if (NULL == pos->cadet_channel)
383 break;
384 channel_weight = get_channel_weight (pos);
385 total_transmitted += channel_weight;
386 /* double weight for idle channels */
387 if (0 != pos->idle)
388 total_transmitted += channel_weight;
389 if (total_transmitted > selected_offset)
390 return pos;
391 }
392 GNUNET_break (0);
393 return NULL;
394}
395
396
403static void
405{
406 char *buf;
407 size_t buf_len;
408
409 if (GNUNET_SYSERR ==
412 &buf,
413 &buf_len))
414 {
416 _ ("Failed to pack DNS request. Dropping.\n"));
418 }
419 else
420 {
422 gettext_noop ("# DNS requests mapped to VPN"),
423 1, GNUNET_NO);
425 buf_len,
426 buf);
427 GNUNET_free (buf);
428 }
430 GNUNET_free (rc);
431}
432
433
441static void
442submit_request (struct ReplyContext *rc);
443
444
460static void
462 int af,
463 const void *address)
464{
465 struct ReplyContext *rc = cls;
466
467 rc->rr = NULL;
468 if (af == AF_UNSPEC)
469 {
472 GNUNET_free (rc);
473 return;
474 }
476 gettext_noop ("# DNS records modified"),
477 1,
478 GNUNET_NO);
479 switch (rc->rec->type)
480 {
482 GNUNET_assert (AF_INET == af);
484 address,
485 sizeof(struct in_addr));
486 break;
487
489 GNUNET_assert (AF_INET6 == af);
491 address,
492 sizeof(struct in6_addr));
493 break;
494
495 default:
496 GNUNET_assert (0);
497 return;
498 }
499 rc->rec = NULL;
500 submit_request (rc);
501}
502
503
513static void
516{
517 int af;
518
519 switch (rec->type)
520 {
522 af = AF_INET;
523 GNUNET_assert (rec->data.raw.data_len == sizeof(struct in_addr));
524 break;
525
527 af = AF_INET6;
528 GNUNET_assert (rec->data.raw.data_len == sizeof(struct in6_addr));
529 break;
530
531 default:
532 GNUNET_assert (0);
533 return;
534 }
535 rc->rec = rec;
537 af,
538 af,
539 rec->data.raw.data,
541 TIMEOUT),
543 rc);
544}
545
546
554static void
556{
557 struct GNUNET_DNSPARSER_Record *ra;
558 unsigned int ra_len;
559 unsigned int i;
560
561 while (1)
562 {
563 switch (rc->group)
564 {
565 case ANSWERS:
566 ra = rc->dns->answers;
567 ra_len = rc->dns->num_answers;
568 break;
569
571 ra = rc->dns->authority_records;
572 ra_len = rc->dns->num_authority_records;
573 break;
574
576 ra = rc->dns->additional_records;
577 ra_len = rc->dns->num_additional_records;
578 break;
579
580 case END:
581 finish_request (rc);
582 return;
583
584 default:
585 GNUNET_assert (0);
586 }
587 for (i = rc->offset; i < ra_len; i++)
588 {
589 switch (ra[i].type)
590 {
592 if (ipv4_pt)
593 {
594 rc->offset = i + 1;
595 modify_address (rc,
596 &ra[i]);
597 return;
598 }
599 break;
600
602 if (ipv6_pt)
603 {
604 rc->offset = i + 1;
605 modify_address (rc,
606 &ra[i]);
607 return;
608 }
609 break;
610 }
611 }
612 rc->group++;
613 }
614}
615
616
624static int
626 unsigned int ra_len)
627{
628 unsigned int i;
629
630 for (i = 0; i < ra_len; i++)
631 {
632 switch (ra[i].type)
633 {
635 if (ipv4_pt)
636 return GNUNET_YES;
637 break;
638
640 if (ipv6_pt)
641 return GNUNET_YES;
642 break;
643 }
644 }
645 return GNUNET_NO;
646}
647
648
660static void
662 struct GNUNET_DNS_RequestHandle *rh,
663 size_t request_length,
664 const char *request)
665{
666 struct GNUNET_DNSPARSER_Packet *dns;
667 struct ReplyContext *rc;
668 int work;
669
671 gettext_noop ("# DNS replies intercepted"),
672 1, GNUNET_NO);
674 request_length);
675 if (NULL == dns)
676 {
678 _ ("Failed to parse DNS request. Dropping.\n"));
680 return;
681 }
682 work = GNUNET_NO;
689 if (! work)
690 {
693 return;
694 }
695 rc = GNUNET_new (struct ReplyContext);
696 rc->rh = rh;
697 rc->dns = dns;
698 rc->offset = 0;
699 rc->group = ANSWERS;
700 submit_request (rc);
701}
702
703
709static void
711{
712 struct RequestContext *rc = cls;
713 struct CadetExit *exit = rc->exit;
714
716 gettext_noop ("# DNS requests dropped (timeout)"),
717 1,
718 GNUNET_NO);
720 GNUNET_free (rc);
721 if ((0 == get_channel_weight (exit)) &&
722 (NULL == exit->receive_queue_head))
723 {
724 /* this straw broke the camel's back: this channel now has
725 such a low score that it will not be used; close it! */
727 exit->cadet_channel = NULL;
729 exit_tail,
730 exit);
732 exit_tail,
733 exit);
734 /* go back to semi-innocent: mark as not great, but
735 avoid a prohibitively negative score (see
736 #get_channel_weight(), which checks for a certain
737 minimum number of transmissions before making
738 up an opinion) */exit->num_transmitted = 5;
739 exit->num_answered = 0;
741 /* now try to open an alternative exit */
742 try_open_exit ();
743 }
744}
745
746
758static void
760 struct GNUNET_DNS_RequestHandle *rh,
761 size_t request_length,
762 const char *request)
763{
764 struct RequestContext *rc;
765 struct GNUNET_MQ_Envelope *env;
766 struct GNUNET_MessageHeader *hdr;
767 struct GNUNET_TUN_DnsHeader dns;
768 struct CadetExit *exit;
769
771 gettext_noop ("# DNS requests intercepted"),
772 1, GNUNET_NO);
773 if (0 == dns_exit_available)
774 {
777 "# DNS requests dropped (DNS cadet channel down)"),
778 1, GNUNET_NO);
780 return;
781 }
782 if (request_length < sizeof(dns))
783 {
786 "# DNS requests dropped (malformed)"),
787 1, GNUNET_NO);
789 return;
790 }
791 exit = choose_exit ();
792 GNUNET_assert (NULL != exit);
793 GNUNET_assert (NULL != exit->cadet_channel);
794
796 request_length,
798 GNUNET_memcpy (&hdr[1],
799 request,
800 request_length);
801 rc = GNUNET_new (struct RequestContext);
802 rc->exit = exit;
803 rc->rh = rh;
806 rc);
807 GNUNET_memcpy (&dns,
808 request,
809 sizeof(dns));
810 rc->dns_id = dns.id;
811 rc->env = env;
813 exit->receive_queue_tail,
814 rc);
815 if (0 < exit->idle)
816 exit->idle--;
817 exit->num_transmitted++;
820}
821
822
824
829{
834
839
840 /* Followed by more DNS payload */
841};
842
844
853static int
855 const struct DnsResponseMessage *msg)
856{
857 return GNUNET_OK; /* all OK */
858}
859
860
867static void
869 const struct DnsResponseMessage *msg)
870{
871 struct CadetExit *exit = cls;
872 size_t mlen;
873 struct RequestContext *rc;
874
875 mlen = ntohs (msg->header.size) - sizeof(*msg);
876 for (rc = exit->receive_queue_head; NULL != rc; rc = rc->next)
877 {
878 if (msg->dns.id == rc->dns_id)
879 {
881 gettext_noop ("# DNS replies received"),
882 1,
883 GNUNET_NO);
885 mlen + sizeof(struct GNUNET_TUN_DnsHeader),
886 (const void *) &msg->dns);
889 rc);
892 GNUNET_free (rc);
894 return;
895 }
896 }
898 gettext_noop ("# DNS replies dropped (too late?)"),
899 1, GNUNET_NO);
900}
901
902
908static void
910{
911 struct RequestContext *rc;
912
913 while (NULL != (rc = exit->receive_queue_head))
914 {
917 rc);
921 GNUNET_free (rc);
922 }
923}
924
925
931static void
932cleanup (void *cls)
933{
934 struct CadetExit *exit;
935
937 "Protocol translation daemon is shutting down now\n");
938 if (NULL != vpn_handle)
939 {
941 vpn_handle = NULL;
942 }
943 while (NULL != (exit = exit_head))
944 {
946 exit_tail,
947 exit);
948 if (NULL != exit->cadet_channel)
949 {
951 exit->cadet_channel = NULL;
952 }
953 abort_all_requests (exit);
954 GNUNET_free (exit);
955 }
956 if (NULL != cadet_handle)
957 {
959 cadet_handle = NULL;
960 }
961 if (NULL != dns_post_handle)
962 {
964 dns_post_handle = NULL;
965 }
966 if (NULL != dns_pre_handle)
967 {
969 dns_pre_handle = NULL;
970 }
971 if (NULL != stats)
972 {
974 stats = NULL;
975 }
976 if (NULL != dht_get)
977 {
979 dht_get = NULL;
980 }
981 if (NULL != dht)
982 {
984 dht = NULL;
985 }
986}
987
988
1000static void
1002 const struct GNUNET_CADET_Channel *channel)
1003{
1004 struct CadetExit *exit = cls;
1005 struct CadetExit *alt;
1006 struct RequestContext *rc;
1007
1008 exit->cadet_channel = NULL;
1010 /* open alternative channels */
1011 /* our channel is now closed, move our requests to an alternative
1012 channel */
1013 alt = choose_exit ();
1014 while (NULL != (rc = exit->receive_queue_head))
1015 {
1018 rc);
1019 rc->exit = alt;
1021 alt->receive_queue_tail,
1022 rc);
1024 GNUNET_MQ_env_copy (rc->env));
1025 }
1026 try_open_exit ();
1027}
1028
1029
1037static void
1039 const struct GNUNET_CADET_Channel *channel,
1040 int window_size)
1041{
1042 struct CadetExit *pos = cls;
1043
1044 pos->idle = window_size;
1045}
1046
1047
1051static void
1053{
1054 struct CadetExit *pos;
1055 uint32_t candidate_count;
1056 uint32_t candidate_selected;
1057 struct GNUNET_HashCode port;
1058
1061 &port);
1062 candidate_count = 0;
1063 for (pos = exit_head; NULL != pos; pos = pos->next)
1064 if (NULL == pos->cadet_channel)
1065 candidate_count++;
1066 if (0 == candidate_count)
1067 {
1069 "No DNS exits available yet.\n");
1070 return;
1071 }
1073 candidate_count);
1074 candidate_count = 0;
1075 for (pos = exit_head; NULL != pos; pos = pos->next)
1076 if (NULL == pos->cadet_channel)
1077 {
1078 candidate_count++;
1079 if (candidate_selected < candidate_count)
1080 {
1081 struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
1082 GNUNET_MQ_hd_var_size (dns_response,
1084 struct DnsResponseMessage,
1085 pos),
1087 };
1088
1089
1090 /* move to the head of the DLL */
1091 pos->cadet_channel
1093 pos,
1094 &pos->peer,
1095 &port,
1098 cadet_handlers);
1099 if (NULL == pos->cadet_channel)
1100 {
1101 GNUNET_break (0);
1102 continue;
1103 }
1105 exit_tail,
1106 pos);
1108 exit_tail,
1109 pos);
1111 return;
1112 }
1113 }
1114 GNUNET_assert (NULL == exit_head);
1115}
1116
1117
1138static void
1140 struct GNUNET_TIME_Absolute exp,
1141 const struct GNUNET_HashCode *key,
1142 const struct GNUNET_PeerIdentity *trunc_peer,
1143 const struct GNUNET_DHT_PathElement *get_path,
1144 unsigned int get_path_length,
1145 const struct GNUNET_DHT_PathElement *put_path,
1146 unsigned int put_path_length,
1148 size_t size, const void *data)
1149{
1150 const struct GNUNET_DNS_Advertisement *ad;
1151 struct CadetExit *exit;
1152
1153 if (sizeof(struct GNUNET_DNS_Advertisement) != size)
1154 {
1155 GNUNET_break (0);
1156 return;
1157 }
1158 ad = data;
1159 for (exit = exit_head; NULL != exit; exit = exit->next)
1160 if (0 == GNUNET_memcmp (&ad->peer,
1161 &exit->peer))
1162 break;
1163 if (NULL == exit)
1164 {
1165 exit = GNUNET_new (struct CadetExit);
1166 exit->peer = ad->peer;
1167 /* channel is closed, so insert at the end */
1169 exit_tail,
1170 exit);
1171 }
1174 ad->expiration_time));
1176 try_open_exit ();
1177}
1178
1179
1188static void
1189run (void *cls, char *const *args GNUNET_UNUSED,
1190 const char *cfgfile GNUNET_UNUSED,
1191 const struct GNUNET_CONFIGURATION_Handle *cfg_)
1192{
1193 struct GNUNET_HashCode dns_key;
1194
1195 cfg = cfg_;
1197 cfg);
1199 "pt",
1200 "TUNNEL_IPV4");
1202 "pt",
1203 "TUNNEL_IPV6");
1205 "pt",
1206 "TUNNEL_DNS");
1207 if (! (ipv4_pt || ipv6_pt || dns_channel))
1208 {
1210 _ ("No useful service enabled. Exiting.\n"));
1212 return;
1213 }
1215 if (ipv4_pt || ipv6_pt)
1216 {
1221 NULL);
1222 if (NULL == dns_post_handle)
1223 {
1225 _ ("Failed to connect to %s service. Exiting.\n"),
1226 "DNS");
1228 return;
1229 }
1231 if (NULL == vpn_handle)
1232 {
1234 _ ("Failed to connect to %s service. Exiting.\n"),
1235 "VPN");
1237 return;
1238 }
1239 }
1240 if (dns_channel)
1241 {
1246 NULL);
1247 if (NULL == dns_pre_handle)
1248 {
1250 _ ("Failed to connect to %s service. Exiting.\n"),
1251 "DNS");
1253 return;
1254 }
1256 if (NULL == cadet_handle)
1257 {
1259 _ ("Failed to connect to %s service. Exiting.\n"),
1260 "CADET");
1262 return;
1263 }
1264 dht = GNUNET_DHT_connect (cfg, 1);
1265 if (NULL == dht)
1266 {
1268 _ ("Failed to connect to %s service. Exiting.\n"),
1269 "DHT");
1271 return;
1272 }
1273 GNUNET_CRYPTO_hash ("dns",
1274 strlen ("dns"),
1275 &dns_key);
1278 &dns_key,
1279 1,
1281 NULL, 0,
1283 NULL);
1284 }
1285}
1286
1287
1295int
1296main (int argc,
1297 char *const *argv)
1298{
1299 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
1301 };
1302 int ret;
1303
1305 argv,
1306 &argc,
1307 &argv))
1308 return 2;
1309 ret = (GNUNET_OK ==
1310 GNUNET_PROGRAM_run (argc,
1311 argv,
1312 "gnunet-daemon-pt",
1313 gettext_noop (
1314 "Daemon to run to perform IP protocol translation to GNUnet"),
1315 options,
1316 &run,
1317 NULL))
1318 ? 0
1319 : 1;
1320 GNUNET_free_nz ((void *) argv);
1321 return ret;
1322}
1323
1324
1325/* end of gnunet-daemon-pt.c */
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
DNS network structs.
#define gettext_noop(String)
Definition: gettext.h:70
static int ret
Final status code.
Definition: gnunet-arm.c:94
static void work(void *cls)
Function called to process work items.
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
static char * address
GNS address for this phone.
static void timeout_request(void *cls)
Task run if the time to answer a DNS request via CADET is over.
static struct GNUNET_DNS_Handle * dns_pre_handle
The handle to DNS pre-resolution modifications.
static struct GNUNET_DHT_Handle * dht
Handle to access the DHT.
static void dns_pre_request_handler(void *cls, struct GNUNET_DNS_RequestHandle *rh, size_t request_length, const char *request)
This function is called before the DNS request has been given to a "local" DNS resolver.
static int ipv4_pt
Are we doing IPv4-pt?
static int work_test(const struct GNUNET_DNSPARSER_Record *ra, unsigned int ra_len)
Test if any of the given records need protocol-translation work.
static struct GNUNET_VPN_Handle * vpn_handle
The handle to the VPN.
#define TIMEOUT
After how long do we time out if we could not get an IP from VPN or CADET?
static struct GNUNET_DNS_Handle * dns_post_handle
The handle to DNS post-resolution modifications.
static void abort_all_requests(struct CadetExit *exit)
Abort all pending DNS requests with the given cadet exit.
static GNUNET_NETWORK_STRUCT_END int check_dns_response(void *cls, const struct DnsResponseMessage *msg)
Process a request via cadet to perform a DNS query.
static int ipv6_pt
Are we doing IPv6-pt?
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg_)
Main function that will be run by the scheduler.
static void modify_address(struct ReplyContext *rc, struct GNUNET_DNSPARSER_Record *rec)
Modify the given DNS record by asking VPN to create a channel to the given address.
static uint32_t get_channel_weight(struct CadetExit *exit)
Compute the weight of the given exit.
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
static int dns_channel
Are we channeling DNS queries?
static const struct GNUNET_CONFIGURATION_Handle * cfg
The handle to the configuration used throughout the process.
static void vpn_allocation_callback(void *cls, int af, const void *address)
Callback invoked from the VPN service once a redirection is available.
static struct CadetExit * exit_head
Head of DLL of cadet exits.
static struct CadetExit * choose_exit()
Choose a cadet exit for a DNS request.
static void cleanup(void *cls)
Function scheduled as very last function, cleans up after us.
static unsigned int dns_exit_available
Number of DNS exit peers we currently have in the cadet channel.
#define MAX_DNS_SIZE
How many bytes of payload do we allow at most for a DNS reply? Given that this is pretty much limited...
static void try_open_exit(void)
We are short on cadet exits, try to open another one.
static void channel_idle_notify_cb(void *cls, const struct GNUNET_CADET_Channel *channel, int window_size)
Function called whenever a channel has excess capacity.
static void submit_request(struct ReplyContext *rc)
Process the next record of the given request context.
static void handle_dht_result(void *cls, struct GNUNET_TIME_Absolute exp, const struct GNUNET_HashCode *key, const struct GNUNET_PeerIdentity *trunc_peer, const struct GNUNET_DHT_PathElement *get_path, unsigned int get_path_length, const struct GNUNET_DHT_PathElement *put_path, unsigned int put_path_length, enum GNUNET_BLOCK_Type type, size_t size, const void *data)
Function called whenever we find an advertisement for a DNS exit in the DHT.
static struct GNUNET_CADET_Handle * cadet_handle
The handle to the CADET service.
static void dns_post_request_handler(void *cls, struct GNUNET_DNS_RequestHandle *rh, size_t request_length, const char *request)
This function is called AFTER we got an IP address for a DNS request.
RequestGroup
Which group of DNS records are we currently processing?
@ ANSWERS
DNS answers.
@ ADDITIONAL_RECORDS
DNS additional records.
@ END
We're done processing.
@ AUTHORITY_RECORDS
DNS authority records.
#define MAX_OPEN_TUNNELS
How many channels do we open at most at the same time?
static void finish_request(struct ReplyContext *rc)
We're done modifying all records in the response.
static void handle_dns_response(void *cls, const struct DnsResponseMessage *msg)
Process a request via cadet to perform a DNS query.
static struct CadetExit * exit_tail
Tail of DLL of cadet exits.
int main(int argc, char *const *argv)
The main function.
static void cadet_channel_end_cb(void *cls, const struct GNUNET_CADET_Channel *channel)
Function called whenever a channel is destroyed.
static struct GNUNET_DHT_GetHandle * dht_get
Our DHT GET operation to find DNS exits.
static char * data
The data to insert into the dht.
struct GNUNET_HashCode key
The key used in the DHT.
static uint32_t type
Type string converted to DNS type value.
unsigned long long drop_percent
Set to non-zero values to create random drops to test retransmissions.
static struct GNUNET_VPN_RedirectionRequest * request
Opaque redirection request handle.
Definition: gnunet-vpn.c:40
Constants for network applications operating on top of the CADET service.
CADET service; establish channels to distant peers.
API to the DHT service.
API to access the DNS service.
API to create, modify and access statistics.
API to access the VPN service.
#define GNUNET_APPLICATION_PORT_INTERNET_RESOLVER
Internet DNS resolution (external DNS gateway).
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition: cadet_api.c:894
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:830
struct GNUNET_MQ_Handle * GNUNET_CADET_get_mq(const struct GNUNET_CADET_Channel *channel)
Obtain the message queue for a connected channel.
Definition: cadet_api.c:1066
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:774
struct GNUNET_CADET_Channel * GNUNET_CADET_channel_create(struct GNUNET_CADET_Handle *h, void *channel_cls, const struct GNUNET_PeerIdentity *destination, const struct GNUNET_HashCode *port, GNUNET_CADET_WindowSizeEventHandler window_changes, GNUNET_CADET_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Create a new channel towards a remote peer.
Definition: cadet_api.c:1015
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Generate a random unsigned 64-bit value.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
struct GNUNET_DHT_Handle * GNUNET_DHT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, unsigned int ht_len)
Initialize the connection with the DHT service.
Definition: dht_api.c:1037
void GNUNET_DHT_get_stop(struct GNUNET_DHT_GetHandle *get_handle)
Stop async DHT-get.
Definition: dht_api.c:1235
struct GNUNET_DHT_GetHandle * GNUNET_DHT_get_start(struct GNUNET_DHT_Handle *handle, enum GNUNET_BLOCK_Type type, const struct GNUNET_HashCode *key, uint32_t desired_replication_level, enum GNUNET_DHT_RouteOption options, const void *xquery, size_t xquery_size, GNUNET_DHT_GetIterator iter, void *iter_cls)
Perform an asynchronous GET operation on the DHT identified.
Definition: dht_api.c:1162
void GNUNET_DHT_disconnect(struct GNUNET_DHT_Handle *handle)
Shutdown connection with the DHT service.
Definition: dht_api.c:1060
@ GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE
Each peer along the way should process the request (otherwise only peers locally closest to the key w...
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void GNUNET_DNSPARSER_free_packet(struct GNUNET_DNSPARSER_Packet *p)
Free memory taken by a packet.
Definition: dnsparser.c:947
#define GNUNET_DNSPARSER_TYPE_A
#define GNUNET_DNSPARSER_TYPE_AAAA
int GNUNET_DNSPARSER_pack(const struct GNUNET_DNSPARSER_Packet *p, uint16_t max, char **buf, size_t *buf_length)
Given a DNS packet p, generate the corresponding UDP payload.
Definition: dnsparser.c:1392
struct GNUNET_DNSPARSER_Packet * GNUNET_DNSPARSER_parse(const char *udp_payload, size_t udp_payload_length)
Parse a UDP payload of a DNS packet in to a nice struct for further processing and manipulation.
Definition: dnsparser.c:727
void GNUNET_DNS_disconnect(struct GNUNET_DNS_Handle *dh)
Disconnect from the DNS service.
Definition: dns_api.c:363
void GNUNET_DNS_request_forward(struct GNUNET_DNS_RequestHandle *rh)
If a GNUNET_DNS_RequestHandler calls this function, the client has no desire to interfer with the req...
Definition: dns_api.c:237
void GNUNET_DNS_request_answer(struct GNUNET_DNS_RequestHandle *rh, uint16_t reply_length, const char *reply)
If a GNUNET_DNS_RequestHandler calls this function, the request is supposed to be answered with the d...
Definition: dns_api.c:296
struct GNUNET_DNS_Handle * GNUNET_DNS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, enum GNUNET_DNS_Flags flags, GNUNET_DNS_RequestHandler rh, void *rh_cls)
Connect to the service-dns.
Definition: dns_api.c:340
void GNUNET_DNS_request_drop(struct GNUNET_DNS_RequestHandle *rh)
If a GNUNET_DNS_RequestHandler calls this function, the request is to be dropped and no response shou...
Definition: dns_api.c:265
@ GNUNET_DNS_FLAG_PRE_RESOLUTION
This client should be called on requests that have not yet been resolved as this client provides a re...
@ GNUNET_DNS_FLAG_POST_RESOLUTION
This client wants to be called on the results of a DNS resolution (either resolved by PRE-RESOLUTION ...
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32.
#define GNUNET_log(kind,...)
void * cls
Closure for mv and cb.
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32;.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_UNUSED
gcc-ism to document unused arguments
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_free_nz(ptr)
Wrapper around free.
struct GNUNET_MQ_Envelope * GNUNET_MQ_env_copy(struct GNUNET_MQ_Envelope *env)
Function to copy an envelope.
Definition: mq.c:359
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:304
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:285
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
Definition: gnunet_mq_lib.h:63
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration,...
Definition: program.c:400
#define GNUNET_MESSAGE_TYPE_VPN_DNS_TO_INTERNET
Type of messages containing an DNS request for a DNS exit service.
#define GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET
Type of messages containing an DNS reply from a DNS exit service.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:562
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition: scheduler.c:1334
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1272
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
enum GNUNET_GenericReturnValue GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1230
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_max(struct GNUNET_TIME_Absolute t1, struct GNUNET_TIME_Absolute t2)
Return the maximum of two absolute time values.
Definition: time.c:367
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:737
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:316
struct GNUNET_VPN_Handle * GNUNET_VPN_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the VPN service.
Definition: vpn_api.c:490
struct GNUNET_VPN_RedirectionRequest * GNUNET_VPN_redirect_to_ip(struct GNUNET_VPN_Handle *vh, int result_af, int addr_af, const void *addr, struct GNUNET_TIME_Absolute expiration_time, GNUNET_VPN_AllocationCallback cb, void *cb_cls)
Tell the VPN that forwarding to the Internet via some exit node is requested.
Definition: vpn_api.c:439
void GNUNET_VPN_disconnect(struct GNUNET_VPN_Handle *vh)
Disconnect from the VPN service.
Definition: vpn_api.c:512
static unsigned int size
Size of the "table".
Definition: peer.c:68
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
GNUNET_BLOCK_Type
WARNING: This header is generated! In order to add DHT block types, you must register them in GANA,...
@ GNUNET_BLOCK_TYPE_DNS
Block for storing DNS exit service advertisements.
Handle to a peer that advertised that it is willing to serve as a DNS exit.
struct CadetExit * next
Kept in a DLL.
struct RequestContext * receive_queue_tail
Tail of DLL of requests waiting for a response.
struct CadetExit * prev
Kept in a DLL.
unsigned int num_answered
How many DNS requests were answered via this channel?
struct GNUNET_TIME_Absolute expiration
At what time did the peer's advertisement expire?
struct GNUNET_CADET_Channel * cadet_channel
Channel we use for DNS requests over CADET, NULL if we did not initialize a channel to this peer yet.
int idle
Size of the window, 0 if we are busy.
struct GNUNET_PeerIdentity peer
Identity of the peer that is providing the exit for us.
unsigned int num_transmitted
How many DNS requests did we transmit via this channel?
struct RequestContext * receive_queue_head
Head of DLL of requests waiting for a response.
Message with a DNS response.
struct GNUNET_MessageHeader header
GNUnet header, of type GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET.
struct GNUNET_TUN_DnsHeader dns
DNS header.
Opaque handle to a channel.
Definition: cadet.h:116
Opaque handle to the service.
Definition: cadet_api.c:39
Handle to a GET request.
Definition: dht_api.c:79
Connection to the DHT service.
Definition: dht_api.c:235
A (signed) path tracking a block's flow through the DHT is represented by an array of path elements,...
Easy-to-process, parsed version of a DNS packet.
unsigned int num_answers
Number of answers in the packet, should be 0 for queries.
struct GNUNET_DNSPARSER_Record * answers
Array of all answers in the packet, must contain "num_answers" entries.
unsigned int num_additional_records
Number of additional records in the packet, should be 0 for queries.
struct GNUNET_DNSPARSER_Record * additional_records
Array of all additional answers in the packet, must contain "num_additional_records" entries.
struct GNUNET_DNSPARSER_Record * authority_records
Array of all authority records in the packet, must contain "num_authority_records" entries.
unsigned int num_authority_records
Number of authoritative answers in the packet, should be 0 for queries.
void * data
Binary record data.
size_t data_len
Number of bytes in data.
A DNS response record.
uint16_t type
See GNUNET_DNSPARSER_TYPE_*.
struct GNUNET_DNSPARSER_RawRecord raw
Raw data for all other types.
union GNUNET_DNSPARSER_Record::@20 data
Payload of the record (which one of these is valid depends on the 'type').
This is the structure describing an DNS exit service.
Definition: block_dns.h:45
struct GNUNET_PeerIdentity peer
The peer providing this service.
Definition: block_dns.h:65
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does this signature expire?
Definition: block_dns.h:60
DNS handle.
Definition: dns_api.c:57
Handle to identify an individual DNS request.
Definition: dns_api.c:35
Definition of a command line option.
A 512-bit hashcode.
Message handler for a specific message type.
Header for all communications.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Definition: scheduler.c:136
Handle for the service.
Time for absolute times used by GNUnet, in microseconds.
uint16_t id
Unique identifier for the request/response.
Opaque VPN handle.
Definition: vpn_api.c:35
Opaque redirection request handle.
Definition: vpn_api.c:77
Information tracked per DNS reply that we are processing.
struct GNUNET_DNS_RequestHandle * rh
Handle to submit the final result.
struct GNUNET_DNSPARSER_Packet * dns
DNS packet that is being modified.
unsigned int offset
Offset in the current record group that is being modified.
struct GNUNET_DNSPARSER_Record * rec
Record for which we have an active redirection request.
struct GNUNET_VPN_RedirectionRequest * rr
Active redirection request with the VPN.
enum RequestGroup group
Group that is being modified.
State we keep for a request that is going out via CADET.
struct GNUNET_SCHEDULER_Task * timeout_task
Task used to abort this operation with timeout.
struct RequestContext * next
We keep these in a DLL.
struct CadetExit * exit
Exit that was chosen for this request.
struct GNUNET_MQ_Envelope * env
Envelope with the request we are transmitting.
uint16_t mlen
Length of the request message that follows this struct.
struct GNUNET_DNS_RequestHandle * rh
Handle for interaction with DNS service.
struct RequestContext * prev
We keep these in a DLL.
uint16_t dns_id
ID of the original DNS request (used to match the reply).