aboutsummaryrefslogtreecommitdiff
path: root/src/namestore/gnunet-zoneimport.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/namestore/gnunet-zoneimport.c')
-rw-r--r--src/namestore/gnunet-zoneimport.c134
1 files changed, 94 insertions, 40 deletions
diff --git a/src/namestore/gnunet-zoneimport.c b/src/namestore/gnunet-zoneimport.c
index 0fd0a4ab8..ddc8b483a 100644
--- a/src/namestore/gnunet-zoneimport.c
+++ b/src/namestore/gnunet-zoneimport.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet 2 This file is part of GNUnet
3 Copyright (C) 2018 GNUnet e.V. 3 Copyright (C) 2018 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20/** 18/**
21 * @file src/namestore/gnunet-zoneimport.c 19 * @file src/namestore/gnunet-zoneimport.c
@@ -59,6 +57,11 @@
59#define SERIES_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS, 10) 57#define SERIES_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS, 10)
60 58
61/** 59/**
60 * How long do DNS records have to last at least after being imported?
61 */
62static struct GNUNET_TIME_Relative minimum_expiration_time;
63
64/**
62 * How many requests do we request from NAMESTORE in one batch 65 * How many requests do we request from NAMESTORE in one batch
63 * during our initial iteration? 66 * during our initial iteration?
64 */ 67 */
@@ -429,9 +432,9 @@ get_label (struct Request *req)
429 GNUNET_break (0); 432 GNUNET_break (0);
430 return NULL; 433 return NULL;
431 } 434 }
432 memcpy (label, 435 GNUNET_memcpy (label,
433 req->hostname, 436 req->hostname,
434 dot - req->hostname); 437 dot - req->hostname);
435 label[dot - req->hostname] = '\0'; 438 label[dot - req->hostname] = '\0';
436 return label; 439 return label;
437} 440}
@@ -453,6 +456,7 @@ build_dns_query (struct Request *req,
453 char *rawp; 456 char *rawp;
454 struct GNUNET_DNSPARSER_Packet p; 457 struct GNUNET_DNSPARSER_Packet p;
455 struct GNUNET_DNSPARSER_Query q; 458 struct GNUNET_DNSPARSER_Query q;
459 int ret;
456 460
457 q.name = (char *) req->hostname; 461 q.name = (char *) req->hostname;
458 q.type = GNUNET_DNSPARSER_TYPE_NS; 462 q.type = GNUNET_DNSPARSER_TYPE_NS;
@@ -464,12 +468,14 @@ build_dns_query (struct Request *req,
464 p.num_queries = 1; 468 p.num_queries = 1;
465 p.queries = &q; 469 p.queries = &q;
466 p.id = req->id; 470 p.id = req->id;
467 if (GNUNET_OK != 471 ret = GNUNET_DNSPARSER_pack (&p,
468 GNUNET_DNSPARSER_pack (&p, 472 UINT16_MAX,
469 UINT16_MAX, 473 &rawp,
470 &rawp, 474 raw_size);
471 raw_size)) 475 if (GNUNET_OK != ret)
472 { 476 {
477 if (GNUNET_NO == ret)
478 GNUNET_free (rawp);
473 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 479 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
474 "Failed to pack query for hostname `%s'\n", 480 "Failed to pack query for hostname `%s'\n",
475 req->hostname); 481 req->hostname);
@@ -486,9 +492,9 @@ build_dns_query (struct Request *req,
486 GNUNET_free (rawp); 492 GNUNET_free (rawp);
487 return NULL; 493 return NULL;
488 } 494 }
489 memcpy (raw, 495 GNUNET_memcpy (raw,
490 rawp, 496 rawp,
491 *raw_size); 497 *raw_size);
492 GNUNET_free (rawp); 498 GNUNET_free (rawp);
493 return raw; 499 return raw;
494} 500}
@@ -632,10 +638,19 @@ check_for_glue (void *cls,
632 size_t off; 638 size_t off;
633 char ip[INET6_ADDRSTRLEN+1]; 639 char ip[INET6_ADDRSTRLEN+1];
634 socklen_t ip_size = (socklen_t) sizeof (ip); 640 socklen_t ip_size = (socklen_t) sizeof (ip);
641 struct GNUNET_TIME_Absolute expiration_time;
642 struct GNUNET_TIME_Relative left;
635 643
636 if (0 != strcasecmp (rec->name, 644 if (0 != strcasecmp (rec->name,
637 gc->ns)) 645 gc->ns))
638 return; 646 return;
647 expiration_time = rec->expiration_time;
648 left = GNUNET_TIME_absolute_get_remaining (expiration_time);
649 if (0 == left.rel_value_us)
650 return; /* ignore expired glue records */
651 /* if expiration window is too short, bump it to configured minimum */
652 if (left.rel_value_us < minimum_expiration_time.rel_value_us)
653 expiration_time = GNUNET_TIME_relative_to_absolute (minimum_expiration_time);
639 dst_len = sizeof (dst); 654 dst_len = sizeof (dst);
640 off = 0; 655 off = 0;
641 switch (rec->type) 656 switch (rec->type)
@@ -668,7 +683,7 @@ check_for_glue (void *cls,
668 { 683 {
669 add_record (gc->req, 684 add_record (gc->req,
670 GNUNET_GNSRECORD_TYPE_GNS2DNS, 685 GNUNET_GNSRECORD_TYPE_GNS2DNS,
671 rec->expiration_time, 686 expiration_time,
672 dst, 687 dst,
673 off); 688 off);
674 gc->found = GNUNET_YES; 689 gc->found = GNUNET_YES;
@@ -702,7 +717,7 @@ check_for_glue (void *cls,
702 { 717 {
703 add_record (gc->req, 718 add_record (gc->req,
704 GNUNET_GNSRECORD_TYPE_GNS2DNS, 719 GNUNET_GNSRECORD_TYPE_GNS2DNS,
705 rec->expiration_time, 720 expiration_time,
706 dst, 721 dst,
707 off); 722 off);
708 gc->found = GNUNET_YES; 723 gc->found = GNUNET_YES;
@@ -722,7 +737,7 @@ check_for_glue (void *cls,
722 { 737 {
723 add_record (gc->req, 738 add_record (gc->req,
724 GNUNET_GNSRECORD_TYPE_GNS2DNS, 739 GNUNET_GNSRECORD_TYPE_GNS2DNS,
725 rec->expiration_time, 740 expiration_time,
726 dst, 741 dst,
727 off); 742 off);
728 gc->found = GNUNET_YES; 743 gc->found = GNUNET_YES;
@@ -768,6 +783,8 @@ process_record (void *cls,
768 char dst[65536]; 783 char dst[65536];
769 size_t dst_len; 784 size_t dst_len;
770 size_t off; 785 size_t off;
786 struct GNUNET_TIME_Absolute expiration_time;
787 struct GNUNET_TIME_Relative left;
771 788
772 dst_len = sizeof (dst); 789 dst_len = sizeof (dst);
773 off = 0; 790 off = 0;
@@ -783,18 +800,27 @@ process_record (void *cls,
783 return; /* does not match hostname, might be glue, but 800 return; /* does not match hostname, might be glue, but
784 not useful for this pass! */ 801 not useful for this pass! */
785 } 802 }
786 if (0 == 803 expiration_time = rec->expiration_time;
787 GNUNET_TIME_absolute_get_remaining (rec->expiration_time).rel_value_us) 804 left = GNUNET_TIME_absolute_get_remaining (expiration_time);
805 if (0 == left.rel_value_us)
788 { 806 {
789 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 807 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
790 "DNS returned expired record for `%s'\n", 808 "DNS returned expired record for `%s'\n",
791 req->hostname); 809 req->hostname);
810 GNUNET_STATISTICS_update (stats,
811 "# expired records obtained from DNS",
812 1,
813 GNUNET_NO);
792 return; /* record expired */ 814 return; /* record expired */
793 } 815 }
816
794 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 817 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
795 "DNS returned record that expires at %s for `%s'\n", 818 "DNS returned record that expires at %s for `%s'\n",
796 GNUNET_STRINGS_absolute_time_to_string (rec->expiration_time), 819 GNUNET_STRINGS_absolute_time_to_string (expiration_time),
797 req->hostname); 820 req->hostname);
821 /* if expiration window is too short, bump it to configured minimum */
822 if (left.rel_value_us < minimum_expiration_time.rel_value_us)
823 expiration_time = GNUNET_TIME_relative_to_absolute (minimum_expiration_time);
798 switch (rec->type) 824 switch (rec->type)
799 { 825 {
800 case GNUNET_DNSPARSER_TYPE_NS: 826 case GNUNET_DNSPARSER_TYPE_NS:
@@ -828,7 +854,7 @@ process_record (void *cls,
828 rec->name); 854 rec->name);
829 add_record (req, 855 add_record (req,
830 GNUNET_GNSRECORD_TYPE_GNS2DNS, 856 GNUNET_GNSRECORD_TYPE_GNS2DNS,
831 rec->expiration_time, 857 expiration_time,
832 dst, 858 dst,
833 off); 859 off);
834 } 860 }
@@ -853,7 +879,7 @@ process_record (void *cls,
853 rec->name); 879 rec->name);
854 add_record (req, 880 add_record (req,
855 rec->type, 881 rec->type,
856 rec->expiration_time, 882 expiration_time,
857 dst, 883 dst,
858 off); 884 off);
859 } 885 }
@@ -878,7 +904,7 @@ process_record (void *cls,
878 rec->name); 904 rec->name);
879 add_record (req, 905 add_record (req,
880 rec->type, 906 rec->type,
881 rec->expiration_time, 907 expiration_time,
882 dst, 908 dst,
883 off); 909 off);
884 } 910 }
@@ -896,7 +922,7 @@ process_record (void *cls,
896 rec->name); 922 rec->name);
897 add_record (req, 923 add_record (req,
898 rec->type, 924 rec->type,
899 rec->expiration_time, 925 expiration_time,
900 dst, 926 dst,
901 off); 927 off);
902 } 928 }
@@ -913,7 +939,7 @@ process_record (void *cls,
913 rec->name); 939 rec->name);
914 add_record (req, 940 add_record (req,
915 rec->type, 941 rec->type,
916 rec->expiration_time, 942 expiration_time,
917 dst, 943 dst,
918 off); 944 off);
919 } 945 }
@@ -931,7 +957,7 @@ process_record (void *cls,
931 rec->name); 957 rec->name);
932 add_record (req, 958 add_record (req,
933 rec->type, 959 rec->type,
934 rec->expiration_time, 960 expiration_time,
935 dst, 961 dst,
936 off); 962 off);
937 } 963 }
@@ -948,7 +974,7 @@ process_record (void *cls,
948 rec->name); 974 rec->name);
949 add_record (req, 975 add_record (req,
950 rec->type, 976 rec->type,
951 rec->expiration_time, 977 expiration_time,
952 dst, 978 dst,
953 off); 979 off);
954 } 980 }
@@ -966,7 +992,7 @@ process_record (void *cls,
966 rec->name); 992 rec->name);
967 add_record (req, 993 add_record (req,
968 rec->type, 994 rec->type,
969 rec->expiration_time, 995 expiration_time,
970 rec->data.raw.data, 996 rec->data.raw.data,
971 rec->data.raw.data_len); 997 rec->data.raw.data_len);
972 break; 998 break;
@@ -1469,6 +1495,16 @@ do_shutdown (void *cls)
1469 1495
1470 1496
1471/** 1497/**
1498 * Iterate over all of the zones we care about and see which records
1499 * we may need to re-fetch when.
1500 *
1501 * @param cls NULL
1502 */
1503static void
1504iterate_zones (void *cls);
1505
1506
1507/**
1472 * Function called if #GNUNET_NAMESTORE_records_lookup() failed. 1508 * Function called if #GNUNET_NAMESTORE_records_lookup() failed.
1473 * Just logs an error. 1509 * Just logs an error.
1474 * 1510 *
@@ -1482,6 +1518,9 @@ ns_lookup_error_cb (void *cls)
1482 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1518 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1483 "Failed to load data from namestore for zone `%s'\n", 1519 "Failed to load data from namestore for zone `%s'\n",
1484 zone->domain); 1520 zone->domain);
1521 zone_it = NULL;
1522 ns_iterator_trigger_next = 0;
1523 iterate_zones (NULL);
1485} 1524}
1486 1525
1487 1526
@@ -1551,7 +1590,17 @@ ns_lookup_result_cb (void *cls,
1551 { 1590 {
1552 struct GNUNET_TIME_Absolute at; 1591 struct GNUNET_TIME_Absolute at;
1553 1592
1554 at.abs_value_us = rd->expiration_time; 1593 if (0 != (rd->flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
1594 {
1595 struct GNUNET_TIME_Relative rel;
1596
1597 rel.rel_value_us = rd->expiration_time;
1598 at = GNUNET_TIME_relative_to_absolute (rel);
1599 }
1600 else
1601 {
1602 at.abs_value_us = rd->expiration_time;
1603 }
1555 add_record (req, 1604 add_record (req,
1556 rd->record_type, 1605 rd->record_type,
1557 at, 1606 at,
@@ -1648,9 +1697,9 @@ queue (const char *hostname)
1648 req = GNUNET_malloc (sizeof (struct Request) + hlen); 1697 req = GNUNET_malloc (sizeof (struct Request) + hlen);
1649 req->zone = zone; 1698 req->zone = zone;
1650 req->hostname = (char *) &req[1]; 1699 req->hostname = (char *) &req[1];
1651 memcpy (req->hostname, 1700 GNUNET_memcpy (req->hostname,
1652 hostname, 1701 hostname,
1653 hlen); 1702 hlen);
1654 req->id = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, 1703 req->id = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
1655 UINT16_MAX); 1704 UINT16_MAX);
1656 GNUNET_CRYPTO_hash (req->hostname, 1705 GNUNET_CRYPTO_hash (req->hostname,
@@ -1800,14 +1849,14 @@ process_stdin (void *cls)
1800 if (0 == idot) 1849 if (0 == idot)
1801 last = GNUNET_TIME_absolute_get (); 1850 last = GNUNET_TIME_absolute_get ();
1802 idot++; 1851 idot++;
1803 if (0 == idot % 10000) 1852 if (0 == idot % 100000)
1804 { 1853 {
1805 struct GNUNET_TIME_Relative delta; 1854 struct GNUNET_TIME_Relative delta;
1806 1855
1807 delta = GNUNET_TIME_absolute_get_duration (last); 1856 delta = GNUNET_TIME_absolute_get_duration (last);
1808 last = GNUNET_TIME_absolute_get (); 1857 last = GNUNET_TIME_absolute_get ();
1809 fprintf (stderr, 1858 fprintf (stderr,
1810 "Imported 10000 records in %s\n", 1859 "Read 100000 domain names in %s\n",
1811 GNUNET_STRINGS_relative_time_to_string (delta, 1860 GNUNET_STRINGS_relative_time_to_string (delta,
1812 GNUNET_YES)); 1861 GNUNET_YES));
1813 GNUNET_STATISTICS_set (stats, 1862 GNUNET_STATISTICS_set (stats,
@@ -1986,6 +2035,11 @@ main (int argc,
1986 "MAPSIZE", 2035 "MAPSIZE",
1987 gettext_noop ("size to use for the main hash map"), 2036 gettext_noop ("size to use for the main hash map"),
1988 &map_size), 2037 &map_size),
2038 GNUNET_GETOPT_option_relative_time ('m',
2039 "minimum-expiration",
2040 "RELATIVETIME",
2041 gettext_noop ("minimum expiration time we assume for imported records"),
2042 &minimum_expiration_time),
1989 GNUNET_GETOPT_OPTION_END 2043 GNUNET_GETOPT_OPTION_END
1990 }; 2044 };
1991 2045