source: trip-planner-front/node_modules/socks/README.md@ 6c1585f

Last change on this file since 6c1585f was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 22.7 KB
RevLine 
[6a3a178]1# socks [![Build Status](https://travis-ci.org/JoshGlazebrook/socks.svg?branch=master)](https://travis-ci.org/JoshGlazebrook/socks) [![Coverage Status](https://coveralls.io/repos/github/JoshGlazebrook/socks/badge.svg?branch=master)](https://coveralls.io/github/JoshGlazebrook/socks?branch=v2)
2
3Fully featured SOCKS proxy client supporting SOCKSv4, SOCKSv4a, and SOCKSv5. Includes Bind and Associate functionality.
4
5### Features
6
7* Supports SOCKS v4, v4a, v5, and v5h protocols.
8* Supports the CONNECT, BIND, and ASSOCIATE commands.
9* Supports callbacks, promises, and events for proxy connection creation async flow control.
10* Supports proxy chaining (CONNECT only).
11* Supports user/password authentication.
12* Supports custom authentication.
13* Built in UDP frame creation & parse functions.
14* Created with TypeScript, type definitions are provided.
15
16### Requirements
17
18* Node.js v10.0+ (Please use [v1](https://github.com/JoshGlazebrook/socks/tree/82d83923ad960693d8b774cafe17443ded7ed584) for older versions of Node.js)
19
20### Looking for v1?
21* Docs for v1 are available [here](https://github.com/JoshGlazebrook/socks/tree/82d83923ad960693d8b774cafe17443ded7ed584)
22
23## Installation
24
25`yarn add socks`
26
27or
28
29`npm install --save socks`
30
31## Usage
32
33```typescript
34// TypeScript
35import { SocksClient, SocksClientOptions, SocksClientChainOptions } from 'socks';
36
37// ES6 JavaScript
38import { SocksClient } from 'socks';
39
40// Legacy JavaScript
41const SocksClient = require('socks').SocksClient;
42```
43
44## Quick Start Example
45
46Connect to github.com (192.30.253.113) on port 80, using a SOCKS proxy.
47
48```javascript
49const options = {
50 proxy: {
51 host: '159.203.75.200', // ipv4 or ipv6 or hostname
52 port: 1080,
53 type: 5 // Proxy version (4 or 5)
54 },
55
56 command: 'connect', // SOCKS command (createConnection factory function only supports the connect command)
57
58 destination: {
59 host: '192.30.253.113', // github.com (hostname lookups are supported with SOCKS v4a and 5)
60 port: 80
61 }
62};
63
64// Async/Await
65try {
66 const info = await SocksClient.createConnection(options);
67
68 console.log(info.socket);
69 // <Socket ...> (this is a raw net.Socket that is established to the destination host through the given proxy server)
70} catch (err) {
71 // Handle errors
72}
73
74// Promises
75SocksClient.createConnection(options)
76.then(info => {
77 console.log(info.socket);
78 // <Socket ...> (this is a raw net.Socket that is established to the destination host through the given proxy server)
79})
80.catch(err => {
81 // Handle errors
82});
83
84// Callbacks
85SocksClient.createConnection(options, (err, info) => {
86 if (!err) {
87 console.log(info.socket);
88 // <Socket ...> (this is a raw net.Socket that is established to the destination host through the given proxy server)
89 } else {
90 // Handle errors
91 }
92});
93```
94
95## Chaining Proxies
96
97**Note:** Chaining is only supported when using the SOCKS connect command, and chaining can only be done through the special factory chaining function.
98
99This example makes a proxy chain through two SOCKS proxies to ip-api.com. Once the connection to the destination is established it sends an HTTP request to get a JSON response that returns ip info for the requesting ip.
100
101```javascript
102const options = {
103 destination: {
104 host: 'ip-api.com', // host names are supported with SOCKS v4a and SOCKS v5.
105 port: 80
106 },
107 command: 'connect', // Only the connect command is supported when chaining proxies.
108 proxies: [ // The chain order is the order in the proxies array, meaning the last proxy will establish a connection to the destination.
109 {
110 host: '159.203.75.235', // ipv4, ipv6, or hostname
111 port: 1081,
112 type: 5
113 },
114 {
115 host: '104.131.124.203', // ipv4, ipv6, or hostname
116 port: 1081,
117 type: 5
118 }
119 ]
120}
121
122// Async/Await
123try {
124 const info = await SocksClient.createConnectionChain(options);
125
126 console.log(info.socket);
127 // <Socket ...> (this is a raw net.Socket that is established to the destination host through the given proxy servers)
128
129 console.log(info.socket.remoteAddress) // The remote address of the returned socket is the first proxy in the chain.
130 // 159.203.75.235
131
132 info.socket.write('GET /json HTTP/1.1\nHost: ip-api.com\n\n');
133 info.socket.on('data', (data) => {
134 console.log(data.toString()); // ip-api.com sees that the last proxy in the chain (104.131.124.203) is connected to it.
135 /*
136 HTTP/1.1 200 OK
137 Access-Control-Allow-Origin: *
138 Content-Type: application/json; charset=utf-8
139 Date: Sun, 24 Dec 2017 03:47:51 GMT
140 Content-Length: 300
141
142 {
143 "as":"AS14061 Digital Ocean, Inc.",
144 "city":"Clifton",
145 "country":"United States",
146 "countryCode":"US",
147 "isp":"Digital Ocean",
148 "lat":40.8326,
149 "lon":-74.1307,
150 "org":"Digital Ocean",
151 "query":"104.131.124.203",
152 "region":"NJ",
153 "regionName":"New Jersey",
154 "status":"success",
155 "timezone":"America/New_York",
156 "zip":"07014"
157 }
158 */
159 });
160} catch (err) {
161 // Handle errors
162}
163
164// Promises
165SocksClient.createConnectionChain(options)
166.then(info => {
167 console.log(info.socket);
168 // <Socket ...> (this is a raw net.Socket that is established to the destination host through the given proxy server)
169
170 console.log(info.socket.remoteAddress) // The remote address of the returned socket is the first proxy in the chain.
171 // 159.203.75.235
172
173 info.socket.write('GET /json HTTP/1.1\nHost: ip-api.com\n\n');
174 info.socket.on('data', (data) => {
175 console.log(data.toString()); // ip-api.com sees that the last proxy in the chain (104.131.124.203) is connected to it.
176 /*
177 HTTP/1.1 200 OK
178 Access-Control-Allow-Origin: *
179 Content-Type: application/json; charset=utf-8
180 Date: Sun, 24 Dec 2017 03:47:51 GMT
181 Content-Length: 300
182
183 {
184 "as":"AS14061 Digital Ocean, Inc.",
185 "city":"Clifton",
186 "country":"United States",
187 "countryCode":"US",
188 "isp":"Digital Ocean",
189 "lat":40.8326,
190 "lon":-74.1307,
191 "org":"Digital Ocean",
192 "query":"104.131.124.203",
193 "region":"NJ",
194 "regionName":"New Jersey",
195 "status":"success",
196 "timezone":"America/New_York",
197 "zip":"07014"
198 }
199 */
200 });
201})
202.catch(err => {
203 // Handle errors
204});
205
206// Callbacks
207SocksClient.createConnectionChain(options, (err, info) => {
208 if (!err) {
209 console.log(info.socket);
210 // <Socket ...> (this is a raw net.Socket that is established to the destination host through the given proxy server)
211
212 console.log(info.socket.remoteAddress) // The remote address of the returned socket is the first proxy in the chain.
213 // 159.203.75.235
214
215 info.socket.write('GET /json HTTP/1.1\nHost: ip-api.com\n\n');
216 info.socket.on('data', (data) => {
217 console.log(data.toString()); // ip-api.com sees that the last proxy in the chain (104.131.124.203) is connected to it.
218 /*
219 HTTP/1.1 200 OK
220 Access-Control-Allow-Origin: *
221 Content-Type: application/json; charset=utf-8
222 Date: Sun, 24 Dec 2017 03:47:51 GMT
223 Content-Length: 300
224
225 {
226 "as":"AS14061 Digital Ocean, Inc.",
227 "city":"Clifton",
228 "country":"United States",
229 "countryCode":"US",
230 "isp":"Digital Ocean",
231 "lat":40.8326,
232 "lon":-74.1307,
233 "org":"Digital Ocean",
234 "query":"104.131.124.203",
235 "region":"NJ",
236 "regionName":"New Jersey",
237 "status":"success",
238 "timezone":"America/New_York",
239 "zip":"07014"
240 }
241 */
242 });
243 } else {
244 // Handle errors
245 }
246});
247```
248
249## Bind Example (TCP Relay)
250
251When the bind command is sent to a SOCKS v4/v5 proxy server, the proxy server starts listening on a new TCP port and the proxy relays then remote host information back to the client. When another remote client connects to the proxy server on this port the SOCKS proxy sends a notification that an incoming connection has been accepted to the initial client and a full duplex stream is now established to the initial client and the client that connected to that special port.
252
253```javascript
254const options = {
255 proxy: {
256 host: '159.203.75.235', // ipv4, ipv6, or hostname
257 port: 1081,
258 type: 5
259 },
260
261 command: 'bind',
262
263 // When using BIND, the destination should be the remote client that is expected to connect to the SOCKS proxy. Using 0.0.0.0 makes the Proxy accept any incoming connection on that port.
264 destination: {
265 host: '0.0.0.0',
266 port: 0
267 }
268};
269
270// Creates a new SocksClient instance.
271const client = new SocksClient(options);
272
273// When the SOCKS proxy has bound a new port and started listening, this event is fired.
274client.on('bound', info => {
275 console.log(info.remoteHost);
276 /*
277 {
278 host: "159.203.75.235",
279 port: 57362
280 }
281 */
282});
283
284// When a client connects to the newly bound port on the SOCKS proxy, this event is fired.
285client.on('established', info => {
286 // info.remoteHost is the remote address of the client that connected to the SOCKS proxy.
287 console.log(info.remoteHost);
288 /*
289 host: 67.171.34.23,
290 port: 49823
291 */
292
293 console.log(info.socket);
294 // <Socket ...> (This is a raw net.Socket that is a connection between the initial client and the remote client that connected to the proxy)
295
296 // Handle received data...
297 info.socket.on('data', data => {
298 console.log('recv', data);
299 });
300});
301
302// An error occurred trying to establish this SOCKS connection.
303client.on('error', err => {
304 console.error(err);
305});
306
307// Start connection to proxy
308client.connect();
309```
310
311## Associate Example (UDP Relay)
312
313When the associate command is sent to a SOCKS v5 proxy server, it sets up a UDP relay that allows the client to send UDP packets to a remote host through the proxy server, and also receive UDP packet responses back through the proxy server.
314
315```javascript
316const options = {
317 proxy: {
318 host: '159.203.75.235', // ipv4, ipv6, or hostname
319 port: 1081,
320 type: 5
321 },
322
323 command: 'associate',
324
325 // When using associate, the destination should be the remote client that is expected to send UDP packets to the proxy server to be forwarded. This should be your local ip, or optionally the wildcard address (0.0.0.0) UDP Client <-> Proxy <-> UDP Client
326 destination: {
327 host: '0.0.0.0',
328 port: 0
329 }
330};
331
332// Create a local UDP socket for sending packets to the proxy.
333const udpSocket = dgram.createSocket('udp4');
334udpSocket.bind();
335
336// Listen for incoming UDP packets from the proxy server.
337udpSocket.on('message', (message, rinfo) => {
338 console.log(SocksClient.parseUDPFrame(message));
339 /*
340 { frameNumber: 0,
341 remoteHost: { host: '165.227.108.231', port: 4444 }, // The remote host that replied with a UDP packet
342 data: <Buffer 74 65 73 74 0a> // The data
343 }
344 */
345});
346
347let client = new SocksClient(associateOptions);
348
349// When the UDP relay is established, this event is fired and includes the UDP relay port to send data to on the proxy server.
350client.on('established', info => {
351 console.log(info.remoteHost);
352 /*
353 {
354 host: '159.203.75.235',
355 port: 44711
356 }
357 */
358
359 // Send 'hello' to 165.227.108.231:4444
360 const packet = SocksClient.createUDPFrame({
361 remoteHost: { host: '165.227.108.231', port: 4444 },
362 data: Buffer.from(line)
363 });
364 udpSocket.send(packet, info.remoteHost.port, info.remoteHost.host);
365});
366
367// Start connection
368client.connect();
369```
370
371**Note:** The associate TCP connection to the proxy must remain open for the UDP relay to work.
372
373## Additional Examples
374
375[Documentation](docs/index.md)
376
377
378## Migrating from v1
379
380Looking for a guide to migrate from v1? Look [here](docs/migratingFromV1.md)
381
382## Api Reference:
383
384**Note:** socks includes full TypeScript definitions. These can even be used without using TypeScript as most IDEs (such as VS Code) will use these type definition files for auto completion intellisense even in JavaScript files.
385
386* Class: SocksClient
387 * [new SocksClient(options[, callback])](#new-socksclientoptions)
388 * [Class Method: SocksClient.createConnection(options[, callback])](#class-method-socksclientcreateconnectionoptions-callback)
389 * [Class Method: SocksClient.createConnectionChain(options[, callback])](#class-method-socksclientcreateconnectionchainoptions-callback)
390 * [Class Method: SocksClient.createUDPFrame(options)](#class-method-socksclientcreateudpframedetails)
391 * [Class Method: SocksClient.parseUDPFrame(data)](#class-method-socksclientparseudpframedata)
392 * [Event: 'error'](#event-error)
393 * [Event: 'bound'](#event-bound)
394 * [Event: 'established'](#event-established)
395 * [client.connect()](#clientconnect)
396 * [client.socksClientOptions](#clientconnect)
397
398### SocksClient
399
400SocksClient establishes SOCKS proxy connections to remote destination hosts. These proxy connections are fully transparent to the server and once established act as full duplex streams. SOCKS v4, v4a, v5, and v5h are supported, as well as the connect, bind, and associate commands.
401
402SocksClient supports creating connections using callbacks, promises, and async/await flow control using two static factory functions createConnection and createConnectionChain. It also internally extends EventEmitter which results in allowing event handling based async flow control.
403
404**SOCKS Compatibility Table**
405
406Note: When using 4a please specify type: 4, and when using 5h please specify type 5.
407
408| Socks Version | TCP | UDP | IPv4 | IPv6 | Hostname |
409| --- | :---: | :---: | :---: | :---: | :---: |
410| SOCKS v4 | ✅ | ❌ | ✅ | ❌ | ❌ |
411| SOCKS v4a | ✅ | ❌ | ✅ | ❌ | ✅ |
412| SOCKS v5 (includes v5h) | ✅ | ✅ | ✅ | ✅ | ✅ |
413
414### new SocksClient(options)
415
416* ```options``` {SocksClientOptions} - An object describing the SOCKS proxy to use, the command to send and establish, and the destination host to connect to.
417
418### SocksClientOptions
419
420```typescript
421{
422 proxy: {
423 host: '159.203.75.200', // ipv4, ipv6, or hostname
424 port: 1080,
425 type: 5 // Proxy version (4 or 5). For v4a use 4, for v5h use 5.
426
427 // Optional fields
428 userId: 'some username', // Used for SOCKS4 userId auth, and SOCKS5 user/pass auth in conjunction with password.
429 password: 'some password', // Used in conjunction with userId for user/pass auth for SOCKS5 proxies.
430 custom_auth_method: 0x80, // If using a custom auth method, specify the type here. If this is set, ALL other custom_auth_*** options must be set as well.
431 custom_auth_request_handler: async () =>. {
432 // This will be called when it's time to send the custom auth handshake. You must return a Buffer containing the data to send as your authentication.
433 return Buffer.from([0x01,0x02,0x03]);
434 },
435 // This is the expected size (bytes) of the custom auth response from the proxy server.
436 custom_auth_response_size: 2,
437 // This is called when the auth response is received. The received packet is passed in as a Buffer, and you must return a boolean indicating the response from the server said your custom auth was successful or failed.
438 custom_auth_response_handler: async (data) => {
439 return data[1] === 0x00;
440 }
441 },
442
443 command: 'connect', // connect, bind, associate
444
445 destination: {
446 host: '192.30.253.113', // ipv4, ipv6, hostname. Hostnames work with v4a and v5.
447 port: 80
448 },
449
450 // Optional fields
451 timeout: 30000, // How long to wait to establish a proxy connection. (defaults to 30 seconds)
452
453 set_tcp_nodelay: true // If true, will turn on the underlying sockets TCP_NODELAY option.
454}
455```
456
457### Class Method: SocksClient.createConnection(options[, callback])
458* ```options``` { SocksClientOptions } - An object describing the SOCKS proxy to use, the command to send and establish, and the destination host to connect to.
459* ```callback``` { Function } - Optional callback function that is called when the proxy connection is established, or an error occurs.
460* ```returns``` { Promise } - A Promise is returned that is resolved when the proxy connection is established, or rejected when an error occurs.
461
462Creates a new proxy connection through the given proxy to the given destination host. This factory function supports callbacks and promises for async flow control.
463
464**Note:** If a callback function is provided, the promise will always resolve regardless of an error occurring. Please be sure to exclusively use either promises or callbacks when using this factory function.
465
466```typescript
467const options = {
468 proxy: {
469 host: '159.203.75.200', // ipv4, ipv6, or hostname
470 port: 1080,
471 type: 5 // Proxy version (4 or 5)
472 },
473
474 command: 'connect', // connect, bind, associate
475
476 destination: {
477 host: '192.30.253.113', // ipv4, ipv6, or hostname
478 port: 80
479 }
480}
481
482// Await/Async (uses a Promise)
483try {
484 const info = await SocksClient.createConnection(options);
485 console.log(info);
486 /*
487 {
488 socket: <Socket ...>, // Raw net.Socket
489 }
490 */
491 / <Socket ...> (this is a raw net.Socket that is established to the destination host through the given proxy server)
492
493} catch (err) {
494 // Handle error...
495}
496
497// Promise
498SocksClient.createConnection(options)
499.then(info => {
500 console.log(info);
501 /*
502 {
503 socket: <Socket ...>, // Raw net.Socket
504 }
505 */
506})
507.catch(err => {
508 // Handle error...
509});
510
511// Callback
512SocksClient.createConnection(options, (err, info) => {
513 if (!err) {
514 console.log(info);
515 /*
516 {
517 socket: <Socket ...>, // Raw net.Socket
518 }
519 */
520 } else {
521 // Handle error...
522 }
523});
524```
525
526### Class Method: SocksClient.createConnectionChain(options[, callback])
527* ```options``` { SocksClientChainOptions } - An object describing a list of SOCKS proxies to use, the command to send and establish, and the destination host to connect to.
528* ```callback``` { Function } - Optional callback function that is called when the proxy connection chain is established, or an error occurs.
529* ```returns``` { Promise } - A Promise is returned that is resolved when the proxy connection chain is established, or rejected when an error occurs.
530
531Creates a new proxy connection chain through a list of at least two SOCKS proxies to the given destination host. This factory method supports callbacks and promises for async flow control.
532
533**Note:** If a callback function is provided, the promise will always resolve regardless of an error occurring. Please be sure to exclusively use either promises or callbacks when using this factory function.
534
535**Note:** At least two proxies must be provided for the chain to be established.
536
537```typescript
538const options = {
539 proxies: [ // The chain order is the order in the proxies array, meaning the last proxy will establish a connection to the destination.
540 {
541 host: '159.203.75.235', // ipv4, ipv6, or hostname
542 port: 1081,
543 type: 5
544 },
545 {
546 host: '104.131.124.203', // ipv4, ipv6, or hostname
547 port: 1081,
548 type: 5
549 }
550 ]
551
552 command: 'connect', // Only connect is supported in chaining mode.
553
554 destination: {
555 host: '192.30.253.113', // ipv4, ipv6, hostname
556 port: 80
557 }
558}
559```
560
561### Class Method: SocksClient.createUDPFrame(details)
562* ```details``` { SocksUDPFrameDetails } - An object containing the remote host, frame number, and frame data to use when creating a SOCKS UDP frame packet.
563* ```returns``` { Buffer } - A Buffer containing all of the UDP frame data.
564
565Creates a SOCKS UDP frame relay packet that is sent and received via a SOCKS proxy when using the associate command for UDP packet forwarding.
566
567**SocksUDPFrameDetails**
568
569```typescript
570{
571 frameNumber: 0, // The frame number (used for breaking up larger packets)
572
573 remoteHost: { // The remote host to have the proxy send data to, or the remote host that send this data.
574 host: '1.2.3.4',
575 port: 1234
576 },
577
578 data: <Buffer 01 02 03 04...> // A Buffer instance of data to include in the packet (actual data sent to the remote host)
579}
580interface SocksUDPFrameDetails {
581 // The frame number of the packet.
582 frameNumber?: number;
583
584 // The remote host.
585 remoteHost: SocksRemoteHost;
586
587 // The packet data.
588 data: Buffer;
589}
590```
591
592### Class Method: SocksClient.parseUDPFrame(data)
593* ```data``` { Buffer } - A Buffer instance containing SOCKS UDP frame data to parse.
594* ```returns``` { SocksUDPFrameDetails } - An object containing the remote host, frame number, and frame data of the SOCKS UDP frame.
595
596```typescript
597const frame = SocksClient.parseUDPFrame(data);
598console.log(frame);
599/*
600{
601 frameNumber: 0,
602 remoteHost: {
603 host: '1.2.3.4',
604 port: 1234
605 },
606 data: <Buffer 01 02 03 04 ...>
607}
608*/
609```
610
611Parses a Buffer instance and returns the parsed SocksUDPFrameDetails object.
612
613## Event: 'error'
614* ```err``` { SocksClientError } - An Error object containing an error message and the original SocksClientOptions.
615
616This event is emitted if an error occurs when trying to establish the proxy connection.
617
618## Event: 'bound'
619* ```info``` { SocksClientBoundEvent } An object containing a Socket and SocksRemoteHost info.
620
621This event is emitted when using the BIND command on a remote SOCKS proxy server. This event indicates the proxy server is now listening for incoming connections on a specified port.
622
623**SocksClientBoundEvent**
624```typescript
625{
626 socket: net.Socket, // The underlying raw Socket
627 remoteHost: {
628 host: '1.2.3.4', // The remote host that is listening (usually the proxy itself)
629 port: 4444 // The remote port the proxy is listening on for incoming connections (when using BIND).
630 }
631}
632```
633
634## Event: 'established'
635* ```info``` { SocksClientEstablishedEvent } An object containing a Socket and SocksRemoteHost info.
636
637This event is emitted when the following conditions are met:
6381. When using the CONNECT command, and a proxy connection has been established to the remote host.
6392. When using the BIND command, and an incoming connection has been accepted by the proxy and a TCP relay has been established.
6403. When using the ASSOCIATE command, and a UDP relay has been established.
641
642When using BIND, 'bound' is first emitted to indicate the SOCKS server is waiting for an incoming connection, and provides the remote port the SOCKS server is listening on.
643
644When using ASSOCIATE, 'established' is emitted with the remote UDP port the SOCKS server is accepting UDP frame packets on.
645
646**SocksClientEstablishedEvent**
647```typescript
648{
649 socket: net.Socket, // The underlying raw Socket
650 remoteHost: {
651 host: '1.2.3.4', // The remote host that is listening (usually the proxy itself)
652 port: 52738 // The remote port the proxy is listening on for incoming connections (when using BIND).
653 }
654}
655```
656
657## client.connect()
658
659Starts connecting to the remote SOCKS proxy server to establish a proxy connection to the destination host.
660
661## client.socksClientOptions
662* ```returns``` { SocksClientOptions } The options that were passed to the SocksClient.
663
664Gets the options that were passed to the SocksClient when it was created.
665
666
667**SocksClientError**
668```typescript
669{ // Subclassed from Error.
670 message: 'An error has occurred',
671 options: {
672 // SocksClientOptions
673 }
674}
675```
676
677# Further Reading:
678
679Please read the SOCKS 5 specifications for more information on how to use BIND and Associate.
680http://www.ietf.org/rfc/rfc1928.txt
681
682# License
683
684This work is licensed under the [MIT license](http://en.wikipedia.org/wiki/MIT_License).
Note: See TracBrowser for help on using the repository browser.