From 23299a9a07123f4c547714a99a0dd8194a1a7394 Mon Sep 17 00:00:00 2001 From: Timofey Gelazoniya Date: Wed, 25 Jun 2025 01:09:07 +0300 Subject: [PATCH] fix: add timeout to SRV record lookup The `dns.promises.resolveSrv` function used for SRV record lookups does not have a user-configurable timeout. This could cause the entire `pingJava` operation to hang for an extended period if the target's DNS server unresponsive. To make the SRV lookup more robust and respect the user-provided timeout, this commit switches to using the `dns.promises.Resolver` class. --- lib/java.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/java.js b/lib/java.js index 1150ff5..e2c4602 100644 --- a/lib/java.js +++ b/lib/java.js @@ -6,7 +6,7 @@ "use strict"; import net from "node:net"; -import dns from "node:dns/promises"; +import { Resolver } from "node:dns/promises"; import createDebug from "debug"; import * as varint from "./varint.js"; @@ -148,22 +148,27 @@ export async function pingJava(host, options = {}) { let targetPort = fallbackPort; try { - debug("attempting SRV lookup for _minecraft._tcp.%s", host); - const srvRecords = await dns.resolveSrv(`_minecraft._tcp.${host}`); + debug( + "attempting SRV lookup for _minecraft._tcp.%s with %dms timeout", + host, + timeout + ); + const resolver = new Resolver({ timeout, tries: 3 }); + const srvRecords = await resolver.resolveSrv(`_minecraft._tcp.${host}`); if (srvRecords.length > 0) { targetHost = srvRecords[0].name; targetPort = srvRecords[0].port; debug("SRV lookup successful, new target: %s:%d", targetHost, targetPort); } } catch (err) { - // Common errors like ENODATA or ENOTFOUND are expected when a server - // does not have an SRV record, so we ignore them and proceed + // Common errors like ENODATA, ENOTFOUND, or a DNS timeout (ETIMEOUT) are expected + // when a server does not have an SRV record, so we ignore them and proceed. + const nonFatalDnsCodes = ["ENODATA", "ENOTFOUND", "ETIMEOUT"]; if ( err instanceof Error && "code" in err && - (err.code === "ENODATA" || err.code === "ENOTFOUND") + nonFatalDnsCodes.includes(err.code) ) { - // Non fatal DNS error, log it and continue debug("SRV lookup for %s failed (%s), using fallback.", host, err.code); } else { // Re-throw anything else to fail the operation