From ab3f4d75395cabe8bedf35e84fc34bf7d044e691 Mon Sep 17 00:00:00 2001
From: Adam Ierymenko <adam.ierymenko@gmail.com>
Date: Sun, 26 Apr 2015 14:05:13 -0700
Subject: Was thinking about this HTTP tunneling stuff but decided against for
 now. Stash unfinished code in attic/

---
 attic/http-tunnel-proxy.js | 134 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 134 insertions(+)
 create mode 100755 attic/http-tunnel-proxy.js

(limited to 'attic')

diff --git a/attic/http-tunnel-proxy.js b/attic/http-tunnel-proxy.js
new file mode 100755
index 00000000..5d8cd583
--- /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 {
+		// /<proxy token>/<ignored>/...
+		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") {
+
+					// /<proxy token>/<ignored> ... waits via old skool long polling
+
+				} else if (request.method === "POST") {
+
+					// /<proxy token>/<ignored>/<dest ip>/<dest port>
+					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);
-- 
cgit v1.2.3