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 
65  ANSWERS = 0,
66 
71 
76 
80  END = 3
81 };
82 
83 
87 struct ReplyContext {
92 
97 
102 
107 
111  unsigned int offset;
112 
117 };
118 
119 
125 struct CadetExit {
129  struct CadetExit *next;
130 
134  struct CadetExit *prev;
135 
141 
146 
151 
156 
161 
165  unsigned int num_transmitted;
166 
170  unsigned int num_answered;
171 
175  /* unsigned */ int idle;
176 };
177 
178 
179 
188 
193 
197  struct CadetExit *exit;
198 
203 
208 
213 
217  uint16_t mlen;
218 
222  uint16_t dns_id;
223 };
224 
225 
231 static struct CadetExit *exit_head;
232 
236 static struct CadetExit *exit_tail;
237 
241 static const struct GNUNET_CONFIGURATION_Handle *cfg;
242 
247 
252 
257 
262 
267 
271 static struct GNUNET_DHT_Handle *dht;
272 
277 
281 static int ipv4_pt;
282 
286 static int ipv6_pt;
287 
291 static int dns_channel;
292 
298 static unsigned int dns_exit_available;
299 
300 
304 static void
305 try_open_exit(void);
306 
307 
317 static uint32_t
319 {
320  uint32_t dropped;
321  uint32_t drop_percent;
322  uint32_t good_percent;
323 
325  dropped = exit->num_transmitted - exit->num_answered;
326  if (exit->num_transmitted > 0)
327  drop_percent = (uint32_t)((100LL * dropped) / exit->num_transmitted);
328  else
329  drop_percent = 50; /* no data */
330  if ((exit->num_transmitted > 20) &&
331  (drop_percent > 25))
332  return 0; /* statistically significant, and > 25% loss, die */
333  good_percent = 100 - drop_percent;
334  GNUNET_assert(0 != good_percent);
335  if (UINT32_MAX / good_percent / good_percent < exit->num_transmitted)
336  return UINT32_MAX; /* formula below would overflow */
337  return 1 + good_percent * good_percent * exit->num_transmitted;
338 }
339 
340 
352 static struct CadetExit *
354 {
355  struct CadetExit *pos;
356  uint64_t total_transmitted;
357  uint64_t selected_offset;
358  uint32_t channel_weight;
359 
360  total_transmitted = 0;
361  for (pos = exit_head; NULL != pos; pos = pos->next)
362  {
363  if (NULL == pos->cadet_channel)
364  break;
365  channel_weight = get_channel_weight(pos);
366  total_transmitted += channel_weight;
367  /* double weight for idle channels */
368  if (0 != pos->idle)
369  total_transmitted += channel_weight;
370  }
371  if (0 == total_transmitted)
372  {
373  /* no channels available, or only a very bad one... */
374  return exit_head;
375  }
377  total_transmitted);
378  total_transmitted = 0;
379  for (pos = exit_head; NULL != pos; pos = pos->next)
380  {
381  if (NULL == pos->cadet_channel)
382  break;
383  channel_weight = get_channel_weight(pos);
384  total_transmitted += channel_weight;
385  /* double weight for idle channels */
386  if (0 != pos->idle)
387  total_transmitted += channel_weight;
388  if (total_transmitted > selected_offset)
389  return pos;
390  }
391  GNUNET_break(0);
392  return NULL;
393 }
394 
395 
402 static void
404 {
405  char *buf;
406  size_t buf_len;
407 
408  if (GNUNET_SYSERR ==
410  MAX_DNS_SIZE,
411  &buf,
412  &buf_len))
413  {
415  _("Failed to pack DNS request. Dropping.\n"));
417  }
418  else
419  {
421  gettext_noop("# DNS requests mapped to VPN"),
422  1, GNUNET_NO);
424  buf_len,
425  buf);
426  GNUNET_free(buf);
427  }
429  GNUNET_free(rc);
430 }
431 
432 
440 static void
441 submit_request(struct ReplyContext *rc);
442 
443 
459 static void
461  int af,
462  const void *address)
463 {
464  struct ReplyContext *rc = cls;
465 
466  rc->rr = NULL;
467  if (af == AF_UNSPEC)
468  {
471  GNUNET_free(rc);
472  return;
473  }
475  gettext_noop("# DNS records modified"),
476  1,
477  GNUNET_NO);
478  switch (rc->rec->type)
479  {
481  GNUNET_assert(AF_INET == af);
483  address,
484  sizeof(struct in_addr));
485  break;
486 
488  GNUNET_assert(AF_INET6 == af);
490  address,
491  sizeof(struct in6_addr));
492  break;
493 
494  default:
495  GNUNET_assert(0);
496  return;
497  }
498  rc->rec = NULL;
499  submit_request(rc);
500 }
501 
502 
512 static void
515 {
516  int af;
517 
518  switch (rec->type)
519  {
521  af = AF_INET;
522  GNUNET_assert(rec->data.raw.data_len == sizeof(struct in_addr));
523  break;
524 
526  af = AF_INET6;
527  GNUNET_assert(rec->data.raw.data_len == sizeof(struct in6_addr));
528  break;
529 
530  default:
531  GNUNET_assert(0);
532  return;
533  }
534  rc->rec = rec;
535  rc->rr = GNUNET_VPN_redirect_to_ip(vpn_handle,
536  af,
537  af,
538  rec->data.raw.data,
541  rc);
542 }
543 
544 
552 static void
554 {
555  struct GNUNET_DNSPARSER_Record *ra;
556  unsigned int ra_len;
557  unsigned int i;
558 
559  while (1)
560  {
561  switch (rc->group)
562  {
563  case ANSWERS:
564  ra = rc->dns->answers;
565  ra_len = rc->dns->num_answers;
566  break;
567 
568  case AUTHORITY_RECORDS:
569  ra = rc->dns->authority_records;
570  ra_len = rc->dns->num_authority_records;
571  break;
572 
573  case ADDITIONAL_RECORDS:
574  ra = rc->dns->additional_records;
575  ra_len = rc->dns->num_additional_records;
576  break;
577 
578  case END:
579  finish_request(rc);
580  return;
581 
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;
598 
600  if (ipv6_pt)
601  {
602  rc->offset = i + 1;
603  modify_address(rc,
604  &ra[i]);
605  return;
606  }
607  break;
608  }
609  }
610  rc->group++;
611  }
612 }
613 
614 
622 static int
624  unsigned int ra_len)
625 {
626  unsigned int i;
627 
628  for (i = 0; i < ra_len; i++)
629  {
630  switch (ra[i].type)
631  {
633  if (ipv4_pt)
634  return GNUNET_YES;
635  break;
636 
638  if (ipv6_pt)
639  return GNUNET_YES;
640  break;
641  }
642  }
643  return GNUNET_NO;
644 }
645 
646 
658 static void
661  size_t request_length,
662  const char *request)
663 {
665  struct ReplyContext *rc;
666  int work;
667 
669  gettext_noop("# DNS replies intercepted"),
670  1, GNUNET_NO);
671  dns = GNUNET_DNSPARSER_parse(request,
672  request_length);
673  if (NULL == dns)
674  {
676  _("Failed to parse DNS request. Dropping.\n"));
678  return;
679  }
680  work = GNUNET_NO;
681  work |= work_test(dns->answers,
682  dns->num_answers);
683  work |= work_test(dns->authority_records,
684  dns->num_authority_records);
685  work |= work_test(dns->additional_records,
687  if (!work)
688  {
691  return;
692  }
693  rc = GNUNET_new(struct ReplyContext);
694  rc->rh = rh;
695  rc->dns = dns;
696  rc->offset = 0;
697  rc->group = ANSWERS;
698  submit_request(rc);
699 }
700 
701 
707 static void
708 timeout_request(void *cls)
709 {
710  struct RequestContext *rc = cls;
711  struct CadetExit *exit = rc->exit;
712 
714  gettext_noop("# DNS requests dropped (timeout)"),
715  1,
716  GNUNET_NO);
718  GNUNET_free(rc);
719  if ((0 == get_channel_weight(exit)) &&
720  (NULL == exit->receive_queue_head))
721  {
722  /* this straw broke the camel's back: this channel now has
723  such a low score that it will not be used; close it! */
725  exit->cadet_channel = NULL;
726  GNUNET_CONTAINER_DLL_remove(exit_head,
727  exit_tail,
728  exit);
730  exit_tail,
731  exit);
732  /* go back to semi-innocent: mark as not great, but
733  avoid a prohibitively negative score (see
734  #get_channel_weight(), which checks for a certain
735  minimum number of transmissions before making
736  up an opinion) */
737  exit->num_transmitted = 5;
738  exit->num_answered = 0;
740  /* now try to open an alternative exit */
741  try_open_exit();
742  }
743 }
744 
745 
757 static void
760  size_t request_length,
761  const char *request)
762 {
763  struct RequestContext *rc;
764  struct GNUNET_MQ_Envelope *env;
765  struct GNUNET_MessageHeader *hdr;
766  struct GNUNET_TUN_DnsHeader dns;
767  struct CadetExit *exit;
768 
770  gettext_noop("# DNS requests intercepted"),
771  1, GNUNET_NO);
772  if (0 == dns_exit_available)
773  {
775  gettext_noop("# DNS requests dropped (DNS cadet channel down)"),
776  1, GNUNET_NO);
778  return;
779  }
780  if (request_length < sizeof(dns))
781  {
783  gettext_noop("# DNS requests dropped (malformed)"),
784  1, GNUNET_NO);
786  return;
787  }
788  exit = choose_exit();
789  GNUNET_assert(NULL != exit);
790  GNUNET_assert(NULL != exit->cadet_channel);
791 
792  env = GNUNET_MQ_msg_extra(hdr,
793  request_length,
795  GNUNET_memcpy(&hdr[1],
796  request,
797  request_length);
798  rc = GNUNET_new(struct RequestContext);
799  rc->exit = exit;
800  rc->rh = rh;
803  rc);
804  GNUNET_memcpy(&dns,
805  request,
806  sizeof(dns));
807  rc->dns_id = dns.id;
808  rc->env = env;
810  exit->receive_queue_tail,
811  rc);
812  if (0 < exit->idle)
813  exit->idle--;
814  exit->num_transmitted++;
816  GNUNET_MQ_env_copy(env));
817 }
818 
819 
821 
825 struct DnsResponseMessage {
829  struct GNUNET_MessageHeader header;
830 
834  struct GNUNET_TUN_DnsHeader dns;
835 
836  /* Followed by more DNS payload */
837 };
838 
840 
849 static int
851  const struct DnsResponseMessage *msg)
852 {
853  return GNUNET_OK; /* all OK */
854 }
855 
856 
863 static void
865  const struct DnsResponseMessage *msg)
866 {
867  struct CadetExit *exit = cls;
868  size_t mlen;
869  struct RequestContext *rc;
870 
871  mlen = ntohs(msg->header.size) - sizeof(*msg);
872  for (rc = exit->receive_queue_head; NULL != rc; rc = rc->next)
873  {
874  if (msg->dns.id == rc->dns_id)
875  {
877  gettext_noop("# DNS replies received"),
878  1,
879  GNUNET_NO);
881  mlen + sizeof(struct GNUNET_TUN_DnsHeader),
882  (const void*)&msg->dns);
884  exit->receive_queue_tail,
885  rc);
887  GNUNET_MQ_discard(rc->env);
888  GNUNET_free(rc);
889  exit->num_answered++;
890  return;
891  }
892  }
894  gettext_noop("# DNS replies dropped (too late?)"),
895  1, GNUNET_NO);
896 }
897 
898 
904 static void
906 {
907  struct RequestContext *rc;
908 
909  while (NULL != (rc = exit->receive_queue_head))
910  {
912  exit->receive_queue_tail,
913  rc);
916  GNUNET_MQ_discard(rc->env);
917  GNUNET_free(rc);
918  }
919 }
920 
921 
927 static void
928 cleanup(void *cls)
929 {
930  struct CadetExit *exit;
931 
933  "Protocol translation daemon is shutting down now\n");
934  if (NULL != vpn_handle)
935  {
936  GNUNET_VPN_disconnect(vpn_handle);
937  vpn_handle = NULL;
938  }
939  while (NULL != (exit = exit_head))
940  {
941  GNUNET_CONTAINER_DLL_remove(exit_head,
942  exit_tail,
943  exit);
944  if (NULL != exit->cadet_channel)
945  {
947  exit->cadet_channel = NULL;
948  }
949  abort_all_requests(exit);
950  GNUNET_free(exit);
951  }
952  if (NULL != cadet_handle)
953  {
954  GNUNET_CADET_disconnect(cadet_handle);
955  cadet_handle = NULL;
956  }
957  if (NULL != dns_post_handle)
958  {
959  GNUNET_DNS_disconnect(dns_post_handle);
960  dns_post_handle = NULL;
961  }
962  if (NULL != dns_pre_handle)
963  {
964  GNUNET_DNS_disconnect(dns_pre_handle);
965  dns_pre_handle = NULL;
966  }
967  if (NULL != stats)
968  {
970  stats = NULL;
971  }
972  if (NULL != dht_get)
973  {
974  GNUNET_DHT_get_stop(dht_get);
975  dht_get = NULL;
976  }
977  if (NULL != dht)
978  {
980  dht = NULL;
981  }
982 }
983 
984 
996 static void
998  const struct GNUNET_CADET_Channel *channel)
999 {
1000  struct CadetExit *exit = cls;
1001  struct CadetExit *alt;
1002  struct RequestContext *rc;
1003 
1004  exit->cadet_channel = NULL;
1006  /* open alternative channels */
1007  /* our channel is now closed, move our requests to an alternative
1008  channel */
1009  alt = choose_exit();
1010  while (NULL != (rc = exit->receive_queue_head))
1011  {
1013  exit->receive_queue_tail,
1014  rc);
1015  rc->exit = alt;
1017  alt->receive_queue_tail,
1018  rc);
1020  GNUNET_MQ_env_copy(rc->env));
1021  }
1022  try_open_exit();
1023 }
1024 
1025 
1033 static void
1035  const struct GNUNET_CADET_Channel *channel,
1036  int window_size)
1037 {
1038  struct CadetExit *pos = cls;
1039 
1040  pos->idle = window_size;
1041 }
1042 
1043 
1047 static void
1049 {
1050  struct CadetExit *pos;
1051  uint32_t candidate_count;
1052  uint32_t candidate_selected;
1053  struct GNUNET_HashCode port;
1054 
1057  &port);
1058  candidate_count = 0;
1059  for (pos = exit_head; NULL != pos; pos = pos->next)
1060  if (NULL == pos->cadet_channel)
1061  candidate_count++;
1062  if (0 == candidate_count)
1063  {
1065  "No DNS exits available yet.\n");
1066  return;
1067  }
1069  candidate_count);
1070  candidate_count = 0;
1071  for (pos = exit_head; NULL != pos; pos = pos->next)
1072  if (NULL == pos->cadet_channel)
1073  {
1074  candidate_count++;
1075  if (candidate_selected < candidate_count)
1076  {
1077  struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
1078  GNUNET_MQ_hd_var_size(dns_response,
1080  struct DnsResponseMessage,
1081  pos),
1083  };
1084 
1085 
1086  /* move to the head of the DLL */
1087  pos->cadet_channel
1088  = GNUNET_CADET_channel_create(cadet_handle,
1089  pos,
1090  &pos->peer,
1091  &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:838
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.
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:671
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:1284
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:1439
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:1256
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.
void GNUNET_DNSPARSER_free_packet(struct GNUNET_DNSPARSER_Packet *p)
Free memory taken by a packet.
Definition: dnsparser.c:853
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:79
#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:517
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:198
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition: cadet_api.c:973
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:1237
void GNUNET_DNS_disconnect(struct GNUNET_DNS_Handle *dh)
Disconnect from the DNS service.
Definition: dns_api.c:368
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: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:529
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.
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:1150
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:60
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:319
DNS handle.
Definition: dns_api.c:55
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:66
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:885
Opaque redirection request handle.
Definition: vpn_api.c:75
void GNUNET_DHT_disconnect(struct GNUNET_DHT_Handle *handle)
Shutdown connection with the DHT service.
Definition: dht_api.c:913
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:78
#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:345
#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:301
struct GNUNET_VPN_Handle * GNUNET_VPN_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the VPN service.
Definition: vpn_api.c:507
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:1065
Handle to identify an individual DNS request.
Definition: dns_api.c:34
#define GNUNET_DNSPARSER_TYPE_AAAA
configuration data
Definition: configuration.c:83
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:242
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:1062
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:131
#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:270
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:351
#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:55
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:412
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:900
#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:1116
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956
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:456