2020-05-15 01:30:40 +00:00
const dns = require ( 'dns' )
const logger = require ( './logger' )
2020-05-15 01:50:51 +00:00
const { TimeTracker } = require ( './time' )
2020-05-15 01:30:40 +00:00
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 ( ) {
2020-05-15 01:43:55 +00:00
return this . _skipSrvUntil && TimeTracker . getEpochMillis ( ) <= this . _skipSrvUntil
2020-05-15 01:30:40 +00:00
}
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
2020-05-15 01:56:59 +00:00
const remainingTime = config . rates . connectTimeout - ( TimeTracker . getEpochMillis ( ) - startTime )
callback ( ip || this . _ip , port || this . _port , remainingTime )
2020-05-15 01:30:40 +00:00
}
}
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 ) {
2020-05-15 01:43:14 +00:00
// Compare config.skipSrvTimeout directly since SKIP_SRV_TIMEOUT has an or'd value
2020-05-15 01:56:59 +00:00
// isSkipSrvTimeoutDisabled == whether the config has a valid skipSrvTimeout value set
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
2020-05-15 01:56:59 +00:00
if ( ! this . _isSkipSrv ( ) && ! isSkipSrvTimeoutDisabled ) {
2020-05-15 01:30:40 +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 ) )
}
fireCallback ( )
} else {
// Only fires if !err && records.length > 0
fireCallback ( records [ 0 ] . name , records [ 0 ] . port )
}
} )
}
}
module . exports = DNSResolver