'use strict'; var net = require('net'); var sni = require('sni'); var jwt = require('jsonwebtoken'); var packer = require('tunnel-packer'); var Transform = require('stream').Transform; var util = require('util'); function MyTransform(options) { if (!(this instanceof MyTransform)) { return new MyTransform(options); } this.__my_addr = options.address; Transform.call(this, options); } util.inherits(MyTransform, Transform); function transform(me, data, encoding, callback) { var address = me.__my_addr; me.push(packer.pack(address, data)); callback(); } MyTransform.prototype._transform = function (data, encoding, callback) { return transform(this, data, encoding, callback); }; function socketToAddr(socket) { return { family: socket.remoteFamily, address: socket.remoteAddress, port: socket.remotePort }; } function addrToId(address) { return address.family + ',' + address.address + ',' + address.port; } function socketToId(socket) { return addrToId(socketToAddr(socket)); } //require('cluster-store').create().then(function (/*store*/) { // initialization is now complete //store.set('foo', 'bar'); var remotes = {}; setInterval(function () { Object.keys(remotes).forEach(function (id) { var remote = remotes[id]; console.log('Remote ', id, 'has', Object.keys(remote.clients).length, 'clients', remote.socket.bytesRead, remote.socket.bytesWritten); /* forEach(function (cid) { var client = remote.clients[cid]; }); */ }); }, 5000); var server443 = net.createServer(function (browser) { browser.once('data', function (hello) { //require('fs').writeFileSync('/tmp/sni.hello.bin', hello); var servername = sni(hello); var remote = remotes[servername]; if (!remote) { console.log("no remote for '" + servername + "'"); browser.end(); return; } var address = socketToAddr(browser); var id = addrToId(address); var wrapForRemote = new MyTransform({ id: id, remoteId: remote.id, address: address, servername: servername }); //socket.unshift(hello); //remote.socket/*.pipe(transform)*/.pipe(socket, { end: false }); var bstream = browser.pipe(wrapForRemote); /* function write() { console.log("client '" + address.address + "' writing to '" + servername + "'"); var bytes = browser.read(); if (bytes) { console.log("wrote ", bytes.byteLength); remote.socket.write(bytes, write); } else { console.log("nothing to write right now"); } } bstream.on('readable', write); */ bstream.on('data', function (chunk) { console.log("client '" + address.address + "' writing to '" + servername + "'", chunk.byteLength); remote.socket.write(chunk); }); var data = packer.pack(address, hello); console.log("client '" + address.address + "' greeting '" + servername + "'", hello.byteLength, data.byteLength); remote.socket.write(data); remote.clients[id] = browser; bstream.on('error', function () { console.error("browser has erred"); //wrapForRemote.write('|_ERROR_|'); delete remote.clients[id]; }); bstream.on('end', function () { console.log("browser has closed the socket"); //wrapForRemote.write('|_END_|'); delete remote.clients[id]; }); }); }); server443.listen(443, function () { console.log('listening on 443'); }); var server5443 = net.createServer(function (rserver) { rserver.once('data', function (hello) { var token; try { token = jwt.decode(hello.toString('utf8')); console.log(token); } catch(e) { rserver.end(); return; } if (!token.name) { console.log("no 'name' in token"); rserver.end(); return; } var remote = { socket: rserver , id: socketToId(rserver) , clients: {} }; var unpacker = packer.create({ onMessage: function (opts) { // opts.data var id = addrToId(opts); console.log("remote '" + remote.id + "' has data for '" + id + "'", opts.data.byteLength); if (!remote.clients[id]) { console.log('no client for', id, opts.data.toString('utf8').substr(0, 100)); //remote.socket.write(packer.pack(opts, Buffer.from('|__END__|'))); return; } remote.clients[id].write(opts.data); } }); console.log('new remote:', token.name); /* var data = packer.pack({ family: 'IPv4', address: '254.254.254.1', port: 443 }, Buffer.from(remote.id)); rserver.write(data, function () { remotes[token.name] = remote; }); */ remotes[token.name] = remote; rserver.on('data', function (chunk) { unpacker.fns.addChunk(chunk); }); function closeEm() { console.log("closing connection to '" + token.name + "'"); delete remotes[token.name]; Object.keys(remote.clients).forEach(function (cid) { remote.clients[cid].end(); delete remote.clients[cid]; }); //remote = null; //rserver = null; //unpacker = null; } rserver.on('end', closeEm); rserver.on('error', closeEm); }); }); server5443.listen(5443, function () { console.log('listening on 5443'); }); var http80 = require('http').createServer(); http80.on('request', function (req, res) { res.end('Happy Day!'); }); var server80 = net.createServer(function (client) { http80.emit('connection', client); }); server80.listen(80, function () { console.log('listening on 80'); }); //});