diff options
author | Christian Grothoff <christian@grothoff.org> | 2018-08-14 15:48:14 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2018-08-14 15:48:14 +0200 |
commit | 68db913bded8a0c606e33994698708e541d1aae0 (patch) | |
tree | ca7441a90e325ffe36fe198ef3b23a922402b5aa /src | |
parent | 1c757482ba7ca48fa108f1613cccc5c775bd957b (diff) | |
download | gnunet-68db913bded8a0c606e33994698708e541d1aae0.tar.gz gnunet-68db913bded8a0c606e33994698708e541d1aae0.zip |
handle case that DNS servers do not return A/AAAA records if we ask for ALL
Diffstat (limited to 'src')
-rw-r--r-- | src/util/gnunet-service-resolver.c | 116 |
1 files changed, 97 insertions, 19 deletions
diff --git a/src/util/gnunet-service-resolver.c b/src/util/gnunet-service-resolver.c index 06af57509..e9397e085 100644 --- a/src/util/gnunet-service-resolver.c +++ b/src/util/gnunet-service-resolver.c | |||
@@ -129,6 +129,12 @@ struct ActiveLookup | |||
129 | char *hostname; | 129 | char *hostname; |
130 | 130 | ||
131 | /** | 131 | /** |
132 | * If @a record_type is #GNUNET_DNSPARSER_TYPE_ALL, did we go again | ||
133 | * for the AAAA records yet? | ||
134 | */ | ||
135 | int did_aaaa; | ||
136 | |||
137 | /** | ||
132 | * type of queried DNS record | 138 | * type of queried DNS record |
133 | */ | 139 | */ |
134 | uint16_t record_type; | 140 | uint16_t record_type; |
@@ -607,6 +613,53 @@ try_cache (const char *hostname, | |||
607 | 613 | ||
608 | 614 | ||
609 | /** | 615 | /** |
616 | * Create DNS query for @a hostname of type @a type | ||
617 | * with DNS request ID @a dns_id. | ||
618 | * | ||
619 | * @param hostname DNS name to query | ||
620 | * @param type requested DNS record type | ||
621 | * @param dns_id what should be the DNS request ID | ||
622 | * @param packet_buf[out] where to write the request packet | ||
623 | * @param packet_size[out] set to size of @a packet_buf on success | ||
624 | * @return #GNUNET_OK on success | ||
625 | */ | ||
626 | static int | ||
627 | pack (const char *hostname, | ||
628 | uint16_t type, | ||
629 | uint16_t dns_id, | ||
630 | char **packet_buf, | ||
631 | size_t *packet_size) | ||
632 | { | ||
633 | struct GNUNET_DNSPARSER_Query query; | ||
634 | struct GNUNET_DNSPARSER_Packet packet; | ||
635 | |||
636 | query.name = (char *)hostname; | ||
637 | query.type = type; | ||
638 | query.dns_traffic_class = GNUNET_TUN_DNS_CLASS_INTERNET; | ||
639 | memset (&packet, | ||
640 | 0, | ||
641 | sizeof (packet)); | ||
642 | packet.num_queries = 1; | ||
643 | packet.queries = &query; | ||
644 | packet.id = htons (dns_id); | ||
645 | packet.flags.recursion_desired = 1; | ||
646 | if (GNUNET_OK != | ||
647 | GNUNET_DNSPARSER_pack (&packet, | ||
648 | UINT16_MAX, | ||
649 | packet_buf, | ||
650 | packet_size)) | ||
651 | { | ||
652 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
653 | "Failed to pack query for hostname `%s'\n", | ||
654 | hostname); | ||
655 | packet_buf = NULL; | ||
656 | return GNUNET_SYSERR; | ||
657 | } | ||
658 | return GNUNET_OK; | ||
659 | } | ||
660 | |||
661 | |||
662 | /** | ||
610 | * We got a result from DNS. Add it to the cache and | 663 | * We got a result from DNS. Add it to the cache and |
611 | * see if we can make our client happy... | 664 | * see if we can make our client happy... |
612 | * | 665 | * |
@@ -687,6 +740,35 @@ handle_resolve_result (void *cls, | |||
687 | rc->records_tail, | 740 | rc->records_tail, |
688 | rle); | 741 | rle); |
689 | } | 742 | } |
743 | /* see if we need to do the 2nd request for AAAA records */ | ||
744 | if ( (GNUNET_DNSPARSER_TYPE_ALL == al->record_type) && | ||
745 | (GNUNET_NO == al->did_aaaa) ) | ||
746 | { | ||
747 | char *packet_buf; | ||
748 | size_t packet_size; | ||
749 | uint16_t dns_id; | ||
750 | |||
751 | dns_id = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, | ||
752 | UINT16_MAX); | ||
753 | if (GNUNET_OK == | ||
754 | pack (al->hostname, | ||
755 | GNUNET_DNSPARSER_TYPE_AAAA, | ||
756 | dns_id, | ||
757 | &packet_buf, | ||
758 | &packet_size)) | ||
759 | { | ||
760 | al->did_aaaa = GNUNET_YES; | ||
761 | al->dns_id = dns_id; | ||
762 | GNUNET_DNSSTUB_resolve_cancel (al->resolve_handle); | ||
763 | al->resolve_handle = | ||
764 | GNUNET_DNSSTUB_resolve (dnsstub_ctx, | ||
765 | packet_buf, | ||
766 | packet_size, | ||
767 | &handle_resolve_result, | ||
768 | al); | ||
769 | return; | ||
770 | } | ||
771 | } | ||
690 | 772 | ||
691 | /* resume by trying again from cache */ | 773 | /* resume by trying again from cache */ |
692 | if (GNUNET_NO == | 774 | if (GNUNET_NO == |
@@ -730,6 +812,7 @@ handle_resolve_timeout (void *cls) | |||
730 | * @param record_type record type to locate | 812 | * @param record_type record type to locate |
731 | * @param request_id client request ID | 813 | * @param request_id client request ID |
732 | * @param client handle to the client | 814 | * @param client handle to the client |
815 | * @return #GNUNET_OK if the DNS query is now pending | ||
733 | */ | 816 | */ |
734 | static int | 817 | static int |
735 | resolve_and_cache (const char* hostname, | 818 | resolve_and_cache (const char* hostname, |
@@ -739,37 +822,32 @@ resolve_and_cache (const char* hostname, | |||
739 | { | 822 | { |
740 | char *packet_buf; | 823 | char *packet_buf; |
741 | size_t packet_size; | 824 | size_t packet_size; |
742 | struct GNUNET_DNSPARSER_Query query; | ||
743 | struct GNUNET_DNSPARSER_Packet packet; | ||
744 | struct ActiveLookup *al; | 825 | struct ActiveLookup *al; |
745 | uint16_t dns_id; | 826 | uint16_t dns_id; |
827 | uint16_t type; | ||
746 | 828 | ||
747 | dns_id =(uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, | ||
748 | UINT16_MAX); | ||
749 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 829 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
750 | "resolve_and_cache\n"); | 830 | "resolve_and_cache\n"); |
751 | query.name = (char *)hostname; | 831 | dns_id = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, |
752 | query.type = record_type; | 832 | UINT16_MAX); |
753 | query.dns_traffic_class = GNUNET_TUN_DNS_CLASS_INTERNET; | 833 | |
754 | memset (&packet, | 834 | if (GNUNET_DNSPARSER_TYPE_ALL == record_type) |
755 | 0, | 835 | type = GNUNET_DNSPARSER_TYPE_A; |
756 | sizeof (packet)); | 836 | else |
757 | packet.num_queries = 1; | 837 | type = record_type; |
758 | packet.queries = &query; | ||
759 | packet.id = htons (dns_id); | ||
760 | packet.flags.recursion_desired = 1; | ||
761 | if (GNUNET_OK != | 838 | if (GNUNET_OK != |
762 | GNUNET_DNSPARSER_pack (&packet, | 839 | pack (hostname, |
763 | UINT16_MAX, | 840 | type, |
764 | &packet_buf, | 841 | dns_id, |
765 | &packet_size)) | 842 | &packet_buf, |
843 | &packet_size)) | ||
766 | { | 844 | { |
767 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 845 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
768 | "Failed to pack query for hostname `%s'\n", | 846 | "Failed to pack query for hostname `%s'\n", |
769 | hostname); | 847 | hostname); |
770 | return GNUNET_SYSERR; | 848 | return GNUNET_SYSERR; |
771 | |||
772 | } | 849 | } |
850 | |||
773 | al = GNUNET_new (struct ActiveLookup); | 851 | al = GNUNET_new (struct ActiveLookup); |
774 | al->hostname = GNUNET_strdup (hostname); | 852 | al->hostname = GNUNET_strdup (hostname); |
775 | al->record_type = record_type; | 853 | al->record_type = record_type; |