Browse code

dns: fix bug when using srv failover, ipv4 and ipv6

- fix crash during ipv4->ipv6 fallback when doing srv failover and when
listening on both ipv4 and ipv6 addresses (the hostname used in the
AAAA fallback lookup was null).

Reported by: Nils Ohlmeier <nils@iptel.org>.

Andrei Pelinescu-Onciul authored on 17/10/2008 19:30:07
Showing 1 changed files
... ...
@@ -42,6 +42,8 @@
42 42
  *  2008-02-04  DNS cache options are adapted for the configuration
43 43
  *		framework (Miklos)
44 44
  *  2008-02-11  dns_cache_init cfg parameter is introduced (Miklos)
45
+ *  2008-10-17  fixed srv continue with 0 hostname (when falling back to
46
+                  aaaa) (andrei)
45 47
  */
46 48
 
47 49
 #ifdef USE_DNS_CACHE
... ...
@@ -2717,6 +2719,8 @@ inline static int dns_ip_resolve(	struct dns_hash_entry** e,
2717 2719
 									int flags)
2718 2720
 {
2719 2721
 	int ret;
2722
+	str host;
2723
+	struct dns_hash_entry* orig;
2720 2724
 
2721 2725
 	ret=-E_DNS_NO_IP;
2722 2726
 	if (*e==0){ /* first call */
... ...
@@ -2738,32 +2742,49 @@ inline static int dns_ip_resolve(	struct dns_hash_entry** e,
2738 2742
 #endif /* USE_IPV6 */
2739 2743
 	}else if ((*e)->type==T_A){
2740 2744
 		/* continue A resolving */
2741
-		ret=dns_a_resolve(e, rr_no, name, ip);
2745
+		/* retrieve host name from the hash entry  (ignore name which might
2746
+		  be null when continuing a srv lookup) */
2747
+		host.s=(*e)->name;
2748
+		host.len=(*e)->name_len;
2749
+		ret=dns_a_resolve(e, rr_no, &host, ip);
2742 2750
 #ifdef USE_IPV6
2743 2751
 		if (ret>=0) return ret;
2744 2752
 		if (!(flags&(DNS_IPV6_ONLY|DNS_IPV6_FIRST|DNS_IPV4_ONLY))){
2745 2753
 			/* not found, try with AAAA */
2746
-			dns_hash_put(*e);
2754
+			orig=*e;
2747 2755
 			*e=0;
2748 2756
 			*rr_no=0;
2749
-			ret=dns_aaaa_resolve(e, rr_no, name, ip);
2757
+			ret=dns_aaaa_resolve(e, rr_no, &host, ip);
2758
+			/* delay original record release until we're finished with host*/
2759
+			dns_hash_put(orig);
2750 2760
 		}
2751 2761
 #endif /* USE_IPV6 */
2752 2762
 	}else if ((*e)->type==T_AAAA){
2763
+		/* retrieve host name from the hash entry  (ignore name which might
2764
+		  be null when continuing a srv lookup) */
2765
+		host.s=(*e)->name;
2766
+		host.len=(*e)->name_len;
2753 2767
 #ifdef USE_IPV6
2754 2768
 		/* continue AAAA resolving */
2755
-		ret=dns_aaaa_resolve(e, rr_no, name, ip);
2769
+		ret=dns_aaaa_resolve(e, rr_no, &host, ip);
2756 2770
 		if (ret>=0) return ret;
2757 2771
 		if ((flags&DNS_IPV6_FIRST) && !(flags&DNS_IPV6_ONLY)){
2758 2772
 			/* not found, try with A */
2759
-			dns_hash_put(*e);
2773
+			orig=*e;
2760 2774
 			*e=0;
2761 2775
 			*rr_no=0;
2762
-			ret=dns_a_resolve(e, rr_no, name, ip);
2776
+			ret=dns_a_resolve(e, rr_no, &host, ip);
2777
+			/* delay original record release until we're finished with host*/
2778
+			dns_hash_put(orig);
2763 2779
 		}
2764 2780
 #else /* USE_IPV6 */
2765 2781
 		/* ipv6 disabled, try with A */
2766
-		ret=dns_a_resolve(e, rr_no, name, ip);
2782
+		orig=*e;
2783
+		*e=0;
2784
+		*rr_no=0;
2785
+		ret=dns_a_resolve(e, rr_no, &host, ip);
2786
+		/* delay original record release until we're finished with host*/
2787
+		dns_hash_put(orig);
2767 2788
 #endif /* USE_IPV6 */
2768 2789
 	}else{
2769 2790
 		LOG(L_CRIT, "BUG: dns_ip_resolve: invalid record type %d\n",