GNUnet 0.29.0
 
Loading...
Searching...
No Matches
gnunet-service-gns_resolver.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2011-2013 GNUnet e.V.
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 */
20
27#include "platform.h"
28#if HAVE_LIBIDN2
29#if HAVE_IDN2_H
30#include <idn2.h>
31#elif HAVE_IDN2_IDN2_H
32#include <idn2/idn2.h>
33#endif
34#elif HAVE_LIBIDN
35#if HAVE_IDNA_H
36#include <idna.h>
37#elif HAVE_IDN_IDNA_H
38#include <idn/idna.h>
39#endif
40#endif
41#include "gnunet_util_lib.h"
42#include "gnunet_dht_service.h"
47#include "gnunet_gns_service.h"
48#include "gnunet-service-gns.h"
52
53
57#define DHT_LOOKUP_TIMEOUT GNUNET_TIME_relative_multiply ( \
58 GNUNET_TIME_UNIT_SECONDS, 60)
59
64#define DHT_LOOKUP_RETRIES 2
65
69#define DNS_LOOKUP_TIMEOUT GNUNET_TIME_relative_multiply ( \
70 GNUNET_TIME_UNIT_SECONDS, 15)
71
75#define DHT_GNS_REPLICATION_LEVEL 10
76
83#define BLOCK_REFRESH_THRESHOLD GNUNET_TIME_relative_multiply ( \
84 GNUNET_TIME_UNIT_MINUTES, 5)
85
89#define BLOCK_REFRESH_TIMEOUT GNUNET_TIME_relative_multiply ( \
90 GNUNET_TIME_UNIT_SECONDS, 30)
91
92
97struct AuthorityChain;
98
99
106{
111
116
121
128
133
137 unsigned int num_results;
138};
139
140
145struct GNS_ResolverHandle;
146
147
229
230
235{
240
245
249 const void *data;
250
256
260 size_t data_size;
261
265 uint32_t record_type;
266};
267
268
430
431
452
453
491
492
497
502
507
511static unsigned long long max_allowed_background_queries;
512
517
522
526static struct CacheOps *co_head;
527
531static struct CacheOps *co_tail;
532
536static struct RefreshOps *ro_head;
537
541static struct RefreshOps *ro_tail;
542
546static int disable_cache;
547
551static const struct GNUNET_CONFIGURATION_Handle *cfg;
552
553
554/* ************************** Resolution **************************** */
555
563static char *
565 char *name)
566{
567 char *ret;
568 size_t s_len = strlen (name);
569
570 if (0 != strcmp (&name[s_len - 2],
571 ".+"))
572 return name; /* did not end in ".+" */
575 "%.*s.%s",
576 (int) (s_len - 2),
577 name,
581 return ret;
582}
583
584
591static void
593{
594 struct GNS_ResolverHandle *rh = cls;
595
596 rh->task_id = NULL;
598}
599
600
606static void
608{
609 rh->proc (rh->proc_cls,
610 0,
611 NULL);
612 GNUNET_assert (NULL == rh->task_id);
614 rh);
615}
616
617
623static void
625{
626 struct GNS_ResolverHandle *rh = cls;
627
628 rh->task_id = NULL;
629 fail_resolution (rh);
630}
631
632
638static int
640{
641 struct protoent *pe = getprotobyname (name);
642 if (pe == NULL)
643 {
645 }
646 return pe->p_proto;
647}
648
649
656static int
657resolver_getservbyname (const char *name, const char *proto)
658{
659 struct servent *se = getservbyname (name, proto);
660 if (se == NULL)
661 {
663 }
664 return se->s_port;
665}
666
667
686static char *
688{
689 const char *rp;
690 const char *dot;
691 size_t len;
692 char *ret;
693 char *srv_name;
694 char *proto_name;
695 int protocol;
696 int service;
697
698 if (0 == rh->name_resolution_pos)
699 return NULL;
700 dot = memrchr (rh->name,
701 (int) '.',
703 if (NULL == dot)
704 {
705 /* done, this was the last one */
706 len = rh->name_resolution_pos;
707 rp = rh->name;
708 rh->name_resolution_pos = 0;
709 }
710 else if ('_' == dot[1])
711 {
720 len = strlen (GNUNET_GNS_EMPTY_LABEL_AT);
721 }
722 else
723 {
724 /* advance by one label */
725 len = rh->name_resolution_pos - (dot - rh->name) - 1;
726 rp = dot + 1;
727 rh->name_resolution_pos = dot - rh->name;
728 }
729 rh->protocol = 0;
730 rh->service = 0;
731 rh->prefix = NULL;
732 ret = GNUNET_strndup (rp, len);
737 if (('_' == rh->name[0]) &&
738 (NULL != (dot = memrchr (rh->name,
739 (int) '.',
740 rh->name_resolution_pos))) &&
741 ('_' == dot[1]) &&
742 (NULL == memrchr (rh->name,
743 (int) '.',
744 dot - rh->name)))
745 {
746 srv_name = GNUNET_strndup (&rh->name[1],
747 (dot - rh->name) - 1);
748 proto_name = GNUNET_strndup (&dot[2],
749 rh->name_resolution_pos - (dot - rh->name)
750 - 2);
751 protocol = resolver_getprotobyname (proto_name);
752 if (0 == protocol)
753 {
755 _ (
756 "Protocol `%s' unknown, skipping labels as BOX retain as SBOX.\n"),
757 proto_name);
758 GNUNET_free (proto_name);
759 GNUNET_free (srv_name);
761 rh->name_resolution_pos = 0;
762 return ret;
763 }
765 proto_name);
766 if (0 == service)
767 {
769 _ (
770 "Service `%s' unknown for protocol `%s', trying as number.\n"),
771 srv_name,
772 proto_name);
773 if (1 != sscanf (srv_name, "%u", &rh->service))
774 {
776 _ (
777 "Service `%s' not a port, skipping service labels as BOX retain as SBOX.\n"),
778 srv_name);
779 GNUNET_free (proto_name);
780 GNUNET_free (srv_name);
782 rh->name_resolution_pos = 0;
783 return ret;
784 }
785 }
786 else
787 {
788 rh->service = ntohs (service);
789 }
790 rh->protocol = protocol;
791 GNUNET_free (proto_name);
792 GNUNET_free (srv_name);
793 }
800 if ((NULL != (dot = memrchr (rh->name,
801 (int) '.',
802 rh->name_resolution_pos)) && '_' == dot[1]) ||
803 ((NULL == memrchr (rh->name,
804 (int) '.',
805 rh->name_resolution_pos)) && '_' == rh->name[0]))
806 {
808 rh->name_resolution_pos = 0;
809 }
810 return ret;
811}
812
813
819static void
821{
822 struct DnsResult *pos;
823 unsigned int n;
824 unsigned int i;
825
826 n = 0;
827 for (pos = rh->dns_result_head; NULL != pos; pos = pos->next)
828 n++;
829 {
830 struct GNUNET_GNSRECORD_Data rd[n];
831
832 i = 0;
833 for (pos = rh->dns_result_head; NULL != pos; pos = pos->next)
834 {
835 rd[i].data = pos->data;
836 rd[i].data_size = pos->data_size;
837 rd[i].record_type = pos->record_type;
845 if (0 == pos->expiration_time)
846 {
848 rd[i].expiration_time = 0;
849 }
850 else
851 {
853 }
854 i++;
855 }
856 GNUNET_assert (i == n);
858 "Transmitting standard DNS result with %u records\n",
859 n);
860 rh->proc (rh->proc_cls,
861 n,
862 rd);
863 }
865}
866
867
877static void
879 uint64_t expiration_time,
880 uint32_t record_type,
881 size_t data_size,
882 const void *data)
883{
884 struct DnsResult *res;
885
886 res = GNUNET_malloc (sizeof(struct DnsResult) + data_size);
887 res->expiration_time = expiration_time;
888 res->data_size = data_size;
889 res->record_type = record_type;
890 res->data = &res[1];
891 GNUNET_memcpy (&res[1],
892 data,
893 data_size);
895 rh->dns_result_tail,
896 res);
897}
898
899
908static void
910 const struct sockaddr *addr,
911 socklen_t addrlen)
912{
913 struct GNS_ResolverHandle *rh = cls;
914 const struct sockaddr_in *sa4;
915 const struct sockaddr_in6 *sa6;
916
917 if (NULL == addr)
918 {
919 rh->std_resolve = NULL;
921 return;
922 }
924 "Received %u bytes of DNS IP data\n",
925 addrlen);
926 switch (addr->sa_family)
927 {
928 case AF_INET:
929 sa4 = (const struct sockaddr_in *) addr;
930 add_dns_result (rh,
931 0 /* expiration time is unknown */,
933 sizeof(struct in_addr),
934 &sa4->sin_addr);
935 break;
936
937 case AF_INET6:
938 sa6 = (const struct sockaddr_in6 *) addr;
939 add_dns_result (rh,
940 0 /* expiration time is unknown */,
942 sizeof(struct in6_addr),
943 &sa6->sin6_addr);
944 break;
945
946 default:
947 GNUNET_break (0);
948 break;
949 }
950}
951
952
958static void
959recursive_resolution (void *cls);
960
961
968static void
969start_resolver_lookup (void *cls);
970
971
980static void
982 const struct GNUNET_TUN_DnsHeader *dns,
983 size_t dns_len)
984{
985 struct GNS_ResolverHandle *rh = cls;
987 const struct GNUNET_DNSPARSER_Record *rec;
988 unsigned int rd_count;
989
990 if (NULL == dns)
991 {
992 rh->dns_request = NULL;
994 rh->task_id = NULL;
995 fail_resolution (rh);
996 return;
997 }
998 if (rh->original_dns_id != dns->id)
999 {
1000 /* DNS answer, but for another query */
1001 return;
1002 }
1003 p = GNUNET_DNSPARSER_parse ((const char *) dns,
1004 dns_len);
1005 if (NULL == p)
1006 {
1008 _ ("Failed to parse DNS response\n"));
1009 return;
1010 }
1011
1012 /* We got a result from DNS */
1014 "Received DNS response for `%s' with %u answers\n",
1015 rh->ac_tail->label,
1016 (unsigned int) p->num_answers);
1017 if ((p->num_answers > 0) &&
1018 (GNUNET_DNSPARSER_TYPE_CNAME == p->answers[0].type) &&
1020 {
1021 int af;
1022
1024 "Got CNAME `%s' from DNS for `%s'\n",
1025 p->answers[0].data.hostname,
1026 rh->name);
1027 if (NULL != rh->std_resolve)
1028 {
1030 "Multiple CNAME results from DNS resolving `%s'! Not really allowed...\n",
1031 rh->name);
1033 }
1034 GNUNET_free (rh->name);
1035 rh->name = GNUNET_strdup (p->answers[0].data.hostname);
1036 rh->name_resolution_pos = strlen (rh->name);
1037 switch (rh->record_type)
1038 {
1040 af = AF_INET;
1041 break;
1042
1044 af = AF_INET6;
1045 break;
1046
1047 default:
1048 af = AF_UNSPEC;
1049 break;
1050 }
1051 if (NULL != rh->leho)
1052 add_dns_result (rh,
1053 GNUNET_TIME_UNIT_HOURS.rel_value_us,
1055 strlen (rh->leho),
1056 rh->leho);
1058 af,
1061 rh);
1064 rh->dns_request = NULL;
1065 return;
1066 }
1067
1068 /* convert from (parsed) DNS to (binary) GNS format! */
1069 rd_count = p->num_answers + p->num_authority_records
1070 + p->num_additional_records;
1071 {
1072 struct GNUNET_GNSRECORD_Data rd[rd_count + 1]; /* +1 for LEHO */
1073 int skip;
1074 char buf[UINT16_MAX];
1075 char *name_ace;
1076 size_t buf_off;
1077 size_t buf_start;
1078
1079 buf_off = 0;
1080 skip = 0;
1081 memset (rd,
1082 0,
1083 sizeof(rd));
1084 for (unsigned int i = 0; i < rd_count; i++)
1085 {
1086 if (i < p->num_answers)
1087 rec = &p->answers[i];
1088 else if (i < p->num_answers + p->num_authority_records)
1089 rec = &p->authority_records[i - p->num_answers];
1090 else
1091 rec = &p->additional_records[i - p->num_answers
1092 - p->num_authority_records];
1093 /* As we copied the full DNS name to 'rh->ac_tail->label', this
1094 should be the correct check to see if this record is actually
1095 a record for our label...
1096 However, DNSPARSER will convert the ACE name to UTF-8 so
1097 we must convert back.
1098 */
1099 if (IDNA_SUCCESS != idna_to_ascii_8z (rec->name,
1100 &name_ace,
1101 IDNA_ALLOW_UNASSIGNED))
1102 {
1104 _ ("Name `%s' cannot be converted to IDNA."),
1105 rec->name);
1106 continue;
1107 }
1108
1109 if (0 != strcmp (name_ace,
1110 rh->ac_tail->label))
1111 {
1113 "Dropping record `%s', does not match desired name `%s'\n",
1114 rec->name,
1115 rh->ac_tail->label);
1116 skip++;
1117 continue;
1118 }
1119 rd[i - skip].record_type = rec->type;
1121 switch (rec->type)
1122 {
1124 if (rec->data.raw.data_len != sizeof(struct in_addr))
1125 {
1126 GNUNET_break_op (0);
1127 skip++;
1128 continue;
1129 }
1130 rd[i - skip].data_size = rec->data.raw.data_len;
1131 rd[i - skip].data = rec->data.raw.data;
1132 break;
1133
1135 if (rec->data.raw.data_len != sizeof(struct in6_addr))
1136 {
1137 GNUNET_break_op (0);
1138 skip++;
1139 continue;
1140 }
1141 rd[i - skip].data_size = rec->data.raw.data_len;
1142 rd[i - skip].data = rec->data.raw.data;
1143 break;
1144
1148 buf_start = buf_off;
1149 if (GNUNET_OK !=
1151 sizeof(buf),
1152 &buf_off,
1153 rec->data.hostname))
1154 {
1155 GNUNET_break (0);
1156 skip++;
1157 continue;
1158 }
1159 rd[i - skip].data_size = buf_off - buf_start;
1160 rd[i - skip].data = &buf[buf_start];
1161 break;
1162
1164 buf_start = buf_off;
1165 if (GNUNET_OK !=
1167 sizeof(buf),
1168 &buf_off,
1169 rec->data.soa))
1170 {
1171 GNUNET_break (0);
1172 skip++;
1173 continue;
1174 }
1175 rd[i - skip].data_size = buf_off - buf_start;
1176 rd[i - skip].data = &buf[buf_start];
1177 break;
1178
1180 buf_start = buf_off;
1181 if (GNUNET_OK !=
1183 sizeof(buf),
1184 &buf_off,
1185 rec->data.mx))
1186 {
1187 GNUNET_break (0);
1188 skip++;
1189 continue;
1190 }
1191 rd[i - skip].data_size = buf_off - buf_start;
1192 rd[i - skip].data = &buf[buf_start];
1193 break;
1194
1196 buf_start = buf_off;
1197 if (GNUNET_OK !=
1199 sizeof(buf),
1200 &buf_off,
1201 rec->data.srv))
1202 {
1203 GNUNET_break (0);
1204 skip++;
1205 continue;
1206 }
1207 rd[i - skip].data_size = buf_off - buf_start;
1208 rd[i - skip].data = &buf[buf_start];
1209 break;
1210
1212 buf_start = buf_off;
1213 if (GNUNET_OK !=
1215 sizeof(buf),
1216 &buf_off,
1217 rec->data.uri))
1218 {
1219 GNUNET_break (0);
1220 skip++;
1221 continue;
1222 }
1223 rd[i - skip].data_size = buf_off - buf_start;
1224 rd[i - skip].data = &buf[buf_start];
1225 break;
1226
1227 default:
1229 _ ("Skipping record of unsupported type %d\n"),
1230 rec->type);
1231 skip++;
1232 continue;
1233 }
1234 } /* end of for all records in answer */
1235 if (NULL != rh->leho)
1236 {
1240 rd[rd_count - skip].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us;
1241 rd[rd_count - skip].data = rh->leho;
1242 rd[rd_count - skip].data_size = strlen (rh->leho);
1243 skip--; /* skip one LESS */
1245 "Adding LEHO %s\n",
1246 rh->leho);
1247 }
1249 "Returning DNS response for `%s' with %u answers\n",
1250 rh->ac_tail->label,
1251 (unsigned int) (rd_count - skip));
1252 rh->proc (rh->proc_cls,
1253 rd_count - skip,
1254 rd);
1256 rh->dns_request = NULL;
1257 }
1258
1259
1261 if (NULL != rh->task_id)
1262 GNUNET_SCHEDULER_cancel (rh->task_id); /* should be timeout task */
1264 rh);
1265}
1266
1267
1276static void
1278{
1279 struct AuthorityChain *ac;
1280 struct GNUNET_DNSPARSER_Query *query;
1281 struct GNUNET_DNSPARSER_Packet *p;
1282 char *dns_request;
1283 size_t dns_request_length;
1284 int ret;
1285
1286 ac = rh->ac_tail;
1287 GNUNET_assert (NULL != ac);
1289 "Starting DNS lookup for `%s'\n",
1290 ac->label);
1292 query = GNUNET_new (struct GNUNET_DNSPARSER_Query);
1293 query->name = GNUNET_strdup (ac->label);
1294 query->type = rh->record_type;
1297 p->queries = query;
1298 p->num_queries = 1;
1299 p->id = (uint16_t) GNUNET_CRYPTO_random_u32 (UINT16_MAX);
1300 p->flags.opcode = GNUNET_TUN_DNS_OPCODE_QUERY;
1301 p->flags.recursion_desired = 1;
1303 1024,
1304 &dns_request,
1305 &dns_request_length);
1306 if (GNUNET_OK != ret)
1307 {
1308 GNUNET_break (0);
1309 rh->proc (rh->proc_cls,
1310 0,
1311 NULL);
1312 GNUNET_assert (NULL == rh->task_id);
1314 rh);
1315 }
1316 else
1317 {
1318 rh->original_dns_id = p->id;
1320 GNUNET_assert (NULL == rh->dns_request);
1321 if (IDNA_SUCCESS != idna_to_unicode_8z8z (ac->label,
1322 &rh->leho,
1323 IDNA_ALLOW_UNASSIGNED))
1324 {
1325 GNUNET_break (0);
1326 rh->proc (rh->proc_cls,
1327 0,
1328 NULL);
1329 GNUNET_assert (NULL == rh->task_id);
1331 rh);
1332 }
1335 dns_request,
1336 dns_request_length,
1338 rh);
1341 rh);
1342 }
1343 if (GNUNET_SYSERR != ret)
1344 GNUNET_free (dns_request);
1346}
1347
1348
1357static void
1359 const char *rname)
1360{
1361 size_t nlen;
1362 char *res;
1363 const char *tld;
1364 struct AuthorityChain *ac;
1365 int af;
1367
1369 "Handling GNS REDIRECT result `%s'\n",
1370 rname);
1371 nlen = strlen (rname);
1372 tld = GNS_get_tld (rname);
1373 if (0 == strcmp ("+", tld))
1374 {
1375 /* REDIRECT resolution continues relative to current domain */
1376 if (0 == rh->name_resolution_pos)
1377 {
1378 res = GNUNET_strndup (rname, nlen - 2);
1379 rh->name_resolution_pos = nlen - 2;
1380 }
1381 else
1382 {
1384 "%.*s.%.*s",
1385 (int) rh->name_resolution_pos,
1386 rh->name,
1387 (int) (nlen - 2),
1388 rname);
1389 rh->name_resolution_pos = strlen (res);
1390 }
1391 GNUNET_free (rh->name);
1392 rh->name = res;
1393 ac = GNUNET_new (struct AuthorityChain);
1394 ac->rh = rh;
1399 /* add AC to tail */
1401 rh->ac_tail,
1402 ac);
1404 rh);
1405 return;
1406 }
1407 if (GNUNET_OK == GNUNET_GNSRECORD_zkey_to_pkey (tld, &zone))
1408 {
1409 /* REDIRECT resolution continues relative to current domain */
1410 if (0 == rh->name_resolution_pos)
1411 {
1413 "%.*s",
1414 (int) (strlen (rname) - (strlen (tld) + 1)),
1415 rname);
1416 }
1417 else
1418 {
1420 "%.*s.%.*s",
1421 (int) rh->name_resolution_pos,
1422 rh->name,
1423 (int) (strlen (rname) - (strlen (tld) + 1)),
1424 rname);
1425 }
1426 rh->name_resolution_pos = strlen (res);
1427 GNUNET_free (rh->name);
1428 rh->name = res;
1429 ac = GNUNET_new (struct AuthorityChain);
1430 ac->rh = rh;
1432 ac->authority_info.gns_authority = zone;
1434 /* add AC to tail */
1436 rh->ac_tail,
1437 ac);
1439 rh);
1440 return;
1441 }
1442
1444 "Got REDIRECT `%s' from GNS for `%s'\n",
1445 rname,
1446 rh->name);
1447 if (NULL != rh->std_resolve)
1448 {
1450 "Multiple REDIRECT results from GNS resolving `%s'! Not really allowed...\n",
1451 rh->name);
1453 }
1454 /* name is absolute, go to DNS */
1455 GNUNET_free (rh->name);
1456 rh->name = GNUNET_strdup (rname);
1457 rh->name_resolution_pos = strlen (rh->name);
1458 switch (rh->record_type)
1459 {
1461 af = AF_INET;
1462 break;
1463
1465 af = AF_INET6;
1466 break;
1467
1468 default:
1469 af = AF_UNSPEC;
1470 break;
1471 }
1473 "Doing standard DNS lookup for `%s'\n",
1474 rh->name);
1475
1477 af,
1480 rh);
1481}
1482
1483
1492static void
1494 const char *cname)
1495{
1496 int af;
1497
1498 GNUNET_free (rh->name);
1499 rh->name = GNUNET_strdup (cname);
1500 rh->name_resolution_pos = strlen (rh->name);
1501 switch (rh->record_type)
1502 {
1504 af = AF_INET;
1505 break;
1506
1508 af = AF_INET6;
1509 break;
1510
1511 default:
1512 af = AF_UNSPEC;
1513 break;
1514 }
1516 "Doing standard DNS lookup for `%s'\n",
1517 rh->name);
1518
1520 af,
1523 rh);
1524}
1525
1526
1534static void
1536 unsigned int rd_count,
1537 const struct GNUNET_GNSRECORD_Data *rd);
1538
1539
1547static void
1549{
1550 struct GNS_ResolverHandle *rh = ac->rh;
1551
1552 if ((NULL != ac->authority_info.dns_authority.gp_head) &&
1554 return; /* more pending and none found yet */
1556 {
1558 "Failed to resolve DNS server for `%s' in GNS2DNS resolution\n",
1560 fail_resolution (rh);
1561 return;
1562 }
1564 return; /* already running, do not launch again! */
1565 /* recurse */
1568 "Will continue resolution using DNS to resolve `%s'\n",
1569 ac->label);
1570 GNUNET_assert (NULL == rh->task_id);
1572 rh);
1573}
1574
1575
1584static void
1586 unsigned int rd_count,
1587 const struct GNUNET_GNSRECORD_Data *rd)
1588{
1589 struct Gns2DnsPending *gp = cls;
1590 struct AuthorityChain *ac = gp->ac;
1591
1594 gp);
1595 /* enable cleanup of 'rh' handle that automatically comes after we return,
1596 and which expects 'rh' to be in the #rlh_head DLL. */
1597 if (NULL != gp->rh)
1598 {
1600 rlh_tail,
1601 gp->rh);
1602 gp->rh = NULL;
1603 }
1604 GNUNET_free (gp);
1606 "Received %u results for IP address of DNS server for GNS2DNS transition\n",
1607 rd_count);
1608 /* find suitable A/AAAA record */
1609 for (unsigned int j = 0; j < rd_count; j++)
1610 {
1611 switch (rd[j].record_type)
1612 {
1614 {
1615 struct sockaddr_in v4;
1616
1617 if (sizeof(struct in_addr) != rd[j].data_size)
1618 {
1619 GNUNET_break_op (0);
1620 continue;
1621 }
1622 memset (&v4,
1623 0,
1624 sizeof(v4));
1625 v4.sin_family = AF_INET;
1626 v4.sin_port = htons (53);
1627#if HAVE_SOCKADDR_IN_SIN_LEN
1628 v4.sin_len = (u_char) sizeof(v4);
1629#endif
1630 GNUNET_memcpy (&v4.sin_addr,
1631 rd[j].data,
1632 sizeof(struct in_addr));
1633 if (GNUNET_OK ==
1636 (const struct sockaddr *) &v4))
1638 break;
1639 }
1640
1642 {
1643 struct sockaddr_in6 v6;
1644
1645 if (sizeof(struct in6_addr) != rd[j].data_size)
1646 {
1647 GNUNET_break_op (0);
1648 continue;
1649 }
1650 /* FIXME: might want to check if we support IPv6 here,
1651 and otherwise skip this one and hope we find another */
1652 memset (&v6,
1653 0,
1654 sizeof(v6));
1655 v6.sin6_family = AF_INET6;
1656 v6.sin6_port = htons (53);
1657#if HAVE_SOCKADDR_IN_SIN_LEN
1658 v6.sin6_len = (u_char) sizeof(v6);
1659#endif
1660 GNUNET_memcpy (&v6.sin6_addr,
1661 rd[j].data,
1662 sizeof(struct in6_addr));
1663 if (GNUNET_OK ==
1666 (const struct sockaddr *) &v6))
1668 break;
1669 }
1670
1671 default:
1672 break;
1673 }
1674 }
1676}
1677
1678
1686static void
1688 const struct sockaddr *addr,
1689 socklen_t addrlen)
1690{
1691 struct Gns2DnsPending *gp = cls;
1692 struct AuthorityChain *ac = gp->ac;
1693 struct sockaddr_storage ss;
1694 struct sockaddr_in *v4;
1695 struct sockaddr_in6 *v6;
1696
1697 if (NULL == addr)
1698 {
1699 /* DNS resolution finished */
1700 if (0 == gp->num_results)
1702 "Failed to use DNS to resolve name of DNS resolver\n");
1705 gp);
1706 GNUNET_free (gp);
1708 return;
1709 }
1710 GNUNET_memcpy (&ss,
1711 addr,
1712 addrlen);
1713 switch (ss.ss_family)
1714 {
1715 case AF_INET:
1716 v4 = (struct sockaddr_in *) &ss;
1717 v4->sin_port = htons (53);
1718 gp->num_results++;
1719 break;
1720
1721 case AF_INET6:
1722 v6 = (struct sockaddr_in6 *) &ss;
1723 v6->sin6_port = htons (53);
1724 gp->num_results++;
1725 break;
1726
1727 default:
1729 "Unsupported AF %d\n",
1730 ss.ss_family);
1731 return;
1732 }
1733 if (GNUNET_OK ==
1735 (struct sockaddr *) &ss))
1737}
1738
1739
1746static void
1753
1754
1761static void
1763 const struct GNUNET_GNSRECORD_Data *rd)
1764{
1765 char *cname;
1766 size_t off;
1767
1768 off = 0;
1770 rd->data_size,
1771 &off);
1772 if ((NULL == cname) ||
1773 (off != rd->data_size))
1774 {
1775 GNUNET_break_op (0); /* record not well-formed */
1776 GNUNET_free (cname);
1777 fail_resolution (rh);
1778 return;
1779 }
1781 cname);
1782 GNUNET_free (cname);
1783}
1784
1785
1792static void
1794 const struct GNUNET_GNSRECORD_Data *rd)
1795{
1796 struct AuthorityChain *ac;
1798
1799 /* delegation to another zone */
1801 rd->data_size,
1802 rd->record_type,
1803 &auth))
1804 {
1805 GNUNET_break_op (0);
1806 fail_resolution (rh);
1807 return;
1808 }
1809 /* expand authority chain */
1810 ac = GNUNET_new (struct AuthorityChain);
1811 ac->rh = rh;
1813 ac->authority_info.gns_authority = auth;
1815 /* add AC to tail */
1817 rh->ac_tail,
1818 ac);
1819 /* recurse */
1821 rh);
1822}
1823
1824
1835static int
1837 unsigned int rd_count,
1838 const struct GNUNET_GNSRECORD_Data *rd)
1839{
1840 struct AuthorityChain *ac;
1841 const char *tld;
1842 char *ns;
1843
1844 ns = NULL;
1845 /* expand authority chain */
1846 ac = GNUNET_new (struct AuthorityChain);
1847 ac->rh = rh;
1849
1850 for (unsigned int i = 0; i < rd_count; i++)
1851 {
1852 char *ip;
1853 char *n;
1854 struct Gns2DnsPending *gp;
1856 struct sockaddr_in v4;
1857 struct sockaddr_in6 v6;
1858
1859 if (GNUNET_GNSRECORD_TYPE_GNS2DNS != rd[i].record_type)
1860 {
1865 GNUNET_free (ns);
1866 GNUNET_free (ac);
1867 return GNUNET_SYSERR;
1868 }
1869 n = GNUNET_strdup ((const char*) rd[i].data);
1870 if (strlen (n) + 1 >= rd[i].data_size)
1871 {
1872 GNUNET_break_op (0);
1873 continue;
1874 }
1875 ip = GNUNET_strdup (rd[i].data + strlen (n) + 1);
1876 /* resolve 'ip' to determine the IP(s) of the DNS
1877 resolver to use for lookup of 'ns' */
1878 if (NULL != ns)
1879 {
1880 if (0 != strcasecmp (ns,
1881 n))
1882 {
1883 /* NS values must all be the same for all GNS2DNS records,
1884 anything else leads to insanity */
1885 GNUNET_break_op (0);
1886 GNUNET_free (n);
1887 GNUNET_free (ip);
1888 continue;
1889 }
1890 GNUNET_free (n);
1891 }
1892 else
1893 {
1894 ns = n;
1895 }
1896
1897 /* check if 'ip' is already an IPv4/IPv6 address */
1898 if ((1 == inet_pton (AF_INET,
1899 ip,
1900 &v4)) ||
1901 (1 == inet_pton (AF_INET6,
1902 ip,
1903 &v6)))
1904 {
1908 ip));
1910 GNUNET_free (ip);
1911 continue;
1912 }
1913 tld = GNS_get_tld (ip);
1914 if ((0 != strcmp (tld, "+")) &&
1915 (GNUNET_OK != GNUNET_GNSRECORD_zkey_to_pkey (tld, &zone)))
1916 {
1917 /* 'ip' is a DNS name */
1918 gp = GNUNET_new (struct Gns2DnsPending);
1919 gp->ac = ac;
1922 gp);
1924 AF_UNSPEC,
1927 gp);
1928 GNUNET_free (ip);
1929 continue;
1930 }
1931 /* 'ip' should be a GNS name */
1932 gp = GNUNET_new (struct Gns2DnsPending);
1933 gp->ac = ac;
1936 gp);
1937 gp->rh = GNUNET_new (struct GNS_ResolverHandle);
1938 if (0 == strcmp (tld, "+"))
1939 {
1940 ip = translate_dot_plus (rh,
1941 ip);
1942 tld = GNS_get_tld (ip);
1943 if (GNUNET_OK !=
1945 &zone))
1946 {
1947 GNUNET_break_op (0);
1948 GNUNET_free (ip);
1949 continue;
1950 }
1951 }
1952 gp->rh->authority_zone = zone;
1954 "Resolving `%s' to determine IP address of DNS server for GNS2DNS transition for `%s'\n",
1955 ip,
1956 ns);
1957 gp->rh->name = ip;
1958 gp->rh->name_resolution_pos = strlen (ip) - strlen (tld) - 1;
1960 gp->rh->proc_cls = gp;
1963 gp->rh->loop_limiter = rh->loop_limiter + 1;
1964 gp->rh->loop_threshold = rh->loop_threshold;
1965 gp->rh->task_id
1967 gp->rh);
1968 } /* end 'for all records' */
1969
1970 if (NULL == ns)
1971 {
1972 /* not a single GNS2DNS record found */
1973 GNUNET_free (ac);
1974 return GNUNET_SYSERR;
1975 }
1977 strcpy (ac->authority_info.dns_authority.name,
1978 ns);
1979 /* for DNS recursion, the label is the full DNS name,
1980 created from the remainder of the GNS name and the
1981 name in the NS record */
1982 GNUNET_asprintf (&ac->label,
1983 "%.*s%s%s",
1984 (int) rh->name_resolution_pos,
1985 rh->name,
1986 (0 != rh->name_resolution_pos) ? "." : "",
1987 ns);
1988 GNUNET_free (ns);
1989
1990 {
1991 /* the GNS name is UTF-8 and may include multibyte chars.
1992 * We have to convert the combined name to a DNS-compatible IDNA.
1993 */
1994 char *tmp = ac->label;
1995
1996 if (IDNA_SUCCESS != idna_to_ascii_8z (tmp,
1997 &ac->label,
1998 IDNA_ALLOW_UNASSIGNED))
1999 {
2001 _ ("Name `%s' cannot be converted to IDNA."),
2002 tmp);
2003 GNUNET_free (tmp);
2004 GNUNET_free (ac);
2005 return GNUNET_SYSERR;
2006 }
2007 GNUNET_free (tmp);
2008 }
2009
2011 rh->ac_tail,
2012 ac);
2013 if (strlen (ac->label) > GNUNET_DNSPARSER_MAX_NAME_LENGTH)
2014 {
2016 _ ("GNS lookup resulted in DNS name that is too long (`%s')\n"),
2017 ac->label);
2018 GNUNET_free (ac->label);
2019 GNUNET_free (ac);
2020 return GNUNET_SYSERR;
2021 }
2023 return GNUNET_OK;
2024}
2025
2026
2027static void
2029 unsigned int rd_count,
2030 const struct GNUNET_GNSRECORD_Data *rd)
2031{
2032 struct GNS_ResolverHandle *rh = cls;
2033 char *cname;
2034 char scratch[UINT16_MAX];
2035 size_t scratch_off;
2036 size_t scratch_start;
2037 size_t off;
2038 struct GNUNET_GNSRECORD_Data rd_new[rd_count];
2039 unsigned int rd_off;
2040
2042 "Resolution succeeded for `%s' in zone %s, got %u records\n",
2043 rh->ac_tail->label,
2045 rd_count);
2046 if (0 == rd_count)
2047 {
2049 _ ("GNS lookup failed (zero records found for `%s')\n"),
2050 rh->name);
2051 fail_resolution (rh);
2052 return;
2053 }
2054
2055 if (0 == rh->name_resolution_pos)
2056 {
2057 /* top-level match, are we done yet? */
2058 if ((rd_count > 0) &&
2061 {
2062 off = 0;
2064 rd[0].data_size,
2065 &off);
2066 if ((NULL == cname) ||
2067 (off != rd[0].data_size))
2068 {
2069 GNUNET_break_op (0);
2070 GNUNET_free (cname);
2071 fail_resolution (rh);
2072 return;
2073 }
2075 cname);
2076 GNUNET_free (cname);
2077 return;
2078 }
2079 if ((rd_count > 0) &&
2082 {
2084 rd[0].data);
2085 return;
2086 }
2087
2088
2089 /* If A/AAAA was requested,
2090 * but we got a GNS2DNS record */
2091 if ((GNUNET_DNSPARSER_TYPE_A == rh->record_type) ||
2093 {
2094 for (unsigned int i = 0; i < rd_count; i++)
2095 {
2096 switch (rd[i].record_type)
2097 {
2099 {
2100 /* delegation to DNS */
2102 "Found GNS2DNS record, delegating to DNS!\n");
2103 if (GNUNET_OK ==
2105 rd_count,
2106 rd))
2107 return;
2108 else
2109 goto fail;
2110 }
2111
2112 default:
2113 break;
2114 } /* end: switch */
2115 } /* end: for rd */
2116 } /* end: name_resolution_pos */
2117 /* convert relative names in record values to absolute names,
2118 using 'scratch' array for memory allocations */
2119 scratch_off = 0;
2120 rd_off = 0;
2121 for (unsigned int i = 0; i < rd_count; i++)
2122 {
2123 GNUNET_assert (rd_off <= i);
2124 if ((((0 != rh->protocol) &&
2125 (0 != rh->service)) || (NULL != rh->prefix)) &&
2130 continue;
2131 /* we _only_ care about boxed records */
2132
2133 GNUNET_assert (rd_off < rd_count);
2134 rd_new[rd_off] = rd[i];
2135 /* Check if the embedded name(s) end in "+", and if so,
2136 replace the "+" with the zone at "ac_tail", changing the name
2137 to a ".ZONEKEY". The name is allocated on the 'scratch' array,
2138 so we can free it afterwards. */
2139 switch (rd[i].record_type)
2140 {
2142 {
2143 char *rname;
2144 rname = GNUNET_strndup (rd[i].data, rd[i].data_size);
2145 rname = translate_dot_plus (rh, rname);
2146 GNUNET_break (NULL != rname);
2147 scratch_start = scratch_off;
2148 memcpy (&scratch[scratch_start], rname, strlen (rname) + 1);
2149 scratch_off += strlen (rname) + 1;
2150 GNUNET_assert (rd_off < rd_count);
2151 rd_new[rd_off].data = &scratch[scratch_start];
2152 rd_new[rd_off].data_size = scratch_off - scratch_start;
2153 rd_off++;
2154 GNUNET_free (rname);
2155 }
2156 break;
2157
2159 {
2160 char *cname_tmp;
2161
2162 off = 0;
2163 cname_tmp = GNUNET_DNSPARSER_parse_name (rd[i].data,
2164 rd[i].data_size,
2165 &off);
2166 if ((NULL == cname_tmp) ||
2167 (off != rd[i].data_size))
2168 {
2169 GNUNET_break_op (0); /* record not well-formed */
2170 }
2171 else
2172 {
2173 cname_tmp = translate_dot_plus (rh, cname_tmp);
2174 GNUNET_break (NULL != cname_tmp);
2175 scratch_start = scratch_off;
2176 if (GNUNET_OK !=
2178 sizeof(scratch),
2179 &scratch_off,
2180 cname_tmp))
2181 {
2182 GNUNET_break (0);
2183 }
2184 else
2185 {
2186 GNUNET_assert (rd_off < rd_count);
2187 rd_new[rd_off].data = &scratch[scratch_start];
2188 rd_new[rd_off].data_size = scratch_off - scratch_start;
2189 rd_off++;
2190 }
2191 }
2192 GNUNET_free (cname_tmp);
2193 }
2194 break;
2195
2197 {
2198 struct GNUNET_DNSPARSER_SoaRecord *soa;
2199
2200 off = 0;
2202 rd[i].data_size,
2203 &off);
2204 if ((NULL == soa) ||
2205 (off != rd[i].data_size))
2206 {
2207 GNUNET_break_op (0); /* record not well-formed */
2208 }
2209 else
2210 {
2211 soa->mname = translate_dot_plus (rh, soa->mname);
2212 soa->rname = translate_dot_plus (rh, soa->rname);
2213 scratch_start = scratch_off;
2214 if (GNUNET_OK !=
2216 sizeof(scratch),
2217 &scratch_off,
2218 soa))
2219 {
2220 GNUNET_break (0);
2221 }
2222 else
2223 {
2224 GNUNET_assert (rd_off < rd_count);
2225 rd_new[rd_off].data = &scratch[scratch_start];
2226 rd_new[rd_off].data_size = scratch_off - scratch_start;
2227 rd_off++;
2228 }
2229 }
2230 if (NULL != soa)
2232 }
2233 break;
2234
2236 {
2237 struct GNUNET_DNSPARSER_MxRecord *mx;
2238
2239 off = 0;
2241 rd[i].data_size,
2242 &off);
2243 if ((NULL == mx) ||
2244 (off != rd[i].data_size))
2245 {
2246 GNUNET_break_op (0); /* record not well-formed */
2247 }
2248 else
2249 {
2250 mx->mxhost = translate_dot_plus (rh, mx->mxhost);
2251 scratch_start = scratch_off;
2252 if (GNUNET_OK !=
2254 sizeof(scratch),
2255 &scratch_off,
2256 mx))
2257 {
2258 GNUNET_break (0);
2259 }
2260 else
2261 {
2262 GNUNET_assert (rd_off < rd_count);
2263 rd_new[rd_off].data = &scratch[scratch_start];
2264 rd_new[rd_off].data_size = scratch_off - scratch_start;
2265 rd_off++;
2266 }
2267 }
2268 if (NULL != mx)
2270 }
2271 break;
2272
2274 {
2275 struct GNUNET_DNSPARSER_SrvRecord *srv;
2276
2277 off = 0;
2279 rd[i].data_size,
2280 &off);
2281 if ((NULL == srv) ||
2282 (off != rd[i].data_size))
2283 {
2284 GNUNET_break_op (0); /* record not well-formed */
2285 }
2286 else
2287 {
2288 srv->target = translate_dot_plus (rh, srv->target);
2289 scratch_start = scratch_off;
2290 if (GNUNET_OK !=
2292 sizeof(scratch),
2293 &scratch_off,
2294 srv))
2295 {
2296 GNUNET_break (0);
2297 }
2298 else
2299 {
2300 GNUNET_assert (rd_off < rd_count);
2301 rd_new[rd_off].data = &scratch[scratch_start];
2302 rd_new[rd_off].data_size = scratch_off - scratch_start;
2303 rd_off++;
2304 }
2305 }
2306 if (NULL != srv)
2308 }
2309 break;
2310
2312 {
2314
2315 off = 0;
2317 rd[i].data_size,
2318 &off);
2319 if ((NULL == uri) ||
2320 (off != rd[i].data_size))
2321 {
2323 _ ("Failed to deserialize URI record with target\n"));
2324 GNUNET_break_op (0); /* record not well-formed */
2325 }
2326 else
2327 {
2328 scratch_start = scratch_off;
2329 if (GNUNET_OK !=
2331 sizeof(scratch),
2332 &scratch_off,
2333 uri))
2334 {
2335 GNUNET_break (0);
2336 }
2337 else
2338 {
2339 GNUNET_assert (rd_off < rd_count);
2340 rd_new[rd_off].data = &scratch[scratch_start];
2341 rd_new[rd_off].data_size = scratch_off - scratch_start;
2342 rd_off++;
2343 }
2344 }
2345 if (NULL != uri)
2347 }
2348 break;
2349
2352 {
2354 if (rd[i].data_size < sizeof(uint32_t))
2355 {
2356 GNUNET_break_op (0);
2357 break;
2358 }
2359 if (GNUNET_OK !=
2361 rd[i].data_size,
2362 rd[i].record_type,
2363 &pubkey))
2364 {
2365 GNUNET_break_op (0);
2366 break;
2367 }
2368 rd_off++;
2369 if (rd[i].record_type != rh->record_type)
2370 {
2371 /* try to resolve "@" */
2372 struct AuthorityChain *ac;
2373
2374 ac = GNUNET_new (struct AuthorityChain);
2375 ac->rh = rh;
2380 rh->ac_tail,
2381 ac);
2383 rh);
2384 return;
2385 }
2386 }
2387 break;
2388
2390 {
2391 /* delegation to DNS */
2393 {
2394 rd_off++;
2395 break; /* do not follow to DNS, we wanted the GNS2DNS record! */
2396 }
2398 "Found GNS2DNS record, delegating to DNS!\n");
2399 if (GNUNET_OK ==
2401 rd_count,
2402 rd))
2403 return;
2404 else
2405 goto fail;
2406 }
2407
2409 {
2410 /* unbox SRV/TLSA records if a specific one was requested */
2411 if ((0 != rh->protocol) &&
2412 (0 != rh->service) &&
2413 (rd[i].data_size >= sizeof(struct GNUNET_GNSRECORD_BoxRecord)))
2414 {
2415 const struct GNUNET_GNSRECORD_BoxRecord *box;
2416
2417 box = rd[i].data;
2419 "Got BOX record, checking if parameters match... %u/%u vs %u/%u\n",
2420 ntohs (box->protocol), ntohs (box->service),
2421 rh->protocol, rh->service);
2422 if ((ntohs (box->protocol) == rh->protocol) &&
2423 (ntohs (box->service) == rh->service))
2424 {
2425 /* Box matches, unbox! */
2426 GNUNET_assert (rd_off < rd_count);
2427 rd_new[rd_off].record_type = ntohl (box->record_type);
2428 rd_new[rd_off].data_size -= sizeof(struct
2430 rd_new[rd_off].data = &box[1];
2431 rd_off++;
2432 }
2433 }
2434 else
2435 {
2436 /* no specific protocol/service specified, preserve all BOX
2437 records (for modern, GNS-enabled applications) */
2438 rd_off++;
2439 }
2440 break;
2441 }
2443 {
2444 /* unbox SBOX records if a specific one was requested */
2445 if ((rh->prefix != NULL) &&
2446 (rd[i].data_size >= sizeof(struct GNUNET_GNSRECORD_SBoxRecord)))
2447 {
2448 const struct GNUNET_GNSRECORD_SBoxRecord *box;
2449 const char *prefix;
2450 size_t prefix_len;
2451
2452 box = rd[i].data;
2453 prefix = rd[i].data + sizeof(struct GNUNET_GNSRECORD_SBoxRecord);
2454 prefix_len = strnlen (
2455 prefix,
2456 rd[i].data_size - sizeof(struct GNUNET_GNSRECORD_SBoxRecord)) + 1;
2457 if (prefix_len - 1 >= rd[i].data_size - sizeof(struct
2459 {
2461 "SBOX record with invalid prefix length, maybe not null-terminated\n");
2462 continue;
2463 }
2465 "Got SBOX record, checking if prefixes match... %s vs %s\n",
2466 prefix, rh->prefix);
2467 if (strcmp (rh->prefix, prefix) == 0)
2468 {
2469 /* Box matches, unbox! */
2470 GNUNET_assert (rd_off < rd_count);
2471 rd_new[rd_off].record_type = ntohl (box->record_type);
2472 rd_new[rd_off].data_size -= sizeof(struct
2474 + prefix_len;
2475 rd_new[rd_off].data = rd[i].data
2476 + sizeof(struct GNUNET_GNSRECORD_SBoxRecord)
2477 + prefix_len;
2478 rd_off++;
2479 }
2480 }
2481 else
2482 {
2484 _ (
2485 "GNS no specific protocol/service specified, preserve all SBOX `%s')\n"),
2486 rh->name);
2487 /* no specific protocol/service specified, preserve all SBOX
2488 records (for modern, GNS-enabled applications) */
2489 rd_off++;
2490 }
2491 break;
2492 }
2493 default:
2494 rd_off++;
2495 break;
2496 } /* end: switch */
2497 } /* end: for rd_count */
2498
2499 GNUNET_free (rh->prefix);
2500 rh->prefix = NULL;
2501
2502 /* yes, we are done, return result */
2504 "Returning GNS response for `%s' with %u answers\n",
2505 rh->ac_tail->label,
2506 rd_off);
2507 rh->proc (rh->proc_cls,
2508 rd_off,
2509 rd_new);
2511 rh);
2512 return;
2513 }
2514
2515 switch (rd[0].record_type)
2516 {
2518 GNUNET_break_op (1 == rd_count); /* REDIRECT should be unique */
2520 &rd[0]);
2521 return;
2522
2524 GNUNET_break_op (1 == rd_count); /* CNAME should be unique */
2526 &rd[0]);
2527 return;
2528
2531 GNUNET_break_op (1 == rd_count); /* PKEY should be unique */
2533 &rd[0]);
2534 return;
2535
2537 if (GNUNET_OK ==
2539 rd_count,
2540 rd))
2541 return;
2542 break;
2543 default:
2545 return;
2547 _ ("Unable to process critical delegation record\n"));
2548 break;
2549 }
2550fail:
2552 _ ("GNS lookup recursion failed (no delegation record found)\n"));
2553 fail_resolution (rh);
2554}
2555
2556
2565static void
2567 int32_t success,
2568 const char *emsg)
2569{
2570 struct CacheOps *co = cls;
2571
2572 co->namecache_qe_cache = NULL;
2573 if (GNUNET_OK != success)
2575 _ ("Failed to cache GNS resolution: %s\n"),
2576 emsg);
2578 co_tail,
2579 co);
2580 GNUNET_free (co);
2581}
2582
2583
2602static void
2604 struct GNUNET_TIME_Absolute exp,
2605 const struct GNUNET_HashCode *key,
2606 const struct GNUNET_PeerIdentity *trunc_peer,
2607 const struct GNUNET_DHT_PathElement *get_path,
2608 unsigned int get_path_length,
2609 const struct GNUNET_DHT_PathElement *put_path,
2610 unsigned int put_path_length,
2612 size_t size,
2613 const void *data)
2614{
2615 struct GNS_ResolverHandle *rh = cls;
2616 struct AuthorityChain *ac = rh->ac_tail;
2617 const struct GNUNET_GNSRECORD_Block *block;
2618 struct CacheOps *co;
2619
2620 (void) exp;
2621 (void) key;
2622 (void) get_path;
2623 (void) get_path_length;
2624 (void) put_path;
2625 (void) put_path_length;
2626 (void) type;
2628 rh->get_handle = NULL;
2630 rh->dht_heap_node = NULL;
2631 /* must be cleared before handle_gns_resolution_result() below gets
2632 to schedule the next step */
2633 if (NULL != rh->task_id)
2634 {
2636 rh->task_id = NULL;
2637 }
2639 "Handling response from the DHT\n");
2640 if (size < sizeof(struct GNUNET_GNSRECORD_Block))
2641 {
2642 /* how did this pass DHT block validation!? */
2643 GNUNET_break (0);
2644 fail_resolution (rh);
2645 return;
2646 }
2647 block = data;
2649 {
2650 /* how did this pass DHT block validation!? */
2651 GNUNET_break (0);
2652 fail_resolution (rh);
2653 return;
2654 }
2656 "Decrypting DHT block of size %llu for `%s', expires %s\n",
2657 (unsigned long long) GNUNET_GNSRECORD_block_get_size (block),
2658 rh->name,
2660 if (GNUNET_OK !=
2663 ac->label,
2665 rh))
2666 {
2667 GNUNET_break_op (0); /* block was ill-formed */
2668 fail_resolution (rh);
2669 return;
2670 }
2673 rel_value_us)
2674 {
2676 "Received expired block from the DHT, will not cache it.\n");
2677 return;
2678 }
2680 return;
2681 /* Cache well-formed blocks */
2683 "Caching response from the DHT in namecache\n");
2684 co = GNUNET_new (struct CacheOps);
2686 block,
2687 &
2689 co);
2691 co_tail,
2692 co);
2693}
2694
2695
2702static void
2704 const struct GNUNET_HashCode *query);
2705
2706
2714static void
2716{
2717 struct GNS_ResolverHandle *rh = cls;
2718 struct GNUNET_HashCode query = rh->dht_query;
2719
2720 rh->task_id = NULL;
2722 rh->get_handle = NULL;
2724 rh->dht_heap_node = NULL;
2726 {
2728 _ ("DHT lookup for `%s' timed out\n"),
2729 rh->name);
2730 fail_resolution (rh);
2731 return;
2732 }
2733 rh->dht_retries++;
2735 "DHT lookup for `%s' under key %s timed out, retrying (%u/%u)\n",
2736 rh->name,
2737 GNUNET_h2s (&query),
2738 rh->dht_retries,
2739 (unsigned int) DHT_LOOKUP_RETRIES);
2741 &query);
2742}
2743
2744
2745static void
2747 const struct GNUNET_HashCode *query)
2748{
2749 struct GNS_ResolverHandle *rx;
2750
2751 GNUNET_assert (NULL == rh->get_handle);
2752 rh->dht_query = *query;
2755 query,
2758 NULL, 0,
2759 &handle_dht_response, rh);
2761 rh,
2763 abs_value_us);
2764 GNUNET_assert (NULL == rh->task_id);
2767 rh);
2770 {
2771 /* fail longest-standing DHT request */
2773 GNUNET_assert (NULL != rx);
2774 rx->dht_heap_node = NULL;
2775 if (NULL != rx->task_id)
2776 {
2778 rx->task_id = NULL;
2779 }
2780 fail_resolution (rx);
2781 }
2782}
2783
2784
2790static void
2792{
2794 ro_tail,
2795 ro);
2796 if (NULL != ro->timeout_task)
2799 GNUNET_free (ro);
2800}
2801
2802
2808static void
2810{
2811 struct RefreshOps *ro = cls;
2812
2813 ro->timeout_task = NULL;
2815 "No fresher block for %s found in the DHT\n",
2816 GNUNET_h2s (&ro->query));
2817 refresh_stop (ro);
2818}
2819
2820
2827static void
2829 struct GNUNET_TIME_Absolute exp,
2830 const struct GNUNET_HashCode *key,
2831 const struct GNUNET_PeerIdentity *trunc_peer,
2832 const struct GNUNET_DHT_PathElement *get_path,
2833 unsigned int get_path_length,
2834 const struct GNUNET_DHT_PathElement *put_path,
2835 unsigned int put_path_length,
2837 size_t size,
2838 const void *data)
2839{
2840 struct RefreshOps *ro = cls;
2841 const struct GNUNET_GNSRECORD_Block *block = data;
2843 struct CacheOps *co;
2844
2845 (void) exp;
2846 (void) key;
2847 (void) trunc_peer;
2848 (void) get_path;
2849 (void) get_path_length;
2850 (void) put_path;
2851 (void) put_path_length;
2852 (void) type;
2853 if ( (size < sizeof (struct GNUNET_GNSRECORD_Block)) ||
2855 {
2856 /* how did this pass DHT block validation!? */
2857 GNUNET_break (0);
2858 return;
2859 }
2861 if (expiration.abs_value_us <= ro->expiration.abs_value_us)
2862 return; /* not an improvement, keep looking */
2864 "Refreshing cached block for %s, now expires %s\n",
2865 GNUNET_h2s (&ro->query),
2867 co = GNUNET_new (struct CacheOps);
2869 block,
2870 &
2872 co);
2874 co_tail,
2875 co);
2876 refresh_stop (ro);
2877}
2878
2879
2887static void
2888start_refresh (const struct GNUNET_HashCode *query,
2890{
2891 struct RefreshOps *ro;
2892
2893 for (ro = ro_head; NULL != ro; ro = ro->next)
2894 if (0 == GNUNET_memcmp (&ro->query,
2895 query))
2896 return; /* already refreshing this one */
2897 ro = GNUNET_new (struct RefreshOps);
2898 ro->query = *query;
2899 ro->expiration = expiration;
2902 query,
2905 NULL, 0,
2907 ro);
2908 if (NULL == ro->get_handle)
2909 {
2910 GNUNET_free (ro);
2911 return;
2912 }
2914 "Looking for a fresher block for %s in the DHT\n",
2915 GNUNET_h2s (query));
2918 ro);
2920 ro_tail,
2921 ro);
2922}
2923
2924
2933static void
2935 unsigned int rd_count,
2936 const struct GNUNET_GNSRECORD_Data *rd)
2937{
2938 struct GNS_ResolverHandle *rh = cls;
2939
2940 if (0 == rd_count)
2942 _ ("GNS namecache returned empty result for `%s'\n"),
2943 rh->name);
2945 rd_count,
2946 rd);
2947}
2948
2949
2956static void
2958 const struct GNUNET_GNSRECORD_Block *block)
2959{
2960 struct GNS_ResolverHandle *rh = cls;
2961 struct AuthorityChain *ac = rh->ac_tail;
2962 const char *label = ac->label;
2963 const struct GNUNET_CRYPTO_BlindablePublicKey *auth =
2965 struct GNUNET_HashCode query;
2966 bool dht_allowed;
2967
2968 GNUNET_assert (NULL != rh->namecache_qe);
2969 rh->namecache_qe = NULL;
2970 dht_allowed = ((GNUNET_GNS_LO_DEFAULT == rh->options) ||
2972 (ac != rh->ac_head)));
2973 if (NULL == block)
2975 "No block found\n");
2976 else
2978 "Got block with expiration %s\n",
2981 if (dht_allowed &&
2982 ((NULL == block) ||
2985 rel_value_us)))
2986 {
2987 /* namecache knows nothing; try DHT lookup */
2989 label,
2990 &query);
2992 "Starting DHT lookup for `%s' in zone `%s' under key `%s'\n",
2993 ac->label,
2995 GNUNET_h2s (&query));
2996 start_dht_request (rh, &query);
2997 return;
2998 }
2999
3000 if ((NULL == block) ||
3003 rel_value_us))
3004 {
3005 /* DHT not permitted and no local result, fail */
3007 "Resolution failed for `%s' in zone %s (DHT lookup not permitted by configuration)\n",
3008 ac->label,
3010 fail_resolution (rh);
3011 return;
3012 }
3014 "Received result from namecache for label `%s'\n",
3015 ac->label);
3016 /* The block is still valid, but a record set that is about to expire
3017 has almost certainly been republished by now; get that version
3018 into the cache before this one dies, instead of paying a cold DHT
3019 lookup then. */
3020 if (dht_allowed &&
3022 GNUNET_GNSRECORD_block_get_expiration (block)).rel_value_us <
3024 {
3026 label,
3027 &query);
3028 start_refresh (&query,
3030 }
3031
3032 if (GNUNET_OK !=
3034 auth,
3035 label,
3037 rh))
3038 {
3039 GNUNET_break_op (0); /* block was ill-formed */
3040 /* try DHT instead */
3042 label,
3043 &query);
3045 "Starting DHT lookup for `%s' in zone `%s' under key `%s'\n",
3046 ac->label,
3048 GNUNET_h2s (&query));
3049 start_dht_request (rh, &query);
3050 return;
3051 }
3052}
3053
3054
3060static void
3062{
3063 struct AuthorityChain *ac = rh->ac_tail;
3064 struct GNUNET_HashCode query;
3065
3067 "Starting GNS resolution for `%s' in zone %s\n",
3068 ac->label,
3071 ac->label,
3072 &query);
3074 {
3075 rh->namecache_qe
3077 &query,
3079 rh);
3080 GNUNET_assert (NULL != rh->namecache_qe);
3081 }
3082 else
3083 {
3085 &query);
3086 }
3087}
3088
3089
3096static void
3098 int is_valid)
3099{
3100 struct GNS_ResolverHandle *rh = cls;
3101 struct AuthorityChain *ac = rh->ac_tail;
3102
3103 rh->rev_check = NULL;
3104 if (GNUNET_YES != is_valid)
3105 {
3107 _ ("Zone %s was revoked, resolution fails\n"),
3110 return;
3111 }
3113}
3114
3115
3121static void
3123{
3124 struct AuthorityChain *ac = rh->ac_tail;
3125
3127 "Starting revocation check for zone %s\n",
3132 rh);
3133 GNUNET_assert (NULL != rh->rev_check);
3134}
3135
3136
3137static void
3139{
3140 struct GNS_ResolverHandle *rh = cls;
3141
3142 rh->task_id = NULL;
3143 if (rh->loop_threshold < rh->loop_limiter++)
3144 {
3146 "Encountered unbounded recursion resolving `%s'\n",
3147 rh->name);
3148 fail_resolution (rh);
3149 return;
3150 }
3151 if (GNUNET_YES == rh->ac_tail->gns_authority)
3153 else
3155}
3156
3157
3158static void
3160{
3161 struct GNS_ResolverHandle *rh = cls;
3162 struct AuthorityChain *ac;
3163 struct in_addr v4;
3164 struct in6_addr v6;
3165
3166 rh->task_id = NULL;
3167 if (1 == inet_pton (AF_INET,
3168 rh->name,
3169 &v4))
3170 {
3171 /* name is IPv4 address, pretend it's an A record */
3173
3174 rd.data = &v4;
3175 rd.data_size = sizeof(v4);
3176 rd.expiration_time = UINT64_MAX;
3178 rd.flags = 0;
3179 rh->proc (rh->proc_cls,
3180 1,
3181 &rd);
3182 GNUNET_assert (NULL == rh->task_id);
3184 rh);
3185 return;
3186 }
3187 if (1 == inet_pton (AF_INET6,
3188 rh->name,
3189 &v6))
3190 {
3191 /* name is IPv6 address, pretend it's an AAAA record */
3193
3194 rd.data = &v6;
3195 rd.data_size = sizeof(v6);
3196 rd.expiration_time = UINT64_MAX;
3198 rd.flags = 0;
3199 rh->proc (rh->proc_cls,
3200 1,
3201 &rd);
3202 GNUNET_assert (NULL == rh->task_id);
3204 rh);
3205 return;
3206 }
3207
3208 ac = GNUNET_new (struct AuthorityChain);
3209 ac->rh = rh;
3211 if (NULL == ac->label)
3212 /* name was just the "TLD", so we default to label
3213 #GNUNET_GNS_EMPTY_LABEL_AT */
3218 rh->ac_tail,
3219 ac);
3221 rh);
3222}
3223
3224
3239struct GNS_ResolverHandle *
3241 uint32_t record_type,
3242 const char *name,
3244 uint16_t recursion_depth_limit,
3246 void *proc_cls)
3247{
3248 struct GNS_ResolverHandle *rh;
3249
3251 "Starting lookup for `%s'\n",
3252 name);
3253 rh = GNUNET_new (struct GNS_ResolverHandle);
3255 rlh_tail,
3256 rh);
3257 rh->authority_zone = *zone;
3258 rh->proc = proc;
3259 rh->proc_cls = proc_cls;
3260 rh->options = options;
3262 rh->name = GNUNET_strdup (name);
3263 rh->name_resolution_pos = strlen (name);
3264 rh->loop_threshold = recursion_depth_limit;
3266 rh);
3267 return rh;
3268}
3269
3270
3276void
3278{
3279 struct DnsResult *dr;
3280 struct AuthorityChain *ac;
3281
3283 rlh_tail,
3284 rh);
3285 if (NULL != rh->dns_request)
3286 {
3288 rh->dns_request = NULL;
3289 }
3290 while (NULL != (ac = rh->ac_head))
3291 {
3293 rh->ac_tail,
3294 ac);
3295 if (GNUNET_NO == ac->gns_authority)
3296 {
3297 struct Gns2DnsPending *gp;
3298
3299 while (NULL != (gp = ac->authority_info.dns_authority.gp_head))
3300 {
3303 gp);
3304 if (NULL != gp->rh)
3305 {
3306 /* rh->g2dc->rh is NOT in the DLL yet, so to enable us
3307 using GNS_resolver_lookup_cancel here, we need to
3308 add it first... */
3310 rlh_tail,
3311 gp->rh);
3312 GNUNET_assert (NULL == gp->rh->task_id);
3315 gp->rh);
3316 gp->rh = NULL;
3317 }
3318 if (NULL != gp->dns_rh)
3319 {
3321 gp->dns_rh = NULL;
3322 }
3323 GNUNET_free (gp);
3324 }
3326 }
3327 GNUNET_free (ac->label);
3328 GNUNET_free (ac);
3329 }
3330 if (NULL != rh->task_id)
3331 {
3333 rh->task_id = NULL;
3334 }
3335 if (NULL != rh->get_handle)
3336 {
3338 rh->get_handle = NULL;
3339 }
3340 if (NULL != rh->dht_heap_node)
3341 {
3343 rh->dht_heap_node = NULL;
3344 }
3345 if (NULL != rh->namecache_qe)
3346 {
3348 rh->namecache_qe = NULL;
3349 }
3350 if (NULL != rh->rev_check)
3351 {
3353 rh->rev_check = NULL;
3354 }
3355 if (NULL != rh->std_resolve)
3356 {
3358 "Canceling standard DNS resolution\n");
3360 rh->std_resolve = NULL;
3361 }
3362 while (NULL != (dr = rh->dns_result_head))
3363 {
3366 dr);
3367 GNUNET_free (dr);
3368 }
3369 if (NULL != rh->prefix)
3370 {
3372 rh->prefix = NULL;
3373 }
3374 GNUNET_free (rh->leho);
3375 GNUNET_free (rh->name);
3376 GNUNET_free (rh);
3377}
3378
3379
3380/* ***************** Resolver initialization ********************* */
3381
3382
3391void
3393 struct GNUNET_DHT_Handle *dht,
3394 const struct GNUNET_CONFIGURATION_Handle *c,
3395 unsigned long long max_bg_queries)
3396{
3397 cfg = c;
3399 dht_handle = dht;
3402 max_allowed_background_queries = max_bg_queries;
3404 "namecache",
3405 "DISABLE");
3408 "Namecache disabled\n");
3409}
3410
3411
3415void
3417{
3418 struct GNS_ResolverHandle *rh;
3419 struct CacheOps *co;
3420
3421 /* abort active resolutions */
3422 while (NULL != (rh = rlh_head))
3423 {
3424 rh->proc (rh->proc_cls,
3425 0,
3426 NULL);
3428 }
3429 while (NULL != ro_head)
3431 while (NULL != (co = co_head))
3432 {
3434 co_tail,
3435 co);
3437 GNUNET_free (co);
3438 }
3440 dht_lookup_heap = NULL;
3441 dht_handle = NULL;
3442 namecache_handle = NULL;
3443}
3444
3445
3446/* end of gnunet-service-gns_resolver.c */
struct GNUNET_GETOPT_CommandLineOption options[]
Definition 002.c:5
static size_t strnlen(const char *s, size_t n)
#define memrchr(s, c, n)
Definition compat.h:49
uint16_t GNUNET_GNS_protocol_name_to_number(const char *name)
#define GNUNET_GNSRECORD_TYPE_BOX
Box record.
#define GNUNET_GNSRECORD_TYPE_GNS2DNS
Delegation to DNS.
#define GNUNET_GNSRECORD_TYPE_REDIRECT
Redirection record.
#define GNUNET_GNSRECORD_TYPE_LEHO
GNS legacy hostname.
#define GNUNET_GNSRECORD_TYPE_SBOX
SBox record.
#define GNUNET_GNSRECORD_TYPE_PKEY
WARNING: This header is generated! In order to add GNS record types, you must register them in GANA,...
#define GNUNET_GNSRECORD_TYPE_EDKEY
GNS zone delegation (EDKEY)
uint16_t GNUNET_GNS_service_port_name_to_number(const char *name)
static int ret
Final status code.
Definition gnunet-arm.c:93
static int prefix
If printing the value of PREFIX has been requested.
static struct GNUNET_DHT_Handle * dht
Handle to the DHT.
static char * data
The data to insert into the dht.
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_TIME_Relative expiration
User supplied expiration value.
static struct GNUNET_CRYPTO_BlindablePublicKey pubkey
Public key of the zone to look in.
static char * name
Name (label) of the records to list.
static struct GNUNET_NAMECACHE_Handle * ns
Handle to the namecache.
static unsigned int rd_count
Number of records for currently parsed set.
static char * res
Currently read line or NULL on EOF.
static struct GNUNET_GNSRECORD_Data rd[50]
The record data under a single label.
static uint32_t type
Type string converted to DNS type value.
static size_t data_size
Number of bytes in data.
static uint8_t proto
Protocol to use.
static struct GNUNET_FS_Uri * uri
Value of URI provided on command-line (when not publishing a file but just creating UBlocks to refer ...
static char * rp
Relying party.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static struct GNUNET_NotificationContext * nc
Notification context for broadcasting to monitors.
const char * GNS_get_tld(const char *name)
Obtain the TLD of the given name.
GNU Name System (main service)
static void refresh_timeout(void *cls)
Nothing fresher showed up in time.
#define DHT_LOOKUP_TIMEOUT
Default DHT timeout for lookups.
#define DNS_LOOKUP_TIMEOUT
Default timeout for DNS lookups.
static int disable_cache
Use namecache.
void GNS_resolver_init(struct GNUNET_NAMECACHE_Handle *nc, struct GNUNET_DHT_Handle *dht, const struct GNUNET_CONFIGURATION_Handle *c, unsigned long long max_bg_queries)
Initialize the resolver.
static unsigned long long max_allowed_background_queries
Maximum amount of parallel queries to the DHT.
static void start_dht_request(struct GNS_ResolverHandle *rh, const struct GNUNET_HashCode *query)
Initiate a DHT query for a set of GNS records.
#define BLOCK_REFRESH_THRESHOLD
If a block we found in the namecache expires within this time, look for a fresher version of it in th...
static void handle_gns2dns_ip(void *cls, const struct sockaddr *addr, socklen_t addrlen)
Function called by the resolver for each address obtained from DNS.
static void handle_revocation_result(void *cls, int is_valid)
Function called with the result from a revocation check.
static int resolver_getprotobyname(const char *name)
Function called to receive the protocol number for a service.
static void dht_lookup_timeout(void *cls)
The DHT did not answer within DHT_LOOKUP_TIMEOUT.
static void recursive_pkey_resolution(struct GNS_ResolverHandle *rh, const struct GNUNET_GNSRECORD_Data *rd)
We found a PKEY record, perform recursive resolution on it.
static void recursive_resolution(void *cls)
Task scheduled to continue with the resolution process.
#define BLOCK_REFRESH_TIMEOUT
How long do we leave a background refresh GET running?
static void start_resolver_lookup(void *cls)
Begin the resolution process from 'name', starting with the identification of the zone specified by '...
static struct GNS_ResolverHandle * rlh_tail
Tail of resolver lookup list.
static void transmit_lookup_dns_result(struct GNS_ResolverHandle *rh)
Gives the cumulative result obtained to the callback and clean up the request.
static char * translate_dot_plus(struct GNS_ResolverHandle *rh, char *name)
Expands a name ending in .
static void recursive_gns_resolution_namecache(struct GNS_ResolverHandle *rh)
Lookup tail of our authority chain in the namecache.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Global configuration.
static void fail_resolution(struct GNS_ResolverHandle *rh)
Function called to asynchronously fail a resolution.
static struct RefreshOps * ro_head
Organized in a DLL.
static void handle_namecache_block_response(void *cls, const struct GNUNET_GNSRECORD_Block *block)
Process a record that was stored in the namecache.
static void start_refresh(const struct GNUNET_HashCode *query, struct GNUNET_TIME_Absolute expiration)
Ask the DHT for a fresher version of query while we answer from a namecache entry that is about to ex...
static void recursive_cname_resolution(struct GNS_ResolverHandle *rh, const struct GNUNET_GNSRECORD_Data *rd)
We found a CNAME record, perform recursive resolution on it.
static void handle_gns_redirect_result(struct GNS_ResolverHandle *rh, const char *rname)
We encountered a REDIRECT record during our resolution.
static int resolver_getservbyname(const char *name, const char *proto)
Function called to receive the port number for a service.
static void add_dns_result(struct GNS_ResolverHandle *rh, uint64_t expiration_time, uint32_t record_type, size_t data_size, const void *data)
Add a result from DNS to the records to be returned to the application.
static void recursive_gns_resolution_revocation(struct GNS_ResolverHandle *rh)
Perform revocation check on tail of our authority chain.
static struct GNUNET_DHT_Handle * dht_handle
Resolver handle to the dht.
static struct GNS_ResolverHandle * rlh_head
Head of resolver lookup list.
void GNS_resolver_lookup_cancel(struct GNS_ResolverHandle *rh)
Cancel active resolution (i.e.
static void handle_refresh_response(void *cls, struct GNUNET_TIME_Absolute exp, const struct GNUNET_HashCode *key, const struct GNUNET_PeerIdentity *trunc_peer, const struct GNUNET_DHT_PathElement *get_path, unsigned int get_path_length, const struct GNUNET_DHT_PathElement *put_path, unsigned int put_path_length, enum GNUNET_BLOCK_Type type, size_t size, const void *data)
A background refresh returned a block.
static void refresh_stop(struct RefreshOps *ro)
End a background refresh.
static void handle_dns_result(void *cls, const struct sockaddr *addr, socklen_t addrlen)
We had to do a DNS lookup.
static struct CacheOps * co_head
Organized in a DLL.
static void handle_dht_response(void *cls, struct GNUNET_TIME_Absolute exp, const struct GNUNET_HashCode *key, const struct GNUNET_PeerIdentity *trunc_peer, const struct GNUNET_DHT_PathElement *get_path, unsigned int get_path_length, const struct GNUNET_DHT_PathElement *put_path, unsigned int put_path_length, enum GNUNET_BLOCK_Type type, size_t size, const void *data)
Iterator called on each result obtained for a DHT operation that expects a reply.
static void dns_result_parser(void *cls, const struct GNUNET_TUN_DnsHeader *dns, size_t dns_len)
Function called with the result of a DNS resolution.
static void recursive_redirect_resolution(struct GNS_ResolverHandle *rh, const struct GNUNET_GNSRECORD_Data *rd)
We found a REDIRECT record, perform recursive resolution on it.
static void namecache_cache_continuation(void *cls, int32_t success, const char *emsg)
Function called once the namestore has completed the request for caching a block.
static void handle_gns_cname_result(struct GNS_ResolverHandle *rh, const char *cname)
We encountered a CNAME record during our resolution.
#define DHT_GNS_REPLICATION_LEVEL
DHT replication level.
static void GNS_resolver_lookup_cancel_(void *cls)
Wrapper around GNS_resolver_lookup_cancel() as a task.
static void recursive_dns_resolution(struct GNS_ResolverHandle *rh)
Perform recursive DNS resolution.
static char * resolver_lookup_get_next_label(struct GNS_ResolverHandle *rh)
Get the next, rightmost label from the name that we are trying to resolve, and update the resolution ...
static void timeout_resolution(void *cls)
Function called when a resolution times out.
static struct CacheOps * co_tail
Organized in a DLL.
static int recursive_gns2dns_resolution(struct GNS_ResolverHandle *rh, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
We found one or more GNS2DNS records, perform recursive resolution on it.
static void handle_gns_namecache_resolution_result(void *cls, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Process a records that were decrypted from a block that we got from the namecache.
static void handle_gns_resolution_result(void *cls, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Process records that were decrypted from a block.
struct GNS_ResolverHandle * GNS_resolver_lookup(const struct GNUNET_CRYPTO_BlindablePublicKey *zone, uint32_t record_type, const char *name, enum GNUNET_GNS_LocalOptions options, uint16_t recursion_depth_limit, GNS_ResultProcessor proc, void *proc_cls)
Lookup of a record in a specific zone calls lookup result processor on result.
static void handle_gns2dns_result(void *cls, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
We've resolved the IP address for the DNS resolver to use after encountering a GNS2DNS record.
static void continue_with_gns2dns(struct AuthorityChain *ac)
We have resolved one or more of the nameservers for a GNS2DNS lookup.
void GNS_resolver_done()
Shutdown resolver.
#define DHT_LOOKUP_RETRIES
How often do we restart a DHT lookup that stayed unanswered for DHT_LOOKUP_TIMEOUT before we give up ...
static struct GNUNET_CONTAINER_Heap * dht_lookup_heap
Heap for limiting parallel DHT lookups.
static struct RefreshOps * ro_tail
Organized in a DLL.
static struct GNUNET_NAMECACHE_Handle * namecache_handle
Our handle to the namecache service.
void(* GNS_ResultProcessor)(void *cls, uint32_t rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Function called with results for a GNS resolution.
static struct GNUNET_Process * p
Helper process we started.
Definition gnunet-uri.c:38
GNUNET_BLOCK_Type
WARNING: This header is generated! In order to add DHT block types, you must register them in GANA,...
@ GNUNET_BLOCK_TYPE_GNS_NAMERECORD
Block for storing GNS record data.
API to the DHT service.
API to the GNS service.
API that can be used to manipulate GNS record data.
API that can be used to store naming information on a GNUnet node.
Functions related to doing DNS lookups.
API to perform and access key revocations.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
uint32_t GNUNET_CRYPTO_random_u32(uint32_t i)
Produce a random value.
void GNUNET_DHT_get_stop(struct GNUNET_DHT_GetHandle *get_handle)
Stop async DHT-get.
Definition dht_api.c:1238
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:1165
@ GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE
Each peer along the way should process the request (otherwise only peers locally closest to the key w...
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_DNSPARSER_TYPE_URI
struct GNUNET_DNSPARSER_MxRecord * GNUNET_DNSPARSER_parse_mx(const char *udp_payload, size_t udp_payload_length, size_t *off)
Parse a DNS MX record.
Definition dnsparser.c:473
int GNUNET_DNSPARSER_builder_add_name(char *dst, size_t dst_len, size_t *off, const char *name)
Add a DNS name to the UDP packet at the given location, converting the name to IDNA notation as neces...
Definition dnsparser.c:1013
void GNUNET_DNSPARSER_free_packet(struct GNUNET_DNSPARSER_Packet *p)
Free memory taken by a packet.
Definition dnsparser.c:978
#define GNUNET_DNSPARSER_TYPE_SRV
#define GNUNET_DNSPARSER_TYPE_SOA
#define GNUNET_DNSPARSER_TYPE_A
void GNUNET_DNSPARSER_free_srv(struct GNUNET_DNSPARSER_SrvRecord *srv)
Free SRV information record.
Definition dnsparser.c:156
#define GNUNET_DNSPARSER_TYPE_PTR
struct GNUNET_DNSPARSER_SoaRecord * GNUNET_DNSPARSER_parse_soa(const char *udp_payload, size_t udp_payload_length, size_t *off)
Parse a DNS SOA record.
Definition dnsparser.c:428
void GNUNET_DNSPARSER_free_uri(struct GNUNET_DNSPARSER_UriRecord *uri)
Free URI information record.
Definition dnsparser.c:171
#define GNUNET_DNSPARSER_TYPE_NS
int GNUNET_DNSPARSER_builder_add_soa(char *dst, size_t dst_len, size_t *off, const struct GNUNET_DNSPARSER_SoaRecord *soa)
Add an SOA record to the UDP packet at the given location.
Definition dnsparser.c:1205
#define GNUNET_DNSPARSER_TYPE_CNAME
struct GNUNET_DNSPARSER_UriRecord * GNUNET_DNSPARSER_parse_uri(const char *udp_payload, size_t udp_payload_length, size_t *off)
Parse a DNS URI record.
Definition dnsparser.c:555
struct GNUNET_DNSPARSER_SrvRecord * GNUNET_DNSPARSER_parse_srv(const char *udp_payload, size_t udp_payload_length, size_t *off)
Parse a DNS SRV record.
Definition dnsparser.c:514
char * GNUNET_DNSPARSER_parse_name(const char *udp_payload, size_t udp_payload_length, size_t *off)
Parse name inside of a DNS query or record.
Definition dnsparser.c:371
int GNUNET_DNSPARSER_builder_add_mx(char *dst, size_t dst_len, size_t *off, const struct GNUNET_DNSPARSER_MxRecord *mx)
Add an MX record to the UDP packet at the given location.
Definition dnsparser.c:1127
void GNUNET_DNSPARSER_free_soa(struct GNUNET_DNSPARSER_SoaRecord *soa)
Free SOA information record.
Definition dnsparser.c:125
int GNUNET_DNSPARSER_builder_add_srv(char *dst, size_t dst_len, size_t *off, const struct GNUNET_DNSPARSER_SrvRecord *srv)
Add an SRV record to the UDP packet at the given location.
Definition dnsparser.c:1246
void GNUNET_DNSPARSER_free_mx(struct GNUNET_DNSPARSER_MxRecord *mx)
Free MX information record.
Definition dnsparser.c:186
#define GNUNET_DNSPARSER_TYPE_AAAA
int GNUNET_DNSPARSER_pack(const struct GNUNET_DNSPARSER_Packet *p, uint16_t max, char **buf, size_t *buf_length)
Given a DNS packet p, generate the corresponding UDP payload.
Definition dnsparser.c:1428
int GNUNET_DNSPARSER_builder_add_uri(char *dst, size_t dst_len, size_t *off, const struct GNUNET_DNSPARSER_UriRecord *uri)
Add an URI record to the UDP packet at the given location.
Definition dnsparser.c:1283
#define GNUNET_DNSPARSER_TYPE_MX
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:756
#define GNUNET_DNSPARSER_MAX_NAME_LENGTH
Maximum length of a name in DNS.
struct GNUNET_DNSSTUB_Context * GNUNET_DNSSTUB_start(unsigned int num_sockets)
Start a DNS stub resolver.
Definition dnsstub.c:585
int GNUNET_DNSSTUB_add_dns_ip(struct GNUNET_DNSSTUB_Context *ctx, const char *dns_ip)
Add nameserver for use by the DNSSTUB.
Definition dnsstub.c:612
void GNUNET_DNSSTUB_stop(struct GNUNET_DNSSTUB_Context *ctx)
Cleanup DNSSTUB resolver.
Definition dnsstub.c:704
struct GNUNET_DNSSTUB_RequestSocket * GNUNET_DNSSTUB_resolve(struct GNUNET_DNSSTUB_Context *ctx, const void *request, size_t request_len, GNUNET_DNSSTUB_ResultCallback rc, void *rc_cls)
Perform DNS resolution using our default IP from init.
Definition dnsstub.c:525
void GNUNET_DNSSTUB_resolve_cancel(struct GNUNET_DNSSTUB_RequestSocket *rs)
Cancel DNS resolution.
Definition dnsstub.c:561
int GNUNET_DNSSTUB_add_dns_sa(struct GNUNET_DNSSTUB_Context *ctx, const struct sockaddr *sa)
Add nameserver for use by the DNSSTUB.
Definition dnsstub.c:664
GNUNET_GNS_LocalOptions
Options for the GNS lookup.
@ GNUNET_GNS_LO_LOCAL_MASTER
For the rightmost label, only look in the cache (it is our local namestore), for the others,...
@ GNUNET_GNS_LO_DEFAULT
Defaults, look in cache, then in DHT.
int GNUNET_GNSRECORD_zkey_to_pkey(const char *zkey, struct GNUNET_CRYPTO_BlindablePublicKey *pkey)
Convert an absolute domain name to the respective public key.
const char * GNUNET_GNSRECORD_z2s(const struct GNUNET_CRYPTO_BlindablePublicKey *z)
Convert a zone to a string (for printing debug messages).
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_block_decrypt(const struct GNUNET_GNSRECORD_Block *block, const struct GNUNET_CRYPTO_BlindablePublicKey *zone_key, const char *label, GNUNET_GNSRECORD_RecordCallback proc, void *proc_cls)
Decrypt block.
size_t GNUNET_GNSRECORD_block_get_size(const struct GNUNET_GNSRECORD_Block *block)
Returns the length of this block in bytes.
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_identity_from_data(const char *data, size_t data_size, uint32_t type, struct GNUNET_CRYPTO_BlindablePublicKey *key)
Build a #GNUNET_GNSRECORD_PublicKey from zone delegation resource record data.
const char * GNUNET_GNSRECORD_pkey_to_zkey(const struct GNUNET_CRYPTO_BlindablePublicKey *pkey)
Convert public key to the respective absolute domain name in the ".zkey" pTLD.
#define GNUNET_GNS_EMPTY_LABEL_AT
String we use to indicate an empty label (top-level entry in the zone).
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_is_critical(uint32_t type)
Check if this type is a critical record.
Definition gnsrecord.c:239
void GNUNET_GNSRECORD_query_from_public_key(const struct GNUNET_CRYPTO_BlindablePublicKey *pub, const char *label, struct GNUNET_HashCode *query)
Calculate the DHT query for a given label in a given zone.
#define GNUNET_GNSRECORD_TYPE_ANY
Record type indicating any record/'*'.
struct GNUNET_TIME_Absolute GNUNET_GNSRECORD_block_get_expiration(const struct GNUNET_GNSRECORD_Block *block)
Returns the expiration of a block.
@ GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION
This expiration time of the record is a relative time (not an absolute time).
@ GNUNET_GNSRECORD_RF_SUPPLEMENTAL
This is a supplemental record.
@ GNUNET_GNSRECORD_RF_NONE
Entry for no flags / cleared flags.
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
void * GNUNET_CONTAINER_heap_remove_root(struct GNUNET_CONTAINER_Heap *heap)
Remove root of the heap.
struct GNUNET_CONTAINER_HeapNode * GNUNET_CONTAINER_heap_insert(struct GNUNET_CONTAINER_Heap *heap, void *element, GNUNET_CONTAINER_HeapCostType cost)
Inserts a new element into the heap.
unsigned int GNUNET_CONTAINER_heap_get_size(const struct GNUNET_CONTAINER_Heap *heap)
Get the current size of the heap.
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
void GNUNET_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.
@ GNUNET_CONTAINER_HEAP_ORDER_MIN
Heap with the minimum cost at the root.
#define GNUNET_log(kind,...)
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_NAMECACHE_cancel(struct GNUNET_NAMECACHE_QueueEntry *qe)
Cancel a namecache operation.
struct GNUNET_NAMECACHE_QueueEntry * GNUNET_NAMECACHE_lookup_block(struct GNUNET_NAMECACHE_Handle *h, const struct GNUNET_HashCode *derived_hash, GNUNET_NAMECACHE_BlockProcessor proc, void *proc_cls)
Get a result for a particular key from the namecache.
struct GNUNET_NAMECACHE_QueueEntry * GNUNET_NAMECACHE_block_cache(struct GNUNET_NAMECACHE_Handle *h, const struct GNUNET_GNSRECORD_Block *block, GNUNET_NAMECACHE_ContinuationWithStatus cont, void *cont_cls)
Store an item in the namecache.
struct GNUNET_RESOLVER_RequestHandle * GNUNET_RESOLVER_ip_get(const char *hostname, int af, struct GNUNET_TIME_Relative timeout, GNUNET_RESOLVER_AddressCallback callback, void *callback_cls)
Convert a string to one or more IP addresses.
void GNUNET_RESOLVER_request_cancel(struct GNUNET_RESOLVER_RequestHandle *rh)
Cancel a request that is still pending with the resolver.
struct GNUNET_REVOCATION_Query * GNUNET_REVOCATION_query(const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_CRYPTO_BlindablePublicKey *key, GNUNET_REVOCATION_Callback func, void *func_cls)
Check if a key was revoked.
void GNUNET_REVOCATION_query_cancel(struct GNUNET_REVOCATION_Query *q)
Cancel key revocation check.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition scheduler.c:1310
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:1283
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
#define GNUNET_TIME_UNIT_HOURS
One hour.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition time.c:406
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition strings.c:671
#define GNUNET_TUN_DNS_CLASS_INTERNET
A few common DNS classes (ok, only one is common, but I list a couple more to make it clear what we'r...
#define GNUNET_TUN_DNS_OPCODE_QUERY
static unsigned int size
Size of the "table".
Definition peer.c:68
#define _(String)
GNU gettext support macro.
Definition platform.h:179
DLL to hold the authority chain we had to pass in the resolution process.
int found
Did we succeed in getting an IP address for any of the DNS servers listed? Once we do,...
char * label
label/name corresponding to the authority
struct AuthorityChain::@63::@64 dns_authority
struct AuthorityChain * next
This is a DLL.
int gns_authority
GNUNET_YES if the authority was a GNS authority, GNUNET_NO if the authority was a DNS authority.
struct GNUNET_DNSSTUB_Context * dns_handle
Handle to perform DNS lookups with this authority (in GNS2DNS handling).
char name[GNUNET_DNSPARSER_MAX_NAME_LENGTH+1]
Domain of the DNS resolver that is the authority.
struct AuthorityChain * prev
This is a DLL.
struct GNS_ResolverHandle * rh
Resolver handle this entry in the chain belongs to.
int launched
Did we start the recursive resolution via DNS?
union AuthorityChain::@63 authority_info
Information about the resolver authority for this label.
struct Gns2DnsPending * gp_head
List of resolutions of the 'ip' of the name server that are still pending.
struct Gns2DnsPending * gp_tail
Tail of list of resolutions of the 'ip' of the name server that are still pending.
Active namestore caching operations.
struct CacheOps * prev
Organized in a DLL.
struct GNUNET_NAMECACHE_QueueEntry * namecache_qe_cache
Pending Namestore caching task.
struct CacheOps * next
Organized in a DLL.
A result we got from DNS.
struct DnsResult * next
Kept in DLL.
size_t data_size
Number of bytes in data.
uint32_t record_type
Type of the GNS/DNS record.
struct DnsResult * prev
Kept in DLL.
uint64_t expiration_time
Expiration time for the DNS record, 0 if we didn't get anything useful (i.e.
const void * data
Binary value stored in the DNS record (appended to this struct)
Handle to a currently pending resolution.
size_t name_resolution_pos
Current offset in name where we are resolving.
int service
For SRV and TLSA records, the number of the service specified in the name.
char * leho
Legacy Hostname to use if we encountered GNS2DNS record and thus can deduct the LEHO from that transi...
struct GNUNET_CONTAINER_HeapNode * dht_heap_node
Heap node associated with this lookup.
void * proc_cls
closure passed to proc
struct GNS_ResolverHandle * next
DLL.
struct GNUNET_DHT_GetHandle * get_handle
Handle for DHT lookups.
struct DnsResult * dns_result_tail
DLL of results we got from DNS.
struct GNUNET_REVOCATION_Query * rev_check
Pending revocation check.
unsigned int loop_limiter
We increment the loop limiter for each step in a recursive resolution.
struct GNUNET_NAMECACHE_QueueEntry * namecache_qe
Pending Namecache lookup task.
struct GNUNET_RESOLVER_RequestHandle * std_resolve
Handle for standard DNS resolution, NULL if none is active.
int record_type
Desired type for the resolution.
struct GNUNET_CRYPTO_BlindablePublicKey authority_zone
The top-level GNS authoritative zone to query.
struct DnsResult * dns_result_head
DLL of results we got from DNS.
struct AuthorityChain * ac_head
DLL to store the authority chain.
unsigned int dht_retries
How many times did we already restart the DHT GET in get_handle because it did not answer within DHT_...
struct AuthorityChain * ac_tail
DLL to store the authority chain.
unsigned int loop_threshold
Maximum value of loop_limiter allowed by client.
struct GNUNET_SCHEDULER_Task * task_id
ID of a task associated with the resolution process.
GNS_ResultProcessor proc
called when resolution phase finishes
uint16_t original_dns_id
16 bit random ID we used in the dns_request.
struct GNS_ResolverHandle * prev
DLL.
struct GNUNET_HashCode dht_query
Key of the DHT GET in get_handle, so that we can re-issue it when it times out.
char * name
The name to resolve.
char * prefix
For SMIMEA,OPENPGPKEY... records.
int protocol
For SRV and TLSA records, the number of the protocol specified in the name.
enum GNUNET_GNS_LocalOptions options
Use only cache.
struct GNUNET_DNSSTUB_RequestSocket * dns_request
Socket for a DNS request, NULL if none is active.
Handle to a node in a heap.
An identity key as per LSD0001.
Handle to a GET request.
Definition dht_api.c:79
Connection to the DHT service.
Definition dht_api.c:235
A (signed) path tracking a block's flow through the DHT is represented by an array of path elements,...
Information from MX records (RFC 1035).
char * mxhost
Name of the mail server.
Easy-to-process, parsed version of a DNS packet.
uint16_t dns_traffic_class
See GNUNET_TUN_DNS_CLASS_*.
uint16_t type
See GNUNET_DNSPARSER_TYPE_*.
char * name
Name of the record that the query is for (0-terminated).
void * data
Binary record data.
size_t data_len
Number of bytes in data.
A DNS response record.
struct GNUNET_DNSPARSER_SoaRecord * soa
SOA data for SOA records.
struct GNUNET_DNSPARSER_SrvRecord * srv
SRV data for SRV records.
struct GNUNET_DNSPARSER_MxRecord * mx
MX data for MX records.
char * hostname
For NS, CNAME and PTR records, this is the uncompressed 0-terminated hostname.
uint16_t type
See GNUNET_DNSPARSER_TYPE_*.
struct GNUNET_TIME_Absolute expiration_time
When does the record expire?
union GNUNET_DNSPARSER_Record::@24 data
Payload of the record (which one of these is valid depends on the 'type').
char * name
Name of the record that the query is for (0-terminated).
struct GNUNET_DNSPARSER_RawRecord raw
Raw data for all other types.
struct GNUNET_DNSPARSER_UriRecord * uri
URI data for URI records.
Information from SOA records (RFC 1035).
char * mname
The domainname of the name server that was the original or primary source of data for this zone.
char * rname
A domainname which specifies the mailbox of the person responsible for this zone.
Information from SRV records (RFC 2782).
char * target
Hostname offering the service.
Information from URI records (RFC 7553).
Handle to the stub resolver.
Definition dnsstub.c:125
UDP socket we are using for sending DNS requests to the Internet.
Definition dnsstub.c:46
Record type used to box up SRV and TLSA records.
uint32_t record_type
GNS record type of the boxed record.
uint16_t service
Service of the boxed record (aka port number), in NBO.
uint16_t protocol
Protocol of the boxed record (6 = TCP, 17 = UDP, etc.).
uint32_t record_type
Type of the GNS/DNS record.
const void * data
Binary value stored in the DNS record.
size_t data_size
Number of bytes in data.
enum GNUNET_GNSRECORD_Flags flags
Flags for the record.
uint64_t expiration_time
Expiration time for the DNS record.
Record type used to box up SMIMEA records.
uint32_t record_type
GNS record type of the boxed record.
A 512-bit hashcode.
Connection to the NAMECACHE service.
An QueueEntry used to store information for a pending NAMECACHE record operation.
The identity of the host (wraps the signing key of the peer).
Handle to a request given to the resolver.
Handle for the key revocation query.
Entry in list of pending tasks.
Definition scheduler.c:141
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
uint64_t rel_value_us
The actual value.
uint16_t id
Unique identifier for the request/response.
Element of a resolution process for looking up the responsible DNS server hostname in a GNS2DNS recur...
struct GNUNET_RESOLVER_RequestHandle * dns_rh
Handle for DNS resolution of the DNS nameserver.
struct Gns2DnsPending * next
Kept in a DLL.
struct Gns2DnsPending * prev
Kept in a DLL.
struct GNS_ResolverHandle * rh
Handle for the resolution of the IP part of the GNS2DNS record.
struct AuthorityChain * ac
Context this activity belongs with.
unsigned int num_results
How many results did we get?
Background lookup for a fresher version of a block that is still in the namecache but about to expire...
struct GNUNET_HashCode query
Query we are refreshing.
struct GNUNET_DHT_GetHandle * get_handle
Our DHT GET.
struct RefreshOps * prev
Organized in a DLL.
struct RefreshOps * next
Organized in a DLL.
struct GNUNET_SCHEDULER_Task * timeout_task
Task that ends this refresh.
struct GNUNET_TIME_Absolute expiration
Expiration time of the best block we have seen so far.