Hey Simon,

when a client makes a query for a reply type that is not cache-able
(i.e., is not one of [A, AAAA, SRV, PTR]), the reply is not mentioned
at all in the log file. This is because extract_names() calls
"continue" on the reply and logging would only have happened in
insert_cache(). A noteworthy exception to this are TXT records that are
handled in do_doctor() separately. However, client association is lost
in this place (can be seen with log-queries=extra).

The attached patch fixes this by ensuring we call log_query() also for
replies that do not enter the cache. I also moved the printing of TXT
records here so "log-queries=extra" works as expected for those, too.

----

Test 1:

$ dig SOA soa.dns.netmeister.org 

> Aug 27 10:33:08 dnsmasq[1497026]: query[SOA] soa.dns.netmeister.org
> from 127.0.0.1
> Aug 27 10:33:08 dnsmasq[1497026]: forwarded soa.dns.netmeister.org to
> 127.0.0.1
> Aug 27 10:33:08 dnsmasq[1497026]: reply soa.dns.netmeister.org is
> non-cached [SOA]

The last line is only visible with my patch.

----

Test 2 (log-queries=extra):

$ dig TXT txt.dns.netmeister.org 

BEFORE (note missing "1 127.0.0.1/45114" in the last two):

> Aug 27 10:35:33 dnsmasq[1497046]: 1 127.0.0.1/45114 query[TXT]
> txt.dns.netmeister.org from 127.0.0.1
> Aug 27 10:35:33 dnsmasq[1497046]: 1 127.0.0.1/45114 forwarded
> txt.dns.netmeister.org to 127.0.0.1
> Aug 27 10:35:33 dnsmasq[1497046]: reply txt.dns.netmeister.org is
> Descriptive text. Completely overloaded for all sorts of things.
> RFC1035 (1987)
> Aug 27 10:35:33 dnsmasq[1497046]: reply txt.dns.netmeister.org is
> Format: <text>

NOW:

> Aug 27 10:35:53 dnsmasq[1497049]: 1 127.0.0.1/42014 query[TXT]
> txt.dns.netmeister.org from 127.0.0.1
> Aug 27 10:35:53 dnsmasq[1497049]: 1 127.0.0.1/42014 forwarded
> txt.dns.netmeister.org to 127.0.0.1
> Aug 27 10:35:53 dnsmasq[1497049]: 1 127.0.0.1/42014 reply
> txt.dns.netmeister.org is Descriptive text. Completely overloaded for
> all sorts of things. RFC1035 (1987)
> Aug 27 10:35:53 dnsmasq[1497049]: 1 127.0.0.1/42014 reply
> txt.dns.netmeister.org is Format: <text>


Best,
Dominik
From b84cf751e933ec7b0fb6113bc0e8a751e25a7178 Mon Sep 17 00:00:00 2001
From: Dominik DL6ER <dl...@dl6er.de>
Date: Fri, 27 Aug 2021 10:28:09 +0200
Subject: [PATCH] Also log non-cacheable replies

Signed-off-by: Dominik DL6ER <dl...@dl6er.de>
---
 src/rfc1035.c | 98 +++++++++++++++++++++++++++++++--------------------
 1 file changed, 60 insertions(+), 38 deletions(-)

diff --git a/src/rfc1035.c b/src/rfc1035.c
index 43d1060..a26a86b 100644
--- a/src/rfc1035.c
+++ b/src/rfc1035.c
@@ -444,34 +444,6 @@ static unsigned char *do_doctor(unsigned char *p, int count, struct dns_header *
 	      break;
 	    }
 	}
-      else if (qtype == T_TXT && name && option_bool(OPT_LOG))
-	{
-	  unsigned char *p1 = p;
-	  if (!CHECK_LEN(header, p1, qlen, rdlen))
-	    return 0;
-	  while ((p1 - p) < rdlen)
-	    {
-	      unsigned int i, len = *p1;
-	      unsigned char *p2 = p1;
-	      if ((p1 + len - p) >= rdlen)
-	        return 0; /* bad packet */
-	      /* make counted string zero-term  and sanitise */
-	      for (i = 0; i < len; i++)
-		{
-		  if (!isprint((int)*(p2+1)))
-		    break;
-		  
-		  *p2 = *(p2+1);
-		  p2++;
-		}
-	      *p2 = 0;
-	      my_syslog(LOG_INFO, "reply %s is %s", name, p1);
-	      /* restore */
-	      memmove(p1 + 1, p1, i);
-	      *p1 = len;
-	      p1 += len+1;
-	    }
-	}		  
       
       if (!ADD_RDLEN(header, p, qlen, rdlen))
 	 return 0; /* bad packet */
@@ -534,6 +506,40 @@ static int find_soa(struct dns_header *header, size_t qlen, char *name, int *doc
   return minttl;
 }
 
+/* Print TXT reply to log */
+static int print_txt(struct dns_header *header, const size_t qlen, char *name,
+		     const int flags, unsigned char *p, const int ardlen)
+{
+  unsigned char *p1 = p;
+  if (!CHECK_LEN(header, p1, qlen, ardlen))
+    return 0;
+  /* Loop over TXT payload */
+  while ((p1 - p) < ardlen)
+    {
+      unsigned int i, len = *p1;
+      unsigned char *p3 = p1;
+      if ((p1 + len - p) >= ardlen)
+	return 0; /* bad packet */
+
+      /* make counted string zero-term and sanitise */
+      for (i = 0; i < len; i++)
+	{
+	  if (!isprint((int)*(p3+1)))
+	    break;
+	  *p3 = *(p3+1);
+	  p3++;
+	}
+
+      *p3 = 0;
+      log_query(flags | F_UPSTREAM, name, NULL, (char*)p1);
+      /* restore */
+      memmove(p1 + 1, p1, i);
+      *p1 = len;
+      p1 += len+1;
+    }
+  return 1;
+}
+
 /* Note that the following code can create CNAME chains that don't point to a real record,
    either because of lack of memory, or lack of SOA records.  These are treated by the cache code as 
    expired and cleaned out that way. 
@@ -689,7 +695,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
 	{
 	  /* everything other than PTR */
 	  struct crec *newc;
-	  int addrlen = 0;
+	  int addrlen = 0, insert = 1;
 
 	  if (qtype == T_A)
 	    {
@@ -704,7 +710,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
 	  else if (qtype == T_SRV)
 	    flags |= F_SRV;
 	  else
-	    continue;
+	    insert = 0;
 	    
 	cname_loop1:
 	  if (!(p1 = skip_questions(header, qlen)))
@@ -790,7 +796,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
 			   if (!extract_name(header, qlen, &tmp, name, 1, 0))
 			     return 0;
 			}
-		      else
+		      else if(insert)
 			{
 			  /* copy address into aligned storage */
 			  if (!CHECK_LEN(header, p1, qlen, addrlen))
@@ -821,15 +827,31 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
 			    }
 #endif
 			}
-		      
-		      newc = cache_insert(name, &addr, C_IN, now, attl, flags | F_FORWARD | secflag);
-		      if (newc && cpp)
+		      if(insert)
 			{
-			  next_uid(newc);
-			  cpp->addr.cname.target.cache = newc;
-			  cpp->addr.cname.uid = newc->uid;
+			  newc = cache_insert(name, &addr, C_IN, now, attl, flags | F_FORWARD | secflag);
+			  if (newc && cpp)
+			    {
+			      next_uid(newc);
+			      cpp->addr.cname.target.cache = newc;
+			      cpp->addr.cname.uid = newc->uid;
+			    }
+			  cpp = NULL;
+			}
+		      else
+			{
+			  /* Handle non-cacheable replies. We still want to log those */
+			  if (aqtype == T_TXT)
+			    {
+			      if(!print_txt(header, qlen, name, flags, p1, ardlen))
+			        return 0;
+			    }
+			  else
+			    {
+			      char *atype = querystr("non-cached ", aqtype);
+			      log_query(flags | F_UPSTREAM, name, NULL, atype);
+			    }
 			}
-		      cpp = NULL;
 		    }
 		}
 	      
-- 
2.25.1

_______________________________________________
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss

Reply via email to