2
0

http-tunnel-proxy.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #!/usr/bin/env node
  2. // Note: this is unfinished and not currently used. Stashed in case we resurrect this idea.
  3. var UDP_PORT_START = 9994;
  4. var UDP_PORT_COUNT = 16384;
  5. var HTTP_PORT = 8080;
  6. var LONG_POLLING_TIMEOUT = 25000;
  7. var http = require('http');
  8. var dgram = require('dgram');
  9. // clients[token] = [ most recent HTTP activity, assigned UDP socket ]
  10. var clients = {};
  11. // GETs[token] = [ [ request, timestamp ], ... ]
  12. var GETs = {};
  13. // mappings[localPort+'/'+remoteIp+'/'+remotePort] = { ZT source: [ token ] }
  14. var mappings = {};
  15. // Array of available UDP sockets to assign randomly to clients
  16. var udpSocketPool = [];
  17. function onIncomingUdp(socket,message,remoteIp,remotePort)
  18. {
  19. if (message.length > 16) {
  20. var mappingKey = socket.localPort + '/' + remoteIp + '/' + remotePort;
  21. var mapping = mappings[mappingKey];
  22. if (mapping) {
  23. var ztDestination = message.readUIntBE(8,5);
  24. if (ztDestination in mapping) {
  25. }
  26. }
  27. }
  28. }
  29. function onOutgoingUdp(token,socket,message,remoteIp,remotePort)
  30. {
  31. if (message.length > 16) {
  32. var ztDestination = message.readUIntBE(8,5);
  33. var ztSource = (message.length >= 28) ? message.readUIntBE(13,5) ? 0;
  34. if ((ztSource & 0xff00000000) == 0xff00000000) // fragment
  35. ztSource = 0;
  36. if ((ztDestination !== 0)&&((ztDestination & 0xff00000000) !== 0xff00000000)) {
  37. socket.send(message,0,message.length,remotePort,remoteIp);
  38. }
  39. }
  40. }
  41. function doHousekeeping()
  42. {
  43. }
  44. for(var udpPort=UDP_PORT_START;udpPort<(UDP_PORT_START+UDP_PORT_COUNT)++udpPort) {
  45. var socket = dgram.createSocket('udp4',function(message,rinfo) { onIncomingUdp(socket,message,rinfo.address,rinfo.port); });
  46. socket.on('listening',function() {
  47. console.log('Listening on '+socket.localPort);
  48. udpSocketPool.push(socket);
  49. }
  50. socket.on('error',function() {
  51. console.log('Error listening on '+socket.localPort);
  52. socket.close();
  53. })
  54. socket.bind(udpPort);
  55. }
  56. server = http.createServer(function(request,response) {
  57. console.log(request.socket.remoteAddress+" "+request.method+" "+request.url);
  58. try {
  59. // /<proxy token>/<ignored>/...
  60. var urlSp = request.url.split('/');
  61. if ((urlSp.length >= 3)&&(udpSocketPool.length > 0)) {
  62. var token = urlSp[1]; // urlSp[0] == '' since URLs start with /
  63. if (token.length >= 8) {
  64. var client = clients[token];
  65. if (!Array.isArray(client)) {
  66. client = [ Date.now(),udpSocketPool[Math.floor(Math.random() * udpSocketPool.length)] ];
  67. clients[token] = client;
  68. } else client[0] = Date.now();
  69. if (request.method === "GET") {
  70. // /<proxy token>/<ignored> ... waits via old skool long polling
  71. } else if (request.method === "POST") {
  72. // /<proxy token>/<ignored>/<dest ip>/<dest port>
  73. if (urlSp.length === 5) {
  74. var ipSp = urlSp[3].split('.');
  75. var port = parseInt(urlSp[4],10);
  76. // Note: do not allow the use of this proxy to talk to privileged ports
  77. if ((ipSp.length === 4)&&(port >= 1024)&&(port <= 0xffff)) {
  78. var ip = [ parseInt(ipSp[0]),parseInt(ipSp[1]),parseInt(ipSp[2]),parseInt(ipSp[3]) ];
  79. if ( (ip[0] > 0)
  80. &&(ip[0] < 240)
  81. &&(ip[0] !== 127)
  82. &&(ip[1] >= 0)
  83. &&(ip[1] <= 255)
  84. &&(ip[2] >= 0)
  85. &&(ip[2] <= 255)
  86. &&(ip[3] > 0)
  87. &&(ip[3] < 255) ) {
  88. var postData = null;
  89. request.on('data',function(chunk) {
  90. postData = ((postData === null) ? chunk : Buffer.concat([ postData,chunk ]));
  91. });
  92. request.on('end',function() {
  93. if (postData !== null)
  94. onOutgoingUdp(token,client[1],postData,urlSp[3],port);
  95. response.writeHead(200,{'Content-Length':0,'Pragma':'no-cache','Cache-Control':'no-cache'});
  96. response.end();
  97. });
  98. return; // no 400 -- read from stream
  99. } // else 400
  100. } // else 400
  101. } // else 400
  102. } // else 400
  103. } // else 400
  104. } // else 400
  105. } catch (e) {} // 400
  106. response.writeHead(400,{'Content-Length':0,'Pragma':'no-cache','Cache-Control':'no-cache'});
  107. response.end();
  108. return;
  109. });
  110. setInterval(doHousekeeping,5000);
  111. server.setTimeout(120000);
  112. server.listen(HTTP_PORT);