On Fri, 2021-08-27 at 11:04 +0200, Dominik DL6ER wrote: > > 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.
Slightly simplified/optimized patch attached. This ensures replies cannot be mistakenly logged as "cached" under certain circumstances by hard-coding flags handed to log_query(). Best, Dominik
From f869e0d301f1635c25898ed9439a4dab9e7ec895 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..93c3363 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, + 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(F_FORWARD | 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, p1, ardlen)) + return 0; + } + else + { + char *atype = querystr("non-cached ", aqtype); + log_query(F_FORWARD | 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