From 8c54cd50d8431481a70dec26a66a5343f2bbbd2c Mon Sep 17 00:00:00 2001 From: Reto Brunner Date: Fri, 3 Nov 2023 20:40:56 +0100 Subject: [PATCH] don't crash on rDNS failure Node apparently throws even on valid ipv6 input in certain environments, probably due to the DNS server returning SERVFAIL. Guard against it and fallback with the plain IP Fixes: https://github.com/thelounge/thelounge/issues/4768 --- server/server.ts | 48 ++++++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/server/server.ts b/server/server.ts index 5ecdea92..38987218 100644 --- a/server/server.ts +++ b/server/server.ts @@ -1015,28 +1015,40 @@ function performAuthentication(this: Socket, data) { } function reverseDnsLookup(ip: string, callback: (hostname: string) => void) { - dns.reverse(ip, (reverseErr, hostnames) => { - if (reverseErr || hostnames.length < 1) { - return callback(ip); - } - - dns.resolve(hostnames[0], net.isIP(ip) === 6 ? "AAAA" : "A", (resolveErr, resolvedIps) => { - // TODO: investigate SoaRecord class - if (!Array.isArray(resolvedIps)) { + // node can throw, even if we provide valid input based on the DNS server + // returning SERVFAIL it seems: https://github.com/thelounge/thelounge/issues/4768 + // so we manually resolve with the ip as a fallback in case something fails + try { + dns.reverse(ip, (reverseErr, hostnames) => { + if (reverseErr || hostnames.length < 1) { return callback(ip); } - if (resolveErr || resolvedIps.length < 1) { - return callback(ip); - } + dns.resolve( + hostnames[0], + net.isIP(ip) === 6 ? "AAAA" : "A", + (resolveErr, resolvedIps) => { + // TODO: investigate SoaRecord class + if (!Array.isArray(resolvedIps)) { + return callback(ip); + } - for (const resolvedIp of resolvedIps) { - if (ip === resolvedIp) { - return callback(hostnames[0]); + if (resolveErr || resolvedIps.length < 1) { + return callback(ip); + } + + for (const resolvedIp of resolvedIps) { + if (ip === resolvedIp) { + return callback(hostnames[0]); + } + } + + return callback(ip); } - } - - return callback(ip); + ); }); - }); + } catch (err) { + log.error(`failed to resolve rDNS for ${ip}, using ip instead`, (err as any).toString()); + setImmediate(callback, ip); // makes sure we always behave asynchronously + } }