From 7dea65c340c7385587744846db2f9d05cf51c0e0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Deuc=D0=B5?= <shurd@sasktel.net>
Date: Mon, 5 Apr 2021 22:21:25 -0400
Subject: [PATCH] Fixes for async lookups

- Add a unique number to event names for each request
  Prevents responses from being acepted by multiple queries
- Don't set Socket.dnsObject for synchronous lookups
- OPcode of 2 is used for status replies (ie: NXDOMAIN)
- Be more careful construct result array in request()
---
 exec/load/dns.js | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/exec/load/dns.js b/exec/load/dns.js
index 419605d0d8..060458e5dc 100644
--- a/exec/load/dns.js
+++ b/exec/load/dns.js
@@ -55,9 +55,10 @@ function DNS(synchronous, servers) {
 		var sock = new Socket(SOCK_DGRAM, "dns", server.indexOf(':') >= 0);
 		sock.bind();
 		sock.connect(server, 53);
-		if (!this.synchronous)
+		if (!this.synchronous) {
 			sock.cbID = sock.on('read', handle_response);
-		sock.dnsObject = this;
+			sock.dnsObject = this;
+		}
 		this.sockets.push(sock);
 	}, this);
 
@@ -394,7 +395,7 @@ DNS.prototype.handle_response = function(sock) {
 	if (!ret.response)
 		return null;
 	ret.opcode = (ascii(resp[2]) & 0x1e) >> 1;
-	if (ret.opcode !== 0)
+	if (ret.opcode !== 0 && ret.opcode !== 2)
 		return null;
 	ret.authoritative = !!(ascii(resp[2]) & (1<<5));
 	ret.truncation = !!(ascii(resp[2]) & (1<<6));
@@ -595,6 +596,7 @@ DNS.prototype.resolve = function(host, callback, thisObj)
 	this.sockets.forEach(function(sock) {
 		ctx.unique_id += '.'+sock.local_port;
 	});
+	ctx.unique_id += this.increment_id().toString();
 
 	if (host === undefined)
 		throw new Error('No host specified');
@@ -652,7 +654,7 @@ DNS.prototype.resolve = function(host, callback, thisObj)
 	function handle_response(resp) {
 		var rectype;
 
-		if (resp !== undefined) {
+		if (resp !== null && resp !== undefined) {
 			switch(resp.queries[0].type) {
 				case DNS.types.A:
 					rectype = 'A';
@@ -665,9 +667,10 @@ DNS.prototype.resolve = function(host, callback, thisObj)
 		if (rectype === undefined)
 			return;
 
-		this[rectype].addrs = [];
+		if (this[rectype].addrs === undefined)
+			this[rectype].addrs = [];
 
-		if (resp !== undefined && resp.answers !== undefined) {
+		if (resp !== null && resp.answers !== undefined) {
 			resp.answers.forEach(function(ans) {
 				if (resp.queries[0].type != ans.type || resp.queries[0].class != ans.class)
 					return;
@@ -692,10 +695,6 @@ DNS.prototype.resolveTypeClass = function(host, type, class, callback, thisObj)
 	var respAAAA;
 	var ret;
 
-	this.sockets.forEach(function(sock) {
-		ctx.unique_id += '.'+sock.local_port;
-	});
-
 	if (host === undefined)
 		throw new Error('No host specified');
 
-- 
GitLab