aboutsummaryrefslogtreecommitdiff
path: root/src/util/gnunet-service-resolver.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-08-14 15:48:14 +0200
committerChristian Grothoff <christian@grothoff.org>2018-08-14 15:48:14 +0200
commit68db913bded8a0c606e33994698708e541d1aae0 (patch)
treeca7441a90e325ffe36fe198ef3b23a922402b5aa /src/util/gnunet-service-resolver.c
parent1c757482ba7ca48fa108f1613cccc5c775bd957b (diff)
downloadgnunet-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/util/gnunet-service-resolver.c')
-rw-r--r--src/util/gnunet-service-resolver.c116
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 */
626static int
627pack (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 */
734static int 817static int
735resolve_and_cache (const char* hostname, 818resolve_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;