net.dns: Fix timeout retry logic
authorMatthew Wild <mwild1@gmail.com>
Thu, 25 Jun 2020 15:28:23 +0100
changeset 10960 03a09fa02e8e
parent 10959 7bcfac630b65
child 10961 8902cecbdd39
net.dns: Fix timeout retry logic On timeout the query would be resent twice - once within servfail(), and again inside the timeout callback. This commit moves all retry logic to servfail().
net/dns.lua
--- a/net/dns.lua	Thu Jun 25 15:22:40 2020 +0100
+++ b/net/dns.lua	Thu Jun 25 15:28:23 2020 +0100
@@ -856,6 +856,9 @@
 		server = self.best_server,
 		delay  = 1,
 		retry  = socket.gettime() + self.delays[1]
+		qclass = qclass;
+		qtype  = qtype;
+		qname  = qname;
 	};
 
 	-- remember the query
@@ -878,19 +881,14 @@
 		local i = 1;
 		timer.add_task(self.timeout, function ()
 			if get(self.wanted, qclass, qtype, qname, co) then
-				if i < num_servers then
 				log("debug", "DNS request timeout %d/%d", i, num_servers)
 					i = i + 1;
-					self:servfail(conn);
-					o.server = self.best_server;
-					conn, err = self:getsocket(o.server);
-					if conn then
-						conn:send(o.packet);
-						return self.timeout;
-					end
-				end
-				-- Tried everything, failed
-				self:cancel(qclass, qtype, qname);
+					self:servfail(self.socket[o.server]);
+--				end
+			end
+			-- Still outstanding? (i.e. retried)
+			if get(self.wanted, qclass, qtype, qname, co) then
+				return self.timeout; -- Then wait
 			end
 		end)
 	end
@@ -917,12 +915,19 @@
 				end
 
 				o.retries = (o.retries or 0) + 1;
-				if o.retries >= #self.server then
-					--print('timeout');
+				local retried;
+				if o.retries < #self.server then
+					sock, err = self:getsocket(o.server);
+					if sock then
+						retried = true;
+							log("debug", "retry %d (immediate)", o.retries);
+							sock:send(o.packet);
+					end
+				end	
+				if not retried then
+					log("debug", 'tried all servers, giving up');
+					self:cancel(o.qclass, o.qtype, o.qname);
 					queries[question] = nil;
-				else
-					sock, err = self:getsocket(o.server);
-					if sock then sock:send(o.packet); end
 				end
 			end
 		end