diff --git a/attic/http-tunnel-proxy.js b/attic/http-tunnel-proxy.js new file mode 100755 index 000000000..5d8cd5837 --- /dev/null +++ b/attic/http-tunnel-proxy.js @@ -0,0 +1,134 @@ +#!/usr/bin/env node + +var UDP_PORT_START = 9994; +var UDP_PORT_COUNT = 16384; +var HTTP_PORT = 8080; +var LONG_POLLING_TIMEOUT = 25000; + +var http = require('http'); +var dgram = require('dgram'); + +// clients[token] = [ most recent HTTP activity, assigned UDP socket ] +var clients = {}; + +// GETs[token] = [ [ request, timestamp ], ... ] +var GETs = {}; + +// mappings[localPort+'/'+remoteIp+'/'+remotePort] = { ZT source: [ token ] } +var mappings = {}; + +// Array of available UDP sockets to assign randomly to clients +var udpSocketPool = []; + +function onIncomingUdp(socket,message,remoteIp,remotePort) +{ + if (message.length > 16) { + var mappingKey = socket.localPort + '/' + remoteIp + '/' + remotePort; + var mapping = mappings[mappingKey]; + if (mapping) { + var ztDestination = message.readUIntBE(8,5); + if (ztDestination in mapping) { + } + } + } +} + +function onOutgoingUdp(token,socket,message,remoteIp,remotePort) +{ + if (message.length > 16) { + var ztDestination = message.readUIntBE(8,5); + var ztSource = (message.length >= 28) ? message.readUIntBE(13,5) ? 0; + if ((ztSource & 0xff00000000) == 0xff00000000) // fragment + ztSource = 0; + + if ((ztDestination !== 0)&&((ztDestination & 0xff00000000) !== 0xff00000000)) { + socket.send(message,0,message.length,remotePort,remoteIp); + } + } +} + +function doHousekeeping() +{ +} + +for(var udpPort=UDP_PORT_START;udpPort<(UDP_PORT_START+UDP_PORT_COUNT)++udpPort) { + var socket = dgram.createSocket('udp4',function(message,rinfo) { onIncomingUdp(socket,message,rinfo.address,rinfo.port); }); + socket.on('listening',function() { + console.log('Listening on '+socket.localPort); + udpSocketPool.push(socket); + } + socket.on('error',function() { + console.log('Error listening on '+socket.localPort); + socket.close(); + }) + socket.bind(udpPort); +} + +server = http.createServer(function(request,response) { + console.log(request.socket.remoteAddress+" "+request.method+" "+request.url); + + try { + // ///... + var urlSp = request.url.split('/'); + if ((urlSp.length >= 3)&&(udpSocketPool.length > 0)) { + var token = urlSp[1]; // urlSp[0] == '' since URLs start with / + + if (token.length >= 8) { + var client = clients[token]; + if (!Array.isArray(client)) { + client = [ Date.now(),udpSocketPool[Math.floor(Math.random() * udpSocketPool.length)] ]; + clients[token] = client; + } else client[0] = Date.now(); + + if (request.method === "GET") { + + // // ... waits via old skool long polling + + } else if (request.method === "POST") { + + // //// + if (urlSp.length === 5) { + var ipSp = urlSp[3].split('.'); + var port = parseInt(urlSp[4],10); + // Note: do not allow the use of this proxy to talk to privileged ports + if ((ipSp.length === 4)&&(port >= 1024)&&(port <= 0xffff)) { + var ip = [ parseInt(ipSp[0]),parseInt(ipSp[1]),parseInt(ipSp[2]),parseInt(ipSp[3]) ]; + if ( (ip[0] > 0) + &&(ip[0] < 240) + &&(ip[0] !== 127) + &&(ip[1] >= 0) + &&(ip[1] <= 255) + &&(ip[2] >= 0) + &&(ip[2] <= 255) + &&(ip[3] > 0) + &&(ip[3] < 255) ) { + var postData = null; + request.on('data',function(chunk) { + postData = ((postData === null) ? chunk : Buffer.concat([ postData,chunk ])); + }); + request.on('end',function() { + if (postData !== null) + onOutgoingUdp(token,client[1],postData,urlSp[3],port); + response.writeHead(200,{'Content-Length':0,'Pragma':'no-cache','Cache-Control':'no-cache'}); + response.end(); + }); + return; // no 400 -- read from stream + } // else 400 + } // else 400 + } // else 400 + + } // else 400 + + } // else 400 + } // else 400 + } catch (e) {} // 400 + + response.writeHead(400,{'Content-Length':0,'Pragma':'no-cache','Cache-Control':'no-cache'}); + response.end(); + return; +}); + +setInterval(doHousekeeping,5000); + +server.setTimeout(120000); +server.listen(HTTP_PORT);