Permalink
Browse files

clinet: getMappings

  • Loading branch information...
indutny committed Aug 14, 2012
1 parent 80f494f commit 37edd1ed2f17bb6d72a6ca84d83a3bc416f54ce0
Showing with 118 additions and 4 deletions.
  1. +6 −0 README.md
  2. +83 −2 lib/nat-upnp/client.js
  3. +2 −1 package.json
  4. +27 −1 test/api-test.js
View
@@ -21,6 +21,12 @@ client.portUnmapping({
public: 12345
});
+client.getMappings(function(err, results) {
+});
+
+client.getMappings({ local: true }, function(err, results) {
+});
+
client.externalIp(function(err, ip) {
});
```
View
@@ -1,4 +1,5 @@
-var nat = require('../nat-upnp');
+var nat = require('../nat-upnp'),
+ async = require('async');
var client = exports;
@@ -41,7 +42,8 @@ Client.prototype.portMapping = function portMapping(options, callback) {
['NewInternalClient', ports.internal.host || address],
['NewEnabled', 1],
['NewPortMappingDescription', options.description || 'node:nat:upnp'],
- ['NewLeaseDuration', options.ttl || 60 * 30]
+ ['NewLeaseDuration', typeof options.ttl === 'number' ?
+ options.ttl : 60 * 30]
], callback);
});
};
@@ -63,6 +65,85 @@ Client.prototype.portUnmapping = function portMapping(options, callback) {
});
};
+Client.prototype.getMappings = function getMappings(options, callback) {
+ if (typeof options === 'function') {
+ callback = options;
+ options = null;
+ }
+
+ if (!options) options = {};
+
+ this.findGateway(function(err, gateway, address) {
+ if (err) return callback(err);
+ var i = 0,
+ end = false,
+ results = [];
+
+ async.whilst(function() {
+ return !end;
+ }, function(callback) {
+ gateway.run('GetGenericPortMappingEntry', [
+ ['NewPortMappingIndex', i++]
+ ], function(err, data) {
+ if (err) {
+ end = true;
+ return callback(null);
+ }
+
+ var key;
+ Object.keys(data).some(function(k) {
+ if (!/:GetGenericPortMappingEntryResponse/.test(k)) return false;
+
+ key = k;
+ return true;
+ });
+ data = data[key];
+
+ var result = {
+ public: {
+ host: typeof data.NewRemoteHost === 'string' &&
+ data.NewRemoteHost || '',
+ port: parseInt(data.NewExternalPort, 10)
+ },
+ private: {
+ host: data.NewInternalClient,
+ port: parseInt(data.NewInternalPort, 10)
+ },
+ protocol: data.NewProtocol.toLowerCase(),
+ enabled: data.NewEnabled == 1,
+ description: data.NewPortMappingDescription,
+ ttl: parseInt(data.NewLeaseDuration, 10)
+ };
+ result.local = result.private.host === address;
+
+ results.push(result);
+
+ callback(null);
+ });
+ }, function(err) {
+ if (err) return callback(err);
+
+ if (options.local) {
+ results = results.filter(function(item) {
+ return item.local;
+ });
+ }
+
+ if (options.description) {
+ results = results.filter(function(item) {
+ if (options.description instanceof RegExp) {
+ return item.description.match(options.description) !== null;
+ } else {
+ return item.description.indexOf(options.description) !== -1;
+ }
+ });
+ }
+
+ callback(null, results);
+ })
+ });
+};
+
Client.prototype.externalIp = function externalIp(callback) {
this.findGateway(function(err, gateway, address) {
gateway.run('GetExternalIPAddress', [], function(err, data) {
View
@@ -16,6 +16,7 @@
},
"dependencies": {
"xml2js": "~0.1.14",
- "request": "~2.10.0"
+ "request": "~2.10.0",
+ "async": "~0.1.22"
}
}
View
@@ -1,4 +1,5 @@
var assert = require('assert'),
+ async = require('async'),
net = require('net'),
natUpnp = require('..');
@@ -18,7 +19,7 @@ describe('NAT-UPNP/Client', function() {
c.portMapping({
public: public,
private: ~~(Math.random() * 65536),
- ttl: 5
+ ttl: 0
}, function(err) {
assert.equal(err, null);
@@ -29,6 +30,31 @@ describe('NAT-UPNP/Client', function() {
});
});
+ it('should find port after mapping', function(callback) {
+ var public = ~~(Math.random() * 65536);
+ c.portMapping({
+ public: public,
+ private: ~~(Math.random() * 65536),
+ description: 'node:nat:upnp:search-test',
+ ttl: 0
+ }, function(err) {
+ assert.equal(err, null);
+
+ c.getMappings({ local: true, description: /search-test/ },
+ function(err, list) {
+ assert.equal(err, null);
+ assert(list.length > 0);
+
+ async.forEach(list, function(item, callback) {
+ c.portUnmapping(item, function(err) {
+ assert.equal(err, null);
+ callback();
+ });
+ }, callback);
+ });
+ });
+ });
+
it('should get external ip address', function(callback) {
c.externalIp(function(err, ip) {
assert.equal(err, null);

0 comments on commit 37edd1e

Please sign in to comment.