import { EventEmitter } from "events" ; import { DNSPacket } from "../coder/DNSPacket" ; import Timeout = NodeJS . Timeout ; export const enum TruncatedQueryResult { ABORT = 1 , AGAIN_TRUNCATED = 2 , FINISHED = 3 } export const enum TruncatedQueryEvent { TIMEOUT = "timeout" } export declare interface TruncatedQuery { on ( event , listener ) : this ; emit ( event ) : boolean ; } export class TruncatedQuery extends EventEmitter { private readonly timeOfArrival : number ; private readonly packet : DNSPacket ; private arrivedPackets = 1 ; private timer : Timeout ; constructor ( packet ) { super ( ) ; this . timeOfArrival = new Date ( ) . getTime ( ) ; this . packet = packet ; this . timer = this . resetTimer ( ) ; } public getPacket ( ) { return this . packet ; } public getArrivedPacketCount ( ) { return this . arrivedPackets ; } public getTotalWaitTime ( ) { return new Date ( ) . getTime ( ) - this . timeOfArrival ; } public appendDNSPacket ( packet ) { this . packet . combineWith ( packet ) ; this . arrivedPackets ++ ; if ( packet . flags . truncation ) { const time = new Date ( ) . getTime ( ) ; if ( time - this . timeOfArrival > 5 * 1000 ) { return TruncatedQueryResult . ABORT ; } this . resetTimer ( ) ; return TruncatedQueryResult . AGAIN_TRUNCATED ; } else { clearTimeout ( this . timer ) ; this . removeAllListeners ( ) ; return TruncatedQueryResult . FINISHED ; } } private resetTimer ( ) { if ( this . timer ) { clearTimeout ( this . timer ) ; } return this . timer = setTimeout ( this . timeout . bind ( this ) , 400 + Math . random ( ) * 100 ) ; } private timeout ( ) { this . emit ( TruncatedQueryEvent . TIMEOUT ) ; this . removeAllListeners ( ) ; } }