GNUnet  0.10.x
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"
28 #include "gnunet_dnsparser_lib.h"
29 #include "gnunet_cadet_service.h"
30 #include "gnunet_tun_lib.h"
31 #include "gnunet_dht_service.h"
32 #include "gnunet_vpn_service.h"
34 #include "gnunet_applications.h"
35 #include "block_dns.h"
36 
37 
41 #define TIMEOUT GNUNET_TIME_UNIT_MINUTES
42 
50 #define MAX_DNS_SIZE (8 * 1024)
51 
55 #define MAX_OPEN_TUNNELS 4
56 
57 
62 {
66  ANSWERS = 0,
67 
72 
77 
81  END = 3
82 };
83 
84 
89 {
94 
99 
104 
109 
113  unsigned int offset;
114 
119 
120 };
121 
122 
128 struct CadetExit
129 {
130 
134  struct CadetExit *next;
135 
139  struct CadetExit *prev;
140 
146 
151 
156 
161 
166 
170  unsigned int num_transmitted;
171 
175  unsigned int num_answered;
176 
180  /* unsigned */ int idle;
181 
182 };
183 
184 
185 
190 {
195 
200 
204  struct CadetExit *exit;
205 
210 
215 
220 
224  uint16_t mlen;
225 
229  uint16_t dns_id;
230 
231 };
232 
233 
239 static struct CadetExit *exit_head;
240 
244 static struct CadetExit *exit_tail;
245 
249 static const struct GNUNET_CONFIGURATION_Handle *cfg;
250 
255 
260 
265 
270 
275 
279 static struct GNUNET_DHT_Handle *dht;
280 
285 
289 static int ipv4_pt;
290 
294 static int ipv6_pt;
295 
299 static int dns_channel;
300 
306 static unsigned int dns_exit_available;
307 
308 
312 static void
313 try_open_exit (void);
314 
315 
325 static uint32_t
327 {
328  uint32_t dropped;
329  uint32_t drop_percent;
330  uint32_t good_percent;
331 
332  GNUNET_assert (exit->num_transmitted >= exit->num_answered);
333  dropped = exit->num_transmitted - exit->num_answered;
334  if (exit->num_transmitted > 0)
335  drop_percent = (uint32_t) ((100LL * dropped) / exit->num_transmitted);
336  else
337  drop_percent = 50; /* no data */
338  if ( (exit->num_transmitted > 20) &&
339  (drop_percent > 25) )
340  return 0; /* statistically significant, and > 25% loss, die */
341  good_percent = 100 - drop_percent;
342  GNUNET_assert (0 != good_percent);
343  if ( UINT32_MAX / good_percent / good_percent < exit->num_transmitted)
344  return UINT32_MAX; /* formula below would overflow */
345  return 1 + good_percent * good_percent * exit->num_transmitted;
346 }
347 
348 
360 static struct CadetExit *
362 {
363  struct CadetExit *pos;
364  uint64_t total_transmitted;
365  uint64_t selected_offset;
366  uint32_t channel_weight;
367 
368  total_transmitted = 0;
369  for (pos = exit_head; NULL != pos; pos = pos->next)
370  {
371  if (NULL == pos->cadet_channel)
372  break;
373  channel_weight = get_channel_weight (pos);
374  total_transmitted += channel_weight;
375  /* double weight for idle channels */
376  if (0 != pos->idle)
377  total_transmitted += channel_weight;
378  }
379  if (0 == total_transmitted)
380  {
381  /* no channels available, or only a very bad one... */
382  return exit_head;
383  }
385  total_transmitted);
386  total_transmitted = 0;
387  for (pos = exit_head; NULL != pos; pos = pos->next)
388  {
389  if (NULL == pos->cadet_channel)
390  break;
391  channel_weight = get_channel_weight (pos);
392  total_transmitted += channel_weight;
393  /* double weight for idle channels */
394  if (0 != pos->idle)
395  total_transmitted += channel_weight;
396  if (total_transmitted > selected_offset)
397  return pos;
398  }
399  GNUNET_break (0);
400  return NULL;
401 }
402 
403 
410 static void
412 {
413  char *buf;
414  size_t buf_len;
415 
416  if (GNUNET_SYSERR ==
418  MAX_DNS_SIZE,
419  &buf,
420  &buf_len))
421  {
423  _("Failed to pack DNS request. Dropping.\n"));
425  }
426  else
427  {
429  gettext_noop ("# DNS requests mapped to VPN"),
430  1, GNUNET_NO);
432  buf_len,
433  buf);
434  GNUNET_free (buf);
435  }
437  GNUNET_free (rc);
438 }
439 
440 
448 static void
449 submit_request (struct ReplyContext *rc);
450 
451 
467 static void
469  int af,
470  const void *address)
471 {
472  struct ReplyContext *rc = cls;
473 
474  rc->rr = NULL;
475  if (af == AF_UNSPEC)
476  {
479  GNUNET_free (rc);
480  return;
481  }
483  gettext_noop ("# DNS records modified"),
484  1,
485  GNUNET_NO);
486  switch (rc->rec->type)
487  {
489  GNUNET_assert (AF_INET == af);
490  GNUNET_memcpy (rc->rec->data.raw.data,
491  address,
492  sizeof (struct in_addr));
493  break;
495  GNUNET_assert (AF_INET6 == af);
496  GNUNET_memcpy (rc->rec->data.raw.data,
497  address,
498  sizeof (struct in6_addr));
499  break;
500  default:
501  GNUNET_assert (0);
502  return;
503  }
504  rc->rec = NULL;
505  submit_request (rc);
506 }
507 
508 
518 static void
521 {
522  int af;
523 
524  switch (rec->type)
525  {
527  af = AF_INET;
528  GNUNET_assert (rec->data.raw.data_len == sizeof (struct in_addr));
529  break;
531  af = AF_INET6;
532  GNUNET_assert (rec->data.raw.data_len == sizeof (struct in6_addr));
533  break;
534  default:
535  GNUNET_assert (0);
536  return;
537  }
538  rc->rec = rec;
539  rc->rr = GNUNET_VPN_redirect_to_ip (vpn_handle,
540  af,
541  af,
542  rec->data.raw.data,
545  rc);
546 }
547 
548 
556 static void
558 {
559  struct GNUNET_DNSPARSER_Record *ra;
560  unsigned int ra_len;
561  unsigned int i;
562 
563  while (1)
564  {
565  switch (rc->group)
566  {
567  case ANSWERS:
568  ra = rc->dns->answers;
569  ra_len = rc->dns->num_answers;
570  break;
571  case AUTHORITY_RECORDS:
572  ra = rc->dns->authority_records;
573  ra_len = rc->dns->num_authority_records;
574  break;
575  case ADDITIONAL_RECORDS:
576  ra = rc->dns->additional_records;
577  ra_len = rc->dns->num_additional_records;
578  break;
579  case END:
580  finish_request (rc);
581  return;
582  default:
583  GNUNET_assert (0);
584  }
585  for (i=rc->offset;i<ra_len;i++)
586  {
587  switch (ra[i].type)
588  {
590  if (ipv4_pt)
591  {
592  rc->offset = i + 1;
593  modify_address (rc,
594  &ra[i]);
595  return;
596  }
597  break;
599  if (ipv6_pt)
600  {
601  rc->offset = i + 1;
602  modify_address (rc,
603  &ra[i]);
604  return;
605  }
606  break;
607  }
608  }
609  rc->group++;
610  }
611 }
612 
613 
621 static int
623  unsigned int ra_len)
624 {
625  unsigned int i;
626 
627  for (i=0;i<ra_len;i++)
628  {
629  switch (ra[i].type)
630  {
632  if (ipv4_pt)
633  return GNUNET_YES;
634  break;
636  if (ipv6_pt)
637  return GNUNET_YES;
638  break;
639  }
640  }
641  return GNUNET_NO;
642 }
643 
644 
656 static void
659  size_t request_length,
660  const char *request)
661 {
663  struct ReplyContext *rc;
664  int work;
665 
667  gettext_noop ("# DNS replies intercepted"),
668  1, GNUNET_NO);
669  dns = GNUNET_DNSPARSER_parse (request,
670  request_length);
671  if (NULL == dns)
672  {
674  _("Failed to parse DNS request. Dropping.\n"));
676  return;
677  }
678  work = GNUNET_NO;
679  work |= work_test (dns->answers,
680  dns->num_answers);
681  work |= work_test (dns->authority_records,
682  dns->num_authority_records);
683  work |= work_test (dns->additional_records,
685  if (! work)
686  {
689  return;
690  }
691  rc = GNUNET_new (struct ReplyContext);
692  rc->rh = rh;
693  rc->dns = dns;
694  rc->offset = 0;
695  rc->group = ANSWERS;
696  submit_request (rc);
697 }
698 
699 
705 static void
706 timeout_request (void *cls)
707 {
708  struct RequestContext *rc = cls;
709  struct CadetExit *exit = rc->exit;
710 
712  gettext_noop ("# DNS requests dropped (timeout)"),
713  1,
714  GNUNET_NO);
716  GNUNET_free (rc);
717  if ( (0 == get_channel_weight (exit)) &&
718  (NULL == exit->receive_queue_head) )
719  {
720  /* this straw broke the camel's back: this channel now has
721  such a low score that it will not be used; close it! */
723  exit->cadet_channel = NULL;
724  GNUNET_CONTAINER_DLL_remove (exit_head,
725  exit_tail,
726  exit);
728  exit_tail,
729  exit);
730  /* go back to semi-innocent: mark as not great, but
731  avoid a prohibitively negative score (see
732  #get_channel_weight(), which checks for a certain
733  minimum number of transmissions before making
734  up an opinion) */
735  exit->num_transmitted = 5;
736  exit->num_answered = 0;
738  /* now try to open an alternative exit */
739  try_open_exit ();
740  }
741 }
742 
743 
755 static void
758  size_t request_length,
759  const char *request)
760 {
761  struct RequestContext *rc;
762  struct GNUNET_MQ_Envelope *env;
763  struct GNUNET_MessageHeader *hdr;
764  struct GNUNET_TUN_DnsHeader dns;
765  struct CadetExit *exit;
766 
768  gettext_noop ("# DNS requests intercepted"),
769  1, GNUNET_NO);
770  if (0 == dns_exit_available)
771  {
773  gettext_noop ("# DNS requests dropped (DNS cadet channel down)"),
774  1, GNUNET_NO);
776  return;
777  }
778  if (request_length < sizeof (dns))
779  {
781  gettext_noop ("# DNS requests dropped (malformed)"),
782  1, GNUNET_NO);
784  return;
785  }
786  exit = choose_exit ();
787  GNUNET_assert (NULL != exit);
788  GNUNET_assert (NULL != exit->cadet_channel);
789 
790  env = GNUNET_MQ_msg_extra (hdr,
791  request_length,
793  GNUNET_memcpy (&hdr[1],
794  request,
795  request_length);
796  rc = GNUNET_new (struct RequestContext);
797  rc->exit = exit;
798  rc->rh = rh;
801  rc);
802  GNUNET_memcpy (&dns,
803  request,
804  sizeof (dns));
805  rc->dns_id = dns.id;
806  rc->env = env;
808  exit->receive_queue_tail,
809  rc);
810  if (0 < exit->idle)
811  exit->idle--;
812  exit->num_transmitted++;
814  GNUNET_MQ_env_copy (env));
815 }
816 
817 
819 
823 struct DnsResponseMessage
824 {
828  struct GNUNET_MessageHeader header;
829 
833  struct GNUNET_TUN_DnsHeader dns;
834 
835  /* Followed by more DNS payload */
836 };
837 
839 
848 static int
850  const struct DnsResponseMessage *msg)
851 {
852  return GNUNET_OK; /* all OK */
853 }
854 
855 
862 static void
864  const struct DnsResponseMessage *msg)
865 {
866  struct CadetExit *exit = cls;
867  size_t mlen;
868  struct RequestContext *rc;
869 
870  mlen = ntohs (msg->header.size) - sizeof (*msg);
871  for (rc = exit->receive_queue_head; NULL != rc; rc = rc->next)
872  {
873  if (msg->dns.id == rc->dns_id)
874  {
876  gettext_noop ("# DNS replies received"),
877  1,
878  GNUNET_NO);
880  mlen + sizeof (struct GNUNET_TUN_DnsHeader),
881  (const void*) &msg->dns);
883  exit->receive_queue_tail,
884  rc);
886  GNUNET_MQ_discard (rc->env);
887  GNUNET_free (rc);
888  exit->num_answered++;
889  return;
890  }
891  }
893  gettext_noop ("# DNS replies dropped (too late?)"),
894  1, GNUNET_NO);
895 }
896 
897 
903 static void
905 {
906  struct RequestContext *rc;
907 
908  while (NULL != (rc = exit->receive_queue_head))
909  {
911  exit->receive_queue_tail,
912  rc);
915  GNUNET_MQ_discard (rc->env);
916  GNUNET_free (rc);
917  }
918 }
919 
920 
926 static void
927 cleanup (void *cls)
928 {
929  struct CadetExit *exit;
930 
932  "Protocol translation daemon is shutting down now\n");
933  if (NULL != vpn_handle)
934  {
935  GNUNET_VPN_disconnect (vpn_handle);
936  vpn_handle = NULL;
937  }
938  while (NULL != (exit = exit_head))
939  {
940  GNUNET_CONTAINER_DLL_remove (exit_head,
941  exit_tail,
942  exit);
943  if (NULL != exit->cadet_channel)
944  {
946  exit->cadet_channel = NULL;
947  }
948  abort_all_requests (exit);
949  GNUNET_free (exit);
950  }
951  if (NULL != cadet_handle)
952  {
953  GNUNET_CADET_disconnect (cadet_handle);
954  cadet_handle = NULL;
955  }
956  if (NULL != dns_post_handle)
957  {
958  GNUNET_DNS_disconnect (dns_post_handle);
959  dns_post_handle = NULL;
960  }
961  if (NULL != dns_pre_handle)
962  {
963  GNUNET_DNS_disconnect (dns_pre_handle);
964  dns_pre_handle = NULL;
965  }
966  if (NULL != stats)
967  {
969  stats = NULL;
970  }
971  if (NULL != dht_get)
972  {
973  GNUNET_DHT_get_stop (dht_get);
974  dht_get = NULL;
975  }
976  if (NULL != dht)
977  {
978  GNUNET_DHT_disconnect (dht);
979  dht = NULL;
980  }
981 }
982 
983 
995 static void
997  const struct GNUNET_CADET_Channel *channel)
998 {
999  struct CadetExit *exit = cls;
1000  struct CadetExit *alt;
1001  struct RequestContext *rc;
1002 
1003  exit->cadet_channel = NULL;
1005  /* open alternative channels */
1006  /* our channel is now closed, move our requests to an alternative
1007  channel */
1008  alt = choose_exit ();
1009  while (NULL != (rc = exit->receive_queue_head))
1010  {
1012  exit->receive_queue_tail,
1013  rc);
1014  rc->exit = alt;
1016  alt->receive_queue_tail,
1017  rc);
1019  GNUNET_MQ_env_copy (rc->env));
1020  }
1021  try_open_exit ();
1022 }
1023 
1024 
1032 static void
1034  const struct GNUNET_CADET_Channel *channel,
1035  int window_size)
1036 {
1037  struct CadetExit *pos = cls;
1038 
1039  pos->idle = window_size;
1040 }
1041 
1042 
1046 static void
1048 {
1049  struct CadetExit *pos;
1050  uint32_t candidate_count;
1051  uint32_t candidate_selected;
1052  struct GNUNET_HashCode port;
1053 
1056  &port);
1057  candidate_count = 0;
1058  for (pos = exit_head; NULL != pos; pos = pos->next)
1059  if (NULL == pos->cadet_channel)
1060  candidate_count++;
1061  if (0 == candidate_count)
1062  {
1064  "No DNS exits available yet.\n");
1065  return;
1066  }
1068  candidate_count);
1069  candidate_count = 0;
1070  for (pos = exit_head; NULL != pos; pos = pos->next)
1071  if (NULL == pos->cadet_channel)
1072  {
1073  candidate_count++;
1074  if (candidate_selected < candidate_count)
1075  {
1076  struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
1077  GNUNET_MQ_hd_var_size (dns_response,
1079  struct DnsResponseMessage,
1080  pos),
1082  };
1083 
1084 
1085  /* move to the head of the DLL */
1086  pos->cadet_channel
1087  = GNUNET_CADET_channel_create (cadet_handle,
1088  pos,
1089  &pos->peer,
1090  &port,
1094  cadet_handlers);
1095  if (NULL == pos->cadet_channel)
1096  {
1097  GNUNET_break (0);
1098  continue;
1099  }
1100  GNUNET_CONTAINER_DLL_remove (exit_head,
1101  exit_tail,
1102  pos);
1103  GNUNET_CONTAINER_DLL_insert (exit_head,
1104  exit_tail,
1105  pos);
1107  return;
1108  }
1109  }
1110  GNUNET_assert (NULL == exit_head);
1111 }
1112 
1113 
1133 static void
1135  struct GNUNET_TIME_Absolute exp,
1136  const struct GNUNET_HashCode *key,
1137  const struct GNUNET_PeerIdentity *get_path,
1138  unsigned int get_path_length,
1139  const struct GNUNET_PeerIdentity *put_path,
1140  unsigned int put_path_length,
1141  enum GNUNET_BLOCK_Type type,
1142  size_t size, const void *data)
1143 {
1144  const struct GNUNET_DNS_Advertisement *ad;
1145  struct CadetExit *exit;
1146 
1147  if (sizeof (struct GNUNET_DNS_Advertisement) != size)
1148  {
1149  GNUNET_break (0);
1150  return;
1151  }
1152  ad = data;
1153  for (exit = exit_head; NULL != exit; exit = exit->next)
1154  if (0 == GNUNET_memcmp (&ad->peer,
1155  &exit->peer))
1156  break;
1157  if (NULL == exit)
1158  {
1159  exit = GNUNET_new (struct CadetExit);
1160  exit->peer = ad->peer;
1161  /* channel is closed, so insert at the end */
1163  exit_tail,
1164  exit);
1165  }
1169  try_open_exit ();
1170 }
1171 
1172 
1181 static void
1182 run (void *cls, char *const *args GNUNET_UNUSED,
1183  const char *cfgfile GNUNET_UNUSED,
1184  const struct GNUNET_CONFIGURATION_Handle *cfg_)
1185 {
1186  struct GNUNET_HashCode dns_key;
1187 
1188  cfg = cfg_;
1189  stats = GNUNET_STATISTICS_create ("pt",
1190  cfg);
1192  "pt",
1193  "TUNNEL_IPV4");
1195  "pt",
1196  "TUNNEL_IPV6");
1198  "pt",
1199  "TUNNEL_DNS");
1200  if (! (ipv4_pt || ipv6_pt || dns_channel))
1201  {
1203  _("No useful service enabled. Exiting.\n"));
1205  return;
1206  }
1208  if (ipv4_pt || ipv6_pt)
1209  {
1210  dns_post_handle
1211  = GNUNET_DNS_connect (cfg,
1214  NULL);
1215  if (NULL == dns_post_handle)
1216  {
1218  _("Failed to connect to %s service. Exiting.\n"),
1219  "DNS");
1221  return;
1222  }
1223  vpn_handle = GNUNET_VPN_connect (cfg);
1224  if (NULL == vpn_handle)
1225  {
1227  _("Failed to connect to %s service. Exiting.\n"),
1228  "VPN");
1230  return;
1231  }
1232  }
1233  if (dns_channel)
1234  {
1235  dns_pre_handle
1236  = GNUNET_DNS_connect (cfg,
1239  NULL);
1240  if (NULL == dns_pre_handle)
1241  {
1243  _("Failed to connect to %s service. Exiting.\n"),
1244  "DNS");
1246  return;
1247  }
1248  cadet_handle = GNUNET_CADET_connect (cfg);
1249  if (NULL == cadet_handle)
1250  {
1252  _("Failed to connect to %s service. Exiting.\n"),
1253  "CADET");
1255  return;
1256  }
1257  dht = GNUNET_DHT_connect (cfg, 1);
1258  if (NULL == dht)
1259  {
1261  _("Failed to connect to %s service. Exiting.\n"),
1262  "DHT");
1264  return;
1265  }
1266  GNUNET_CRYPTO_hash ("dns",
1267  strlen ("dns"),
1268  &dns_key);
1269  dht_get = GNUNET_DHT_get_start (dht,
1271  &dns_key,
1272  1,
1274  NULL, 0,
1276  NULL);
1277  }
1278 }
1279 
1280 
1288 int
1289 main (int argc,
1290  char *const *argv)
1291 {
1292  static const struct GNUNET_GETOPT_CommandLineOption options[] = {
1294  };
1295  int ret;
1296 
1298  argv,
1299  &argc,
1300  &argv))
1301  return 2;
1302  ret = (GNUNET_OK ==
1303  GNUNET_PROGRAM_run (argc,
1304  argv,
1305  "gnunet-daemon-pt",
1306  gettext_noop ("Daemon to run to perform IP protocol translation to GNUnet"),
1307  options,
1308  &run,
1309  NULL))
1310  ? 0
1311  : 1;
1312  GNUNET_free ((void*) argv);
1313  return ret;
1314 }
1315 
1316 
1317 /* end of gnunet-daemon-pt.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct GNUNET_DNSPARSER_Record * answers
Array of all answers in the packet, must contain "num_answers" entries.
uint16_t type
See GNUNET_DNSPARSER_TYPE_*.
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:849
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 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 void submit_request(struct ReplyContext *rc)
Process the next record of the given request context.
unsigned int offset
Offset in the current record group that is being modified.
static struct GNUNET_DHT_GetHandle * dht_get
Our DHT GET operation to find DNS exits.
struct GNUNET_PeerIdentity peer
Identity of the peer that is providing the exit for us.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static char * expiration
Credential TTL.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:670
This is the structure describing an DNS exit service.
Definition: block_dns.h:40
uint16_t mlen
Length of the request message that follows this struct.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
Opaque handle to the service.
Definition: cadet_api.c:38
struct GNUNET_VPN_RedirectionRequest * rr
Active redirection request with the VPN.
DNS answers.
GNUNET_BLOCK_Type
Blocks in the datastore and the datacache must have a unique type.
#define GNUNET_UNUSED
gcc-ism to document unused arguments
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Random on unsigned 64-bit values.
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, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1293
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
int GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1521
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:245
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
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:1259
This client wants to be called on the results of a DNS resolution (either resolved by PRE-RESOLUTION ...
static const struct GNUNET_CONFIGURATION_Handle * cfg
The handle to the configuration used throughout the process.
static struct GNUNET_CADET_Handle * cadet_handle
The handle to the CADET service.
struct GNUNET_MessageHeader header
GNUnet header, of type GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET.
void GNUNET_DNSPARSER_free_packet(struct GNUNET_DNSPARSER_Packet *p)
Free memory taken by a packet.
Definition: dnsparser.c:854
We&#39;re done processing.
struct GNUNET_TIME_Absolute expiration
At what time did the peer&#39;s advertisement expire?
#define GNUNET_NO
Definition: gnunet_common.h:81
Opaque handle to a channel.
Definition: cadet_api.c:80
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
static void vpn_allocation_callback(void *cls, int af, const void *address)
Callback invoked from the VPN service once a redirection is available.
enum RequestGroup group
Group that is being modified.
static void work(void *cls)
Function called to process work items.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Definition of a command line option.
DNS additional records.
static void handle_dht_result(void *cls, struct GNUNET_TIME_Absolute exp, const struct GNUNET_HashCode *key, const struct GNUNET_PeerIdentity *get_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *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.
#define GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET
Type of messages containing an DNS reply from a DNS exit service.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
unsigned int num_answered
How many DNS requests were answered via this channel?
struct GNUNET_DNSPARSER_Record * additional_records
Array of all additional answers in the packet, must contain "num_additional_records" entries...
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.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
static unsigned int dns_exit_available
Number of DNS exit peers we currently have in the cadet channel.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:524
static int ret
Final status code.
Definition: gnunet-arm.c:89
Handle for the service.
static struct CadetExit * exit_head
Head of DLL of cadet exits.
static uint32_t get_channel_weight(struct CadetExit *exit)
Compute the weight of the given exit.
unsigned int num_answers
Number of answers in the packet, should be 0 for queries.
uint16_t id
Unique identifier for the request/response.
unsigned int num_transmitted
How many DNS requests did we transmit via this channel?
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct CadetExit * exit
Exit that was chosen for this request.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won&#39;t work on W32.
Connection to the DHT service.
Definition: dht_api.c:205
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition: cadet_api.c:995
Opaque VPN handle.
Definition: vpn_api.c:34
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
Block for storing DNS exit service advertisements.
struct GNUNET_CADET_Channel * cadet_channel
Channel we use for DNS requests over CADET, NULL if we did not initialze a channel to this peer yet...
#define GNUNET_MESSAGE_TYPE_VPN_DNS_TO_INTERNET
Type of messages containing an DNS request for a DNS exit service.
static struct CadetExit * choose_exit()
Choose a cadet exit for a DNS request.
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 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:52
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:1246
void GNUNET_DNS_disconnect(struct GNUNET_DNS_Handle *dh)
Disconnect from the DNS service.
Definition: dns_api.c:373
DNS authority records.
#define GNUNET_memcpy(dst, src, n)
struct CadetExit * next
Kept in a DLL.
void * cls
Closure for mv and cb.
unsigned int num_additional_records
Number of additional records in the packet, should be 0 for queries.
static void handle_dns_response(void *cls, const struct DnsResponseMessage *msg)
Process a request via cadet to perform a DNS query.
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:662
static int dns_channel
Are we channeling DNS queries?
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:44
struct GNUNET_SCHEDULER_Task * timeout_task
Task used to abort this operation with timeout.
static int ipv6_pt
Are we doing IPv6-pt?
struct RequestContext * next
We keep these in a DLL.
struct RequestContext * prev
We keep these in a DLL.
#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 struct GNUNET_DNS_Handle * dns_pre_handle
The handle to DNS pre-resolution modifications.
static void finish_request(struct ReplyContext *rc)
We&#39;re done modifying all records in the response.
void GNUNET_VPN_disconnect(struct GNUNET_VPN_Handle *vh)
Disconnect from the VPN service.
Definition: vpn_api.c:526
struct GNUNET_DNSPARSER_Record * rec
Record for which we have an active redirection request.
static char buf[2048]
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:317
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.
Default options: unreliable, default buffering, not out of order.
int main(int argc, char *const *argv)
The main function.
State we keep for a request that is going out via CADET.
uint16_t dns_id
ID of the original DNS request (used to match the reply).
A DNS response record.
struct GNUNET_DNSPARSER_Record * authority_records
Array of all authority records in the packet, must contain "num_authority_records" entries...
A 512-bit hashcode.
Message handler for a specific message type.
void GNUNET_DHT_get_stop(struct GNUNET_DHT_GetHandle *get_handle)
Stop async DHT-get.
Definition: dht_api.c:1160
unsigned long long drop_percent
Set to non-zero values to create random drops to test retransmissions.
struct GNUNET_PeerIdentity peer
The peer providing this service.
Definition: block_dns.h:61
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.
struct GNUNET_MQ_Envelope * env
Envelope with the request we are transmitting.
struct GNUNET_DNSPARSER_Packet * dns
DNS packet that is being modified.
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:321
DNS handle.
Definition: dns_api.c:58
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
struct GNUNET_HashCode key
The key used in the DHT.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static int ipv4_pt
Are we doing IPv4-pt?
static unsigned int size
Size of the "table".
Definition: peer.c:67
size_t data_len
Number of bytes in data.
static void try_open_exit(void)
We are short on cadet exits, try to open another one.
void * data
Binary record data.
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:895
Opaque redirection request handle.
Definition: vpn_api.c:77
void GNUNET_DHT_disconnect(struct GNUNET_DHT_Handle *handle)
Shutdown connection with the DHT service.
Definition: dht_api.c:923
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static void cadet_channel_end_cb(void *cls, const struct GNUNET_CADET_Channel *channel)
Function called whenever a channel is destroyed.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
unsigned int num_authority_records
Number of authoritative answers in the packet, should be 0 for queries.
static struct GNUNET_DHT_Handle * dht
Handle to access the DHT.
struct GNUNET_TUN_DnsHeader dns
DNS header.
static void abort_all_requests(struct CadetExit *exit)
Abort all pending DNS requests with the given cadet exit.
struct RequestContext * receive_queue_tail
Tail of DLL of requests waiting for a response.
Handle to a GET request.
Definition: dht_api.c:80
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
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:350
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won&#39;t work on W32;.
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:306
struct GNUNET_VPN_Handle * GNUNET_VPN_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the VPN service.
Definition: vpn_api.c:504
The identity of the host (wraps the signing key of the peer).
Handle to identify an individual DNS request.
Definition: dns_api.c:34
#define GNUNET_DNSPARSER_TYPE_AAAA
configuration data
Definition: configuration.c:85
void GNUNET_DNS_request_forward(struct GNUNET_DNS_RequestHandle *rh)
If a GNUNET_DNS_RequestHandler calls this function, the request is given to other clients or the glob...
Definition: dns_api.c:247
int idle
Size of the window, 0 if we are busy.
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.
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:1072
Easy-to-process, parsed version of a DNS packet.
Message with a DNS response.
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
#define GNUNET_APPLICATION_PORT_INTERNET_RESOLVER
Internet DNS resolution (external DNS gateway).
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:275
int 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, parse options).
Definition: program.c:361
RequestGroup
Which group of DNS records are we currently processing?
#define MAX_OPEN_TUNNELS
How many channels do we open at most at the same time?
This client should be called on requests that have not yet been resolved as this client provides a re...
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
Header for all communications.
Time for absolute times used by GNUnet, in microseconds.
struct RequestContext * receive_queue_head
Head of DLL of requests waiting for a response.
#define GNUNET_YES
Definition: gnunet_common.h:80
static struct CadetExit * exit_tail
Tail of DLL of cadet exits.
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:353
#define TIMEOUT
After how long do we time out if we could not get an IP from VPN or CADET?
union GNUNET_DNSPARSER_Record::@27 data
Payload of the record (which one of these is valid depends on the &#39;type&#39;).
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does this signature expire?
Definition: block_dns.h:56
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
struct GNUNET_DNS_RequestHandle * rh
Handle to submit the final result.
Handle to a peer that advertised that it is willing to serve as a DNS exit.
int 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".
uint32_t data
The data value.
struct GNUNET_MQ_Envelope * GNUNET_MQ_env_copy(struct GNUNET_MQ_Envelope *env)
Function to copy an envelope.
Definition: mq.c:414
struct CadetExit * prev
Kept in a DLL.
struct GNUNET_DNS_RequestHandle * rh
Handle for interaction with DNS service.
static char * address
GNS address for this phone.
struct GNUNET_DNSPARSER_RawRecord raw
Raw data for all other types.
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:911
#define GNUNET_DNSPARSER_TYPE_A
static void timeout_request(void *cls)
Task run if the time to answer a DNS request via CADET is over.
Information tracked per DNS reply that we are processing.
static struct GNUNET_DNS_Handle * dns_post_handle
The handle to DNS post-resolution modifications.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
Each peer along the way should look at &#39;enc&#39; (otherwise only the k-peers closest to the key should lo...
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
static void cleanup(void *cls)
Function scheduled as very last function, cleans up after us.
#define GNUNET_free(ptr)
Wrapper around free.
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, enum GNUNET_CADET_ChannelOption options, 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:1088
#define gettext_noop(String)
Definition: gettext.h:69
struct GNUNET_MQ_Handle * GNUNET_CADET_get_mq(const struct GNUNET_CADET_Channel *channel)
Obtain the message queue for a connected peer.
Definition: cadet_api.c:1142
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965
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:455