cleanup and bugfix
This commit is contained in:
		
							parent
							
								
									3fe62c6b02
								
							
						
					
					
						commit
						d0ae3a1c0f
					
				
							
								
								
									
										123
									
								
								telebitd.js
									
									
									
									
									
								
							
							
						
						
									
										123
									
								
								telebitd.js
									
									
									
									
									
								
							| @ -86,9 +86,29 @@ module.exports.create = function (state) { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   function onWsConnection(ws, upgradeReq) { |   function onWsConnection(ws, upgradeReq) { | ||||||
|     if (state.debug) { console.log('[ws] connection'); } |  | ||||||
|     var socketId = Packer.socketToId(upgradeReq.socket); |     var socketId = Packer.socketToId(upgradeReq.socket); | ||||||
|  |     if (state.debug) { console.log('[ws] connection', socketId); } | ||||||
|  | 
 | ||||||
|     var remotes = {}; |     var remotes = {}; | ||||||
|  |     var firstToken; | ||||||
|  |     var authn = (upgradeReq.headers.authorization||'').split(/\s+/); | ||||||
|  |     if (authn[0] && 'basic' === authn[0].toLowerCase()) { | ||||||
|  |       try { | ||||||
|  |         authn = new Buffer(authn[1], 'base64').toString('ascii').split(':'); | ||||||
|  |         firstToken = authn[1]; | ||||||
|  |       } catch (err) { } | ||||||
|  |     } | ||||||
|  |     if (!firstToken) { | ||||||
|  |       firstToken = url.parse(upgradeReq.url, true).query.access_token; | ||||||
|  |     } | ||||||
|  |     if (firstToken) { | ||||||
|  |       var err = addToken(firstToken, true); | ||||||
|  |       if (err) { | ||||||
|  |         sendTunnelMsg(null, [0, err], 'control'); | ||||||
|  |         ws.close(); | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     function logName() { |     function logName() { | ||||||
|       var result = Object.keys(remotes).map(function (jwtoken) { |       var result = Object.keys(remotes).map(function (jwtoken) { | ||||||
| @ -97,6 +117,7 @@ module.exports.create = function (state) { | |||||||
| 
 | 
 | ||||||
|       return result || socketId; |       return result || socketId; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|     function sendTunnelMsg(addr, data, service) { |     function sendTunnelMsg(addr, data, service) { | ||||||
|       ws.send(Packer.pack(addr, data, service), {binary: true}); |       ws.send(Packer.pack(addr, data, service), {binary: true}); | ||||||
|     } |     } | ||||||
| @ -112,6 +133,7 @@ module.exports.create = function (state) { | |||||||
| 
 | 
 | ||||||
|       return browserConn; |       return browserConn; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|     function closeBrowserConn(cid) { |     function closeBrowserConn(cid) { | ||||||
|       var remote; |       var remote; | ||||||
|       Object.keys(remotes).some(function (jwtoken) { |       Object.keys(remotes).some(function (jwtoken) { | ||||||
| @ -194,7 +216,6 @@ module.exports.create = function (state) { | |||||||
|       token.ws = ws; |       token.ws = ws; | ||||||
|       token.upgradeReq = upgradeReq; |       token.upgradeReq = upgradeReq; | ||||||
|       token.clients = {}; |       token.clients = {}; | ||||||
|       token.dynamicPorts = []; |  | ||||||
| 
 | 
 | ||||||
|       token.pausedConns = []; |       token.pausedConns = []; | ||||||
|       ws._socket.on('drain', function () { |       ws._socket.on('drain', function () { | ||||||
| @ -220,19 +241,37 @@ module.exports.create = function (state) { | |||||||
|         Devices.add(state.deviceLists, domainname, token); |         Devices.add(state.deviceLists, domainname, token); | ||||||
|       }); |       }); | ||||||
| 
 | 
 | ||||||
|       function handleTcpServer() { |       if (!firstToken || firstToken === jwtoken) { | ||||||
|         var serviceport = this.address().port; |         firstToken = jwtoken; | ||||||
|         console.info('[DynTcpConn] Port', serviceport, 'now open for', token.deviceId); |         token.dynamicPorts = []; | ||||||
|         token.dynamicPorts.push(serviceport); |  | ||||||
|         Devices.add(state.deviceLists, serviceport, token); |  | ||||||
|       } |  | ||||||
| 
 | 
 | ||||||
|       try { |         function onDynTcpReady() { | ||||||
|         token.server = require('net').createServer(onDynTcpConn).listen(0, handleTcpServer); |           var serviceport = this.address().port; | ||||||
|       } catch(e) { |           console.info('[DynTcpConn] Port', serviceport, 'now open for', token.deviceId); | ||||||
|         // what a wonderful problem it will be the day that this bug needs to be fixed
 |           token.dynamicPorts.push(serviceport); | ||||||
|         // (i.e. there are enough users to run out of ports)
 |           Devices.add(state.deviceLists, serviceport, token); | ||||||
|         console.error("Error assigning a dynamic port to a new connection:", e); |           sendTunnelMsg( | ||||||
|  |             null | ||||||
|  |           , [ 2 | ||||||
|  |             , 'grant' | ||||||
|  |             , [ ['tcp', serviceport] | ||||||
|  |               , ['https', 'ssh.test.telebit.cloud' ] | ||||||
|  |               ] | ||||||
|  |             ] | ||||||
|  |           , 'control' | ||||||
|  |           ); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         try { | ||||||
|  |           token.server = require('net').createServer(onDynTcpConn).listen(0, onDynTcpReady); | ||||||
|  |           token.server.on('error', function (e) { | ||||||
|  |             console.error("Server Error assigning a dynamic port to a new connection:", e); | ||||||
|  |           }); | ||||||
|  |         } catch(e) { | ||||||
|  |           // what a wonderful problem it will be the day that this bug needs to be fixed
 | ||||||
|  |           // (i.e. there are enough users to run out of ports)
 | ||||||
|  |           console.error("Error assigning a dynamic port to a new connection:", e); | ||||||
|  |         } | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       remotes[jwtoken] = token; |       remotes[jwtoken] = token; | ||||||
| @ -256,12 +295,14 @@ module.exports.create = function (state) { | |||||||
|       }); |       }); | ||||||
|       remote.ws = null; |       remote.ws = null; | ||||||
|       remote.upgradeReq = null; |       remote.upgradeReq = null; | ||||||
|       remote.serverPort = remote.server.address().port; |       if (remote.server) { | ||||||
|       remote.server.close(function () { |         remote.serverPort = remote.server.address().port; | ||||||
|         console.log("[DynTcpConn] closing server for ", remote.serverPort); |         remote.server.close(function () { | ||||||
|         remote.serverPort = null; |           console.log("[DynTcpConn] closing server for ", remote.serverPort); | ||||||
|       }); |           remote.serverPort = null; | ||||||
|       remote.server = null; |         }); | ||||||
|  |         remote.server = null; | ||||||
|  |       } | ||||||
| 
 | 
 | ||||||
|       // Close all of the existing browser connections associated with this websocket connection.
 |       // Close all of the existing browser connections associated with this websocket connection.
 | ||||||
|       Object.keys(remote.clients).forEach(function (cid) { |       Object.keys(remote.clients).forEach(function (cid) { | ||||||
| @ -272,26 +313,6 @@ module.exports.create = function (state) { | |||||||
|       return null; |       return null; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     var firstToken; |  | ||||||
|     var authn = (upgradeReq.headers.authorization||'').split(/\s+/); |  | ||||||
|     if (authn[0] && 'basic' === authn[0].toLowerCase()) { |  | ||||||
|       try { |  | ||||||
|         authn = new Buffer(authn[1], 'base64').toString('ascii').split(':'); |  | ||||||
|         firstToken = authn[1]; |  | ||||||
|       } catch (err) { } |  | ||||||
|     } |  | ||||||
|     if (!firstToken) { |  | ||||||
|       firstToken = url.parse(upgradeReq.url, true).query.access_token; |  | ||||||
|     } |  | ||||||
|     if (firstToken) { |  | ||||||
|       var err = addToken(firstToken); |  | ||||||
|       if (err) { |  | ||||||
|         sendTunnelMsg(null, [0, err], 'control'); |  | ||||||
|         ws.close(); |  | ||||||
|         return; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     var commandHandlers = { |     var commandHandlers = { | ||||||
|       add_token: addToken |       add_token: addToken | ||||||
|     , delete_token: function (token) { |     , delete_token: function (token) { | ||||||
| @ -413,11 +434,10 @@ module.exports.create = function (state) { | |||||||
|     }; |     }; | ||||||
|     var unpacker = Packer.create(packerHandlers); |     var unpacker = Packer.create(packerHandlers); | ||||||
| 
 | 
 | ||||||
|     var lastActivity = Date.now(); |  | ||||||
|     var timeoutId; |  | ||||||
|     function refreshTimeout() { |     function refreshTimeout() { | ||||||
|       lastActivity = Date.now(); |       lastActivity = Date.now(); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|     function checkTimeout() { |     function checkTimeout() { | ||||||
|       // Determine how long the connection has been "silent", ie no activity.
 |       // Determine how long the connection has been "silent", ie no activity.
 | ||||||
|       var silent = Date.now() - lastActivity; |       var silent = Date.now() - lastActivity; | ||||||
| @ -447,18 +467,13 @@ module.exports.create = function (state) { | |||||||
|         ws.close(1013, 'connection timeout'); |         ws.close(1013, 'connection timeout'); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     timeoutId = setTimeout(checkTimeout, activityTimeout); |  | ||||||
| 
 | 
 | ||||||
|     // Note that our websocket library automatically handles pong responses on ping requests
 |     function forwardMessage(chunk) { | ||||||
|     // before it even emits the event.
 |  | ||||||
|     ws.on('ping', refreshTimeout); |  | ||||||
|     ws.on('pong', refreshTimeout); |  | ||||||
|     ws.on('message', function forwardMessage(chunk) { |  | ||||||
|       refreshTimeout(); |       refreshTimeout(); | ||||||
|       if (state.debug) { console.log('[ws] device => client : demultiplexing message ', chunk.byteLength, 'bytes'); } |       if (state.debug) { console.log('[ws] device => client : demultiplexing message ', chunk.byteLength, 'bytes'); } | ||||||
|       //console.log(chunk.toString());
 |       //console.log(chunk.toString());
 | ||||||
|       unpacker.fns.addChunk(chunk); |       unpacker.fns.addChunk(chunk); | ||||||
|     }); |     } | ||||||
| 
 | 
 | ||||||
|     function hangup() { |     function hangup() { | ||||||
|       clearTimeout(timeoutId); |       clearTimeout(timeoutId); | ||||||
| @ -469,6 +484,16 @@ module.exports.create = function (state) { | |||||||
|       ws.terminate(); |       ws.terminate(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     var lastActivity = Date.now(); | ||||||
|  |     var timeoutId; | ||||||
|  | 
 | ||||||
|  |     timeoutId = setTimeout(checkTimeout, activityTimeout); | ||||||
|  | 
 | ||||||
|  |     // Note that our websocket library automatically handles pong responses on ping requests
 | ||||||
|  |     // before it even emits the event.
 | ||||||
|  |     ws.on('ping', refreshTimeout); | ||||||
|  |     ws.on('pong', refreshTimeout); | ||||||
|  |     ws.on('message', forwardMessage); | ||||||
|     ws.on('close', hangup); |     ws.on('close', hangup); | ||||||
|     ws.on('error', hangup); |     ws.on('error', hangup); | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user