Blob Blame History Raw
From 7c80b06983505a0cb52d5e112777c9acbe2cb300 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Fri, 22 Jan 2021 16:49:12 +0000
Subject: [PATCH] Move fd into frec_src, fixes
 15b60ddf935a531269bb8c68198de012a4967156

If identical queries from IPv4 and IPv6 sources are combined by the
new code added in 15b60ddf935a531269bb8c68198de012a4967156 then replies
can end up being sent via the wrong family of socket. The ->fd
should be per query, not per-question.

In bind-interfaces mode, this could also result in replies being sent
via the wrong socket even when IPv4/IPV6 issues are not in play.

(cherry picked from commit 04490bf622ac84891aad6f2dd2edf83725decdee)

Fix for 12af2b171de0d678d98583e2190789e544440e02

(cherry picked from commit 3f535da79e7a42104543ef5c7b5fa2bed819a78b)
---
 src/dnsmasq.h | 3 ++-
 src/forward.c | 5 +++--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 9f5b48b..77f59b9 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -607,6 +607,7 @@ struct frec {
     union mysockaddr source;
     struct all_addr dest;
     unsigned int iface, log_id;
+    int fd;
     unsigned short orig_id;
     struct frec_src *next;
   } frec_src;
@@ -616,7 +617,7 @@ struct frec {
   struct randfd *rfd6;
 #endif
   unsigned short new_id;
-  int fd, forwardall, flags;
+  int forwardall, flags;
   time_t time;
   unsigned char *hash[HASH_SIZE];
 #ifdef HAVE_DNSSEC 
diff --git a/src/forward.c b/src/forward.c
index a0b1f1d..637f220 100644
--- a/src/forward.c
+++ b/src/forward.c
@@ -366,6 +366,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
 	      new->dest = *dst_addr;
 	      new->log_id = daemon->log_id;
 	      new->iface = dst_iface;
+	      new->fd = udpfd;
 	    }
 	  
 	  return 1;
@@ -390,8 +391,8 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
 	  forward->frec_src.dest = *dst_addr;
 	  forward->frec_src.iface = dst_iface;
 	  forward->frec_src.next = NULL;
+	  forward->frec_src.fd = udpfd;
 	  forward->new_id = get_id();
-	  forward->fd = udpfd;
 	  memcpy(forward->hash, hash, HASH_SIZE);
 	  forward->forwardall = 0;
 	  forward->flags = fwd_flags;
@@ -1169,7 +1170,7 @@ void reply_query(int fd, int family, time_t now)
 	    {
 	      header->id = htons(src->orig_id);
 	      
-	      send_from(forward->fd, option_bool(OPT_NOWILD) || option_bool (OPT_CLEVERBIND), daemon->packet, nn, 
+	      send_from(src->fd, option_bool(OPT_NOWILD) || option_bool (OPT_CLEVERBIND), daemon->packet, nn, 
 			&src->source, &src->dest, src->iface);
 
 	      if (option_bool(OPT_EXTRALOG) && src != &forward->frec_src)
-- 
2.26.2