diff options
Diffstat (limited to 'src/namestore/gnunet-zoneimport.c')
-rw-r--r-- | src/namestore/gnunet-zoneimport.c | 134 |
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 | */ | ||
62 | static 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 | */ | ||
1503 | static void | ||
1504 | iterate_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 | ||