mirror of
				https://github.com/Ylianst/MeshCentral.git
				synced 2025-03-09 15:40:18 +00:00 
			
		
		
		
	Improved tunnel clean up, #4172
This commit is contained in:
		
							parent
							
								
									22edf8d45f
								
							
						
					
					
						commit
						d2b39fef3e
					
				
					 1 changed files with 25 additions and 6 deletions
				
			
		
							
								
								
									
										31
									
								
								apprelays.js
									
										
									
									
									
								
							
							
						
						
									
										31
									
								
								apprelays.js
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -82,6 +82,7 @@ module.exports.CreateWebRelaySession = function (parent, db, req, args, domain,
 | 
			
		|||
    var pendingRequests = [];
 | 
			
		||||
    var nextTunnelId = 1;
 | 
			
		||||
    var tunnels = {};
 | 
			
		||||
    var errorCount = 0; // If we keep closing tunnels without processing requests, fail the requests
 | 
			
		||||
 | 
			
		||||
    // Any HTTP cookie set by the device is going to be shared between all tunnels to that device.
 | 
			
		||||
    obj.webCookies = {};
 | 
			
		||||
| 
						 | 
				
			
			@ -121,6 +122,12 @@ module.exports.CreateWebRelaySession = function (parent, db, req, args, domain,
 | 
			
		|||
 | 
			
		||||
    // Handle request
 | 
			
		||||
    function handleNextRequest() {
 | 
			
		||||
        // if there are not pending requests, do nothing
 | 
			
		||||
        if (pendingRequests.length == 0) return;
 | 
			
		||||
 | 
			
		||||
        // If the errorCount is high, something is really wrong, we are opening lots of tunnels and not processing any requests.
 | 
			
		||||
        if (errorCount > 5) { close(); return; }
 | 
			
		||||
 | 
			
		||||
        // Check to see if any of the tunnels are free
 | 
			
		||||
        var count = 0;
 | 
			
		||||
        for (var i in tunnels) {
 | 
			
		||||
| 
						 | 
				
			
			@ -140,12 +147,10 @@ module.exports.CreateWebRelaySession = function (parent, db, req, args, domain,
 | 
			
		|||
    function launchNewTunnel() {
 | 
			
		||||
        // Launch a new tunnel
 | 
			
		||||
        const tunnel = module.exports.CreateWebRelay(obj, db, args, domain);
 | 
			
		||||
        tunnel.onclose = function (tunnelId) {
 | 
			
		||||
        tunnel.onclose = function (tunnelId, processedCount) {
 | 
			
		||||
            if (processedCount == 0) { errorCount++; } // If this tunnel closed without processing any requests, mark this as an error
 | 
			
		||||
            delete tunnels[tunnelId];
 | 
			
		||||
            // Count how many non-websocket tunnels are active
 | 
			
		||||
            var count = 0;
 | 
			
		||||
            for (var i in tunnels) { count += (tunnels[i].isWebSocket ? 0 : 1); }
 | 
			
		||||
            if (count == 0) { launchNewTunnel(); }
 | 
			
		||||
            handleNextRequest();
 | 
			
		||||
        }
 | 
			
		||||
        tunnel.onconnect = function (tunnelId) {
 | 
			
		||||
            if (pendingRequests.length > 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -154,6 +159,7 @@ module.exports.CreateWebRelaySession = function (parent, db, req, args, domain,
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
        tunnel.oncompleted = function (tunnelId) {
 | 
			
		||||
            errorCount = 0; // Something got completed, clear any error count
 | 
			
		||||
            if (pendingRequests.length > 0) {
 | 
			
		||||
                const x = pendingRequests.shift();
 | 
			
		||||
                if (x[2] == true) { tunnels[tunnelId].processWebSocket(x[0], x[1]); } else { tunnels[tunnelId].processRequest(x[0], x[1]); }
 | 
			
		||||
| 
						 | 
				
			
			@ -166,11 +172,21 @@ module.exports.CreateWebRelaySession = function (parent, db, req, args, domain,
 | 
			
		|||
 | 
			
		||||
    // Close all tunnels
 | 
			
		||||
    function close() {
 | 
			
		||||
        // Set the session as closed
 | 
			
		||||
        if (obj.closed == true) return;
 | 
			
		||||
        obj.closed = true;
 | 
			
		||||
 | 
			
		||||
        // Close all tunnels
 | 
			
		||||
        for (var i in tunnels) { tunnels[i].close(); }
 | 
			
		||||
        tunnels = null;
 | 
			
		||||
 | 
			
		||||
        // Close any pending requests
 | 
			
		||||
        for (var i in pendingRequests) { if (pendingRequests[i][2] == true) { pendingRequests[i][1].end(); } else { pendingRequests[i][1].close(); } }
 | 
			
		||||
 | 
			
		||||
        // Notify of session closure
 | 
			
		||||
        if (obj.onclose) { obj.onclose(obj.userid + '/' + obj.sessionId); }
 | 
			
		||||
 | 
			
		||||
        // Cleanup
 | 
			
		||||
        delete obj.userid;
 | 
			
		||||
        delete obj.lastOperation;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -189,6 +205,7 @@ module.exports.CreateWebRelay = function (parent, db, args, domain) {
 | 
			
		|||
    obj.relayActive = false;
 | 
			
		||||
    obj.closed = false;
 | 
			
		||||
    obj.isWebSocket = false;
 | 
			
		||||
    obj.processedRequestCount = 0;
 | 
			
		||||
    const constants = (require('crypto').constants ? require('crypto').constants : require('constants')); // require('constants') is deprecated in Node 11.10, use require('crypto').constants instead.
 | 
			
		||||
 | 
			
		||||
    // Events
 | 
			
		||||
| 
						 | 
				
			
			@ -341,7 +358,7 @@ module.exports.CreateWebRelay = function (parent, db, args, domain) {
 | 
			
		|||
        if (obj.ws) { obj.ws.close(); delete obj.ws; }
 | 
			
		||||
 | 
			
		||||
        // Event disconnection
 | 
			
		||||
        if (obj.onclose) { obj.onclose(obj.tunnelId); }
 | 
			
		||||
        if (obj.onclose) { obj.onclose(obj.tunnelId, obj.processedRequestCount); }
 | 
			
		||||
 | 
			
		||||
        obj.relayActive = false;
 | 
			
		||||
    };
 | 
			
		||||
| 
						 | 
				
			
			@ -461,6 +478,7 @@ module.exports.CreateWebRelay = function (parent, db, args, domain) {
 | 
			
		|||
                if ((obj.socketXHeader['transfer-encoding'] != null) && (obj.socketXHeader['transfer-encoding'].toLowerCase() == 'chunked')) { obj.socketParseState = 1; }
 | 
			
		||||
                if (obj.isWebSocket) {
 | 
			
		||||
                    if ((obj.socketXHeader['connection'] != null) && (obj.socketXHeader['connection'].toLowerCase() == 'upgrade')) {
 | 
			
		||||
                        obj.processedRequestCount++;
 | 
			
		||||
                        obj.socketParseState = 2; // Switch to decoding websocket frames
 | 
			
		||||
                        obj.ws._socket.resume(); // Resume the browser's websocket
 | 
			
		||||
                    } else {
 | 
			
		||||
| 
						 | 
				
			
			@ -615,6 +633,7 @@ module.exports.CreateWebRelay = function (parent, db, args, domain) {
 | 
			
		|||
                delete obj.res;
 | 
			
		||||
 | 
			
		||||
                // Event completion
 | 
			
		||||
                obj.processedRequestCount++;
 | 
			
		||||
                if (obj.oncompleted) { obj.oncompleted(obj.tunnelId); }
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue