tested working upnp and pmp
This commit is contained in:
		
							parent
							
								
									62509a4800
								
							
						
					
					
						commit
						6382701c91
					
				
							
								
								
									
										66
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										66
									
								
								README.md
									
									
									
									
									
								
							| @ -1,17 +1,79 @@ | |||||||
| # holepunch | # holepunch | ||||||
| 
 | 
 | ||||||
| A node.js library and cli for using UPnP SSDP | A node.js library (api) and command (cli) for using UPnP SSDP | ||||||
| and ZeroConf (Bonjour) NAT-PMP | and ZeroConf (Bonjour) NAT-PMP | ||||||
| to make home and office devices and services Internet-accessible. | to make home and office devices and services Internet-accessible. | ||||||
| 
 | 
 | ||||||
| ## Progress | ## Progress | ||||||
| 
 | 
 | ||||||
| in development | it now works :-) | ||||||
|  | 
 | ||||||
|  | still in development | ||||||
| 
 | 
 | ||||||
| ```bash | ```bash | ||||||
|  | git clone git@github.com:Daplie/holepunch.git | ||||||
|  | 
 | ||||||
|  | pushd holepunch | ||||||
|  | 
 | ||||||
| node bin/holepunch.js --debug | node bin/holepunch.js --debug | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  | ## Install | ||||||
|  | 
 | ||||||
|  | **Commandline Tool** | ||||||
|  | ```bash | ||||||
|  | npm install --global holepunch | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | **node.js Library** | ||||||
|  | ``` | ||||||
|  | npm install --save holepunch | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## Commandline (CLI) | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | holepunch --help | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | holepunch --plain-ports 80,65080 --tls-ports 443,65443 | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | TODO `--prebound-ports 22` | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | Usage: | ||||||
|  |   holepunch.js [OPTIONS] [ARGS] | ||||||
|  | 
 | ||||||
|  | Options: | ||||||
|  |       --debug BOOLEAN       show traces and logs | ||||||
|  | 
 | ||||||
|  |       --plain-ports STRING  Port numbers to test with plaintext loopback. | ||||||
|  |                             (default: 65080) | ||||||
|  |                             (formats: <port>,<internal:external>) | ||||||
|  | 
 | ||||||
|  |       --tls-ports STRING    Port numbers to test with tls loopback. | ||||||
|  |                             (default: null) | ||||||
|  | 
 | ||||||
|  |       --ipify-urls STRING   Comma separated list of URLs to test for external ip. | ||||||
|  |                             (default: api.ipify.org) | ||||||
|  | 
 | ||||||
|  |       --protocols STRING    Comma separated list of ip mapping protocols. | ||||||
|  |                             (default: none,upnp,pmp) | ||||||
|  | 
 | ||||||
|  |       --rvpn-configs STRING Comma separated list of Reverse VPN config files in | ||||||
|  |                             the order they should be tried. (default: null) | ||||||
|  | 
 | ||||||
|  |   -h, --help                Display help and usage details | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## API | ||||||
|  | 
 | ||||||
|  | ```javascript | ||||||
|  | var punch = require('holepunch'); | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
| # License | # License | ||||||
| 
 | 
 | ||||||
| MPL-2.0 | MPL-2.0 | ||||||
|  | |||||||
| @ -71,7 +71,8 @@ cli.main(function(_, options) { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   return hp.create(args).then(function () { |   return hp.create(args).then(function () { | ||||||
|     console.log('wishing wanting waiting'); |     //console.log('[HP] wishing wanting waiting');
 | ||||||
|     //process.exit(0);
 |     console.log('complete, exiting'); | ||||||
|  |     process.exit(0); | ||||||
|   }); |   }); | ||||||
| }); | }); | ||||||
|  | |||||||
| @ -41,7 +41,7 @@ function createSocket() { | |||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|   socket.on('message', function (chunk, info) { |   socket.on('message', function (chunk, info) { | ||||||
|     var message = chunk.toString(); |     var message = chunk.toString('utf8'); | ||||||
| 
 | 
 | ||||||
|     console.log('[MESSAGE RECEIVED]'); |     console.log('[MESSAGE RECEIVED]'); | ||||||
|     console.log(info); |     console.log(info); | ||||||
|  | |||||||
							
								
								
									
										14
									
								
								lib/index.js
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								lib/index.js
									
									
									
									
									
								
							| @ -14,7 +14,7 @@ module.exports.create = function (args) { | |||||||
| 
 | 
 | ||||||
|   if (args.debug) { |   if (args.debug) { | ||||||
|     console.log('[HP] create servers'); |     console.log('[HP] create servers'); | ||||||
|     console.log(servers); |     //console.log(servers);
 | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   function getExternalIps() { |   function getExternalIps() { | ||||||
| @ -63,8 +63,8 @@ module.exports.create = function (args) { | |||||||
|       return portInfo; |       return portInfo; | ||||||
|     }, function (err) { |     }, function (err) { | ||||||
|       if (args.debug) { |       if (args.debug) { | ||||||
|         console.error('[HP] loopback test err'); |         console.log('[HP] loopback did not complete'); | ||||||
|         console.error(err.stack); |         console.log(err.stack); | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       return PromiseA.reject(err); |       return PromiseA.reject(err); | ||||||
| @ -83,7 +83,7 @@ module.exports.create = function (args) { | |||||||
|       ip.ports = []; |       ip.ports = []; | ||||||
| 
 | 
 | ||||||
|       if (opts.debug) { |       if (opts.debug) { | ||||||
|         console.log('[HP] no pretest', opts.pretest); |         console.log('[HP] pretest = ', opts.pretest); | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       if (!opts.pretest) { |       if (!opts.pretest) { | ||||||
| @ -124,12 +124,18 @@ module.exports.create = function (args) { | |||||||
|       if (-1 !== args.protocols.indexOf('upnp') |       if (-1 !== args.protocols.indexOf('upnp') | ||||||
|         ||  -1 !== args.protocols.indexOf('ssdp') |         ||  -1 !== args.protocols.indexOf('ssdp') | ||||||
|       ) { |       ) { | ||||||
|  |         if (args.debug) { | ||||||
|  |           console.log('[HP] will try upnp'); | ||||||
|  |         } | ||||||
|         mappers.push(require('./upnp')); |         mappers.push(require('./upnp')); | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       if (-1 !== args.protocols.indexOf('pmp') |       if (-1 !== args.protocols.indexOf('pmp') | ||||||
|         || -1 !== args.protocols.indexOf('nat-pmp') |         || -1 !== args.protocols.indexOf('nat-pmp') | ||||||
|       ) { |       ) { | ||||||
|  |         if (args.debug) { | ||||||
|  |           console.log('[HP] will try nat-pmp'); | ||||||
|  |         } | ||||||
|         mappers.push(require('./pmp')); |         mappers.push(require('./pmp')); | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										16
									
								
								lib/pmp.js
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								lib/pmp.js
									
									
									
									
									
								
							| @ -68,9 +68,11 @@ function pmpForwardHelper(gw, portInfo) { | |||||||
|     // TODO why did I use a setTimeout here? event loop / timing bug?
 |     // TODO why did I use a setTimeout here? event loop / timing bug?
 | ||||||
|     setTimeout(function () { |     setTimeout(function () { | ||||||
|       client.externalIp(function (err, info) { |       client.externalIp(function (err, info) { | ||||||
|         console.error('[HP] Error: setTimeout client.externalIp:'); |         if (err) { | ||||||
|         console.error(err.stack); |           console.error('[HP] Error: setTimeout client.externalIp:'); | ||||||
|         if (err) { return PromiseA.reject(err); } |           console.error(err.stack); | ||||||
|  |           return PromiseA.reject(err); | ||||||
|  |         } | ||||||
|         console.log('Current external IP address: %s', info.ip.join('.')); |         console.log('Current external IP address: %s', info.ip.join('.')); | ||||||
|         setPortForward(); |         setPortForward(); | ||||||
|       }); |       }); | ||||||
| @ -78,13 +80,17 @@ function pmpForwardHelper(gw, portInfo) { | |||||||
|   }); |   }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function pmpForward(port) { | function pmpForward(portInfo) { | ||||||
|   return getGateway().then(function (gw) { |   return getGateway().then(function (gw) { | ||||||
|     return pmpForwardHelper(gw, port); |     return pmpForwardHelper(gw, portInfo); | ||||||
|   }); |   }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| module.exports = function (args, ips, portInfo) { | module.exports = function (args, ips, portInfo) { | ||||||
|  |   if (args.debug) { | ||||||
|  |     console.log('[HP] [pmp] portInfo'); | ||||||
|  |     console.log(portInfo); | ||||||
|  |   } | ||||||
|   return pmpForward(portInfo); |   return pmpForward(portInfo); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -8,8 +8,10 @@ function requestAsync(opts) { | |||||||
|   return new PromiseA(function (resolve, reject) { |   return new PromiseA(function (resolve, reject) { | ||||||
|     var httpr = (false === opts.secure) ? http : https; |     var httpr = (false === opts.secure) ? http : https; | ||||||
| 
 | 
 | ||||||
|     console.log('[HP] loopback test opts'); |     if (opts.debug) { | ||||||
|     console.log(opts); |       console.log('[HP] requestAsync opts'); | ||||||
|  |       console.log(opts); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     var req = httpr.request(opts, function (res) { |     var req = httpr.request(opts, function (res) { | ||||||
|       var data = ''; |       var data = ''; | ||||||
| @ -22,10 +24,13 @@ function requestAsync(opts) { | |||||||
|         reject(err); |         reject(err); | ||||||
|       }); |       }); | ||||||
|       res.on('data', function (chunk) { |       res.on('data', function (chunk) { | ||||||
|  |         clearTimeout(req.__timtok); | ||||||
|  | 
 | ||||||
|         if (opts.debug > 2) { |         if (opts.debug > 2) { | ||||||
|           console.log('HP: request chunk:'); |           console.log('HP: request chunk:'); | ||||||
|           console.log(chunk); |           console.log(chunk); | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|         data += chunk.toString('utf8'); |         data += chunk.toString('utf8'); | ||||||
|       }); |       }); | ||||||
|       res.on('end', function () { |       res.on('end', function () { | ||||||
| @ -38,6 +43,13 @@ function requestAsync(opts) { | |||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     req.on('error', reject); |     req.on('error', reject); | ||||||
|  |     req.setTimeout(3 * 1000); | ||||||
|  |     req.on('socket', function (socket) { | ||||||
|  |       req.__timtok = setTimeout(function () { | ||||||
|  |         req.abort(); | ||||||
|  |       }, 3 * 1000); | ||||||
|  |       socket.setTimeout(3 * 1000); | ||||||
|  |     }); | ||||||
|     req.end(); |     req.end(); | ||||||
|   }); |   }); | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										18
									
								
								lib/upnp.js
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								lib/upnp.js
									
									
									
									
									
								
							| @ -1,17 +1,27 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| //var PromiseA = require('bluebird').Promise;
 | var PromiseA = require('bluebird').Promise; | ||||||
| var natUpnp = require('holepunch-upnp'); | var natUpnp = require('holepunch-upnp'); | ||||||
| 
 | 
 | ||||||
| function upnpForward(opts) { | function upnpForward(opts) { | ||||||
|   return natUpnp.createClient({ timeout: 3000 }).then(function (client) { |   if (opts.debug) { | ||||||
|  |     console.log('[HP] [upnp] opts'); | ||||||
|  |     console.log(opts); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return natUpnp.createClient({ timeout: 3 * 1000 }).then(function (client) { | ||||||
|  |     if (opts.debug) { | ||||||
|  |       console.log('[HP] [upnp] created client'); | ||||||
|  |       console.log(client); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     return client.portMapping({ |     return client.portMapping({ | ||||||
|       public: opts.external || opts.public || opts.internal |       public: opts.external || opts.public || opts.internal | ||||||
|     , private: opts.internal || opts.private || opts.public || opts.external |     , private: opts.internal || opts.private || opts.public || opts.external | ||||||
|     , ttl: opts.ttl || 0 |     , ttl: opts.ttl || 0 | ||||||
|     }).then(function (result) { |     }).then(function (result) { | ||||||
|       if (opts.debug) { |       if (opts.debug) { | ||||||
|         console.log('[HP] upnp result'); |         console.log('[HP] [upnp] result'); | ||||||
|         console.log(result); |         console.log(result); | ||||||
|       } |       } | ||||||
|       return result; |       return result; | ||||||
| @ -37,7 +47,9 @@ module.exports = function (args, ips, portInfo) { | |||||||
|   return upnpForward({ |   return upnpForward({ | ||||||
|     debug: args.debug |     debug: args.debug | ||||||
|   , private: portInfo.internal |   , private: portInfo.internal | ||||||
|  |   , internal: portInfo.internal | ||||||
|   , public: portInfo.external |   , public: portInfo.external | ||||||
|  |   , external: portInfo.external | ||||||
|   // , localAddress: ip.localAddress
 |   // , localAddress: ip.localAddress
 | ||||||
|   }); |   }); | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -1,10 +1,10 @@ | |||||||
| { | { | ||||||
|   "name": "holepunch", |   "name": "holepunch", | ||||||
|   "version": "1.0.0-alpha.1", |   "version": "1.0.0-alpha.2", | ||||||
|   "description": "Get a direct ip connection by any means possible - direct (public ip), upnp (Microsoft), nat-pmp (Apple), or punch a hole through a firewall using a Reverse VPN (Daplie).", |   "description": "Get a direct ip connection by any means possible - direct (public ip), upnp (Microsoft), nat-pmp (Apple), or punch a hole through a firewall using a Reverse VPN (Daplie).", | ||||||
|   "main": "index.js", |   "main": "index.js", | ||||||
|   "bin": { |   "bin": { | ||||||
|     "holepunch": "holepunch.js" |     "holepunch": "bin/holepunch.js" | ||||||
|   }, |   }, | ||||||
|   "directories": { |   "directories": { | ||||||
|     "example": "examples" |     "example": "examples" | ||||||
| @ -16,10 +16,11 @@ | |||||||
|     "holepunch-nat-pmp": "^1.0.0-alpha.1", |     "holepunch-nat-pmp": "^1.0.0-alpha.1", | ||||||
|     "holepunch-upnp": "^1.0.0-alpha.1", |     "holepunch-upnp": "^1.0.0-alpha.1", | ||||||
|     "localhost.daplie.com-certificates": "^1.1.2", |     "localhost.daplie.com-certificates": "^1.1.2", | ||||||
|     "netroute": "^1.0.2", |  | ||||||
|     "request": "^2.67.0", |  | ||||||
|     "scmp": "^1.0.0" |     "scmp": "^1.0.0" | ||||||
|   }, |   }, | ||||||
|  |   "optionalDependencies": { | ||||||
|  |     "netroute": "^1.0.2" | ||||||
|  |   }, | ||||||
|   "devDependencies": {}, |   "devDependencies": {}, | ||||||
|   "scripts": { |   "scripts": { | ||||||
|     "test": "echo \"Error: no test specified\" && exit 1" |     "test": "echo \"Error: no test specified\" && exit 1" | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user