Improved agent coredump processing.
Ylian Saint-Hilaire committed
Oct 27, 2020 at 16:40 UTC
ed45f7b4a72ec0260712657a924bbeda7c6c2938
3 files changed
+48
-12
agents/meshcore.js
+28
-6
@@ -1140,8 +1140,12 @@ function createMeshCore(agent) {
1140
case 'coredump':
1141
// Set the current agent coredump situation.
1142
if (data.value === true) {
1143
- // TODO: This replace() below is not ideal, would be better to remove the .exe at the end instead of replace.
1144
- process.coreDumpLocation = (process.platform == 'win32') ? (process.execPath.replace('.exe', '.dmp')) : (process.execPath + '.dmp');
1143
+ if (process.platform == 'win32') {
1144
+ // TODO: This replace() below is not ideal, would be better to remove the .exe at the end instead of replace.
1145
+ process.coreDumpLocation = process.execPath.replace('.exe', '.dmp');
1146
+ } else {
1147
+ process.coreDumpLocation = (process.cwd() != '//') ? (process.cwd() + 'core') : null;
1148
+ }
1149
} else if (data.value === false) {
1150
process.coreDumpLocation = null;
1151
}
@@ -1151,8 +1155,18 @@ function createMeshCore(agent) {
1155
var r = { action: 'getcoredump', value: (process.coreDumpLocation != null) };
1156
var coreDumpPath = null;
1157
if (process.platform == 'win32') { coreDumpPath = process.coreDumpLocation; } else { coreDumpPath = (process.cwd() != '//') ? fs.existsSync(process.cwd() + 'core') : null; }
1154
- if ((coreDumpPath != null) && (fs.existsSync(coreDumpPath))) { r.exists = (db.Get('CoreDumpTime') != require('fs').statSync(coreDumpPath).mtime); }
1155
- if (r.exists == true) { r.agenthashhex = getSHA384FileHash(process.execPath).toString('hex'); }
1158
+ if ((coreDumpPath != null) && (fs.existsSync(coreDumpPath))) {
1159
+ try {
1160
+ var coredate = fs.statSync(coreDumpPath).mtime;
1161
+ var coretime = new Date(coredate).getTime();
1162
+ var agenttime = new Date(fs.statSync(process.execPath).mtime).getTime();
1163
+ if (coretime > agenttime) { r.exists = (db.Get('CoreDumpTime') != coredate); }
1164
+ } catch (ex) { }
1165
+ }
1166
+ if (r.exists == true) {
1167
+ r.agenthashhex = getSHA384FileHash(process.execPath).toString('hex'); // Hash of current agent
1168
+ r.corehashhex = getSHA384FileHash(coreDumpPath).toString('hex'); // Hash of core dump file
1169
+ }
1170
mesh.SendCommand(JSON.stringify(r));
1171
default:
1172
// Unknown action, ignore it.
@@ -2662,9 +2676,17 @@ function createMeshCore(agent) {
2676
response = 'coredump is: ' + ((process.coreDumpLocation == null) ? 'off' : 'on');
2677
if (process.coreDumpLocation != null) {
2678
if (process.platform == 'win32') {
2665
- if (fs.existsSync(process.coreDumpLocation)) { response += '\r\n CoreDump present at: ' + process.coreDumpLocation; }
2679
+ if (fs.existsSync(process.coreDumpLocation)) {
2680
+ response += '\r\n CoreDump present at: ' + process.coreDumpLocation;
2681
+ response += '\r\n CoreDump Time: ' + new Date(fs.statSync(process.coreDumpLocation).mtime).getTime();
2682
+ response += '\r\n Agent Time : ' + new Date(fs.statSync(process.execPath).mtime).getTime();
2683
+ }
2684
} else {
2667
- if ((process.cwd() != '//') && fs.existsSync(process.cwd() + 'core')) { response += '\r\n CoreDump present at: ' + process.cwd() + 'core'; }
2685
+ if ((process.cwd() != '//') && fs.existsSync(process.cwd() + 'core')) {
2686
+ response += '\r\n CoreDump present at: ' + process.cwd() + 'core';
2687
+ response += '\r\n CoreDump Time: ' + new Date(fs.statSync(process.cwd() + 'core').mtime).getTime();
2688
+ response += '\r\n Agent Time : ' + new Date(fs.statSync(process.execPath).mtime).getTime();
2689
+ }
2690
}
2691
}
2692
break;
meshagent.js
+2
-2
@@ -1395,7 +1395,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
1395
1396
// Get the core dump uploaded to the server.
1397
parent.lastCoreDumpRequest = Date.now();
1398
- obj.RequestCoreDump(command.agenthashhex);
1398
+ obj.RequestCoreDump(command.agenthashhex, command.corehashhex);
1399
});
1400
});
1401
}
@@ -1668,7 +1668,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
1668
}
1669
1670
// Request that the core dump file on this agent be uploaded to the server
1671
- obj.RequestCoreDump = function (agenthashhex) {
1671
+ obj.RequestCoreDump = function (agenthashhex, corehashhex) {
1672
if (agenthashhex.length > 16) { agenthashhex = agenthashhex.substring(0, 16); }
1673
const cookie = parent.parent.encodeCookie({ a: 'aft', b: 'coredump', c: obj.agentInfo.agentId + '-' + agenthashhex + '-' + obj.nodeid + '.dmp' }, parent.parent.loginCookieEncryptionKey);
1674
obj.send('{"action":"msg","type":"tunnel","value":"*/' + (((domain.dns == null) && (domain.id != '')) ? (domain.id + '/') : '') + 'agenttransfer.ashx?c=' + cookie + '","rights":"4294967295"}');
webserver.js
+18
-4
@@ -3753,7 +3753,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
3753
onFileOpen.xws.send(JSON.stringify({ action: 'download', sub: 'startack', id: onFileOpen.xws.xid, ack: 1 })); // Ask for a directory (test)
3754
};
3755
callback.xws = this;
3756
- obj.fs.open(this.xfilepath, 'w', callback)
3756
+ obj.fs.open(this.xfilepath + '.part', 'w', callback);
3757
break;
3758
}
3759
}
@@ -3769,7 +3769,11 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
3769
if (onFileDataWritten.xflags & 1) {
3770
// End of file
3771
parent.debug('web', "Completed downloads of agent dumpfile, " + onFileDataWritten.xws.xfilelen + " bytes.");
3772
- if (onFileDataWritten.xws.xfile) { try { obj.fs.close(onFileDataWritten.xws.xfile, function (err) { }); } catch (ex) { } }
3772
+ if (onFileDataWritten.xws.xfile) {
3773
+ obj.fs.close(onFileDataWritten.xws.xfile, function (err) { });
3774
+ obj.fs.rename(onFileDataWritten.xws.xfilepath + '.part', onFileDataWritten.xws.xfilepath, function (err) { });
3775
+ onFileDataWritten.xws.xfile = null;
3776
+ }
3777
onFileDataWritten.xws.send(JSON.stringify({ action: 'markcoredump' })); // Ask to delete the core dump file
3778
try { onFileDataWritten.xws.close(); } catch (ex) { }
3779
} else {
@@ -3785,7 +3789,11 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
3789
if (flags & 1) {
3790
// End of file
3791
parent.debug('web', "Completed downloads of agent dumpfile, " + this.xfilelen + " bytes.");
3788
- if (this.xfile) { try { obj.fs.close(this.xfile, function (err) { }); } catch (ex) { } }
3792
+ if (this.xfile) {
3793
+ obj.fs.close(this.xfile, function (err) { });
3794
+ obj.fs.rename(this.xfilepath + '.part', this.xfilepath, function (err) { });
3795
+ this.xfile = null;
3796
+ }
3797
this.send(JSON.stringify({ action: 'markcoredump' })); // Ask to delete the core dump file
3798
try { this.close(); } catch (ex) { }
3799
} else {
@@ -3800,7 +3808,12 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
3808
ws.on('error', function (err) { console.log('Agent file transfer server error from ' + req.clientIp + ', ' + err.toString().split('\r')[0] + '.'); });
3809
3810
// If closed, do nothing
3803
- ws.on('close', function (req) { });
3811
+ ws.on('close', function (req) {
3812
+ if (this.xfile) {
3813
+ obj.fs.close(this.xfile, function (err) { });
3814
+ obj.fs.unlink(this.xfilepath + '.part', function (err) { }); // Remove a partial file
3815
+ }
3816
+ });
3817
}
3818
3819
// Handle the web socket echo request, just echo back the data sent
@@ -5853,6 +5866,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
5866
obj.GetNodeRights = function (user, mesh, nodeid) {
5867
if ((user == null) || (mesh == null) || (nodeid == null)) { return 0; }
5868
if (typeof user == 'string') { user = obj.users[user]; }
5869
+ if (user == null) { return 0; }
5870
var r = obj.GetMeshRights(user, mesh);
5871
if (r == 0xFFFFFFFF) return r;
5872