]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
AAAA/A failover fix and CNAME recursion deprecation
authoramosjeffries <>
Fri, 11 Jan 2008 10:49:18 +0000 (10:49 +0000)
committeramosjeffries <>
Fri, 11 Jan 2008 10:49:18 +0000 (10:49 +0000)
A bug in the final version of squid internal DNS resolver logics
caused any failover A results to overwrite the paired previous AAAA.

This patch adds state to store the DNS results between failover queries
and to merge the final sets before passing them out to the requestor.

Lookups should now be seemlessly handled within the DNS resolver stub.

CNAME recursion at the ipcache level should now be obsolete and has been
wrapped in a new ./configure --with-dns-cname option which defaults off.
That code has proven to be problematic anyway and will be no great loss.

Additional counters have been added to the squid statistics to track the
amount of queries of each type have been encountered.

configure.in
doc/release-notes/release-3.1.html
doc/release-notes/release-3.1.man
doc/release-notes/release-3.1.sgml
include/rfc1035.h
lib/rfc1035.c
src/dns_internal.cc
src/ipcache.cc

index b0248288b05bc9f8132620b9a1a41ab5250e9637..976104b0aa90158d33af97d5015f15a7363e2b8c 100644 (file)
@@ -1,7 +1,7 @@
 
 dnl  Configuration input file for Squid
 dnl
-dnl  $Id: configure.in,v 1.493 2007/12/27 15:48:53 hno Exp $
+dnl  $Id: configure.in,v 1.494 2008/01/11 03:49:18 amosjeffries Exp $
 dnl
 dnl
 dnl
@@ -11,7 +11,7 @@ AM_CONFIG_HEADER(include/autoconf.h)
 AC_CONFIG_AUX_DIR(cfgaux)
 AC_CONFIG_SRCDIR([src/main.cc])
 AM_INIT_AUTOMAKE([tar-ustar])
-AC_REVISION($Revision: 1.493 $)dnl
+AC_REVISION($Revision: 1.494 $)dnl
 AC_PREFIX_DEFAULT(/usr/local/squid)
 AM_MAINTAINER_MODE
 
@@ -1790,6 +1790,15 @@ AC_ARG_WITH(localhost-ipv6,
 # end IPv6-only options
 fi
 
+dnl Optional CNAME-Recursion by Internal DNS engine
+AC_MSG_CHECKING([whether DNS CNAME recursion wanted])
+AC_ARG_WITH(dns-cname,
+  [  --with-dns-cname         Enable CNAME-Recursion in Internal DNS stub.],
+  [AC_DEFINE(DNS_CNAME, 1, [ 1 == Enable expermental CNAME recursion inside Squid DNS resolver stub]) AC_MSG_RESULT(yes)],
+  [AC_DEFINE(DNS_CNAME, 0, [ 0 == Disable expermental CNAME recursion inside Squid DNS resolver stub]) AC_MSG_RESULT(no)]
+)
+
+
 AC_ARG_WITH(filedescriptors,
 [  --with-filedescriptors=NUMBER
                           Force squid to support NUMBER filedescriptors],
index 5afdc230b0aff9d1f962a75e6ac847599a56cb76..23f45698c99c39bdc75660ff66e74f9a5a271629 100644 (file)
@@ -7,7 +7,7 @@
 <BODY>
 <H1>Squid 3.1.PRE1 release notes</H1>
 
-<H2>Squid Developers</H2>$Id: release-3.1.html,v 1.3 2008/01/11 02:38:58 amosjeffries Exp $
+<H2>Squid Developers</H2>$Id: release-3.1.html,v 1.4 2008/01/11 03:49:18 amosjeffries Exp $
 <HR>
 <EM>This document contains the release notes for version 3.1 of Squid.
 Squid is a WWW Cache application developed by the National Laboratory
@@ -50,7 +50,7 @@ While this release is not deemed ready for production use, we believe it is read
 
 <H3>Internet Protocol version 6 (IPv6)</H3>
 
-<P>Squid 3.1 supports IPv6. To enable IPv6 support, use the --enable-ipv6 ./configure option</P>
+<P>Squid 3.1 supports IPv6. To enable IPv6 support, use the ./configure --enable-ipv6 option</P>
 
 <H3>New Features for IPv6</H3>
 
@@ -185,7 +185,6 @@ Squid will follow a policy of prefering IPv6 links, keeping the IPv4 only as a s
 </DL>
 </P>
 
-
 <H3><A NAME="modifiedtags"></A> Changes to existing tags</H3>
 
 <P>
@@ -202,7 +201,9 @@ Squid will follow a policy of prefering IPv6 links, keeping the IPv4 only as a s
 
 <DT><B>external_acl_type</B><DD>
 <P>New options 'ipv4' and 'ipv6' are added to set the IPv4/v6 protocol between squid and its helpers.
-Please be aware of some limits to these options. see IPv6 Limits in section 2 above.
+Please be aware of some limits to these options. These options only affet the transport protocol used
+to send data to and from the helpers. Squid in IPv6-mode may still send %SRC addresses in IPv4 or IPv6
+format, so all helpers will need to be checked and converted to cope with such information cleanly.
 <PRE>
           ipv4 / ipv6   IP-mode used to communicate to this helper.
                         For compatability with older configurations and helpers
@@ -300,7 +301,7 @@ It has thus been turned off by default. Making the 'best choice' IP continue in
 The default is to build with 127.0.0.1 and ::1 being considered seperate IP.
 see the IPv6 details above for a better description. </P>
 
-<DT><B>--with-ipv6-split-stack&lt;</B><DD>
+<DT><B>--with-ipv6-split-stack</B><DD>
 <P>Enable special additions for IPv6 support in Windows XP.
 see the IPv6 details above for a better description.</P>
 
@@ -308,6 +309,15 @@ see the IPv6 details above for a better description.</P>
 <P>Enable special additions for IPv6 support in Windows Vista.
 see the IPv6 details above for a better description.</P>
 
+<DT><B>--with-dns-cname</B><DD>
+<P>Enable CNAME recursion within the Internal DNS resolver stub squid uses.
+This has no effect on the external DNS helper.
+Please note this extension is still experimental and may encounter problems.
+To see if it is actually needed you can run squid without it for a period and
+check the CNAME-Only Requests statistics squid maintains.
+If it produces ongoing serious problems the external helper may be needed
+but please report the bugs anyway.</P>
+
 </DL>
 </P>
 <H3><A NAME="modifiedoptions"></A> Changes to existing options</H3>
index 2eb458621a945d0a1f7da003b485aa1c745a2efe..b183dac3b7e554368d1036316f86ec5534fd5e85 100644 (file)
@@ -1,4 +1,4 @@
-Squid 3.1.PRE1 release notesSquid Developers$Id: release-3.1.man,v 1.3 2008/01/11 02:38:58 amosjeffries Exp $This document contains the release notes for version 3.1 of Squid.
+Squid 3.1.PRE1 release notesSquid Developers$Id: release-3.1.man,v 1.4 2008/01/11 03:49:18 amosjeffries Exp $This document contains the release notes for version 3.1 of Squid.
 Squid is a WWW Cache application developed by the National Laboratory
 for Applied Network Research and members of the Web Caching community.Notice
 
@@ -45,7 +45,7 @@ Most user-facing changes are reflected in squid.conf (see below).
 Internet Protocol version 6 (IPv6)
 
 .Pp
-Squid 3.1 supports IPv6. To enable IPv6 support, use the --enable-ipv6 ./configure option
+Squid 3.1 supports IPv6. To enable IPv6 support, use the ./configure --enable-ipv6 option
 .Pp
 New Features for IPv6
 
@@ -231,7 +231,6 @@ New option to import entire secondary configuration files into squid.conf.
 .if \n(ll>1 .RE
 .nr ll -1
 .Pp
-.Pp
 Changes to existing tags
 
 .Pp
@@ -260,7 +259,9 @@ New preset content
 .nr bi 1
 .Pp
 New options 'ipv4' and 'ipv6' are added to set the IPv4/v6 protocol between squid and its helpers.
-Please be aware of some limits to these options. see IPv6 Limits in section 2 above.
+Please be aware of some limits to these options. These options only affet the transport protocol used
+to send data to and from the helpers. Squid in IPv6-mode may still send %SRC addresses in IPv4 or IPv6
+format, so all helpers will need to be checked and converted to cope with such information cleanly.
 .DS
 .sp 
 .ft RR
@@ -391,7 +392,7 @@ Build support for squid to map all 127.0.0.1 traffic onto ::1.
 The default is to build with 127.0.0.1 and ::1 being considered seperate IP.
 see the IPv6 details above for a better description. 
 .Pp
-.IP "--with-ipv6-split-stack<"
+.IP "--with-ipv6-split-stack"
 .nr bi 1
 .Pp
 Enable special additions for IPv6 support in Windows XP.
@@ -403,6 +404,17 @@ see the IPv6 details above for a better description.
 Enable special additions for IPv6 support in Windows Vista.
 see the IPv6 details above for a better description.
 .Pp
+.IP "--with-dns-cname"
+.nr bi 1
+.Pp
+Enable CNAME recursion within the Internal DNS resolver stub squid uses.
+This has no effect on the external DNS helper.
+Please note this extension is still experimental and may encounter problems.
+To see if it is actually needed you can run squid without it for a period and
+check the CNAME-Only Requests statistics squid maintains.
+If it produces ongoing serious problems the external helper may be needed
+but please report the bugs anyway.
+.Pp
 .if \n(ll>1 .RE
 .nr ll -1
 Changes to existing options
index f83dd7a4992b61f34c272da93fa8ab1e14bdae29..a1fd8fbdf288bf0a9b50128e4e14024185b2eb44 100644 (file)
@@ -2,7 +2,7 @@
 <article>\r
 <title>Squid 3.1.PRE1 release notes</title>\r
 <author>Squid Developers</author>\r
-<date>$Id: release-3.1.sgml,v 1.3 2008/01/11 02:38:58 amosjeffries Exp $</date>\r
+<date>$Id: release-3.1.sgml,v 1.4 2008/01/11 03:49:18 amosjeffries Exp $</date>\r
 \r
 <abstract>\r
 This document contains the release notes for version 3.1 of Squid.\r
@@ -47,7 +47,7 @@ Most user-facing changes are reflected in squid.conf (see below).
 \r
 <sect2>Internet Protocol version 6 (IPv6)\r
 \r
-<p>Squid 3.1 supports IPv6. To enable IPv6 support, use the --enable-ipv6 ./configure option\r
+<p>Squid 3.1 supports IPv6. To enable IPv6 support, use the ./configure --enable-ipv6 option\r
 \r
 <sect3>New Features for IPv6\r
 \r
@@ -168,7 +168,6 @@ This section gives a thorough account of those changes in three categories:
 \r
 </descrip>\r
 \r
-\r
 <sect2>Changes to existing tags<label id="modifiedtags">\r
 <p>\r
 <descrip>\r
@@ -182,7 +181,9 @@ This section gives a thorough account of those changes in three categories:
 \r
         <tag>external_acl_type</tag>\r
         <p>New options 'ipv4' and 'ipv6' are added to set the IPv4/v6 protocol between squid and its helpers.\r
-           Please be aware of some limits to these options. see IPv6 Limits in section 2 above.\r
+           Please be aware of some limits to these options. These options only affet the transport protocol used\r
+          to send data to and from the helpers. Squid in IPv6-mode may still send %SRC addresses in IPv4 or IPv6\r
+          format, so all helpers will need to be checked and converted to cope with such information cleanly.\r
         <verb>\r
           ipv4 / ipv6   IP-mode used to communicate to this helper.\r
                         For compatability with older configurations and helpers\r
@@ -267,7 +268,7 @@ This section gives an account of those changes in three categories:
            see the IPv6 details above for a better description. \r
         </p>\r
 \r
-        <tag>--with-ipv6-split-stack<</tag>\r
+        <tag>--with-ipv6-split-stack</tag>\r
         <p>Enable special additions for IPv6 support in Windows XP.\r
            see the IPv6 details above for a better description.</p>\r
 \r
@@ -275,6 +276,16 @@ This section gives an account of those changes in three categories:
        <p>Enable special additions for IPv6 support in Windows Vista.\r
            see the IPv6 details above for a better description.</p>\r
 \r
+        <tag>--with-dns-cname</tag>\r
+        <p>Enable CNAME recursion within the Internal DNS resolver stub squid uses.\r
+           This has no effect on the external DNS helper.\r
+           Please note this extension is still experimental and may encounter problems.\r
+          To see if it is actually needed you can run squid without it for a period and\r
+          check the CNAME-Only Requests statistics squid maintains.\r
+          If it produces ongoing serious problems the external helper may be needed\r
+          but please report the bugs anyway.\r
+        </p>\r
+\r
 </descrip>\r
 </p>\r
 \r
index 8ef3625c53342005ff1b089159950b1c35b32bbe..81ab43664078dce34f37af32f031edc607d65e1d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: rfc1035.h,v 1.19 2007/12/14 23:11:44 amosjeffries Exp $
+ * $Id: rfc1035.h,v 1.20 2008/01/11 03:49:20 amosjeffries Exp $
  *
  * AUTHOR: Duane Wessels
  *
@@ -95,6 +95,7 @@ SQUIDCEXTERN int rfc1035MessageUnpack(const char *buf,
     size_t sz,
     rfc1035_message ** answer);
 SQUIDCEXTERN int rfc1035QueryCompare(const rfc1035_query *, const rfc1035_query *);
+SQUIDCEXTERN void rfc1035RRDestroy(rfc1035_rr ** rr, int n);
 SQUIDCEXTERN void rfc1035MessageDestroy(rfc1035_message ** message);
 SQUIDCEXTERN int rfc1035_errno;
 SQUIDCEXTERN const char *rfc1035_error_message;
index c9db5520b4a0a67f4a078d4e95ce8413ce01b3ef..70d8c2b61c1fc1308615f0d2dc1c9a732d90dce5 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: rfc1035.c,v 1.52 2007/12/19 02:36:27 amosjeffries Exp $
+ * $Id: rfc1035.c,v 1.53 2008/01/11 03:49:21 amosjeffries Exp $
  *
  * Low level DNS protocol routines
  * AUTHOR: Duane Wessels
@@ -471,12 +471,13 @@ rfc1035SetErrno(int n)
     }
 }
 
-static void
+void
 rfc1035RRDestroy(rfc1035_rr ** rr, int n)
 {
-    if (*rr == NULL)
+    if (*rr == NULL || n < 1) {
        return;
-    assert(n > 0);
+    }
+
     while (n--) {
        if ((*rr)[n].rdata)
            xfree((*rr)[n].rdata);
index fc90f7eebd1b594c6065d9b32e4a789d41476529..7fa16a8d6bfb3308918fc988399888bacda3ec6d 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: dns_internal.cc,v 1.103 2007/12/29 17:56:25 hno Exp $
+ * $Id: dns_internal.cc,v 1.104 2008/01/11 03:49:22 amosjeffries Exp $
  *
  * DEBUG: section 78    DNS lookups; interacts with lib/rfc1035.c
  * AUTHOR: Duane Wessels
@@ -117,6 +117,10 @@ struct _idns_query
     unsigned short domain;
     unsigned short do_searchpath;
     bool need_A;
+    struct {
+        int count;
+        rfc1035_rr *answers;
+    } initial_AAAA;
 };
 
 struct _nsvc
@@ -925,6 +929,7 @@ idnsGrokReply(const char *buf, size_t sz)
     }
 
     if (message->tc) {
+        debugs(78, 3, HERE << "Resolver requested TC (" << q->query.name << ")");
         dlinkDelete(&q->lru, &lru_list);
         rfc1035MessageDestroy(&message);
 
@@ -1003,7 +1008,7 @@ idnsGrokReply(const char *buf, size_t sz)
     if(q->need_A && (Config.onoff.dns_require_A == 1 || n <= 0 ) )
     {
         /* ERROR or NO AAAA exist. Failover to A records. */
-        /* AYJ: Apparently its also a good idea to lookup and store the A records
+        /*      Apparently its also a good idea to lookup and store the A records
          *      just in case the AAAA are not available when we need them.
          *      This could occur due to number of network failings beyond our control
          *      thus the || above allowing the user to request always both.
@@ -1016,6 +1021,14 @@ idnsGrokReply(const char *buf, size_t sz)
         else // admin requested this.
             debugs(78, 3, "idnsGrokReply: " << q->name << " AAAA query done. Configured to retrieve A now also.");
 
+        // move the initial message results into the failover query for merging later.
+        if(n > 0) {
+            q->initial_AAAA.count = message->ancount;
+            q->initial_AAAA.answers = message->answer;
+            message->answer = NULL;
+        }
+
+        // remove the hashed query info
         idnsDropMessage(message, q);
 
         q->start_t = current_time;
@@ -1029,9 +1042,39 @@ idnsGrokReply(const char *buf, size_t sz)
     }
 #endif
 
+   /** If there are two result sets from preceeding AAAA and A lookups merge them with a preference for AAAA */
+   if(q->initial_AAAA.count > 0 && n > 0) {
+        /* two sets of RR need merging */
+        rfc1035_rr *result = (rfc1035_rr*) xmalloc( sizeof(rfc1035_rr)*(n + q->initial_AAAA.count) );
+        rfc1035_rr *tmp = result;
+
+        debugs(78, 6, HERE << "Merging DNS results " << q->name << " AAAA has " << q->initial_AAAA.count << " RR, A has " << n << " RR");
+
+        memcpy(tmp, q->initial_AAAA.answers, (sizeof(rfc1035_rr)*(q->initial_AAAA.count)) );
+        tmp += q->initial_AAAA.count;
+        /* free the RR object without freeing its child strings (they are now taken by the copy above) */
+        safe_free(q->initial_AAAA.answers);
+
+        memcpy( tmp, message->answer, (sizeof(rfc1035_rr)*n) );
+        /* free the RR object without freeing its child strings (they are now taken by the copy above) */
+        safe_free(message->answer);
+
+        message->answer = result;
+        n += q->initial_AAAA.count;
+        q->initial_AAAA.count=0;
+    }
+    else if(q->initial_AAAA.count > 0 && n <= 0) {
+        /* initial of dual queries was the only result set. */
+        debugs(78, 6, HERE << "Merging DNS results " << q->name << " AAAA has " << q->initial_AAAA.count << " RR, A has " << n << " RR");
+        rfc1035RRDestroy(&(message->answer), n);
+        message->answer = q->initial_AAAA.answers;
+        n = q->initial_AAAA.count;
+    }
+    /* else initial results were empty. just use the final set as authoritative */
+
+    debugs(78, 6, HERE << "Sending " << n << " DNS results to caller.");
     idnsCallback(q, message->answer, n, q->error);
     rfc1035MessageDestroy(&message);
-
     cbdataFree(q);
 }
 
index 7cfc5bb63a8273cfcd5dce07b546d55a4dea15d7..c4a4a807dde12235b4623e370f0ceca596adc85c 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ipcache.cc,v 1.266 2008/01/10 08:13:43 amosjeffries Exp $
+ * $Id: ipcache.cc,v 1.267 2008/01/11 03:49:22 amosjeffries Exp $
  *
  * DEBUG: section 14    IP Cache
  * AUTHOR: Harvest Derived
@@ -57,7 +57,9 @@ struct _ipcache_entry
     struct timeval request_time;
     dlink_node lru;
     unsigned short locks;
+#if DNS_CNAME
     unsigned short cname_wait;
+#endif
 
     struct
     {
@@ -80,6 +82,10 @@ static struct
     int misses;
     int negative_hits;
     int numeric_hits;
+    int rr_a;
+    int rr_aaaa;
+    int rr_cname;
+    int cname_only;
     int invalid;
 }
 IpcacheStats;
@@ -251,18 +257,22 @@ ipcacheAddEntry(ipcache_entry * i)
 {
     hash_link *e = (hash_link *)hash_lookup(ip_table, i->hash.key);
 
+#if DNS_CNAME
     /* INET6 : should NOT be adding this entry until all CNAME have been received. */
     assert(i->cname_wait == 0);
+#endif
 
     if (NULL != e) {
         /* avoid colission */
         ipcache_entry *q = (ipcache_entry *) e;
+#if DNS_CNAME
         if(q == i)  {
             /* can occur with Multiple-depth CNAME Recursion if parent returned early with additional */
             /* just need to drop from the hash without releasing actual memory */
             ipcacheRelease(q, false);
         }
         else
+#endif
             ipcacheRelease(q);
     }
 
@@ -408,6 +418,8 @@ ipcacheParse(ipcache_entry *i, rfc1035_rr * answers, int nr, const char *error_m
     int na = 0;
     int ttl = 0;
     const char *name = (const char *)i->hash.key;
+    int cname_found = 0;
+
     i->expires = squid_curtime + Config.negativeDnsTtl;
     i->flags.negcached = 1;
     safe_free(i->addrs.in_addrs);
@@ -441,6 +453,7 @@ ipcacheParse(ipcache_entry *i, rfc1035_rr * answers, int nr, const char *error_m
                continue;
            }
            na++;
+            IpcacheStats.rr_aaaa++;
            continue;
        }
 #endif
@@ -451,11 +464,16 @@ ipcacheParse(ipcache_entry *i, rfc1035_rr * answers, int nr, const char *error_m
                continue;
            }
            na++;
+            IpcacheStats.rr_a++;
            continue;
        }
 
             /* With A and AAAA, the CNAME does not necessarily come with additional records to use. */
         if (answers[k].type == RFC1035_TYPE_CNAME) {
+            cname_found=1;
+            IpcacheStats.rr_cname++;
+
+#if DNS_CNAME
             debugs(14, 5, "ipcacheParse: " << name << " CNAME " << answers[k].rdata << " (checking destination: " << i << ").");
             const ipcache_addrs *res = ipcache_gethostbyname(answers[k].rdata, 0);
             if(res) {
@@ -468,18 +486,28 @@ ipcacheParse(ipcache_entry *i, rfc1035_rr * answers, int nr, const char *error_m
                 ipcache_nbgethostbyname(answers[k].rdata, ipcacheHandleCnameRecurse, new generic_cbdata(i) );
                 i->cname_wait++;
             }
+#endif /* DNS_CNAME */
+
             continue;
         }
+
+        // otherwise its an unknown RR. debug at level 9 since we usually want to ignore these and they are common.
+        debugs(14, 9, HERE << "Unknown RR type received: type=" << answers[k].type << " starting at " << &(answers[k]) );
     }
 
+#if DNS_CNAME
     if(na == 0 && i->cname_wait >0 ) {
         /* don't set any error message (yet). Allow recursion to do its work first. */
+        IpcacheStats.cname_only++;
         return 0;
     }
+#endif /* DNS_CNAME */
 
     if (na == 0) {
         debugs(14, 1, "ipcacheParse: No Address records in response to '" << name << "'");
         i->error_message = xstrdup("No Address records");
+        if(cname_found)
+            IpcacheStats.cname_only++;
         return 0;
     }
 
@@ -513,7 +541,9 @@ ipcacheParse(ipcache_entry *i, rfc1035_rr * answers, int nr, const char *error_m
             debugs(14, 3, "ipcacheParse: " << name << " #" << j << " " << i->addrs.in_addrs[j] );
             j++;
 #endif
-        } else if (answers[k].type == RFC1035_TYPE_CNAME) {
+        }
+#if DNS_CNAME
+        else if (answers[k].type == RFC1035_TYPE_CNAME) {
             debugs(14, 3, "ipcacheParse: " << name << " #x CNAME " << answers[k].rdata);
             const ipcache_addrs *res = ipcache_gethostbyname(answers[k].rdata, 0);
             if(res) {
@@ -528,6 +558,7 @@ ipcacheParse(ipcache_entry *i, rfc1035_rr * answers, int nr, const char *error_m
                 debugs(14, 9, "ipcacheParse: " << answers[k].rdata << " (CNAME) waiting on A/AAAA records.");
             }
         }
+#endif /* DNS_CNAME */
 
         if (ttl == 0 || (int) answers[k].ttl < ttl)
             ttl = answers[k].ttl;
@@ -550,12 +581,14 @@ ipcacheParse(ipcache_entry *i, rfc1035_rr * answers, int nr, const char *error_m
 
     i->flags.negcached = 0;
 
+#if DNS_CNAME
     /* SPECIAL CASE: may get here IFF CNAME received with Additional records */
     /*               reurn  0/'wait for further details' value.              */
     /*               NP: 'No DNS Results' is a return -1 +msg                */
     if(i->cname_wait)
         return 0;
     else
+#endif /* DNS_CNAME */
         return i->addrs.count;
 }
 
@@ -809,6 +842,14 @@ stat_ipcache_get(StoreEntry * sentry)
                       IpcacheStats.numeric_hits);
     storeAppendPrintf(sentry, "IPcache Misses:          %d\n",
                       IpcacheStats.misses);
+    storeAppendPrintf(sentry, "IPcache Retrieved A: %d\n",
+                      IpcacheStats.rr_a);
+    storeAppendPrintf(sentry, "IPcache Retrieved AAAA: %d\n",
+                      IpcacheStats.rr_aaaa);
+    storeAppendPrintf(sentry, "IPcache Retrieved CNAME: %d\n",
+                      IpcacheStats.rr_cname);
+    storeAppendPrintf(sentry, "IPcache CNAME-Only Response: %d\n",
+                      IpcacheStats.cname_only);
     storeAppendPrintf(sentry, "IPcache Invalid Request: %d\n",
                       IpcacheStats.invalid);
     storeAppendPrintf(sentry, "\n\n");
@@ -826,6 +867,7 @@ stat_ipcache_get(StoreEntry * sentry)
     }
 }
 
+#if DNS_CNAME
 /**
  * Takes two IPAddress arrays and merges them into a single array
  * which is allocated dynamically to fit the number of unique addresses
@@ -937,10 +979,12 @@ debugs(14,8, HERE << "A[" << t << "]=IPv6 " << aaddrs[t]);
 
     assert(outlen == fc); // otherwise something broke badly!
 }
+#endif /* DNS_CNAME */
 
 static void
 ipcacheHandleCnameRecurse(const ipcache_addrs *addrs, void *cbdata)
 {
+#if DNS_CNAME
     ipcache_entry *i = NULL;
     char *pname = NULL;
     IPAddress *tmpbuf = NULL;
@@ -1036,6 +1080,7 @@ ipcacheHandleCnameRecurse(const ipcache_addrs *addrs, void *cbdata)
         ipcacheCallback(i);
     }
     // else still more CNAME to be found.
+#endif /* DNS_CNAME */
 }
 
 void