| 72 | } |
| 73 | |
| 74 | class SocksConnection { |
| 75 | private _buffer = Buffer.from([]); |
| 76 | private _offset = 0; |
| 77 | private _fence = 0; |
| 78 | private _fenceCallback: (() => void) | undefined; |
| 79 | private _socket: net.Socket; |
| 80 | private _boundOnData: (buffer: Buffer) => void; |
| 81 | private _uid: string; |
| 82 | private _client: SocksConnectionClient; |
| 83 | |
| 84 | constructor(uid: string, socket: net.Socket, client: SocksConnectionClient) { |
| 85 | this._uid = uid; |
| 86 | this._socket = socket; |
| 87 | this._client = client; |
| 88 | this._boundOnData = this._onData.bind(this); |
| 89 | socket.on('data', this._boundOnData); |
| 90 | socket.on('close', () => this._onClose()); |
| 91 | socket.on('end', () => this._onClose()); |
| 92 | socket.on('error', () => this._onClose()); |
| 93 | this._run().catch(() => this._socket.end()); |
| 94 | } |
| 95 | |
| 96 | async _run() { |
| 97 | assert(await this._authenticate()); |
| 98 | const { command, host, port } = await this._parseRequest(); |
| 99 | if (command !== SocksCommand.CONNECT) { |
| 100 | this._writeBytes(Buffer.from([ |
| 101 | 0x05, |
| 102 | SocksReply.CommandNotSupported, |
| 103 | 0x00, // RSV |
| 104 | 0x01, // IPv4 |
| 105 | 0x00, 0x00, 0x00, 0x00, // Address |
| 106 | 0x00, 0x00 // Port |
| 107 | ])); |
| 108 | return; |
| 109 | } |
| 110 | |
| 111 | this._socket.off('data', this._boundOnData); |
| 112 | this._client.onSocketRequested({ uid: this._uid, host, port }); |
| 113 | } |
| 114 | |
| 115 | async _authenticate(): Promise<boolean> { |
| 116 | // Request: |
| 117 | // +----+----------+----------+ |
| 118 | // |VER | NMETHODS | METHODS | |
| 119 | // +----+----------+----------+ |
| 120 | // | 1 | 1 | 1 to 255 | |
| 121 | // +----+----------+----------+ |
| 122 | |
| 123 | // Response: |
| 124 | // +----+--------+ |
| 125 | // |VER | METHOD | |
| 126 | // +----+--------+ |
| 127 | // | 1 | 1 | |
| 128 | // +----+--------+ |
| 129 | |
| 130 | const version = await this._readByte(); |
| 131 | assert(version === 0x05, 'The VER field must be set to x05 for this version of the protocol, was ' + version); |
nothing calls this directly
no test coverage detected
searching dependent graphs…