Minetrack/lib/dns.js

98 lines
2.6 KiB
JavaScript
Raw Permalink Normal View History

2023-12-30 23:03:54 +00:00
const dns = require("dns");
2023-12-30 23:03:54 +00:00
const logger = require("./logger");
2023-12-30 23:03:54 +00:00
const { TimeTracker } = require("./time");
2023-12-30 23:03:54 +00:00
const config = require("../config");
2023-12-30 23:03:54 +00:00
const SKIP_SRV_TIMEOUT = config.skipSrvTimeout || 60 * 60 * 1000;
class DNSResolver {
2023-12-30 23:03:54 +00:00
constructor(ip, port) {
this._ip = ip;
this._port = port;
}
2023-12-30 23:03:54 +00:00
_skipSrv() {
this._skipSrvUntil = TimeTracker.getEpochMillis() + SKIP_SRV_TIMEOUT;
}
2023-12-30 23:03:54 +00:00
_isSkipSrv() {
return (
this._skipSrvUntil && TimeTracker.getEpochMillis() <= this._skipSrvUntil
);
}
2023-12-30 23:03:54 +00:00
resolve(callback) {
if (this._isSkipSrv()) {
2023-12-30 23:03:54 +00:00
callback(this._ip, this._port, config.rates.connectTimeout);
2023-12-30 23:03:54 +00:00
return;
}
2023-12-30 23:03:54 +00:00
const startTime = TimeTracker.getEpochMillis();
2023-12-30 23:03:54 +00:00
let callbackFired = false;
const fireCallback = (ip, port) => {
if (!callbackFired) {
2023-12-30 23:03:54 +00:00
callbackFired = true;
// Send currentTime - startTime to provide remaining connectionTime allowance
2023-12-30 23:03:54 +00:00
const remainingTime =
config.rates.connectTimeout -
(TimeTracker.getEpochMillis() - startTime);
2023-12-30 23:03:54 +00:00
callback(ip || this._ip, port || this._port, remainingTime);
}
2023-12-30 23:03:54 +00:00
};
2023-12-30 23:03:54 +00:00
const timeoutCallback = setTimeout(
fireCallback,
config.rates.connectTimeout
);
2023-12-30 23:03:54 +00:00
dns.resolveSrv("_minecraft._tcp." + this._ip, (err, records) => {
// Cancel the timeout handler if not already fired
if (!callbackFired) {
2023-12-30 23:03:54 +00:00
clearTimeout(timeoutCallback);
}
// Test if the error indicates a miss, or if the records returned are empty
2023-12-30 23:03:54 +00:00
if (
(err && (err.code === "ENOTFOUND" || err.code === "ENODATA")) ||
!records ||
records.length === 0
) {
2020-05-15 01:43:14 +00:00
// Compare config.skipSrvTimeout directly since SKIP_SRV_TIMEOUT has an or'd value
// isSkipSrvTimeoutDisabled == whether the config has a valid skipSrvTimeout value set
2023-12-30 23:03:54 +00:00
const isSkipSrvTimeoutDisabled =
typeof config.skipSrvTimeout === "number" &&
config.skipSrvTimeout === 0;
2020-05-15 01:43:14 +00:00
// Only activate _skipSrv if the skipSrvTimeout value is either NaN or > 0
// 0 represents a disabled flag
if (!this._isSkipSrv() && !isSkipSrvTimeoutDisabled) {
2023-12-30 23:03:54 +00:00
this._skipSrv();
logger.log(
"warn",
"No SRV records were resolved for %s. Minetrack will skip attempting to resolve %s SRV records for %d minutes.",
this._ip,
this._ip,
SKIP_SRV_TIMEOUT / (60 * 1000)
);
}
2023-12-30 23:03:54 +00:00
fireCallback();
} else {
// Only fires if !err && records.length > 0
2023-12-30 23:03:54 +00:00
fireCallback(records[0].name, records[0].port);
}
2023-12-30 23:03:54 +00:00
});
}
}
2023-12-30 23:03:54 +00:00
module.exports = DNSResolver;