Skip to content

Instantly share code, notes, and snippets.

@metal3d
Created August 9, 2011 22:16
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save metal3d/1135356 to your computer and use it in GitHub Desktop.
Save metal3d/1135356 to your computer and use it in GitHub Desktop.
NAT Traversal with node (0.5.x)
/*
NAT traversal system to let 2 computers behind firewall to communicate.
Example:
Client A (your machine) has public ip 1.1.1.1
Client B (distant machine) has public ip 2.2.2.2
You want to bind port 5556 on your machine
Distant Client want to bind port 5557
Command on A:
node nat-traversal.js 5556 2.2.2.2 5557
Command on B:
node nat-traversal.js 5557 1.1.1.1 5556
When both clients are connected, stdin is sent to other side
*/
var dgram = require("dgram"),
readline = require('readline');
//0 and 1 are "node" ans "scriptname"
//s is a simple struct
var s = {
HOSTPORT : parseInt(process.argv[2]),
DESTIP : process.argv[3],
DESTPORT : parseInt(process.argv[4]),
ACK_GARBAGE : new Buffer("node-transversal-garbage"),
ACK_MAGICK : new Buffer("node-transversal-magick"),
server: dgram.createSocket("udp4"),
listening : false
}
function sendMSG(msg, indicator) {
if (indicator==undefined || indicator) process.stdout.write('.');
s.server.send(
msg, 0 ,
msg.length,
s.DESTPORT, s.DESTIP);
}
s.server.on("listening", function () {
var address = s.server.address();
console.log("server listening " +
address.address + ":" + address.port);
});
s.server.on("message", function (msg, rinfo) {
if (s.listening) {
console.log(msg.toString());
}
else if (msg.toString() == s.ACK_MAGICK.toString()) {
//here we must continue to send datas... ans recieve...
s.listening = true;
//now, we can read from stdin and send datas to outside
(function (){
//this is encapsulated to not lose locals
var i = readline.createInterface(
process.stdin,
process.stdout, null);
var input = "";
i.input.on('data', function (data){
if (data!="\r" && data!="\n") {
input+=data;
}else {
var b = new Buffer(input);
sendMSG(b, false);
input = "";
}
})
})();
}//endif
});
//listen on local port
s.server.bind(s.HOSTPORT);
/*Begin the show ! */
//send some packets to fool outside firewall...
for (var i=0; i<10; i++) {
setTimeout(function (){sendMSG( s.ACK_GARBAGE); }, 1000*i);
}
//and last with the magick message...
setTimeout(function (){sendMSG( s.ACK_MAGICK); } , 1000*(i++));
setTimeout(function (){
console.log("Ready");
},1000*(i++))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment