| 
									
										
										
										
											2015-12-30 08:22:04 +00:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var PromiseA = require('bluebird'); | 
					
						
							|  |  |  | var natpmp = require('holepunch-nat-pmp'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function getGateway() { | 
					
						
							|  |  |  |   var exec = require('child_process').exec; | 
					
						
							|  |  |  |   var netroute; | 
					
						
							|  |  |  |   var gw; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   try { | 
					
						
							|  |  |  |     netroute = require('netroute'); | 
					
						
							|  |  |  |     gw = netroute.getGateway(); | 
					
						
							|  |  |  |   } catch(e) { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (gw) { | 
					
						
							|  |  |  |     return PromiseA.resolve(gw); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return new PromiseA(function (resolve, reject) { | 
					
						
							|  |  |  |     exec('ip route show default', function (err, stdout, stderr) { | 
					
						
							|  |  |  |       var gw; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (err || stderr) { reject(err || stderr); return; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // default via 192.168.1.1 dev eth0
 | 
					
						
							|  |  |  |       gw = stdout.replace(/^default via (\d+\.\d+\.\d+\.\d+) dev[\s\S]+/m, '$1'); | 
					
						
							|  |  |  |       console.log('Possible PMP gateway is', gw); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return gw; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function pmpForwardHelper(gw, portInfo) { | 
					
						
							|  |  |  |   return new PromiseA(function (resolve, reject) { | 
					
						
							|  |  |  |     // create a "client" instance connecting to your local gateway
 | 
					
						
							|  |  |  |     var client = natpmp.connect(gw); | 
					
						
							| 
									
										
										
										
											2015-12-31 02:21:29 +00:00
										 |  |  |     client.on('error', function (err) { | 
					
						
							|  |  |  |       reject(err); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2015-12-30 08:22:04 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     function setPortForward() { | 
					
						
							|  |  |  |       // setup a new port mapping
 | 
					
						
							|  |  |  |       client.portMapping({ | 
					
						
							|  |  |  |         private: portInfo.internal || portInfo.private | 
					
						
							|  |  |  |           || portInfo.external || portInfo.public | 
					
						
							|  |  |  |       , public: portInfo.external || portInfo.public | 
					
						
							|  |  |  |           || portInfo.internal || portInfo.private | 
					
						
							| 
									
										
										
										
											2015-12-30 08:46:22 +00:00
										 |  |  |       , ttl: portInfo.ttl || 7200 // 0 // 600
 | 
					
						
							| 
									
										
										
										
											2015-12-30 08:22:04 +00:00
										 |  |  |       }, function (err, info) { | 
					
						
							|  |  |  |         if (err) { | 
					
						
							|  |  |  |           reject(err); | 
					
						
							|  |  |  |           return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         console.log(info); | 
					
						
							|  |  |  |         // {
 | 
					
						
							|  |  |  |         //   type: 'tcp',
 | 
					
						
							|  |  |  |         //   epoch: 8922109,
 | 
					
						
							|  |  |  |         //   private: 22,
 | 
					
						
							|  |  |  |         //   public: 2222,
 | 
					
						
							|  |  |  |         //   ...
 | 
					
						
							|  |  |  |         // }
 | 
					
						
							| 
									
										
										
										
											2015-12-31 02:21:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         client.close(); | 
					
						
							| 
									
										
										
										
											2015-12-30 08:22:04 +00:00
										 |  |  |         resolve(); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // explicitly ask for the current external IP address
 | 
					
						
							| 
									
										
										
										
											2015-12-30 11:48:33 -05:00
										 |  |  |     // TODO why did I use a setTimeout here? event loop / timing bug?
 | 
					
						
							| 
									
										
										
										
											2015-12-30 08:22:04 +00:00
										 |  |  |     setTimeout(function () { | 
					
						
							|  |  |  |       client.externalIp(function (err, info) { | 
					
						
							| 
									
										
										
										
											2015-12-30 21:40:52 +00:00
										 |  |  |         if (err) { | 
					
						
							|  |  |  |           console.error('[HP] Error: setTimeout client.externalIp:'); | 
					
						
							|  |  |  |           console.error(err.stack); | 
					
						
							|  |  |  |           return PromiseA.reject(err); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-12-30 08:22:04 +00:00
										 |  |  |         console.log('Current external IP address: %s', info.ip.join('.')); | 
					
						
							|  |  |  |         setPortForward(); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-30 21:40:52 +00:00
										 |  |  | function pmpForward(portInfo) { | 
					
						
							| 
									
										
										
										
											2015-12-30 08:22:04 +00:00
										 |  |  |   return getGateway().then(function (gw) { | 
					
						
							| 
									
										
										
										
											2015-12-30 21:40:52 +00:00
										 |  |  |     return pmpForwardHelper(gw, portInfo); | 
					
						
							| 
									
										
										
										
											2015-12-30 08:22:04 +00:00
										 |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports = function (args, ips, portInfo) { | 
					
						
							| 
									
										
										
										
											2015-12-30 21:40:52 +00:00
										 |  |  |   if (args.debug) { | 
					
						
							|  |  |  |     console.log('[HP] [pmp] portInfo'); | 
					
						
							|  |  |  |     console.log(portInfo); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-12-30 08:22:04 +00:00
										 |  |  |   return pmpForward(portInfo); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports.pmpForward = pmpForward; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-31 02:21:29 +00:00
										 |  |  | /* | 
					
						
							| 
									
										
										
										
											2015-12-30 08:22:04 +00:00
										 |  |  | function usage() { | 
					
						
							|  |  |  |   console.warn(""); | 
					
						
							|  |  |  |   console.warn("node helpers/pmp-forward [public port] [private port] [ttl]"); | 
					
						
							|  |  |  |   console.warn(""); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function run() { | 
					
						
							|  |  |  |   var pubPort = parseInt(process.argv[2], 10) || 0; | 
					
						
							|  |  |  |   var privPort = parseInt(process.argv[3], 10) || pubPort; | 
					
						
							|  |  |  |   var ttl = parseInt(process.argv[4], 10) || 0; | 
					
						
							|  |  |  |   var options = { public: pubPort, private: privPort, ttl: ttl }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!pubPort) { | 
					
						
							|  |  |  |     usage(); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   exports.pmpForward(options).then(function () { | 
					
						
							|  |  |  |     console.log('done'); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if (require.main === module) { | 
					
						
							|  |  |  |   run(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-12-31 02:21:29 +00:00
										 |  |  | */ |