75 lines
2.3 KiB
JavaScript
75 lines
2.3 KiB
JavaScript
const dns = require('dns')
|
|
|
|
const logger = require('./logger')
|
|
const TimeTracker = require('./time')
|
|
|
|
const config = require('../config')
|
|
|
|
const SKIP_SRV_TIMEOUT = config.skipSrvTimeout || 60 * 60 * 1000
|
|
|
|
class DNSResolver {
|
|
constructor (ip, port) {
|
|
this._ip = ip
|
|
this._port = port
|
|
}
|
|
|
|
_skipSrv () {
|
|
this._skipSrvUntil = TimeTracker.getEpochMillis() + SKIP_SRV_TIMEOUT
|
|
}
|
|
|
|
_isSkipSrv () {
|
|
return this._skipSrvUntil && TimeTracker.getEpochMillis() <= this._skipSrvUntil
|
|
}
|
|
|
|
resolve (callback) {
|
|
if (this._isSkipSrv()) {
|
|
callback(this._ip, this._port, config.rates.connectTimeout)
|
|
|
|
return
|
|
}
|
|
|
|
const startTime = TimeTracker.getEpochMillis()
|
|
|
|
let callbackFired = false
|
|
|
|
const fireCallback = (ip, port) => {
|
|
if (!callbackFired) {
|
|
callbackFired = true
|
|
|
|
// Send currentTime - startTime to provide remaining connectionTime allowance
|
|
callback(ip || this._ip, port || this._port, TimeTracker.getEpochMillis() - startTime)
|
|
}
|
|
}
|
|
|
|
const timeoutCallback = setTimeout(fireCallback, config.rates.connectTimeout)
|
|
|
|
dns.resolveSrv('_minecraft._tcp.' + this._ip, (err, records) => {
|
|
// Cancel the timeout handler if not already fired
|
|
if (!callbackFired) {
|
|
clearTimeout(timeoutCallback)
|
|
}
|
|
|
|
// Test if the error indicates a miss, or if the records returned are empty
|
|
if ((err && (err.code === 'ENOTFOUND' || err.code === 'ENODATA')) || !records || records.length === 0) {
|
|
// Compare config.skipSrvTimeout directly since SKIP_SRV_TIMEOUT has an or'd value
|
|
const isSkipSrvTimeoutActive = typeof config.skipSrvTimeout !== 'number' || config.skipSrvTimeout > 0
|
|
|
|
// Only activate _skipSrv if the skipSrvTimeout value is either NaN or > 0
|
|
// 0 represents a disabled flag
|
|
if (!this._isSkipSrv() && !isSkipSrvTimeoutActive) {
|
|
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))
|
|
}
|
|
|
|
fireCallback()
|
|
} else {
|
|
// Only fires if !err && records.length > 0
|
|
fireCallback(records[0].name, records[0].port)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
module.exports = DNSResolver
|