Skip to content

Instantly share code, notes, and snippets.

@gabonator
Created November 18, 2017 15:43
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gabonator/2fcada21db97faab6e0576cf25e6ea03 to your computer and use it in GitHub Desktop.
Save gabonator/2fcada21db97faab6e0576cf25e6ea03 to your computer and use it in GitHub Desktop.
simple IP tunneling using public server in nodejs
var net = require('net');
var tunnel = null;
var target = null;
// tunnel server
var serverInfo = {port:8811, host:"public.server.com"};
// target device we want to access on network where this script is running
var targetInfo = {port:1001, host:"ip.local.network"};
function listen()
{
tunnel = new net.Socket();
tunnel.connect(serverInfo.port, serverInfo.host, function() {
console.log('Tunnel connected');
});
tunnel.on('error', function(ex) {
console.log("Tunnel error: " + ex.code);
});
tunnel.on('data', function(data) {
var indexOpen = data.indexOf("[g:open]");
if (indexOpen != -1)
{
push(data.slice(0, indexOpen));
push(data.slice(indexOpen + "[g:open]".length, data.length));
open();
return;
}
var indexClose = data.indexOf("[g:close]");
if (indexClose != -1)
{
push(data.slice(0, indexClose));
push(data.slice(indexClose + "[g:close]".length, data.length));
close();
return;
}
push(data);
});
tunnel.on('close', function() {
tunnel = null;
console.log('Connection closed, reconnecting in 5 seconds');
setTimeout(listen, 5000);
});
}
function open()
{
console.log("Requesting to open target...");
if (target)
{
target.destroy();
}
target = new net.Socket();
target.connect(targetInfo.port, targetInfo.host, function() {
console.log('Target connected');
});
target.on('error', function(ex) {
console.log("Error: " + ex.code);
});
target.on('data', function(data) {
if (tunnel) // must exist!
tunnel.write(data);
else
console.log("Tunel does not exist! unable to forward");
// console.log("target->remote:"+data.length + " bytes");
});
}
function close()
{
console.log("Target session closed");
if (target)
target.destroy();
}
function push(data)
{
if (!data.length)
return;
// console.log("remote->target:"+data.length + " bytes");
if (target)
target.write(data);
else
console.log("Target does not exist! unable to forward");
}
listen();
/*
home publicly accessible server remote
from both devices
tunnel client ----------------- tunnel server ---------------------- remote tv
| 8811 | 9911
| tunnel server -+- remote server
| 8811 9911
1001
oscam server
*/
const net = require('net');
var remoteClient = null;
var tunnelClient = null;
var serverInfo = {portPublic:9911, portTunnel:8811};
const tunnelServer = net.createServer(function(c) {
console.log('tunnel server: connected');
tunnelClient = c;
c.on('data', function(data) {
console.log("tunnel->remote "+data.length);
if (remoteClient)
remoteClient.write(data);
});
c.on('end', function() {
console.log('tunnel server: client disconnected');
tunnelClient = null;
if (remoteClient)
remoteClient.destroy();
});
c.on('error', function() {
console.log('tunnel server: client error');
tunnelClient = null;
if (remoteClient)
remoteClient.destroy();
});
c.on('close', function() {
console.log('tunnel server: client closed');
tunnelClient = null;
if (remoteClient)
remoteClient.destroy();
});
});
tunnelServer.on('error', function(err) {
throw err;
});
tunnelServer.listen(serverInfo.portTunnel, function() {
console.log('tunnel server bound: ' + serverInfo.portTunnel);
});
////////////////////////////
const remoteServer = net.createServer(function(c) {
console.log('remote server: remote tv connected');
remoteClient = c;
if (tunnelClient)
tunnelClient.write("[g:open]");
else
{
c.destroy();
console.log("nemam kam poslat open request");
}
c.on('data', function (data) {
console.log("remote->tunnel "+data.length);
if (tunnelClient)
tunnelClient.write(data);
});
c.on('end', function() {
console.log('remote server: client disconnected');
if (tunnelClient && remoteClient)
tunnelClient.write("[g:close]");
remoteClient = null;
});
c.on('error', function () {
console.log('remote server: client error');
if (tunnelClient && remoteClient)
tunnelClient.write("[g:close]");
remoteClient = null;
});
c.on('close', function () {
console.log('remote server: client closed');
if (tunnelClient && remoteClient)
tunnelClient.write("[g:close]");
remoteClient = null;
});
});
remoteServer.on('error', function(err) {
throw err;
});
remoteServer.listen(serverInfo.portPublic, function () {
console.log('remote server bound: ' + serverInfo.portPublic);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment