tested working upnp and pmp

This commit is contained in:
AJ ONeal 2015-12-30 21:40:52 +00:00
parent 62509a4800
commit 6382701c91
8 changed files with 123 additions and 23 deletions

View File

@ -1,17 +1,79 @@
# 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
to make home and office devices and services Internet-accessible.
## Progress
in development
it now works :-)
still in development
```bash
git clone git@github.com:Daplie/holepunch.git
pushd holepunch
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
MPL-2.0

View File

@ -71,7 +71,8 @@ cli.main(function(_, options) {
}
return hp.create(args).then(function () {
console.log('wishing wanting waiting');
//process.exit(0);
//console.log('[HP] wishing wanting waiting');
console.log('complete, exiting');
process.exit(0);
});
});

View File

@ -41,7 +41,7 @@ function createSocket() {
});
socket.on('message', function (chunk, info) {
var message = chunk.toString();
var message = chunk.toString('utf8');
console.log('[MESSAGE RECEIVED]');
console.log(info);

View File

@ -14,7 +14,7 @@ module.exports.create = function (args) {
if (args.debug) {
console.log('[HP] create servers');
console.log(servers);
//console.log(servers);
}
function getExternalIps() {
@ -63,8 +63,8 @@ module.exports.create = function (args) {
return portInfo;
}, function (err) {
if (args.debug) {
console.error('[HP] loopback test err');
console.error(err.stack);
console.log('[HP] loopback did not complete');
console.log(err.stack);
}
return PromiseA.reject(err);
@ -83,7 +83,7 @@ module.exports.create = function (args) {
ip.ports = [];
if (opts.debug) {
console.log('[HP] no pretest', opts.pretest);
console.log('[HP] pretest = ', opts.pretest);
}
if (!opts.pretest) {
@ -124,12 +124,18 @@ module.exports.create = function (args) {
if (-1 !== args.protocols.indexOf('upnp')
|| -1 !== args.protocols.indexOf('ssdp')
) {
if (args.debug) {
console.log('[HP] will try upnp');
}
mappers.push(require('./upnp'));
}
if (-1 !== args.protocols.indexOf('pmp')
|| -1 !== args.protocols.indexOf('nat-pmp')
) {
if (args.debug) {
console.log('[HP] will try nat-pmp');
}
mappers.push(require('./pmp'));
}

View File

@ -68,9 +68,11 @@ function pmpForwardHelper(gw, portInfo) {
// TODO why did I use a setTimeout here? event loop / timing bug?
setTimeout(function () {
client.externalIp(function (err, info) {
if (err) {
console.error('[HP] Error: setTimeout client.externalIp:');
console.error(err.stack);
if (err) { return PromiseA.reject(err); }
return PromiseA.reject(err);
}
console.log('Current external IP address: %s', info.ip.join('.'));
setPortForward();
});
@ -78,13 +80,17 @@ function pmpForwardHelper(gw, portInfo) {
});
}
function pmpForward(port) {
function pmpForward(portInfo) {
return getGateway().then(function (gw) {
return pmpForwardHelper(gw, port);
return pmpForwardHelper(gw, portInfo);
});
}
module.exports = function (args, ips, portInfo) {
if (args.debug) {
console.log('[HP] [pmp] portInfo');
console.log(portInfo);
}
return pmpForward(portInfo);
};

View File

@ -8,8 +8,10 @@ function requestAsync(opts) {
return new PromiseA(function (resolve, reject) {
var httpr = (false === opts.secure) ? http : https;
console.log('[HP] loopback test opts');
if (opts.debug) {
console.log('[HP] requestAsync opts');
console.log(opts);
}
var req = httpr.request(opts, function (res) {
var data = '';
@ -22,10 +24,13 @@ function requestAsync(opts) {
reject(err);
});
res.on('data', function (chunk) {
clearTimeout(req.__timtok);
if (opts.debug > 2) {
console.log('HP: request chunk:');
console.log(chunk);
}
data += chunk.toString('utf8');
});
res.on('end', function () {
@ -38,6 +43,13 @@ function requestAsync(opts) {
});
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();
});
}

View File

@ -1,17 +1,27 @@
'use strict';
//var PromiseA = require('bluebird').Promise;
var PromiseA = require('bluebird').Promise;
var natUpnp = require('holepunch-upnp');
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({
public: opts.external || opts.public || opts.internal
, private: opts.internal || opts.private || opts.public || opts.external
, ttl: opts.ttl || 0
}).then(function (result) {
if (opts.debug) {
console.log('[HP] upnp result');
console.log('[HP] [upnp] result');
console.log(result);
}
return result;
@ -37,7 +47,9 @@ module.exports = function (args, ips, portInfo) {
return upnpForward({
debug: args.debug
, private: portInfo.internal
, internal: portInfo.internal
, public: portInfo.external
, external: portInfo.external
// , localAddress: ip.localAddress
});
};

View File

@ -1,10 +1,10 @@
{
"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).",
"main": "index.js",
"bin": {
"holepunch": "holepunch.js"
"holepunch": "bin/holepunch.js"
},
"directories": {
"example": "examples"
@ -16,10 +16,11 @@
"holepunch-nat-pmp": "^1.0.0-alpha.1",
"holepunch-upnp": "^1.0.0-alpha.1",
"localhost.daplie.com-certificates": "^1.1.2",
"netroute": "^1.0.2",
"request": "^2.67.0",
"scmp": "^1.0.0"
},
"optionalDependencies": {
"netroute": "^1.0.2"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"