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