Fix KVM clean up on WebRTC disconnect in meshcore.js.

This commit is contained in:
Ylian Saint-Hilaire 2019-01-03 14:46:52 -08:00
parent 7873bbba3f
commit 744c2faa6c
12 changed files with 38 additions and 19 deletions

View File

@ -1,3 +1,4 @@
@ECHO OFF
MD modules_meshcmd_min MD modules_meshcmd_min
MD modules_meshcore_min MD modules_meshcore_min
"..\..\WebSiteCompiler\bin\Debug\WebSiteCompiler.exe" compressalljs "modules_meshcore" "modules_meshcore_min" "..\..\WebSiteCompiler\bin\Debug\WebSiteCompiler.exe" compressalljs "modules_meshcore" "modules_meshcore_min"

View File

@ -1,3 +1,4 @@
@ECHO OFF
DEL meshcmd.min.js DEL meshcmd.min.js
DEL meshcore.min.js DEL meshcore.min.js
DEL modules_meshcmd_min\*.min.js DEL modules_meshcmd_min\*.min.js

File diff suppressed because one or more lines are too long

View File

@ -701,8 +701,17 @@ function createMeshCore(agent) {
this.end = function () { this.end = function () {
--this.desktop.kvm.connectionCount; --this.desktop.kvm.connectionCount;
// Unpipe the web socket
this.unpipe(this.httprequest.desktop.kvm); this.unpipe(this.httprequest.desktop.kvm);
this.httprequest.desktop.kvm.unpipe(this); this.httprequest.desktop.kvm.unpipe(this);
// Unpipe the WebRTC channel if needed (This will also be done when the WebRTC channel ends).
if (this.rtcchannel) {
this.rtcchannel.unpipe(this.httprequest.desktop.kvm);
this.httprequest.desktop.kvm.unpipe(this.rtcchannel);
}
if (this.desktop.kvm.connectionCount == 0) { if (this.desktop.kvm.connectionCount == 0) {
// Display a toast message // Display a toast message
//require('toaster').Toast('MeshCentral', 'Remote Desktop Control Ended.'); //require('toaster').Toast('MeshCentral', 'Remote Desktop Control Ended.');
@ -995,7 +1004,12 @@ function createMeshCore(agent) {
this.rtcchannel = rtcchannel; this.rtcchannel = rtcchannel;
this.websocket.rtcchannel = rtcchannel; this.websocket.rtcchannel = rtcchannel;
this.websocket.rtcchannel.on('data', onTunnelWebRTCControlData); this.websocket.rtcchannel.on('data', onTunnelWebRTCControlData);
this.websocket.rtcchannel.on('end', function () { /*sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC data channel closed');*/ }); this.websocket.rtcchannel.on('end', function () {
// The WebRTC channel closed, unpipe the KVM now. This is also done when the web socket closes.
/*sendConsoleText('Tunnel #' + this.websocket.tunnel.index + ' WebRTC data channel closed');*/
this.unpipe(this.websocket.desktop.kvm);
this.websocket.httprequest.desktop.kvm.unpipe(this);
});
this.websocket.write("{\"ctrlChannel\":\"102938\",\"type\":\"webrtc0\"}"); // Indicate we are ready for WebRTC switch-over. this.websocket.write("{\"ctrlChannel\":\"102938\",\"type\":\"webrtc0\"}"); // Indicate we are ready for WebRTC switch-over.
}); });
var sdp = null; var sdp = null;
@ -1719,7 +1733,7 @@ function createMeshCore(agent) {
var rtc = require('ILibWebRTC'); var rtc = require('ILibWebRTC');
webRtcDesktop.webrtc = rtc.createConnection(); webRtcDesktop.webrtc = rtc.createConnection();
webRtcDesktop.webrtc.on('connected', function () { }); webRtcDesktop.webrtc.on('connected', function () { });
webRtcDesktop.webrtc.on('disconnected', function () { webRtcCleanUp(); }); webRtcDesktop.webrtc.on('disconnected', function () { obj.webRtcCleanUp(); });
webRtcDesktop.webrtc.on('dataChannel', function (rtcchannel) { webRtcDesktop.webrtc.on('dataChannel', function (rtcchannel) {
webRtcDesktop.rtcchannel = rtcchannel; webRtcDesktop.rtcchannel = rtcchannel;
webRtcDesktop.kvm = mesh.getRemoteDesktopStream(); webRtcDesktop.kvm = mesh.getRemoteDesktopStream();
@ -1727,7 +1741,7 @@ function createMeshCore(agent) {
webRtcDesktop.rtcchannel.on('end', function () { obj.webRtcCleanUp(); }); webRtcDesktop.rtcchannel.on('end', function () { obj.webRtcCleanUp(); });
webRtcDesktop.rtcchannel.on('data', function (x) { obj.kvmCtrlData(this, x); }); webRtcDesktop.rtcchannel.on('data', function (x) { obj.kvmCtrlData(this, x); });
webRtcDesktop.rtcchannel.pipe(webRtcDesktop.kvm, { dataTypeSkip: 1, end: false }); webRtcDesktop.rtcchannel.pipe(webRtcDesktop.kvm, { dataTypeSkip: 1, end: false });
//webRtcDesktop.kvm.on('end', function () { console.log('WebRTC DataChannel closed2'); webRtcCleanUp(); }); //webRtcDesktop.kvm.on('end', function () { console.log('WebRTC DataChannel closed2'); obj.webRtcCleanUp(); });
//webRtcDesktop.rtcchannel.on('data', function (data) { console.log('WebRTC data: ' + data); }); //webRtcDesktop.rtcchannel.on('data', function (data) { console.log('WebRTC data: ' + data); });
}); });
obj.kvmSetData(JSON.stringify({ action: 'answer', ver: 1, sdp: webRtcDesktop.webrtc.setOffer(data.sdp) })); obj.kvmSetData(JSON.stringify({ action: 'answer', ver: 1, sdp: webRtcDesktop.webrtc.setOffer(data.sdp) }));
@ -1885,7 +1899,8 @@ function createMeshCore(agent) {
} }
} }
obj.webRtcCleanUp = function() { obj.webRtcCleanUp = function () {
sendConsoleText('webRtcCleanUp');
if (webRtcDesktop == null) return; if (webRtcDesktop == null) return;
if (webRtcDesktop.rtcchannel) { if (webRtcDesktop.rtcchannel) {
try { webRtcDesktop.rtcchannel.close(); } catch (e) { } try { webRtcDesktop.rtcchannel.close(); } catch (e) { }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -159,7 +159,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
if (obj.nodeid != null) { obj.parent.parent.debug(1, 'Agent update required, NodeID=0x' + obj.nodeid.substring(0, 16) + ', ' + obj.agentExeInfo.desc); } if (obj.nodeid != null) { obj.parent.parent.debug(1, 'Agent update required, NodeID=0x' + obj.nodeid.substring(0, 16) + ', ' + obj.agentExeInfo.desc); }
obj.fs.open(obj.agentExeInfo.path, 'r', function (err, fd) { obj.fs.open(obj.agentExeInfo.path, 'r', function (err, fd) {
if (err) { return console.error(err); } if (err) { return console.error(err); }
obj.agentUpdate = { oldHash: agenthash, ptr: 0, buf: Buffer.from(agentUpdateBlockSize + 4), fd: fd }; obj.agentUpdate = { oldHash: agenthash, ptr: 0, buf: Buffer.alloc(agentUpdateBlockSize + 4), fd: fd };
// We got the agent file open on the server side, tell the agent we are sending an update starting with the SHA384 hash of the result // We got the agent file open on the server side, tell the agent we are sending an update starting with the SHA384 hash of the result
//console.log("Agent update file open."); //console.log("Agent update file open.");

View File

@ -90,7 +90,7 @@ function CreateMeshCentralServer(config, args) {
try { require('./pass').hash('test', function () { }); } catch (e) { console.log('Old version of node, must upgrade.'); return; } // TODO: Not sure if this test works or not. try { require('./pass').hash('test', function () { }); } catch (e) { console.log('Old version of node, must upgrade.'); return; } // TODO: Not sure if this test works or not.
// Check for invalid arguments // Check for invalid arguments
var validArguments = ['_', 'notls', 'user', 'port', 'aliasport', 'mpsport', 'mpsaliasport', 'redirport', 'cert', 'mpscert', 'deletedomain', 'deletedefaultdomain', 'showall', 'showusers', 'shownodes', 'showmeshes', 'showevents', 'showpower', 'clearpower', 'showiplocations', 'help', 'exactports', 'install', 'uninstall', 'start', 'stop', 'restart', 'debug', 'filespath', 'datapath', 'noagentupdate', 'launch', 'noserverbackup', 'mongodb', 'mongodbcol', 'wanonly', 'lanonly', 'nousers', 'mpsdebug', 'mpspass', 'ciralocalfqdn', 'dbexport', 'dbimport', 'selfupdate', 'tlsoffload', 'userallowedip', 'fastcert', 'swarmport', 'swarmdebug', 'logintoken', 'logintokenkey', 'logintokengen', 'logintokengen', 'mailtokengen', 'admin', 'unadmin', 'sessionkey', 'sessiontime', 'minify']; var validArguments = ['_', 'notls', 'user', 'port', 'aliasport', 'mpsport', 'mpsaliasport', 'redirport', 'cert', 'mpscert', 'deletedomain', 'deletedefaultdomain', 'showall', 'showusers', 'shownodes', 'showmeshes', 'showevents', 'showpower', 'clearpower', 'showiplocations', 'help', 'exactports', 'install', 'uninstall', 'start', 'stop', 'restart', 'debug', 'filespath', 'datapath', 'noagentupdate', 'launch', 'noserverbackup', 'mongodb', 'mongodbcol', 'wanonly', 'lanonly', 'nousers', 'mpsdebug', 'mpspass', 'ciralocalfqdn', 'dbexport', 'dbimport', 'selfupdate', 'tlsoffload', 'userallowedip', 'fastcert', 'swarmport', 'swarmdebug', 'logintoken', 'logintokenkey', 'logintokengen', 'logintokengen', 'mailtokengen', 'admin', 'unadmin', 'sessionkey', 'sessiontime', 'minify', 'minifycore'];
for (var arg in obj.args) { obj.args[arg.toLocaleLowerCase()] = obj.args[arg]; if (validArguments.indexOf(arg.toLocaleLowerCase()) == -1) { console.log('Invalid argument "' + arg + '", use --help.'); return; } } for (var arg in obj.args) { obj.args[arg.toLocaleLowerCase()] = obj.args[arg]; if (validArguments.indexOf(arg.toLocaleLowerCase()) == -1) { console.log('Invalid argument "' + arg + '", use --help.'); return; } }
if (obj.args.mongodb == true) { console.log('Must specify: --mongodb [connectionstring] \r\nSee https://docs.mongodb.com/manual/reference/connection-string/ for MongoDB connection string.'); return; } if (obj.args.mongodb == true) { console.log('Must specify: --mongodb [connectionstring] \r\nSee https://docs.mongodb.com/manual/reference/connection-string/ for MongoDB connection string.'); return; }
for (i in obj.config.settings) { obj.args[i] = obj.config.settings[i]; } // Place all settings into arguments, arguments have already been placed into settings so arguments take precedence. for (i in obj.config.settings) { obj.args[i] = obj.config.settings[i]; } // Place all settings into arguments, arguments have already been placed into settings so arguments take precedence.
@ -250,6 +250,7 @@ function CreateMeshCentralServer(config, args) {
if (obj.args.mpsport == null || typeof obj.args.mpsport != 'number') obj.args.mpsport = 4433; if (obj.args.mpsport == null || typeof obj.args.mpsport != 'number') obj.args.mpsport = 4433;
if (obj.args.mpsaliasport != null && (typeof obj.args.mpsaliasport != 'number')) obj.args.mpsaliasport = null; if (obj.args.mpsaliasport != null && (typeof obj.args.mpsaliasport != 'number')) obj.args.mpsaliasport = null;
if (obj.args.notls == null && obj.args.redirport == null) obj.args.redirport = 80; if (obj.args.notls == null && obj.args.redirport == null) obj.args.redirport = 80;
if (obj.args.minifycore === 0) obj.args.minifycore = false;
if (typeof obj.args.debug == 'number') obj.debugLevel = obj.args.debug; if (typeof obj.args.debug == 'number') obj.debugLevel = obj.args.debug;
if (obj.args.debug == true) obj.debugLevel = 1; if (obj.args.debug == true) obj.debugLevel = 1;
obj.db = require('./db.js').CreateDB(obj); obj.db = require('./db.js').CreateDB(obj);
@ -897,11 +898,11 @@ function CreateMeshCentralServer(config, args) {
'linux-noamt': 'var addedModules = [];\r\n' 'linux-noamt': 'var addedModules = [];\r\n'
}; };
try { meshCore = obj.fs.readFileSync(obj.path.join(meshcorePath, 'meshcore.min.js')).toString(); } catch (e) { } // Favor minified meshcore if present. if (obj.args.minifycore !== false) { try { meshCore = obj.fs.readFileSync(obj.path.join(meshcorePath, 'meshcore.min.js')).toString(); } catch (e) { } } // Favor minified meshcore if present.
if (meshCore == null) { try { meshCore = obj.fs.readFileSync(obj.path.join(meshcorePath, 'meshcore.js')).toString(); } catch (e) { } } // Use non-minified meshcore. if (meshCore == null) { try { meshCore = obj.fs.readFileSync(obj.path.join(meshcorePath, 'meshcore.js')).toString(); } catch (e) { } } // Use non-minified meshcore.
if (meshCore != null) { if (meshCore != null) {
var moduleDirPath = null; var moduleDirPath = null;
try { moduleDirPath = obj.path.join(meshcorePath, 'modules_meshcore_min'); modulesDir = obj.fs.readdirSync(moduleDirPath); } catch (e) { } // Favor minified modules if present. if (obj.args.minifycore !== false) { try { moduleDirPath = obj.path.join(meshcorePath, 'modules_meshcore_min'); modulesDir = obj.fs.readdirSync(moduleDirPath); } catch (e) { } } // Favor minified modules if present.
if (modulesDir == null) { try { moduleDirPath = obj.path.join(meshcorePath, 'modules_meshcore'); modulesDir = obj.fs.readdirSync(moduleDirPath); } catch (e) { } } // Use non-minified mofules. if (modulesDir == null) { try { moduleDirPath = obj.path.join(meshcorePath, 'modules_meshcore'); modulesDir = obj.fs.readdirSync(moduleDirPath); } catch (e) { } } // Use non-minified mofules.
if (modulesDir != null) { if (modulesDir != null) {
for (var i in modulesDir) { for (var i in modulesDir) {
@ -952,17 +953,17 @@ function CreateMeshCentralServer(config, args) {
obj.updateMeshCmd = function (func) { obj.updateMeshCmd = function (func) {
// Figure out where meshcmd.js is and read it. // Figure out where meshcmd.js is and read it.
var meshCmd = null, meshcmdPath, moduleAdditions = 'var addedModules = [];\r\n', moduleDirPath, modulesDir = null; var meshCmd = null, meshcmdPath, moduleAdditions = 'var addedModules = [];\r\n', moduleDirPath, modulesDir = null;
if (obj.fs.existsSync(obj.path.join(obj.datapath, 'meshcmd.min.js'))) { meshcmdPath = obj.path.join(obj.datapath, 'meshcmd.min.js'); meshCmd = obj.fs.readFileSync(meshcmdPath).toString(); } if ((obj.args.minifycore !== false) && (obj.fs.existsSync(obj.path.join(obj.datapath, 'meshcmd.min.js')))) { meshcmdPath = obj.path.join(obj.datapath, 'meshcmd.min.js'); meshCmd = obj.fs.readFileSync(meshcmdPath).toString(); }
else if (obj.fs.existsSync(obj.path.join(obj.datapath, 'meshcmd.js'))) { meshcmdPath = obj.path.join(obj.datapath, 'meshcmd.js'); meshCmd = obj.fs.readFileSync(meshcmdPath).toString(); } else if (obj.fs.existsSync(obj.path.join(obj.datapath, 'meshcmd.js'))) { meshcmdPath = obj.path.join(obj.datapath, 'meshcmd.js'); meshCmd = obj.fs.readFileSync(meshcmdPath).toString(); }
else if (obj.fs.existsSync(obj.path.join(__dirname, 'agents', 'meshcmd.min.js'))) { meshcmdPath = obj.path.join(__dirname, 'agents', 'meshcmd.min.js'); meshCmd = obj.fs.readFileSync(meshcmdPath).toString(); } else if ((obj.args.minifycore !== false) && (obj.fs.existsSync(obj.path.join(__dirname, 'agents', 'meshcmd.min.js')))) { meshcmdPath = obj.path.join(__dirname, 'agents', 'meshcmd.min.js'); meshCmd = obj.fs.readFileSync(meshcmdPath).toString(); }
else if (obj.fs.existsSync(obj.path.join(__dirname, 'agents', 'meshcmd.js'))) { meshcmdPath = obj.path.join(__dirname, 'agents', 'meshcmd.js'); meshCmd = obj.fs.readFileSync(meshcmdPath).toString(); } else if (obj.fs.existsSync(obj.path.join(__dirname, 'agents', 'meshcmd.js'))) { meshcmdPath = obj.path.join(__dirname, 'agents', 'meshcmd.js'); meshCmd = obj.fs.readFileSync(meshcmdPath).toString(); }
else { obj.defaultMeshCmd = null; if (func != null) { func(false); } } // meshcmd.js not found else { obj.defaultMeshCmd = null; if (func != null) { func(false); } } // meshcmd.js not found
meshCmd = meshCmd.replace("'***Mesh*Cmd*Version***'", '\'' + obj.currentVer + '\''); meshCmd = meshCmd.replace("'***Mesh*Cmd*Version***'", '\'' + obj.currentVer + '\'');
// Figure out where the modules_meshcmd folder is. // Figure out where the modules_meshcmd folder is.
try { moduleDirPath = obj.path.join(meshcmdPath, 'modules_meshcmd_min'); modulesDir = obj.fs.readdirSync(moduleDirPath); } catch (e) { } // Favor minified modules if present. if (obj.args.minifycore !== false) { try { moduleDirPath = obj.path.join(meshcmdPath, 'modules_meshcmd_min'); modulesDir = obj.fs.readdirSync(moduleDirPath); } catch (e) { } } // Favor minified modules if present.
if (modulesDir == null) { try { moduleDirPath = obj.path.join(meshcmdPath, 'modules_meshcmd'); modulesDir = obj.fs.readdirSync(moduleDirPath); } catch (e) { } } // Use non-minified mofules. if (modulesDir == null) { try { moduleDirPath = obj.path.join(meshcmdPath, 'modules_meshcmd'); modulesDir = obj.fs.readdirSync(moduleDirPath); } catch (e) { } } // Use non-minified mofules.
if (modulesDir == null) { try { moduleDirPath = obj.path.join(__dirname, 'agents', 'modules_meshcmd_min'); modulesDir = obj.fs.readdirSync(moduleDirPath); } catch (e) { } } // Favor minified modules if present. if (obj.args.minifycore !== false) { if (modulesDir == null) { try { moduleDirPath = obj.path.join(__dirname, 'agents', 'modules_meshcmd_min'); modulesDir = obj.fs.readdirSync(moduleDirPath); } catch (e) { } } } // Favor minified modules if present.
if (modulesDir == null) { try { moduleDirPath = obj.path.join(__dirname, 'agents', 'modules_meshcmd'); modulesDir = obj.fs.readdirSync(moduleDirPath); } catch (e) { } } // Use non-minified mofules. if (modulesDir == null) { try { moduleDirPath = obj.path.join(__dirname, 'agents', 'modules_meshcmd'); modulesDir = obj.fs.readdirSync(moduleDirPath); } catch (e) { } } // Use non-minified mofules.
// Read all .js files in the meshcmd modules folder. // Read all .js files in the meshcmd modules folder.
@ -1211,6 +1212,7 @@ function CreateMeshCentralServer(config, args) {
// Update server state. Writes a server state file. // Update server state. Writes a server state file.
var meshServerState = {}; var meshServerState = {};
obj.updateServerState = function (name, val) { obj.updateServerState = function (name, val) {
//console.log('updateServerState', name, val);
try { try {
if ((name != null) && (val != null)) { if ((name != null) && (val != null)) {
var changed = false; var changed = false;

View File

@ -1,6 +1,6 @@
{ {
"name": "meshcentral", "name": "meshcentral",
"version": "0.2.5-l", "version": "0.2.5-m",
"keywords": [ "keywords": [
"Remote Management", "Remote Management",
"Intel AMT", "Intel AMT",