UNPKG

@firaenix/bittorrent-protocol

Version:

Simple, robust, BitTorrent peer wire protocol implementation

229 lines (228 loc) 7.8 kB
/// <reference types="node" /> import BitField from 'bitfield'; import stream from 'readable-stream'; import { ExtendedHandshake } from './Extension'; import { IExtension } from './models/IExtension'; import { PieceRequest, RequestCallback } from './models/PieceRequest'; import { ParseRequest } from './models/ParseRequest'; import { WireEvents } from './models/WireEvents'; import { ExtensionsMap } from './models/ExtensionsMap'; export declare class Wire extends stream.Duplex { _debugId: string; peerId: string | undefined; peerIdBuffer: Buffer | undefined; type: 'webrtc' | 'tcpIncoming' | 'tcpOutgoing' | 'webSeed' | null; amChoking: boolean; amInterested: boolean; peerChoking: boolean; peerInterested: boolean; peerPieces: BitField; peerExtensions: ExtensionsMap; requests: PieceRequest[]; peerRequests: PieceRequest[]; extendedMapping: { [key: number]: string; }; peerExtendedMapping: { [key: string]: number; }; extendedHandshake: ExtendedHandshake; peerExtendedHandshake: ExtendedHandshake; _ext: { [extensionName: string]: IExtension; }; _nextExt: number; uploaded: number; downloaded: number; uploadSpeed: (speed: number) => void; downloadSpeed: (speed: number) => void; _keepAliveInterval: number | NodeJS.Timeout | undefined; _timeout: number | NodeJS.Timeout | undefined; _timeoutMs: number; destroyed: boolean; _finished: boolean; _parseRequests: Array<ParseRequest>; _buffer: Buffer; _timeoutUnref: unknown; _handshakeSent: boolean; _extendedHandshakeSent: boolean; _handshakeSuccess: boolean; _extendedHandshakeSuccess: boolean; wireName: string | undefined; constructor(name?: string); once<U extends keyof WireEvents>(event: U, listener: WireEvents[U]): this; on<U extends keyof WireEvents>(event: U, listener: WireEvents[U]): this; off<U extends keyof WireEvents>(event: U, listener: WireEvents[U]): this; emit<U extends keyof WireEvents>(event: U, ...args: Parameters<WireEvents[U]>): boolean; /** * Set whether to send a "keep-alive" ping (sent every 55s) * @param {boolean} enable */ setKeepAlive(enable: boolean): void; /** * Set the amount of time to wait before considering a request to be "timed out" * @param {number} ms * @param {boolean=} unref (should the timer be unref'd? default: false) */ setTimeout(ms: number, unref?: boolean): void; destroy(): this; end(...args: any[]): void; /** * Use the specified protocol extension. * @param {function} Extension */ use(newExtension: (wire: Wire) => IExtension): void; /** * Message "keep-alive": <len=0000> */ keepAlive(): void; /** * Message: "handshake" <pstrlen><pstr><reserved><info_hash><peer_id> * @param {Buffer|string} infoHash (as Buffer or *hex* string) * @param {Buffer|string} peerId * @param {Object} extensions */ handshake(infoHash: Buffer | string, peerId: Buffer | string, extensions?: any): void; private _sendExtendedHandshake; /** * Message "choke": <len=0001><id=0> */ choke(): void; /** * Message "unchoke": <len=0001><id=1> */ unchoke(): void; /** * Message "interested": <len=0001><id=2> */ interested(): void; /** * Message "uninterested": <len=0001><id=3> */ uninterested(): void; /** * Message "have": <len=0005><id=4><piece index> * @param {number} index */ have(index: number): void; /** * Message "bitfield": <len=0001+X><id=5><bitfield> * @param {BitField|Buffer} bitfield */ bitfield(bitfield: BitField | Buffer): void; /** * Callback will be resolved when onPiece(index, offset, length, buffer) is called or something fails when requesting. * * NOTE: index,offset,length are used as a key to look up the callback later. * * So make sure you specify the length correctly or you will never get your callback. * * If the other party sends the same index and offset but a buffer of a different length, you will not recieve your callback. * * Message "request": <len=0013><id=6><index><begin><length> * @param {number} index * @param {number} offset * @param {number} length * @param {function} cb */ request(index: number, offset: number, length: number, cb: RequestCallback): void; /** * Message "piece": <len=0009+X><id=7><index><begin><block> * @param {number} index * @param {number} offset * @param {Buffer} buffer */ piece(index: number, offset: number, buffer: Buffer): void; /** * Message "cancel": <len=0013><id=8><index><begin><length> * @param {number} index * @param {number} offset * @param {number} length */ cancel(index: number, offset: number, length: number): void; /** * Message: "port" <len=0003><id=9><listen-port> * @param {Number} port */ port(port: number): void; /** * Message: "extended" <len=0005+X><id=20><ext-number><payload> * @param {number|string} ext * @param {Object} obj */ extended(ext: number | string, obj: object): void; /** * Duplex stream method. Called whenever the remote peer stream wants data. No-op * since we'll just push data whenever we get it. */ _read(): void; /** * Send a message to the remote peer. */ private _message; private _push; private _onKeepAlive; private _onHandshake; private _onChoke; private _onUnchoke; private _onInterested; private _onUninterested; private _onHave; private _onBitField; private _onRequest; private _onPiece; private _onCancel; private _onPort; private onExtendedMessage; private onExtendedHandshake; private _onExtended; private _onTimeout; /** * Duplex stream method. Called whenever the remote peer has data for us. Data that the * remote peer sends gets buffered (i.e. not actually processed) until the right number * of bytes have arrived, determined by the last call to `this._parse(number, callback)`. * Once enough bytes have arrived to process the message, the callback function * (i.e. `this._parser`) gets called with the full buffer of data. * @param {Buffer} data * @param {string} encoding * @param {function} cb */ _write(data: Buffer, encoding: string, cb: (e: any) => void): void; private parseStream; private _callback; private _clearTimeout; private _updateTimeout; /** * Takes a number of bytes that the local peer is waiting to receive from the remote peer * in order to parse a complete message, and a callback function to be called once enough * bytes have arrived. * @param {number} size * @param {function} parser */ private _parse; /** * Handle the first 4 bytes of a message, to determine the length of bytes that must be * waited for in order to have the whole message. * @param {Buffer} buffer */ private _onMessageLength; /** * Handle a message from the remote peer. * @param {Buffer} buffer */ private _onMessage; private _parseHandshake; private _onFinish; private _debug; /** * Retrieves the first entity from the requests array that matches the index, offset and length given. * * Often used in conjunction with _callback to call back to waiting piece requests * @param requests * @param pieceIdx * @param offset * @param length */ private _pull; } export default Wire;