GNUnet  0.11.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 
127 struct CadetExit
128 {
132  struct CadetExit *next;
133 
137  struct CadetExit *prev;
138 
144 
149 
154 
159 
164 
168  unsigned int num_transmitted;
169 
173  unsigned int num_answered;
174 
178  /* unsigned */ int idle;
179 };
180 
181 
186 {
191 
196 
200  struct CadetExit *exit;
201 
206 
211 
216 
220  uint16_t mlen;
221 
225  uint16_t dns_id;
226 };
227 
228 
234 static struct CadetExit *exit_head;
235 
239 static struct CadetExit *exit_tail;
240 
244 static const struct GNUNET_CONFIGURATION_Handle *cfg;
245 
250 
255 
260 
265 
270 
274 static struct GNUNET_DHT_Handle *dht;
275 
280 
284 static int ipv4_pt;
285 
289 static int ipv6_pt;
290 
294 static int dns_channel;
295 
301 static unsigned int dns_exit_available;
302 
303 
307 static void
308 try_open_exit (void);
309 
310 
320 static uint32_t
322 {
323  uint32_t dropped;
324  uint32_t drop_percent;
325  uint32_t good_percent;
326 
327  GNUNET_assert (exit->num_transmitted >= exit->num_answered);
328  dropped = exit->num_transmitted - exit->num_answered;
329  if (exit->num_transmitted > 0)
330  drop_percent = (uint32_t) ((100LL * dropped) / exit->num_transmitted);
331  else
332  drop_percent = 50; /* no data */
333  if ((exit->num_transmitted > 20) &&
334  (drop_percent > 25))
335  return 0; /* statistically significant, and > 25% loss, die */
336  good_percent = 100 - drop_percent;
337  GNUNET_assert (0 != good_percent);
338  if (UINT32_MAX / good_percent / good_percent < exit->num_transmitted)
339  return UINT32_MAX; /* formula below would overflow */
340  return 1 + good_percent * good_percent * exit->num_transmitted;
341 }
342 
343 
355 static struct CadetExit *
357 {
358  struct CadetExit *pos;
359  uint64_t total_transmitted;
360  uint64_t selected_offset;
361  uint32_t channel_weight;
362 
363  total_transmitted = 0;
364  for (pos = exit_head; NULL != pos; pos = pos->next)
365  {
366  if (NULL == pos->cadet_channel)
367  break;
368  channel_weight = get_channel_weight (pos);
369  total_transmitted += channel_weight;
370  /* double weight for idle channels */
371  if (0 != pos->idle)
372  total_transmitted += channel_weight;
373  }
374  if (0 == total_transmitted)
375  {
376  /* no channels available, or only a very bad one... */
377  return exit_head;
378  }
380  total_transmitted);
381  total_transmitted = 0;
382  for (pos = exit_head; NULL != pos; pos = pos->next)
383  {
384  if (NULL == pos->cadet_channel)
385  break;
386  channel_weight = get_channel_weight (pos);
387  total_transmitted += channel_weight;
388  /* double weight for idle channels */
389  if (0 != pos->idle)
390  total_transmitted += channel_weight;
391  if (total_transmitted > selected_offset)
392  return pos;
393  }
394  GNUNET_break (0);
395  return NULL;
396 }
397 
398 
405 static void
407 {
408  char *buf;
409  size_t buf_len;
410 
411  if (GNUNET_SYSERR ==
413  MAX_DNS_SIZE,
414  &buf,
415  &buf_len))
416  {
418  _ ("Failed to pack DNS request. Dropping.\n"));
420  }
421  else
422  {
424  gettext_noop ("# DNS requests mapped to VPN"),
425  1, GNUNET_NO);
427  buf_len,
428  buf);
429  GNUNET_free (buf);
430  }
432  GNUNET_free (rc);
433 }
434 
435 
443 static void
444 submit_request (struct ReplyContext *rc);
445 
446 
462 static void
464  int af,
465  const void *address)
466 {
467  struct ReplyContext *rc = cls;
468 
469  rc->rr = NULL;
470  if (af == AF_UNSPEC)
471  {
474  GNUNET_free (rc);
475  return;
476  }
478  gettext_noop ("# DNS records modified"),
479  1,
480  GNUNET_NO);
481  switch (rc->rec->type)
482  {
484  GNUNET_assert (AF_INET == af);
485  GNUNET_memcpy (rc->rec->data.raw.data,
486  address,
487  sizeof(struct in_addr));
488  break;
489 
491  GNUNET_assert (AF_INET6 == af);
492  GNUNET_memcpy (rc->rec->data.raw.data,
493  address,
494  sizeof(struct in6_addr));
495  break;
496 
497  default:
498  GNUNET_assert (0);
499  return;
500  }
501  rc->rec = NULL;
502  submit_request (rc);
503 }
504 
505 
515 static void
518 {
519  int af;
520 
521  switch (rec->type)
522  {
524  af = AF_INET;
525  GNUNET_assert (rec->data.raw.data_len == sizeof(struct in_addr));
526  break;
527 
529  af = AF_INET6;
530  GNUNET_assert (rec->data.raw.data_len == sizeof(struct in6_addr));
531  break;
532 
533  default:
534  GNUNET_assert (0);
535  return;
536  }
537  rc->rec = rec;
538  rc->rr = GNUNET_VPN_redirect_to_ip (vpn_handle,
539  af,
540  af,
541  rec->data.raw.data,
543  TIMEOUT),
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 
572  case AUTHORITY_RECORDS:
573  ra = rc->dns->authority_records;
574  ra_len = rc->dns->num_authority_records;
575  break;
576 
577  case ADDITIONAL_RECORDS:
578  ra = rc->dns->additional_records;
579  ra_len = rc->dns->num_additional_records;
580  break;
581 
582  case END:
583  finish_request (rc);
584  return;
585 
586  default:
587  GNUNET_assert (0);
588  }
589  for (i = rc->offset; i < ra_len; i++)
590  {
591  switch (ra[i].type)
592  {
594  if (ipv4_pt)
595  {
596  rc->offset = i + 1;
597  modify_address (rc,
598  &ra[i]);
599  return;
600  }
601  break;
602 
604  if (ipv6_pt)
605  {
606  rc->offset = i + 1;
607  modify_address (rc,
608  &ra[i]);
609  return;
610  }
611  break;
612  }
613  }
614  rc->group++;
615  }
616 }
617 
618 
626 static int
628  unsigned int ra_len)
629 {
630  unsigned int i;
631 
632  for (i = 0; i < ra_len; i++)
633  {
634  switch (ra[i].type)
635  {
637  if (ipv4_pt)
638  return GNUNET_YES;
639  break;
640 
642  if (ipv6_pt)
643  return GNUNET_YES;
644  break;
645  }
646  }
647  return GNUNET_NO;
648 }
649 
650 
662 static void
665  size_t request_length,
666  const char *request)
667 {
669  struct ReplyContext *rc;
670  int work;
671 
673  gettext_noop ("# DNS replies intercepted"),
674  1, GNUNET_NO);
675  dns = GNUNET_DNSPARSER_parse (request,
676  request_length);
677  if (NULL == dns)
678  {
680  _ ("Failed to parse DNS request. Dropping.\n"));
682  return;
683  }
684  work = GNUNET_NO;
685  work |= work_test (dns->answers,
686  dns->num_answers);
687  work |= work_test (dns->authority_records,
688  dns->num_authority_records);
689  work |= work_test (dns->additional_records,
691  if (! work)
692  {
695  return;
696  }
697  rc = GNUNET_new (struct ReplyContext);
698  rc->rh = rh;
699  rc->dns = dns;
700  rc->offset = 0;
701  rc->group = ANSWERS;
702  submit_request (rc);
703 }
704 
705 
711 static void
712 timeout_request (void *cls)
713 {
714  struct RequestContext *rc = cls;
715  struct CadetExit *exit = rc->exit;
716 
718  gettext_noop ("# DNS requests dropped (timeout)"),
719  1,
720  GNUNET_NO);
722  GNUNET_free (rc);
723  if ((0 == get_channel_weight (exit)) &&
724  (NULL == exit->receive_queue_head))
725  {
726  /* this straw broke the camel's back: this channel now has
727  such a low score that it will not be used; close it! */
729  exit->cadet_channel = NULL;
730  GNUNET_CONTAINER_DLL_remove (exit_head,
731  exit_tail,
732  exit);
734  exit_tail,
735  exit);
736  /* go back to semi-innocent: mark as not great, but
737  avoid a prohibitively negative score (see
738  #get_channel_weight(), which checks for a certain
739  minimum number of transmissions before making
740  up an opinion) */exit->num_transmitted = 5;
741  exit->num_answered = 0;
743  /* now try to open an alternative exit */
744  try_open_exit ();
745  }
746 }
747 
748 
760 static void
763  size_t request_length,
764  const char *request)
765 {
766  struct RequestContext *rc;
767  struct GNUNET_MQ_Envelope *env;
768  struct GNUNET_MessageHeader *hdr;
769  struct GNUNET_TUN_DnsHeader dns;
770  struct CadetExit *exit;
771 
773  gettext_noop ("# DNS requests intercepted"),
774  1, GNUNET_NO);
775  if (0 == dns_exit_available)
776  {
778  gettext_noop (
779  "# DNS requests dropped (DNS cadet channel down)"),
780  1, GNUNET_NO);
782  return;
783  }
784  if (request_length < sizeof(dns))
785  {
787  gettext_noop (
788  "# DNS requests dropped (malformed)"),
789  1, GNUNET_NO);
791  return;
792  }
793  exit = choose_exit ();
794  GNUNET_assert (NULL != exit);
795  GNUNET_assert (NULL != exit->cadet_channel);
796 
797  env = GNUNET_MQ_msg_extra (hdr,
798  request_length,
800  GNUNET_memcpy (&hdr[1],
801  request,
802  request_length);
803  rc = GNUNET_new (struct RequestContext);
804  rc->exit = exit;
805  rc->rh = rh;
808  rc);
809  GNUNET_memcpy (&dns,
810  request,
811  sizeof(dns));
812  rc->dns_id = dns.id;
813  rc->env = env;
815  exit->receive_queue_tail,
816  rc);
817  if (0 < exit->idle)
818  exit->idle--;
819  exit->num_transmitted++;
821  GNUNET_MQ_env_copy (env));
822 }
823 
824 
826 
830 struct DnsResponseMessage
831 {
835  struct GNUNET_MessageHeader header;
836 
840  struct GNUNET_TUN_DnsHeader dns;
841 
842  /* Followed by more DNS payload */
843 };
844 
846 
855 static int
857  const struct DnsResponseMessage *msg)
858 {
859  return GNUNET_OK; /* all OK */
860 }
861 
862 
869 static void
871  const struct DnsResponseMessage *msg)
872 {
873  struct CadetExit *exit = cls;
874  size_t mlen;
875  struct RequestContext *rc;
876 
877  mlen = ntohs (msg->header.size) - sizeof(*msg);
878  for (rc = exit->receive_queue_head; NULL != rc; rc = rc->next)
879  {
880  if (msg->dns.id == rc->dns_id)
881  {
883  gettext_noop ("# DNS replies received"),
884  1,
885  GNUNET_NO);
887  mlen + sizeof(struct GNUNET_TUN_DnsHeader),
888  (const void*) &msg->dns);
890  exit->receive_queue_tail,
891  rc);
893  GNUNET_MQ_discard (rc->env);
894  GNUNET_free (rc);
895  exit->num_answered++;
896  return;
897  }
898  }
900  gettext_noop ("# DNS replies dropped (too late?)"),
901  1, GNUNET_NO);
902 }
903 
904 
910 static void
912 {
913  struct RequestContext *rc;
914 
915  while (NULL != (rc = exit->receive_queue_head))
916  {
918  exit->receive_queue_tail,
919  rc);
922  GNUNET_MQ_discard (rc->env);
923  GNUNET_free (rc);
924  }
925 }
926 
927 
933 static void
934 cleanup (void *cls)
935 {
936  struct CadetExit *exit;
937 
939  "Protocol translation daemon is shutting down now\n");
940  if (NULL != vpn_handle)
941  {
942  GNUNET_VPN_disconnect (vpn_handle);
943  vpn_handle = NULL;
944  }
945  while (NULL != (exit = exit_head))
946  {
947  GNUNET_CONTAINER_DLL_remove (exit_head,
948  exit_tail,
949  exit);
950  if (NULL != exit->cadet_channel)
951  {
953  exit->cadet_channel = NULL;
954  }
955  abort_all_requests (exit);
956  GNUNET_free (exit);
957  }
958  if (NULL != cadet_handle)
959  {
960  GNUNET_CADET_disconnect (cadet_handle);
961  cadet_handle = NULL;
962  }
963  if (NULL != dns_post_handle)
964  {
965  GNUNET_DNS_disconnect (dns_post_handle);
966  dns_post_handle = NULL;
967  }
968  if (NULL != dns_pre_handle)
969  {
970  GNUNET_DNS_disconnect (dns_pre_handle);
971  dns_pre_handle = NULL;
972  }
973  if (NULL != stats)
974  {
976  stats = NULL;
977  }
978  if (NULL != dht_get)
979  {
980  GNUNET_DHT_get_stop (dht_get);
981  dht_get = NULL;
982  }
983  if (NULL != dht)
984  {
985  GNUNET_DHT_disconnect (dht);
986  dht = NULL;
987  }
988 }
989 
990 
1002 static void
1004  const struct GNUNET_CADET_Channel *channel)
1005 {
1006  struct CadetExit *exit = cls;
1007  struct CadetExit *alt;
1008  struct RequestContext *rc;
1009 
1010  exit->cadet_channel = NULL;
1012  /* open alternative channels */
1013  /* our channel is now closed, move our requests to an alternative
1014  channel */
1015  alt = choose_exit ();
1016  while (NULL != (rc = exit->receive_queue_head))
1017  {
1019  exit->receive_queue_tail,
1020  rc);
1021  rc->exit = alt;
1023  alt->receive_queue_tail,
1024  rc);
1026  GNUNET_MQ_env_copy (rc->env));
1027  }
1028  try_open_exit ();
1029 }
1030 
1031 
1039 static void
1041  const struct GNUNET_CADET_Channel *channel,
1042  int window_size)
1043 {
1044  struct CadetExit *pos = cls;
1045 
1046  pos->idle = window_size;
1047 }
1048 
1049 
1053 static void
1055 {
1056  struct CadetExit *pos;
1057  uint32_t candidate_count;
1058  uint32_t candidate_selected;
1059  struct GNUNET_HashCode port;
1060 
1063  &port);
1064  candidate_count = 0;
1065  for (pos = exit_head; NULL != pos; pos = pos->next)
1066  if (NULL == pos->cadet_channel)
1067  candidate_count++;
1068  if (0 == candidate_count)
1069  {
1071  "No DNS exits available yet.\n");
1072  return;
1073  }
1075  candidate_count);
1076  candidate_count = 0;
1077  for (pos = exit_head; NULL != pos; pos = pos->next)
1078  if (NULL == pos->cadet_channel)
1079  {
1080  candidate_count++;
1081  if (candidate_selected < candidate_count)
1082  {
1083  struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
1084  GNUNET_MQ_hd_var_size (dns_response,
1086  struct DnsResponseMessage,
1087  pos),
1089  };
1090 
1091 
1092  /* move to the head of the DLL */
1093  pos->cadet_channel
1094  = GNUNET_CADET_channel_create (cadet_handle,
1095  pos,
1096  &pos->peer,
1097  &port,
1100  cadet_handlers);
1101  if (NULL == pos->cadet_channel)
1102  {
1103  GNUNET_break (0);
1104  continue;
1105  }
1106  GNUNET_CONTAINER_DLL_remove (exit_head,
1107  exit_tail,
1108  pos);
1109  GNUNET_CONTAINER_DLL_insert (exit_head,
1110  exit_tail,
1111  pos);
1113  return;
1114  }
1115  }
1116  GNUNET_assert (NULL == exit_head);
1117 }
1118 
1119 
1139 static void
1141  struct GNUNET_TIME_Absolute exp,
1142  const struct GNUNET_HashCode *key,
1143  const struct GNUNET_PeerIdentity *get_path,
1144  unsigned int get_path_length,
1145  const struct GNUNET_PeerIdentity *put_path,
1146  unsigned int put_path_length,
1147  enum GNUNET_BLOCK_Type type,
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 
1188 static void
1189 run (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_;
1196  stats = GNUNET_STATISTICS_create ("pt",
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  {
1217  dns_post_handle
1218  = GNUNET_DNS_connect (cfg,
1221  NULL);
1222  if (NULL == dns_post_handle)
1223  {
1225  _ ("Failed to connect to %s service. Exiting.\n"),
1226  "DNS");
1228  return;
1229  }
1230  vpn_handle = GNUNET_VPN_connect (cfg);
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  {
1242  dns_pre_handle
1243  = GNUNET_DNS_connect (cfg,
1246  NULL);
1247  if (NULL == dns_pre_handle)
1248  {
1250  _ ("Failed to connect to %s service. Exiting.\n"),
1251  "DNS");
1253  return;
1254  }
1255  cadet_handle = GNUNET_CADET_connect (cfg);
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);
1276  dht_get = GNUNET_DHT_get_start (dht,
1278  &dns_key,
1279  1,
1281  NULL, 0,
1283  NULL);
1284  }
1285 }
1286 
1287 
1295 int
1296 main (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 ((void*) argv);
1321  return ret;
1322 }
1323 
1324 
1325 /* 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:841
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 struct GNUNET_VPN_RedirectionRequest * request
Opaque redirection request handle.
Definition: gnunet-vpn.c:41
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:673
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:1300
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:1438
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:246
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:1257
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.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
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:78
Opaque handle to a channel.
Definition: cadet_api.c:80
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
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:526
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:201
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition: cadet_api.c:976
Opaque VPN handle.
Definition: vpn_api.c:34
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
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:1253
void GNUNET_DNS_disconnect(struct GNUNET_DNS_Handle *dh)
Disconnect from the DNS service.
Definition: dns_api.c:369
DNS authority records.
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:656
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:48
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:534
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
union GNUNET_DNSPARSER_Record::@24 data
Payload of the record (which one of these is valid depends on the &#39;type&#39;).
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.
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.
static char * expiration
Credential TTL.
Definition: gnunet-abd.c:96
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:1155
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:56
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:76
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:890
Opaque redirection request handle.
Definition: vpn_api.c:76
void GNUNET_DHT_disconnect(struct GNUNET_DHT_Handle *handle)
Shutdown connection with the DHT service.
Definition: dht_api.c:918
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:79
#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:346
#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:302
struct GNUNET_VPN_Handle * GNUNET_VPN_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the VPN service.
Definition: vpn_api.c:512
The identity of the host (wraps the signing key of the peer).
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:1068
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:243
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:1067
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:271
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:367
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:77
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?
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:903
#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.
#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:1119
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966
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:461