socks 2.3.1 → 2.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,13 +1,15 @@
1
1
  "use strict";
2
2
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
4
  return new (P || (P = Promise))(function (resolve, reject) {
4
5
  function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
6
  function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
9
  });
9
10
  };
10
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.SocksClientError = exports.SocksClient = void 0;
11
13
  const events_1 = require("events");
12
14
  const net = require("net");
13
15
  const ip = require("ip");
@@ -16,14 +18,15 @@ const constants_1 = require("../common/constants");
16
18
  const helpers_1 = require("../common/helpers");
17
19
  const receivebuffer_1 = require("../common/receivebuffer");
18
20
  const util_1 = require("../common/util");
21
+ Object.defineProperty(exports, "SocksClientError", { enumerable: true, get: function () { return util_1.SocksClientError; } });
19
22
  class SocksClient extends events_1.EventEmitter {
20
23
  constructor(options) {
21
24
  super();
22
- this._options = Object.assign({}, options);
25
+ this.options = Object.assign({}, options);
23
26
  // Validate SocksClientOptions
24
27
  helpers_1.validateSocksClientOptions(options);
25
28
  // Default state
26
- this.state = constants_1.SocksClientState.Created;
29
+ this.setState(constants_1.SocksClientState.Created);
27
30
  }
28
31
  /**
29
32
  * Creates a new SOCKS connection.
@@ -81,6 +84,7 @@ class SocksClient extends events_1.EventEmitter {
81
84
  return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
82
85
  let sock;
83
86
  try {
87
+ // tslint:disable-next-line:no-increment-decrement
84
88
  for (let i = 0; i < options.proxies.length; i++) {
85
89
  const nextProxy = options.proxies[i];
86
90
  // If we've reached the last proxy in the chain, the destination is the actual destination, otherwise it's the next proxy.
@@ -88,14 +92,13 @@ class SocksClient extends events_1.EventEmitter {
88
92
  ? options.destination
89
93
  : {
90
94
  host: options.proxies[i + 1].ipaddress,
91
- port: options.proxies[i + 1].port
95
+ port: options.proxies[i + 1].port,
92
96
  };
93
97
  // Creates the next connection in the chain.
94
98
  const result = yield SocksClient.createConnection({
95
99
  command: 'connect',
96
100
  proxy: nextProxy,
97
- destination: nextDestination
98
- // Initial connection ignores this as sock is undefined. Subsequent connections re-use the first proxy socket to form a chain.
101
+ destination: nextDestination,
99
102
  });
100
103
  // If sock is undefined, assign it here.
101
104
  if (!sock) {
@@ -173,75 +176,73 @@ class SocksClient extends events_1.EventEmitter {
173
176
  frameNumber,
174
177
  remoteHost: {
175
178
  host: remoteHost,
176
- port: remotePort
179
+ port: remotePort,
177
180
  },
178
- data: buff.readBuffer()
181
+ data: buff.readBuffer(),
179
182
  };
180
183
  }
181
- /**
182
- * Gets the SocksClient internal state.
183
- */
184
- get state() {
185
- return this._state;
186
- }
187
184
  /**
188
185
  * Internal state setter. If the SocksClient is in an error state, it cannot be changed to a non error state.
189
186
  */
190
- set state(newState) {
191
- if (this._state !== constants_1.SocksClientState.Error) {
192
- this._state = newState;
187
+ setState(newState) {
188
+ if (this.state !== constants_1.SocksClientState.Error) {
189
+ this.state = newState;
193
190
  }
194
191
  }
195
192
  /**
196
193
  * Starts the connection establishment to the proxy and destination.
197
- * @param existing_socket Connected socket to use instead of creating a new one (internal use).
194
+ * @param existingSocket Connected socket to use instead of creating a new one (internal use).
198
195
  */
199
- connect(existing_socket) {
200
- this._onDataReceived = (data) => this.onDataReceived(data);
201
- this._onClose = () => this.onClose();
202
- this._onError = (err) => this.onError(err);
203
- this._onConnect = () => this.onConnect();
196
+ connect(existingSocket) {
197
+ this.onDataReceived = (data) => this.onDataReceivedHandler(data);
198
+ this.onClose = () => this.onCloseHandler();
199
+ this.onError = (err) => this.onErrorHandler(err);
200
+ this.onConnect = () => this.onConnectHandler();
204
201
  // Start timeout timer (defaults to 30 seconds)
205
- const timer = setTimeout(() => this.onEstablishedTimeout(), this._options.timeout || constants_1.DEFAULT_TIMEOUT);
202
+ const timer = setTimeout(() => this.onEstablishedTimeout(), this.options.timeout || constants_1.DEFAULT_TIMEOUT);
206
203
  // check whether unref is available as it differs from browser to NodeJS (#33)
207
204
  if (timer.unref && typeof timer.unref === 'function') {
208
205
  timer.unref();
209
206
  }
210
207
  // If an existing socket is provided, use it to negotiate SOCKS handshake. Otherwise create a new Socket.
211
- if (existing_socket) {
212
- this._socket = existing_socket;
208
+ if (existingSocket) {
209
+ this.socket = existingSocket;
213
210
  }
214
211
  else {
215
- this._socket = new net.Socket();
212
+ this.socket = new net.Socket();
216
213
  }
217
214
  // Attach Socket error handlers.
218
- this._socket.once('close', this._onClose);
219
- this._socket.once('error', this._onError);
220
- this._socket.once('connect', this._onConnect);
221
- this._socket.on('data', this._onDataReceived);
222
- this.state = constants_1.SocksClientState.Connecting;
223
- this._receiveBuffer = new receivebuffer_1.ReceiveBuffer();
224
- if (existing_socket) {
225
- this._socket.emit('connect');
215
+ this.socket.once('close', this.onClose);
216
+ this.socket.once('error', this.onError);
217
+ this.socket.once('connect', this.onConnect);
218
+ this.socket.on('data', this.onDataReceived);
219
+ this.setState(constants_1.SocksClientState.Connecting);
220
+ this.receiveBuffer = new receivebuffer_1.ReceiveBuffer();
221
+ if (existingSocket) {
222
+ this.socket.emit('connect');
226
223
  }
227
224
  else {
228
- this._socket.connect(this._options.proxy.port, this._options.proxy.host || this._options.proxy.ipaddress);
229
- if (this._options.set_tcp_nodelay !== undefined &&
230
- this._options.set_tcp_nodelay !== null) {
231
- this._socket.setNoDelay(!!this._options.set_tcp_nodelay);
225
+ this.socket.connect(this.getSocketOptions());
226
+ if (this.options.set_tcp_nodelay !== undefined &&
227
+ this.options.set_tcp_nodelay !== null) {
228
+ this.socket.setNoDelay(!!this.options.set_tcp_nodelay);
232
229
  }
233
230
  }
234
231
  // Listen for established event so we can re-emit any excess data received during handshakes.
235
- this.prependOnceListener('established', info => {
232
+ this.prependOnceListener('established', (info) => {
236
233
  setImmediate(() => {
237
- if (this._receiveBuffer.length > 0) {
238
- const excessData = this._receiveBuffer.get(this._receiveBuffer.length);
234
+ if (this.receiveBuffer.length > 0) {
235
+ const excessData = this.receiveBuffer.get(this.receiveBuffer.length);
239
236
  info.socket.emit('data', excessData);
240
237
  }
241
238
  info.socket.resume();
242
239
  });
243
240
  });
244
241
  }
242
+ // Socket options (defaults host/port to options.proxy.host/options.proxy.port)
243
+ getSocketOptions() {
244
+ return Object.assign(Object.assign({}, this.options.socket_options), { host: this.options.proxy.host || this.options.proxy.ipaddress, port: this.options.proxy.port });
245
+ }
245
246
  /**
246
247
  * Handles internal Socks timeout callback.
247
248
  * Note: If the Socks client is not BoundWaitingForConnection or Established, the connection will be closed.
@@ -249,33 +250,33 @@ class SocksClient extends events_1.EventEmitter {
249
250
  onEstablishedTimeout() {
250
251
  if (this.state !== constants_1.SocksClientState.Established &&
251
252
  this.state !== constants_1.SocksClientState.BoundWaitingForConnection) {
252
- this._closeSocket(constants_1.ERRORS.ProxyConnectionTimedOut);
253
+ this.closeSocket(constants_1.ERRORS.ProxyConnectionTimedOut);
253
254
  }
254
255
  }
255
256
  /**
256
257
  * Handles Socket connect event.
257
258
  */
258
- onConnect() {
259
- this.state = constants_1.SocksClientState.Connected;
259
+ onConnectHandler() {
260
+ this.setState(constants_1.SocksClientState.Connected);
260
261
  // Send initial handshake.
261
- if (this._options.proxy.type === 4) {
262
+ if (this.options.proxy.type === 4) {
262
263
  this.sendSocks4InitialHandshake();
263
264
  }
264
265
  else {
265
266
  this.sendSocks5InitialHandshake();
266
267
  }
267
- this.state = constants_1.SocksClientState.SentInitialHandshake;
268
+ this.setState(constants_1.SocksClientState.SentInitialHandshake);
268
269
  }
269
270
  /**
270
271
  * Handles Socket data event.
271
272
  * @param data
272
273
  */
273
- onDataReceived(data) {
274
+ onDataReceivedHandler(data) {
274
275
  /*
275
276
  All received data is appended to a ReceiveBuffer.
276
277
  This makes sure that all the data we need is received before we attempt to process it.
277
278
  */
278
- this._receiveBuffer.append(data);
279
+ this.receiveBuffer.append(data);
279
280
  // Process data that we have.
280
281
  this.processData();
281
282
  }
@@ -284,10 +285,10 @@ class SocksClient extends events_1.EventEmitter {
284
285
  */
285
286
  processData() {
286
287
  // If we have enough data to process the next step in the SOCKS handshake, proceed.
287
- if (this._receiveBuffer.length >= this._nextRequiredPacketBufferSize) {
288
+ if (this.receiveBuffer.length >= this.nextRequiredPacketBufferSize) {
288
289
  // Sent initial handshake, waiting for response.
289
290
  if (this.state === constants_1.SocksClientState.SentInitialHandshake) {
290
- if (this._options.proxy.type === 4) {
291
+ if (this.options.proxy.type === 4) {
291
292
  // Socks v4 only has one handshake response.
292
293
  this.handleSocks4FinalHandshakeResponse();
293
294
  }
@@ -306,7 +307,7 @@ class SocksClient extends events_1.EventEmitter {
306
307
  // Socks BIND established. Waiting for remote connection via proxy.
307
308
  }
308
309
  else if (this.state === constants_1.SocksClientState.BoundWaitingForConnection) {
309
- if (this._options.proxy.type === 4) {
310
+ if (this.options.proxy.type === 4) {
310
311
  this.handleSocks4IncomingConnectionResponse();
311
312
  }
312
313
  else {
@@ -317,7 +318,7 @@ class SocksClient extends events_1.EventEmitter {
317
318
  // do nothing (prevents closing of the socket)
318
319
  }
319
320
  else {
320
- this._closeSocket(constants_1.ERRORS.InternalError);
321
+ this.closeSocket(constants_1.ERRORS.InternalError);
321
322
  }
322
323
  }
323
324
  }
@@ -325,56 +326,56 @@ class SocksClient extends events_1.EventEmitter {
325
326
  * Handles Socket close event.
326
327
  * @param had_error
327
328
  */
328
- onClose() {
329
- this._closeSocket(constants_1.ERRORS.SocketClosed);
329
+ onCloseHandler() {
330
+ this.closeSocket(constants_1.ERRORS.SocketClosed);
330
331
  }
331
332
  /**
332
333
  * Handles Socket error event.
333
334
  * @param err
334
335
  */
335
- onError(err) {
336
- this._closeSocket(err.message);
336
+ onErrorHandler(err) {
337
+ this.closeSocket(err.message);
337
338
  }
338
339
  /**
339
340
  * Removes internal event listeners on the underlying Socket.
340
341
  */
341
342
  removeInternalSocketHandlers() {
342
343
  // Pauses data flow of the socket (this is internally resumed after 'established' is emitted)
343
- this._socket.pause();
344
- this._socket.removeListener('data', this._onDataReceived);
345
- this._socket.removeListener('close', this._onClose);
346
- this._socket.removeListener('error', this._onError);
347
- this._socket.removeListener('connect', this.onConnect);
344
+ this.socket.pause();
345
+ this.socket.removeListener('data', this.onDataReceived);
346
+ this.socket.removeListener('close', this.onClose);
347
+ this.socket.removeListener('error', this.onError);
348
+ this.socket.removeListener('connect', this.onConnect);
348
349
  }
349
350
  /**
350
351
  * Closes and destroys the underlying Socket. Emits an error event.
351
352
  * @param err { String } An error string to include in error event.
352
353
  */
353
- _closeSocket(err) {
354
+ closeSocket(err) {
354
355
  // Make sure only one 'error' event is fired for the lifetime of this SocksClient instance.
355
356
  if (this.state !== constants_1.SocksClientState.Error) {
356
357
  // Set internal state to Error.
357
- this.state = constants_1.SocksClientState.Error;
358
+ this.setState(constants_1.SocksClientState.Error);
358
359
  // Destroy Socket
359
- this._socket.destroy();
360
+ this.socket.destroy();
360
361
  // Remove internal listeners
361
362
  this.removeInternalSocketHandlers();
362
363
  // Fire 'error' event.
363
- this.emit('error', new util_1.SocksClientError(err, this._options));
364
+ this.emit('error', new util_1.SocksClientError(err, this.options));
364
365
  }
365
366
  }
366
367
  /**
367
368
  * Sends initial Socks v4 handshake request.
368
369
  */
369
370
  sendSocks4InitialHandshake() {
370
- const userId = this._options.proxy.userId || '';
371
+ const userId = this.options.proxy.userId || '';
371
372
  const buff = new smart_buffer_1.SmartBuffer();
372
373
  buff.writeUInt8(0x04);
373
- buff.writeUInt8(constants_1.SocksCommand[this._options.command]);
374
- buff.writeUInt16BE(this._options.destination.port);
374
+ buff.writeUInt8(constants_1.SocksCommand[this.options.command]);
375
+ buff.writeUInt16BE(this.options.destination.port);
375
376
  // Socks 4 (IPv4)
376
- if (net.isIPv4(this._options.destination.host)) {
377
- buff.writeBuffer(ip.toBuffer(this._options.destination.host));
377
+ if (net.isIPv4(this.options.destination.host)) {
378
+ buff.writeBuffer(ip.toBuffer(this.options.destination.host));
378
379
  buff.writeStringNT(userId);
379
380
  // Socks 4a (hostname)
380
381
  }
@@ -384,42 +385,42 @@ class SocksClient extends events_1.EventEmitter {
384
385
  buff.writeUInt8(0x00);
385
386
  buff.writeUInt8(0x01);
386
387
  buff.writeStringNT(userId);
387
- buff.writeStringNT(this._options.destination.host);
388
+ buff.writeStringNT(this.options.destination.host);
388
389
  }
389
- this._nextRequiredPacketBufferSize =
390
+ this.nextRequiredPacketBufferSize =
390
391
  constants_1.SOCKS_INCOMING_PACKET_SIZES.Socks4Response;
391
- this._socket.write(buff.toBuffer());
392
+ this.socket.write(buff.toBuffer());
392
393
  }
393
394
  /**
394
395
  * Handles Socks v4 handshake response.
395
396
  * @param data
396
397
  */
397
398
  handleSocks4FinalHandshakeResponse() {
398
- const data = this._receiveBuffer.get(8);
399
+ const data = this.receiveBuffer.get(8);
399
400
  if (data[1] !== constants_1.Socks4Response.Granted) {
400
- this._closeSocket(`${constants_1.ERRORS.Socks4ProxyRejectedConnection} - (${constants_1.Socks4Response[data[1]]})`);
401
+ this.closeSocket(`${constants_1.ERRORS.Socks4ProxyRejectedConnection} - (${constants_1.Socks4Response[data[1]]})`);
401
402
  }
402
403
  else {
403
404
  // Bind response
404
- if (constants_1.SocksCommand[this._options.command] === constants_1.SocksCommand.bind) {
405
+ if (constants_1.SocksCommand[this.options.command] === constants_1.SocksCommand.bind) {
405
406
  const buff = smart_buffer_1.SmartBuffer.fromBuffer(data);
406
407
  buff.readOffset = 2;
407
408
  const remoteHost = {
408
409
  port: buff.readUInt16BE(),
409
- host: ip.fromLong(buff.readUInt32BE())
410
+ host: ip.fromLong(buff.readUInt32BE()),
410
411
  };
411
412
  // If host is 0.0.0.0, set to proxy host.
412
413
  if (remoteHost.host === '0.0.0.0') {
413
- remoteHost.host = this._options.proxy.ipaddress;
414
+ remoteHost.host = this.options.proxy.ipaddress;
414
415
  }
415
- this.state = constants_1.SocksClientState.BoundWaitingForConnection;
416
- this.emit('bound', { socket: this._socket, remoteHost });
416
+ this.setState(constants_1.SocksClientState.BoundWaitingForConnection);
417
+ this.emit('bound', { remoteHost, socket: this.socket });
417
418
  // Connect response
418
419
  }
419
420
  else {
420
- this.state = constants_1.SocksClientState.Established;
421
+ this.setState(constants_1.SocksClientState.Established);
421
422
  this.removeInternalSocketHandlers();
422
- this.emit('established', { socket: this._socket });
423
+ this.emit('established', { socket: this.socket });
423
424
  }
424
425
  }
425
426
  }
@@ -428,20 +429,20 @@ class SocksClient extends events_1.EventEmitter {
428
429
  * @param data
429
430
  */
430
431
  handleSocks4IncomingConnectionResponse() {
431
- const data = this._receiveBuffer.get(8);
432
+ const data = this.receiveBuffer.get(8);
432
433
  if (data[1] !== constants_1.Socks4Response.Granted) {
433
- this._closeSocket(`${constants_1.ERRORS.Socks4ProxyRejectedIncomingBoundConnection} - (${constants_1.Socks4Response[data[1]]})`);
434
+ this.closeSocket(`${constants_1.ERRORS.Socks4ProxyRejectedIncomingBoundConnection} - (${constants_1.Socks4Response[data[1]]})`);
434
435
  }
435
436
  else {
436
437
  const buff = smart_buffer_1.SmartBuffer.fromBuffer(data);
437
438
  buff.readOffset = 2;
438
439
  const remoteHost = {
439
440
  port: buff.readUInt16BE(),
440
- host: ip.fromLong(buff.readUInt32BE())
441
+ host: ip.fromLong(buff.readUInt32BE()),
441
442
  };
442
- this.state = constants_1.SocksClientState.Established;
443
+ this.setState(constants_1.SocksClientState.Established);
443
444
  this.removeInternalSocketHandlers();
444
- this.emit('established', { socket: this._socket, remoteHost });
445
+ this.emit('established', { remoteHost, socket: this.socket });
445
446
  }
446
447
  }
447
448
  /**
@@ -452,7 +453,7 @@ class SocksClient extends events_1.EventEmitter {
452
453
  buff.writeUInt8(0x05);
453
454
  // We should only tell the proxy we support user/pass auth if auth info is actually provided.
454
455
  // Note: As of Tor v0.3.5.7+, if user/pass auth is an option from the client, by default it will always take priority.
455
- if (this._options.proxy.userId || this._options.proxy.password) {
456
+ if (this.options.proxy.userId || this.options.proxy.password) {
456
457
  buff.writeUInt8(2);
457
458
  buff.writeUInt8(constants_1.Socks5Auth.NoAuth);
458
459
  buff.writeUInt8(constants_1.Socks5Auth.UserPass);
@@ -461,22 +462,22 @@ class SocksClient extends events_1.EventEmitter {
461
462
  buff.writeUInt8(1);
462
463
  buff.writeUInt8(constants_1.Socks5Auth.NoAuth);
463
464
  }
464
- this._nextRequiredPacketBufferSize =
465
+ this.nextRequiredPacketBufferSize =
465
466
  constants_1.SOCKS_INCOMING_PACKET_SIZES.Socks5InitialHandshakeResponse;
466
- this._socket.write(buff.toBuffer());
467
- this.state = constants_1.SocksClientState.SentInitialHandshake;
467
+ this.socket.write(buff.toBuffer());
468
+ this.setState(constants_1.SocksClientState.SentInitialHandshake);
468
469
  }
469
470
  /**
470
471
  * Handles initial Socks v5 handshake response.
471
472
  * @param data
472
473
  */
473
474
  handleInitialSocks5HandshakeResponse() {
474
- const data = this._receiveBuffer.get(2);
475
+ const data = this.receiveBuffer.get(2);
475
476
  if (data[0] !== 0x05) {
476
- this._closeSocket(constants_1.ERRORS.InvalidSocks5IntiailHandshakeSocksVersion);
477
+ this.closeSocket(constants_1.ERRORS.InvalidSocks5IntiailHandshakeSocksVersion);
477
478
  }
478
479
  else if (data[1] === 0xff) {
479
- this._closeSocket(constants_1.ERRORS.InvalidSocks5InitialHandshakeNoAcceptedAuthType);
480
+ this.closeSocket(constants_1.ERRORS.InvalidSocks5InitialHandshakeNoAcceptedAuthType);
480
481
  }
481
482
  else {
482
483
  // If selected Socks v5 auth method is no auth, send final handshake request.
@@ -488,7 +489,7 @@ class SocksClient extends events_1.EventEmitter {
488
489
  this.sendSocks5UserPassAuthentication();
489
490
  }
490
491
  else {
491
- this._closeSocket(constants_1.ERRORS.InvalidSocks5InitialHandshakeUnknownAuthType);
492
+ this.closeSocket(constants_1.ERRORS.InvalidSocks5InitialHandshakeUnknownAuthType);
492
493
  }
493
494
  }
494
495
  }
@@ -498,28 +499,28 @@ class SocksClient extends events_1.EventEmitter {
498
499
  * Note: No auth and user/pass are currently supported.
499
500
  */
500
501
  sendSocks5UserPassAuthentication() {
501
- const userId = this._options.proxy.userId || '';
502
- const password = this._options.proxy.password || '';
502
+ const userId = this.options.proxy.userId || '';
503
+ const password = this.options.proxy.password || '';
503
504
  const buff = new smart_buffer_1.SmartBuffer();
504
505
  buff.writeUInt8(0x01);
505
506
  buff.writeUInt8(Buffer.byteLength(userId));
506
507
  buff.writeString(userId);
507
508
  buff.writeUInt8(Buffer.byteLength(password));
508
509
  buff.writeString(password);
509
- this._nextRequiredPacketBufferSize =
510
+ this.nextRequiredPacketBufferSize =
510
511
  constants_1.SOCKS_INCOMING_PACKET_SIZES.Socks5UserPassAuthenticationResponse;
511
- this._socket.write(buff.toBuffer());
512
- this.state = constants_1.SocksClientState.SentAuthentication;
512
+ this.socket.write(buff.toBuffer());
513
+ this.setState(constants_1.SocksClientState.SentAuthentication);
513
514
  }
514
515
  /**
515
516
  * Handles Socks v5 auth handshake response.
516
517
  * @param data
517
518
  */
518
519
  handleInitialSocks5AuthenticationHandshakeResponse() {
519
- this.state = constants_1.SocksClientState.ReceivedAuthenticationResponse;
520
- const data = this._receiveBuffer.get(2);
520
+ this.setState(constants_1.SocksClientState.ReceivedAuthenticationResponse);
521
+ const data = this.receiveBuffer.get(2);
521
522
  if (data[1] !== 0x00) {
522
- this._closeSocket(constants_1.ERRORS.Socks5AuthenticationFailed);
523
+ this.closeSocket(constants_1.ERRORS.Socks5AuthenticationFailed);
523
524
  }
524
525
  else {
525
526
  this.sendSocks5CommandRequest();
@@ -531,27 +532,27 @@ class SocksClient extends events_1.EventEmitter {
531
532
  sendSocks5CommandRequest() {
532
533
  const buff = new smart_buffer_1.SmartBuffer();
533
534
  buff.writeUInt8(0x05);
534
- buff.writeUInt8(constants_1.SocksCommand[this._options.command]);
535
+ buff.writeUInt8(constants_1.SocksCommand[this.options.command]);
535
536
  buff.writeUInt8(0x00);
536
537
  // ipv4, ipv6, domain?
537
- if (net.isIPv4(this._options.destination.host)) {
538
+ if (net.isIPv4(this.options.destination.host)) {
538
539
  buff.writeUInt8(constants_1.Socks5HostType.IPv4);
539
- buff.writeBuffer(ip.toBuffer(this._options.destination.host));
540
+ buff.writeBuffer(ip.toBuffer(this.options.destination.host));
540
541
  }
541
- else if (net.isIPv6(this._options.destination.host)) {
542
+ else if (net.isIPv6(this.options.destination.host)) {
542
543
  buff.writeUInt8(constants_1.Socks5HostType.IPv6);
543
- buff.writeBuffer(ip.toBuffer(this._options.destination.host));
544
+ buff.writeBuffer(ip.toBuffer(this.options.destination.host));
544
545
  }
545
546
  else {
546
547
  buff.writeUInt8(constants_1.Socks5HostType.Hostname);
547
- buff.writeUInt8(this._options.destination.host.length);
548
- buff.writeString(this._options.destination.host);
548
+ buff.writeUInt8(this.options.destination.host.length);
549
+ buff.writeString(this.options.destination.host);
549
550
  }
550
- buff.writeUInt16BE(this._options.destination.port);
551
- this._nextRequiredPacketBufferSize =
551
+ buff.writeUInt16BE(this.options.destination.port);
552
+ this.nextRequiredPacketBufferSize =
552
553
  constants_1.SOCKS_INCOMING_PACKET_SIZES.Socks5ResponseHeader;
553
- this._socket.write(buff.toBuffer());
554
- this.state = constants_1.SocksClientState.SentFinalHandshake;
554
+ this.socket.write(buff.toBuffer());
555
+ this.setState(constants_1.SocksClientState.SentFinalHandshake);
555
556
  }
556
557
  /**
557
558
  * Handles Socks v5 final handshake response.
@@ -559,9 +560,9 @@ class SocksClient extends events_1.EventEmitter {
559
560
  */
560
561
  handleSocks5FinalHandshakeResponse() {
561
562
  // Peek at available data (we need at least 5 bytes to get the hostname length)
562
- const header = this._receiveBuffer.peek(5);
563
+ const header = this.receiveBuffer.peek(5);
563
564
  if (header[0] !== 0x05 || header[1] !== constants_1.Socks5Response.Granted) {
564
- this._closeSocket(`${constants_1.ERRORS.InvalidSocks5FinalHandshakeRejected} - ${constants_1.Socks5Response[header[1]]}`);
565
+ this.closeSocket(`${constants_1.ERRORS.InvalidSocks5FinalHandshakeRejected} - ${constants_1.Socks5Response[header[1]]}`);
565
566
  }
566
567
  else {
567
568
  // Read address type
@@ -572,18 +573,18 @@ class SocksClient extends events_1.EventEmitter {
572
573
  if (addressType === constants_1.Socks5HostType.IPv4) {
573
574
  // Check if data is available.
574
575
  const dataNeeded = constants_1.SOCKS_INCOMING_PACKET_SIZES.Socks5ResponseIPv4;
575
- if (this._receiveBuffer.length < dataNeeded) {
576
- this._nextRequiredPacketBufferSize = dataNeeded;
576
+ if (this.receiveBuffer.length < dataNeeded) {
577
+ this.nextRequiredPacketBufferSize = dataNeeded;
577
578
  return;
578
579
  }
579
- buff = smart_buffer_1.SmartBuffer.fromBuffer(this._receiveBuffer.get(dataNeeded).slice(4));
580
+ buff = smart_buffer_1.SmartBuffer.fromBuffer(this.receiveBuffer.get(dataNeeded).slice(4));
580
581
  remoteHost = {
581
582
  host: ip.fromLong(buff.readUInt32BE()),
582
- port: buff.readUInt16BE()
583
+ port: buff.readUInt16BE(),
583
584
  };
584
585
  // If given host is 0.0.0.0, assume remote proxy ip instead.
585
586
  if (remoteHost.host === '0.0.0.0') {
586
- remoteHost.host = this._options.proxy.ipaddress;
587
+ remoteHost.host = this.options.proxy.ipaddress;
587
588
  }
588
589
  // Hostname
589
590
  }
@@ -591,55 +592,57 @@ class SocksClient extends events_1.EventEmitter {
591
592
  const hostLength = header[4];
592
593
  const dataNeeded = constants_1.SOCKS_INCOMING_PACKET_SIZES.Socks5ResponseHostname(hostLength); // header + host length + host + port
593
594
  // Check if data is available.
594
- if (this._receiveBuffer.length < dataNeeded) {
595
- this._nextRequiredPacketBufferSize = dataNeeded;
595
+ if (this.receiveBuffer.length < dataNeeded) {
596
+ this.nextRequiredPacketBufferSize = dataNeeded;
596
597
  return;
597
598
  }
598
- buff = smart_buffer_1.SmartBuffer.fromBuffer(this._receiveBuffer.get(dataNeeded).slice(5) // Slice at 5 to skip host length
599
- );
599
+ buff = smart_buffer_1.SmartBuffer.fromBuffer(this.receiveBuffer.get(dataNeeded).slice(5));
600
600
  remoteHost = {
601
601
  host: buff.readString(hostLength),
602
- port: buff.readUInt16BE()
602
+ port: buff.readUInt16BE(),
603
603
  };
604
604
  // IPv6
605
605
  }
606
606
  else if (addressType === constants_1.Socks5HostType.IPv6) {
607
607
  // Check if data is available.
608
608
  const dataNeeded = constants_1.SOCKS_INCOMING_PACKET_SIZES.Socks5ResponseIPv6;
609
- if (this._receiveBuffer.length < dataNeeded) {
610
- this._nextRequiredPacketBufferSize = dataNeeded;
609
+ if (this.receiveBuffer.length < dataNeeded) {
610
+ this.nextRequiredPacketBufferSize = dataNeeded;
611
611
  return;
612
612
  }
613
- buff = smart_buffer_1.SmartBuffer.fromBuffer(this._receiveBuffer.get(dataNeeded).slice(4));
613
+ buff = smart_buffer_1.SmartBuffer.fromBuffer(this.receiveBuffer.get(dataNeeded).slice(4));
614
614
  remoteHost = {
615
615
  host: ip.toString(buff.readBuffer(16)),
616
- port: buff.readUInt16BE()
616
+ port: buff.readUInt16BE(),
617
617
  };
618
618
  }
619
619
  // We have everything we need
620
- this.state = constants_1.SocksClientState.ReceivedFinalResponse;
620
+ this.setState(constants_1.SocksClientState.ReceivedFinalResponse);
621
621
  // If using CONNECT, the client is now in the established state.
622
- if (constants_1.SocksCommand[this._options.command] === constants_1.SocksCommand.connect) {
623
- this.state = constants_1.SocksClientState.Established;
622
+ if (constants_1.SocksCommand[this.options.command] === constants_1.SocksCommand.connect) {
623
+ this.setState(constants_1.SocksClientState.Established);
624
624
  this.removeInternalSocketHandlers();
625
- this.emit('established', { socket: this._socket });
625
+ this.emit('established', { socket: this.socket });
626
626
  }
627
- else if (constants_1.SocksCommand[this._options.command] === constants_1.SocksCommand.bind) {
627
+ else if (constants_1.SocksCommand[this.options.command] === constants_1.SocksCommand.bind) {
628
628
  /* If using BIND, the Socks client is now in BoundWaitingForConnection state.
629
629
  This means that the remote proxy server is waiting for a remote connection to the bound port. */
630
- this.state = constants_1.SocksClientState.BoundWaitingForConnection;
631
- this._nextRequiredPacketBufferSize =
630
+ this.setState(constants_1.SocksClientState.BoundWaitingForConnection);
631
+ this.nextRequiredPacketBufferSize =
632
632
  constants_1.SOCKS_INCOMING_PACKET_SIZES.Socks5ResponseHeader;
633
- this.emit('bound', { socket: this._socket, remoteHost });
633
+ this.emit('bound', { remoteHost, socket: this.socket });
634
634
  /*
635
635
  If using Associate, the Socks client is now Established. And the proxy server is now accepting UDP packets at the
636
636
  given bound port. This initial Socks TCP connection must remain open for the UDP relay to continue to work.
637
637
  */
638
638
  }
639
- else if (constants_1.SocksCommand[this._options.command] === constants_1.SocksCommand.associate) {
640
- this.state = constants_1.SocksClientState.Established;
639
+ else if (constants_1.SocksCommand[this.options.command] === constants_1.SocksCommand.associate) {
640
+ this.setState(constants_1.SocksClientState.Established);
641
641
  this.removeInternalSocketHandlers();
642
- this.emit('established', { socket: this._socket, remoteHost });
642
+ this.emit('established', {
643
+ remoteHost,
644
+ socket: this.socket,
645
+ });
643
646
  }
644
647
  }
645
648
  }
@@ -648,9 +651,9 @@ class SocksClient extends events_1.EventEmitter {
648
651
  */
649
652
  handleSocks5IncomingConnectionResponse() {
650
653
  // Peek at available data (we need at least 5 bytes to get the hostname length)
651
- const header = this._receiveBuffer.peek(5);
654
+ const header = this.receiveBuffer.peek(5);
652
655
  if (header[0] !== 0x05 || header[1] !== constants_1.Socks5Response.Granted) {
653
- this._closeSocket(`${constants_1.ERRORS.Socks5ProxyRejectedIncomingBoundConnection} - ${constants_1.Socks5Response[header[1]]}`);
656
+ this.closeSocket(`${constants_1.ERRORS.Socks5ProxyRejectedIncomingBoundConnection} - ${constants_1.Socks5Response[header[1]]}`);
654
657
  }
655
658
  else {
656
659
  // Read address type
@@ -661,18 +664,18 @@ class SocksClient extends events_1.EventEmitter {
661
664
  if (addressType === constants_1.Socks5HostType.IPv4) {
662
665
  // Check if data is available.
663
666
  const dataNeeded = constants_1.SOCKS_INCOMING_PACKET_SIZES.Socks5ResponseIPv4;
664
- if (this._receiveBuffer.length < dataNeeded) {
665
- this._nextRequiredPacketBufferSize = dataNeeded;
667
+ if (this.receiveBuffer.length < dataNeeded) {
668
+ this.nextRequiredPacketBufferSize = dataNeeded;
666
669
  return;
667
670
  }
668
- buff = smart_buffer_1.SmartBuffer.fromBuffer(this._receiveBuffer.get(dataNeeded).slice(4));
671
+ buff = smart_buffer_1.SmartBuffer.fromBuffer(this.receiveBuffer.get(dataNeeded).slice(4));
669
672
  remoteHost = {
670
673
  host: ip.fromLong(buff.readUInt32BE()),
671
- port: buff.readUInt16BE()
674
+ port: buff.readUInt16BE(),
672
675
  };
673
676
  // If given host is 0.0.0.0, assume remote proxy ip instead.
674
677
  if (remoteHost.host === '0.0.0.0') {
675
- remoteHost.host = this._options.proxy.ipaddress;
678
+ remoteHost.host = this.options.proxy.ipaddress;
676
679
  }
677
680
  // Hostname
678
681
  }
@@ -680,38 +683,37 @@ class SocksClient extends events_1.EventEmitter {
680
683
  const hostLength = header[4];
681
684
  const dataNeeded = constants_1.SOCKS_INCOMING_PACKET_SIZES.Socks5ResponseHostname(hostLength); // header + host length + port
682
685
  // Check if data is available.
683
- if (this._receiveBuffer.length < dataNeeded) {
684
- this._nextRequiredPacketBufferSize = dataNeeded;
686
+ if (this.receiveBuffer.length < dataNeeded) {
687
+ this.nextRequiredPacketBufferSize = dataNeeded;
685
688
  return;
686
689
  }
687
- buff = smart_buffer_1.SmartBuffer.fromBuffer(this._receiveBuffer.get(dataNeeded).slice(5) // Slice at 5 to skip host length
688
- );
690
+ buff = smart_buffer_1.SmartBuffer.fromBuffer(this.receiveBuffer.get(dataNeeded).slice(5));
689
691
  remoteHost = {
690
692
  host: buff.readString(hostLength),
691
- port: buff.readUInt16BE()
693
+ port: buff.readUInt16BE(),
692
694
  };
693
695
  // IPv6
694
696
  }
695
697
  else if (addressType === constants_1.Socks5HostType.IPv6) {
696
698
  // Check if data is available.
697
699
  const dataNeeded = constants_1.SOCKS_INCOMING_PACKET_SIZES.Socks5ResponseIPv6;
698
- if (this._receiveBuffer.length < dataNeeded) {
699
- this._nextRequiredPacketBufferSize = dataNeeded;
700
+ if (this.receiveBuffer.length < dataNeeded) {
701
+ this.nextRequiredPacketBufferSize = dataNeeded;
700
702
  return;
701
703
  }
702
- buff = smart_buffer_1.SmartBuffer.fromBuffer(this._receiveBuffer.get(dataNeeded).slice(4));
704
+ buff = smart_buffer_1.SmartBuffer.fromBuffer(this.receiveBuffer.get(dataNeeded).slice(4));
703
705
  remoteHost = {
704
706
  host: ip.toString(buff.readBuffer(16)),
705
- port: buff.readUInt16BE()
707
+ port: buff.readUInt16BE(),
706
708
  };
707
709
  }
708
- this.state = constants_1.SocksClientState.Established;
710
+ this.setState(constants_1.SocksClientState.Established);
709
711
  this.removeInternalSocketHandlers();
710
- this.emit('established', { socket: this._socket, remoteHost });
712
+ this.emit('established', { remoteHost, socket: this.socket });
711
713
  }
712
714
  }
713
715
  get socksClientOptions() {
714
- return Object.assign({}, this._options);
716
+ return Object.assign({}, this.options);
715
717
  }
716
718
  }
717
719
  exports.SocksClient = SocksClient;