Compare commits
	
		
			No commits in common. "b8c423edca834d8787a5ccd4a7fb02be59118967" and "175286e791005c96a94cb05ff4163d9c0be02694" have entirely different histories.
		
	
	
		
			b8c423edca
			...
			175286e791
		
	
		
							
								
								
									
										137
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										137
									
								
								README.md
									
									
									
									
									
								
							| @ -2,129 +2,32 @@ | |||||||
| 
 | 
 | ||||||
| | Sponsored by [ppl](https://ppl.family) | | | Sponsored by [ppl](https://ppl.family) | | ||||||
| 
 | 
 | ||||||
| "The M-PROXY Protocol" for node.js | A strategy for packing and unpacking tunneled network messages (or any stream) in node.js | ||||||
| 
 | 
 | ||||||
| A strategy for packing and unpacking multiplexed streams. | Examples | ||||||
| <small>Where you have distinct clients on one side trying to reach distinct servers on the other.</small> |  | ||||||
| 
 |  | ||||||
| ``` |  | ||||||
| Browser <--\                   /--> Device |  | ||||||
| Browser <---- M-PROXY Service ----> Device |  | ||||||
| Browser <--/                   \--> Device |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| <small>Many clients may connect to a single device. A single client may connect to many devices.</small> |  | ||||||
| 
 |  | ||||||
| It's the kind of thing you'd use to build a poor man's VPN, or port-forward router. |  | ||||||
| 
 |  | ||||||
| The M-PROXY Protocol |  | ||||||
| =================== |  | ||||||
| 
 |  | ||||||
| This is similar to "The PROXY Protocol" (a la HAProxy), but desgined for multiplexed tls, http, tcp, and udp |  | ||||||
| tunneled over arbitrary streams (such as WebSockets). |  | ||||||
| 
 |  | ||||||
| It also has a backchannel for communicating with the proxy itself. |  | ||||||
| 
 |  | ||||||
| Each message has a header with a socket identifier (family, addr, port), and may have additional information. |  | ||||||
| 
 |  | ||||||
| ``` |  | ||||||
| <version><headerlen><family>,<address>,<port>,<datalen>,<service>,<port>,<name> |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| ``` |  | ||||||
| <254><45>IPv4,127.0.1.1,4321,199,https,443,example.com |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| ``` |  | ||||||
| version                  (8 bits) 254 is version 1 |  | ||||||
| 
 |  | ||||||
| header length            (8 bits) the remaining length of the header before data begins |  | ||||||
| 
 |  | ||||||
|                                   These values are used to identify a specific client among many |  | ||||||
| socket family            (string) the IPv4 or IPv6 connection from a client |  | ||||||
| socket address           (string) the x.x.x.x remote address of the client |  | ||||||
| socket port              (string) the 1-65536 source port of the remote client |  | ||||||
| 
 |  | ||||||
| data length              (string) the number of bytes in the wrapped packet, in case the network re-chunks the packet |  | ||||||
| 
 |  | ||||||
|                                   These optional values can be very useful at the start of a new connection |  | ||||||
| service name             (string) Either a standard service name (port + protocol), such as 'https' |  | ||||||
|                                   as listed in /etc/services, otherwise 'tls', 'tcp', or 'udp' for generics |  | ||||||
|                                   Also used for messages with the proxy (i.e. authentication) |  | ||||||
|                                     * 'control' for authentication, etc |  | ||||||
|                                     * 'error' for a specific client |  | ||||||
|                                     * 'pause' to pause upload to a specific client (not the whole tunnel) |  | ||||||
|                                     * 'resume' to resume upload to a specific client (not the whole tunnel) |  | ||||||
| service port             (string) The listening port, such as 443. Useful for non-standard or dynamic services. |  | ||||||
| host or server name      (string) Useful for services that can be routed by name, such as http, https, smtp, and dns. |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| v1 is text-based. Future versions may be binary. |  | ||||||
| 
 |  | ||||||
| API |  | ||||||
| === |  | ||||||
| 
 | 
 | ||||||
| ```js | ```js | ||||||
| var Packer = require('proxy-packer'); | var Packer = require('proxy-packer'); | ||||||
| ``` |  | ||||||
| 
 | 
 | ||||||
| ```js | Packer.create({ | ||||||
| unpacker = Packer.create(handlers);                       // Create a state machine for unpacking |   onmessage: function (msg) { | ||||||
| 
 |     // msg = { family, address, port, service, data }; | ||||||
| handlers.oncontrol = function (tun) { }                   // for communicating with the proxy |   } | ||||||
|                                                           // tun.data is an array | , onend: function (msg) { | ||||||
|                                                           //     '[ -1, "[Error] bad hello" ]' |     // msg = { family, address, port }; | ||||||
|                                                           //     '[ 0, "[Error] out-of-band error message" ]' |   } | ||||||
|                                                           //     '[ 1, "hello", 254, [ "add_token", "delete_token" ] ]' | , onerror: function (err) { | ||||||
|                                                           //     '[ 1, "add_token" ]' |  | ||||||
|                                                           //     '[ 1, "delete_token" ]' |  | ||||||
| 
 |  | ||||||
| handlers.onmessage = function (tun) { }                   // a client has sent a message |  | ||||||
|                                                           // tun = { family, address, port, data |  | ||||||
|                                                           //       , service, serviceport, name }; |  | ||||||
| 
 |  | ||||||
| handlers.onpause = function (tun) { }                     // proxy requests to pause upload to a client |  | ||||||
|                                                           // tun = { family, address, port }; |  | ||||||
| 
 |  | ||||||
| handlers.onresume = function (tun) { }                    // proxy requests to resume upload to a client |  | ||||||
|                                                           // tun = { family, address, port }; |  | ||||||
| 
 |  | ||||||
| handlers.onend = function (tun) { }                       // proxy requests to close a client's socket |  | ||||||
|                                                           // tun = { family, address, port }; |  | ||||||
| 
 |  | ||||||
| handlers.onerror = function (err) { }                     // proxy is relaying a client's error |  | ||||||
|     // err = { message, family, address, port }; |     // err = { message, family, address, port }; | ||||||
| ``` |   } | ||||||
|  | }); | ||||||
| 
 | 
 | ||||||
| <!-- | var chunk = Packer.pack(address, data, service); | ||||||
| TODO | var addr = Packer.socketToAddr(socket); | ||||||
|  | var id = Packer.addrToId(address); | ||||||
|  | var id = Packer.socketToId(socket); | ||||||
| 
 | 
 | ||||||
| handlers.onconnect = function (tun) { }                   // a new client has connected | var myDuplex = Packer.Stream.create(socketOrStream); | ||||||
| 
 | 
 | ||||||
| --> |  | ||||||
| 
 |  | ||||||
| ```js |  | ||||||
| var chunk = Packer.pack(tun, data);                       // Add M-PROXY header to data |  | ||||||
|                                                           // tun = { family, address, port |  | ||||||
|                                                           //       , service, serviceport, name } |  | ||||||
| 
 |  | ||||||
| var addr = Packer.socketToAddr(socket);                   // Probe raw, raw socket for address info |  | ||||||
| 
 |  | ||||||
| var id = Packer.addrToId(address);                        // Turn M-PROXY address info into a deterministic id |  | ||||||
| 
 |  | ||||||
| var id = Packer.socketToId(socket);                       // Turn raw, raw socket info into a deterministic id |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| ## API Helpers |  | ||||||
| 
 |  | ||||||
| ```js |  | ||||||
| var socket = Packer.Stream.wrapSocket(socketOrStream);   // workaround for https://github.com/nodejs/node/issues/8854 |  | ||||||
|                                                          // which was just closed recently, but probably still needs |  | ||||||
|                                                          // something more like this (below) to work as intended |  | ||||||
|                                                          // https://github.com/findhit/proxywrap/blob/master/lib/proxywrap.js |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| ```js |  | ||||||
| var myTransform = Packer.Transform.create({ | var myTransform = Packer.Transform.create({ | ||||||
|   address: { |   address: { | ||||||
|     family: '...' |     family: '...' | ||||||
| @ -142,7 +45,7 @@ If you want to write a compatible packer, just make sure that for any given inpu | |||||||
| you get the same output as the packer does. | you get the same output as the packer does. | ||||||
| 
 | 
 | ||||||
| ```bash | ```bash | ||||||
| node test/pack.js input.json output.bin | node test-pack.js input.json output.bin | ||||||
| hexdump output.bin | hexdump output.bin | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| @ -154,10 +57,8 @@ Where `input.json` looks something like this: | |||||||
| , "address": { | , "address": { | ||||||
|     "family": "IPv4" |     "family": "IPv4" | ||||||
|   , "address": "127.0.1.1" |   , "address": "127.0.1.1" | ||||||
|   , "port": 4321 |   , "port": 443 | ||||||
|   , "service": "foo" |   , "service": "foo" | ||||||
|   , "serviceport": 443 |  | ||||||
|   , "name": 'example.com' |  | ||||||
|   } |   } | ||||||
| , "filepath": "./sni.tcp.bin" | , "filepath": "./sni.tcp.bin" | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										87
									
								
								index.js
									
									
									
									
									
								
							
							
						
						
									
										87
									
								
								index.js
									
									
									
									
									
								
							| @ -120,8 +120,6 @@ Packer.create = function (opts) { | |||||||
|     machine.port    = machine._headers[2]; |     machine.port    = machine._headers[2]; | ||||||
|     machine.bodyLen = parseInt(machine._headers[3], 10) || 0; |     machine.bodyLen = parseInt(machine._headers[3], 10) || 0; | ||||||
|     machine.service = machine._headers[4]; |     machine.service = machine._headers[4]; | ||||||
|     machine.serviceport = machine._headers[5]; |  | ||||||
|     machine.name = machine._headers[6]; |  | ||||||
|     //console.log('machine.service', machine.service);
 |     //console.log('machine.service', machine.service);
 | ||||||
| 
 | 
 | ||||||
|     return true; |     return true; | ||||||
| @ -154,8 +152,6 @@ Packer.create = function (opts) { | |||||||
|     msg.address = machine.address; |     msg.address = machine.address; | ||||||
|     msg.port    = machine.port; |     msg.port    = machine.port; | ||||||
|     msg.service = machine.service; |     msg.service = machine.service; | ||||||
|     msg.serviceport = machine.serviceport; |  | ||||||
|     msg.name        = machine.name; |  | ||||||
|     msg.data    = data; |     msg.data    = data; | ||||||
| 
 | 
 | ||||||
|     if (machine.emit) { |     if (machine.emit) { | ||||||
| @ -186,7 +182,7 @@ Packer.create = function (opts) { | |||||||
|   return machine; |   return machine; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| Packer.pack = function (meta, data, service) { | Packer.pack = function (address, data, service) { | ||||||
|   data = data || Buffer.from(' '); |   data = data || Buffer.from(' '); | ||||||
|   if (!Buffer.isBuffer(data)) { |   if (!Buffer.isBuffer(data)) { | ||||||
|     data = new Buffer(JSON.stringify(data)); |     data = new Buffer(JSON.stringify(data)); | ||||||
| @ -196,7 +192,7 @@ Packer.pack = function (meta, data, service) { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (service && service !== 'control') { |   if (service && service !== 'control') { | ||||||
|     meta.service = service; |     address.service = service; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   var version = 1; |   var version = 1; | ||||||
| @ -206,62 +202,19 @@ Packer.pack = function (meta, data, service) { | |||||||
|   } |   } | ||||||
|   else { |   else { | ||||||
|     header = Buffer.from([ |     header = Buffer.from([ | ||||||
|       meta.family, meta.address, meta.port, data.byteLength, |       address.family, address.address, address.port, data.byteLength, (address.service || '') | ||||||
|       (meta.service || ''), (meta.serviceport || ''), (meta.name || '') |  | ||||||
|     ].join(',')); |     ].join(',')); | ||||||
|   } |   } | ||||||
|   var metaBuf = Buffer.from([ 255 - version, header.length ]); |   var meta = Buffer.from([ 255 - version, header.length ]); | ||||||
|   var buf = Buffer.alloc(metaBuf.byteLength + header.byteLength + data.byteLength); |   var buf = Buffer.alloc(meta.byteLength + header.byteLength + data.byteLength); | ||||||
| 
 | 
 | ||||||
|   metaBuf.copy(buf, 0); |   meta.copy(buf, 0); | ||||||
|   header.copy(buf, 2); |   header.copy(buf, 2); | ||||||
|   data.copy(buf, 2 + header.byteLength); |   data.copy(buf, 2 + header.byteLength); | ||||||
| 
 | 
 | ||||||
|   return buf; |   return buf; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| function extractSocketProps(socket, propNames) { |  | ||||||
|   var props = {}; |  | ||||||
| 
 |  | ||||||
|   if (socket.remotePort) { |  | ||||||
|     propNames.forEach(function (propName) { |  | ||||||
|       props[propName] = socket[propName]; |  | ||||||
|     }); |  | ||||||
|   } else if (socket._remotePort) { |  | ||||||
|     propNames.forEach(function (propName) { |  | ||||||
|       props[propName] = socket['_' + propName]; |  | ||||||
|     }); |  | ||||||
|   } else if ( |  | ||||||
|     socket._handle |  | ||||||
|     && socket._handle._parent |  | ||||||
|     && socket._handle._parent.owner |  | ||||||
|     && socket._handle._parent.owner.stream |  | ||||||
|     && socket._handle._parent.owner.stream.remotePort |  | ||||||
|   ) { |  | ||||||
|     propNames.forEach(function (propName) { |  | ||||||
|       props[propName] = socket._handle._parent.owner.stream[propName]; |  | ||||||
|     }); |  | ||||||
|   } else if ( |  | ||||||
|     socket._handle._parentWrap |  | ||||||
|     && socket._handle._parentWrap |  | ||||||
|     && socket._handle._parentWrap.remotePort |  | ||||||
|   ) { |  | ||||||
|     propNames.forEach(function (propName) { |  | ||||||
|       props[propName] = socket._handle._parentWrap[propName]; |  | ||||||
|     }); |  | ||||||
|   } else if ( |  | ||||||
|     socket._handle._parentWrap |  | ||||||
|     && socket._handle._parentWrap._handle |  | ||||||
|     && socket._handle._parentWrap._handle.owner |  | ||||||
|     && socket._handle._parentWrap._handle.owner.stream |  | ||||||
|     && socket._handle._parentWrap._handle.owner.stream.remotePort |  | ||||||
|   ) { |  | ||||||
|     propNames.forEach(function (propName) { |  | ||||||
|       props[propName] = socket._handle._parentWrap._handle.owner.stream[propName]; |  | ||||||
|     }); |  | ||||||
|   } |  | ||||||
|   return props; |  | ||||||
| } |  | ||||||
| function extractSocketProp(socket, propName) { | function extractSocketProp(socket, propName) { | ||||||
|   // remoteAddress, remotePort... ugh... https://github.com/nodejs/node/issues/8854
 |   // remoteAddress, remotePort... ugh... https://github.com/nodejs/node/issues/8854
 | ||||||
|   var value = socket[propName] || socket['_' + propName]; |   var value = socket[propName] || socket['_' + propName]; | ||||||
| @ -282,12 +235,10 @@ Packer.socketToAddr = function (socket) { | |||||||
|   // tlsSocket.remoteAddress = remoteAddress; // causes core dump
 |   // tlsSocket.remoteAddress = remoteAddress; // causes core dump
 | ||||||
|   // console.log(tlsSocket.remoteAddress);
 |   // console.log(tlsSocket.remoteAddress);
 | ||||||
| 
 | 
 | ||||||
|   var props = extractSocketProps(socket, [ 'remoteFamily', 'remoteAddress', 'remotePort', 'localPort' ]); |  | ||||||
|   return { |   return { | ||||||
|     family:  props.remoteFamily |     family:  extractSocketProp(socket, 'remoteFamily') | ||||||
|   , address: props.remoteAddress |   , address: extractSocketProp(socket, 'remoteAddress') | ||||||
|   , port:    props.remotePort |   , port:    extractSocketProp(socket, 'remotePort') | ||||||
|   , serviceport: props.localPort |  | ||||||
|   }; |   }; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| @ -317,22 +268,9 @@ var sockFuncs = [ | |||||||
| , 'setNoDelay' | , 'setNoDelay' | ||||||
| , 'setTimeout' | , 'setTimeout' | ||||||
| ]; | ]; | ||||||
|  | // Improved workaround for  https://github.com/nodejs/node/issues/8854
 | ||||||
| // Unlike Packer.Stream.create this should handle all of the events needed to make everything work.
 | // Unlike Packer.Stream.create this should handle all of the events needed to make everything work.
 | ||||||
| Packer.wrapSocket = function (socket) { | Packer.wrapSocket = function (socket) { | ||||||
|   // node v10.2+ doesn't need a workaround for  https://github.com/nodejs/node/issues/8854
 |  | ||||||
|   addressNames.forEach(function (name) { |  | ||||||
|     Object.defineProperty(socket, name, { |  | ||||||
|       enumerable: false, |  | ||||||
|       configurable: true, |  | ||||||
|       get: function() { |  | ||||||
|         return extractSocketProp(socket, name); |  | ||||||
|       } |  | ||||||
|     }); |  | ||||||
|   }); |  | ||||||
|   return socket; |  | ||||||
|   // Improved workaround for  https://github.com/nodejs/node/issues/8854
 |  | ||||||
|   /* |  | ||||||
|   // TODO use defineProperty to override remotePort, etc
 |  | ||||||
|   var myDuplex = new require('stream').Duplex(); |   var myDuplex = new require('stream').Duplex(); | ||||||
|   addressNames.forEach(function (name) { |   addressNames.forEach(function (name) { | ||||||
|     myDuplex[name] = extractSocketProp(socket, name); |     myDuplex[name] = extractSocketProp(socket, name); | ||||||
| @ -374,7 +312,6 @@ Packer.wrapSocket = function (socket) { | |||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|   return myDuplex; |   return myDuplex; | ||||||
|   */ |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| var Transform = require('stream').Transform; | var Transform = require('stream').Transform; | ||||||
| @ -386,8 +323,6 @@ function MyTransform(options) { | |||||||
|   } |   } | ||||||
|   this.__my_addr = options.address; |   this.__my_addr = options.address; | ||||||
|   this.__my_service = options.service; |   this.__my_service = options.service; | ||||||
|   this.__my_serviceport = options.serviceport; |  | ||||||
|   this.__my_name = options.name; |  | ||||||
|   Transform.call(this, options); |   Transform.call(this, options); | ||||||
| } | } | ||||||
| util.inherits(MyTransform, Transform); | util.inherits(MyTransform, Transform); | ||||||
| @ -396,8 +331,6 @@ MyTransform.prototype._transform = function (data, encoding, callback) { | |||||||
|   var address = this.__my_addr; |   var address = this.__my_addr; | ||||||
| 
 | 
 | ||||||
|   address.service = address.service || this.__my_service; |   address.service = address.service || this.__my_service; | ||||||
|   address.serviceport = address.serviceport || this.__my_serviceport; |  | ||||||
|   address.name = address.name || this.__my_name; |  | ||||||
|   this.push(Packer.pack(address, data)); |   this.push(Packer.pack(address, data)); | ||||||
|   callback(); |   callback(); | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -2,9 +2,8 @@ | |||||||
| , "address": { | , "address": { | ||||||
|     "family": "IPv4" |     "family": "IPv4" | ||||||
|   , "address": "127.0.1.1" |   , "address": "127.0.1.1" | ||||||
|   , "port": 4321 |   , "port": 443 | ||||||
|   , "service": "https" |   , "service": "foo" | ||||||
|   , "serviceport": 443 |  | ||||||
|   } |   } | ||||||
| , "filepath": "./sni.hello.bin" | , "filepath": "./sni.hello.bin" | ||||||
| } | } | ||||||
										
											Binary file not shown.
										
									
								
							| @ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|   "name": "proxy-packer", |   "name": "proxy-packer", | ||||||
|   "version": "1.4.3", |   "version": "1.4.2", | ||||||
|   "description": "A strategy for packing and unpacking a proxy stream (i.e. packets through a tunnel). Handles multiplexed and tls connections. Used by telebit and telebitd.", |   "description": "A strategy for packing and unpacking a proxy stream (i.e. packets through a tunnel). Handles multiplexed and tls connections. Used by telebit and telebitd.", | ||||||
|   "main": "index.js", |   "main": "index.js", | ||||||
|   "scripts": { |   "scripts": { | ||||||
|  | |||||||
| @ -4,30 +4,24 @@ | |||||||
| var fs = require('fs'); | var fs = require('fs'); | ||||||
| var infile = process.argv[2]; | var infile = process.argv[2]; | ||||||
| var outfile = process.argv[3]; | var outfile = process.argv[3]; | ||||||
| var sni = require('sni'); |  | ||||||
| 
 | 
 | ||||||
| if (!infile || !outfile) { | if (!infile || !outfile) { | ||||||
|   console.error("Usage:"); |   console.error("Usage:"); | ||||||
|   console.error("node test/pack.js test/input.json test/output.bin"); |   console.error("node test-pack.js input.json output.bin"); | ||||||
|   process.exit(1); |   process.exit(1); | ||||||
|   return; |   return; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var path = require('path'); |  | ||||||
| var json = JSON.parse(fs.readFileSync(infile, 'utf8')); | var json = JSON.parse(fs.readFileSync(infile, 'utf8')); | ||||||
| var data = require('fs').readFileSync(path.resolve(path.dirname(infile), json.filepath), null); | var data = require('fs').readFileSync(json.filepath, null); | ||||||
| var Packer = require('../index.js'); | var Packer = require('./index.js'); | ||||||
| 
 |  | ||||||
| var servername = sni(data); |  | ||||||
| var m = data.toString().match(/(?:^|[\r\n])Host: ([^\r\n]+)[\r\n]*/im); |  | ||||||
| var hostname = (m && m[1].toLowerCase() || '').split(':')[0]; |  | ||||||
| 
 | 
 | ||||||
| /* | /* | ||||||
| function pack() { | function pack() { | ||||||
|   var version = json.version; |   var version = json.version; | ||||||
|   var address = json.address; |   var address = json.address; | ||||||
|   var header = address.family + ',' + address.address + ',' + address.port + ',' + data.byteLength |   var header = address.family + ',' + address.address + ',' + address.port + ',' + data.byteLength | ||||||
|     + ',' + (address.service || '') + ',' + (address.serviceport || '') + ',' + (servername || hostname || '') |     + ',' + (address.service || '') | ||||||
|     ; |     ; | ||||||
|   var buf = Buffer.concat([ |   var buf = Buffer.concat([ | ||||||
|     Buffer.from([ 255 - version, header.length ]) |     Buffer.from([ 255 - version, header.length ]) | ||||||
| @ -37,7 +31,6 @@ function pack() { | |||||||
| } | } | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| json.address.name = servername || hostname; |  | ||||||
| var buf = Packer.pack(json.address, data); | var buf = Packer.pack(json.address, data); | ||||||
| fs.writeFileSync(outfile, buf, null); | fs.writeFileSync(outfile, buf, null); | ||||||
| console.log("wrote " + buf.byteLength + " bytes to '" + outfile + "' ('hexdump " + outfile + "' to inspect)"); | console.log("wrote " + buf.byteLength + " bytes to '" + outfile + "' ('hexdump " + outfile + "' to inspect)"); | ||||||
| @ -1,18 +1,16 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| var sni = require('sni'); | var sni = require('sni'); | ||||||
| var hello = require('fs').readFileSync(__dirname + '/sni.hello.bin'); | var hello = require('fs').readFileSync('./sni.hello.bin'); | ||||||
| var version = 1; | var version = 1; | ||||||
| var address = { | var address = { | ||||||
|   family: 'IPv4' |   family: 'IPv4' | ||||||
| , address: '127.0.1.1' | , address: '127.0.1.1' | ||||||
| , port: 4321 | , port: 443 | ||||||
| , service: 'foo-https' | , service: 'foo' | ||||||
| , serviceport: 443 |  | ||||||
| , name: 'foo-pokemap.hellabit.com' |  | ||||||
| }; | }; | ||||||
| var header = address.family + ',' + address.address + ',' + address.port + ',' + hello.byteLength | var header = address.family + ',' + address.address + ',' + address.port + ',' + hello.byteLength | ||||||
|   + ',' + (address.service || '') + ',' + (address.serviceport || '') + ',' + (address.name || '') |   + ',' + (address.service || '') | ||||||
|   ; |   ; | ||||||
| var buf = Buffer.concat([ | var buf = Buffer.concat([ | ||||||
|   Buffer.from([ 255 - version, header.length ]) |   Buffer.from([ 255 - version, header.length ]) | ||||||
| @ -22,21 +20,21 @@ var buf = Buffer.concat([ | |||||||
| var services = { 'ssh': 22, 'http': 4080, 'https': 8443 }; | var services = { 'ssh': 22, 'http': 4080, 'https': 8443 }; | ||||||
| var clients = {}; | var clients = {}; | ||||||
| var count = 0; | var count = 0; | ||||||
| var packer = require('../'); | var packer = require('./'); | ||||||
| var machine = packer.create({ | var machine = packer.create({ | ||||||
|   onmessage: function (tun) { |   onmessage: function (opts) { | ||||||
|     var id = tun.family + ',' + tun.address + ',' + tun.port; |     var id = opts.family + ',' + opts.address + ',' + opts.port; | ||||||
|     var service = 'https'; |     var service = 'https'; | ||||||
|     var port = services[service]; |     var port = services[service]; | ||||||
|     var servername = sni(tun.data); |     var servername = sni(opts.data); | ||||||
| 
 | 
 | ||||||
|     console.log(''); |     console.log(''); | ||||||
|     console.log('[onMessage]'); |     console.log('[onMessage]'); | ||||||
|     if (!tun.data.equals(hello)) { |     if (!opts.data.equals(hello)) { | ||||||
|       throw new Error("'data' packet is not equal to original 'hello' packet"); |       throw new Error("'data' packet is not equal to original 'hello' packet"); | ||||||
|     } |     } | ||||||
|     console.log('all', tun.data.byteLength, 'bytes are equal'); |     console.log('all', opts.data.byteLength, 'bytes are equal'); | ||||||
|     console.log('src:', tun.family, tun.address + ':' + tun.port + ':' + tun.serviceport); |     console.log('src:', opts.family, opts.address + ':' + opts.port); | ||||||
|     console.log('dst:', 'IPv4 127.0.0.1:' + port); |     console.log('dst:', 'IPv4 127.0.0.1:' + port); | ||||||
| 
 | 
 | ||||||
|     if (!clients[id]) { |     if (!clients[id]) { | ||||||
| @ -44,7 +42,7 @@ var machine = packer.create({ | |||||||
|       if (!servername) { |       if (!servername) { | ||||||
|         throw new Error("no servername found for '" + id + "'"); |         throw new Error("no servername found for '" + id + "'"); | ||||||
|       } |       } | ||||||
|       console.log("servername: '" + servername + "'", tun.name); |       console.log("servername: '" + servername + "'"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     count += 1; |     count += 1; | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user