telebit-relay.js/serve.js

206 lines
5.7 KiB
JavaScript

'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');
});
//});