DB performance fixes.

This commit is contained in:
Ylian Saint-Hilaire 2019-02-20 15:26:27 -08:00
parent 05e724f862
commit 7b475d57fc
8 changed files with 77 additions and 73 deletions

4
db.js
View File

@ -71,10 +71,12 @@ module.exports.CreateDB = function (parent) {
// Check if we need to reset indexes // Check if we need to reset indexes
var indexesByName = {}, indexCount = 0; var indexesByName = {}, indexCount = 0;
for (var i in indexes) { indexesByName[indexes[i].name] = indexes[i]; indexCount++; } for (var i in indexes) { indexesByName[indexes[i].name] = indexes[i]; indexCount++; }
if ((indexCount != 3) || (indexesByName['IdsAndTime1'] == null) || (indexesByName['ExpireTime1'] == null)) { if ((indexCount != 5) || (indexesByName['Username1'] == null) || (indexesByName['DomainNodeTime1'] == null) || (indexesByName['IdsAndTime1'] == null) || (indexesByName['ExpireTime1'] == null)) {
// Reset all indexes // Reset all indexes
console.log('Resetting events indexes...'); console.log('Resetting events indexes...');
obj.eventsfile.dropIndexes(function (err) { obj.eventsfile.dropIndexes(function (err) {
obj.eventsfile.createIndex({ username: 1 }, { sparse: 1, name: 'Username1' });
obj.eventsfile.createIndex({ domain: 1, nodeid: 1, time: -1 }, { sparse: 1, name: 'DomainNodeTime1' });
obj.eventsfile.createIndex({ ids: 1, time: -1 }, { sparse: 1, name: 'IdsAndTime1' }); obj.eventsfile.createIndex({ ids: 1, time: -1 }, { sparse: 1, name: 'IdsAndTime1' });
obj.eventsfile.createIndex({ "time": 1 }, { expireAfterSeconds: expireEventsSeconds, name: 'ExpireTime1' }); obj.eventsfile.createIndex({ "time": 1 }, { expireAfterSeconds: expireEventsSeconds, name: 'ExpireTime1' });
}); });

View File

@ -1017,8 +1017,9 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
if ((command.intelamt.uuid != null) && (device.intelamt.uuid != command.intelamt.uuid)) { changes.push('AMT uuid'); device.intelamt.uuid = command.intelamt.uuid; change = 1; log = 1; } if ((command.intelamt.uuid != null) && (device.intelamt.uuid != command.intelamt.uuid)) { changes.push('AMT uuid'); device.intelamt.uuid = command.intelamt.uuid; change = 1; log = 1; }
} }
if ((command.users != null) && (device.users != command.users)) { device.users = command.users; change = 1; } // Don't save this to the db. if ((command.users != null) && (device.users != command.users)) { device.users = command.users; change = 1; } // Don't save this to the db.
if (mesh.mtype == 2) { if ((mesh.mtype == 2) && (!obj.args.wanonly)) {
if (device.host != obj.remoteaddr) { device.host = obj.remoteaddr; change = 1; log = 1; changes.push('host'); } // In WAN mode, the hostname of a computer is not important. Don't log hostname changes.
if (device.host != obj.remoteaddr) { device.host = obj.remoteaddr; change = 1; changes.push('host'); }
// TODO: Check that the agent has an interface that is the same as the one we got this websocket connection on. Only set if we have a match. // TODO: Check that the agent has an interface that is the same as the one we got this websocket connection on. Only set if we have a match.
} }

View File

@ -246,80 +246,77 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
// Check the CIRA username, which should be the start of the MeshID. // Check the CIRA username, which should be the start of the MeshID.
if (usernameLen != 16) { Debug(1, 'MPS:Username length not 16', username, password); SendUserAuthFail(socket); return -1; } if (usernameLen != 16) { Debug(1, 'MPS:Username length not 16', username, password); SendUserAuthFail(socket); return -1; }
var meshIdStart = '/' + username; var meshIdStart = '/' + username, mesh = null;
obj.db.GetAllType('mesh', function (err, docs) { if (obj.parent.webserver.meshes) { for (var i in obj.parent.webserver.meshes) { if (obj.parent.webserver.meshes[i]._id.replace(/\@/g, 'X').replace(/\$/g, 'X').indexOf(meshIdStart) > 0) { mesh = obj.parent.webserver.meshes[i]; break; } } }
var mesh = null; if (mesh == null) { Debug(1, 'MPS:Mesh not found', username, password); SendUserAuthFail(socket); return -1; }
for (var i in docs) { if (docs[i]._id.replace(/\@/g, 'X').replace(/\$/g, 'X').indexOf(meshIdStart) > 0) { mesh = docs[i]; break; } }
if (mesh == null) { Debug(1, 'MPS:Mesh not found', username, password); SendUserAuthFail(socket); return -1; }
// If this is a agent-less mesh, use the device guid 3 times as ID. // If this is a agent-less mesh, use the device guid 3 times as ID.
if (mesh.mtype == 1) { if (mesh.mtype == 1) {
// Intel AMT GUID (socket.tag.SystemId) will be used as NodeID // Intel AMT GUID (socket.tag.SystemId) will be used as NodeID
var systemid = socket.tag.SystemId.split('-').join(''); var systemid = socket.tag.SystemId.split('-').join('');
var nodeid = Buffer.from(systemid + systemid + systemid, 'hex').toString('base64').replace(/\+/g, '@').replace(/\//g, '$'); var nodeid = Buffer.from(systemid + systemid + systemid, 'hex').toString('base64').replace(/\+/g, '@').replace(/\//g, '$');
socket.tag.name = ''; socket.tag.name = '';
socket.tag.nodeid = 'node/' + mesh.domain + '/' + nodeid; // Turn 16bit systemid guid into 48bit nodeid that is base64 encoded socket.tag.nodeid = 'node/' + mesh.domain + '/' + nodeid; // Turn 16bit systemid guid into 48bit nodeid that is base64 encoded
socket.tag.meshid = mesh._id; socket.tag.meshid = mesh._id;
socket.tag.connectTime = Date.now(); socket.tag.connectTime = Date.now();
obj.db.Get(socket.tag.nodeid, function (err, nodes) { obj.db.Get(socket.tag.nodeid, function (err, nodes) {
if (nodes.length == 0) { if (nodes.length == 0) {
if (mesh.mtype == 1) { if (mesh.mtype == 1) {
// Node is not in the database, add it. Credentials will be empty until added by the user. // Node is not in the database, add it. Credentials will be empty until added by the user.
var device = { type: 'node', mtype: 1, _id: socket.tag.nodeid, meshid: socket.tag.meshid, name: socket.tag.name, host: null, domain: mesh.domain, intelamt: { user: '', pass: '', tls: 0, state: 2 } }; var device = { type: 'node', mtype: 1, _id: socket.tag.nodeid, meshid: socket.tag.meshid, name: socket.tag.name, host: null, domain: mesh.domain, intelamt: { user: '', pass: '', tls: 0, state: 2 } };
obj.db.Set(device); obj.db.Set(device);
// Event the new node // Event the new node
var device2 = common.Clone(device); var device2 = common.Clone(device);
if (device2.intelamt.pass != undefined) delete device2.intelamt.pass; // Remove the Intel AMT password before eventing this. if (device2.intelamt.pass != undefined) delete device2.intelamt.pass; // Remove the Intel AMT password before eventing this.
var change = 'CIRA added device ' + socket.tag.name + ' to mesh ' + mesh.name; var change = 'CIRA added device ' + socket.tag.name + ' to mesh ' + mesh.name;
obj.parent.DispatchEvent(['*', socket.tag.meshid], obj, { etype: 'node', action: 'addnode', node: device2, msg: change, domain: mesh.domain }); obj.parent.DispatchEvent(['*', socket.tag.meshid], obj, { etype: 'node', action: 'addnode', node: device2, msg: change, domain: mesh.domain });
} else {
// New CIRA connection for unknown node, disconnect.
console.log('CIRA connection for unknown node with incorrect mesh type. meshid: ' + socket.tag.meshid);
socket.end();
return;
}
} else { } else {
// Node is already present
var node = nodes[0];
if ((node.intelamt != undefined) && (node.intelamt.state == 2)) { socket.tag.host = node.intelamt.host; }
}
// Add the connection to the MPS connection list
obj.ciraConnections[socket.tag.nodeid] = socket;
obj.parent.SetConnectivityState(socket.tag.meshid, socket.tag.nodeid, socket.tag.connectTime, 2, 7); // TODO: Right now report power state as "present" (7) until we can poll.
SendUserAuthSuccess(socket); // Notify the auth success on the CIRA connection
});
} else if (mesh.mtype == 2) { // If this is a agent mesh, search the mesh for this device UUID
// Intel AMT GUID (socket.tag.SystemId) will be used to search the node
obj.db.getAmtUuidNode(mesh._id, socket.tag.SystemId, function (err, nodes) {
if (nodes.length == 0) {
// New CIRA connection for unknown node, disconnect. // New CIRA connection for unknown node, disconnect.
console.log('CIRA connection for unknown node. meshid: ' + mesh._id + ', uuid: ' + systemid); console.log('CIRA connection for unknown node with incorrect mesh type. meshid: ' + socket.tag.meshid);
socket.end(); socket.end();
return; return;
} }
} else {
// Node is present // Node is already present
var node = nodes[0]; var node = nodes[0];
if ((node.intelamt != undefined) && (node.intelamt.state == 2)) { socket.tag.host = node.intelamt.host; } if ((node.intelamt != undefined) && (node.intelamt.state == 2)) { socket.tag.host = node.intelamt.host; }
socket.tag.nodeid = node._id; }
socket.tag.meshid = mesh._id;
socket.tag.connectTime = Date.now();
// Add the connection to the MPS connection list // Add the connection to the MPS connection list
obj.ciraConnections[socket.tag.nodeid] = socket; obj.ciraConnections[socket.tag.nodeid] = socket;
obj.parent.SetConnectivityState(socket.tag.meshid, socket.tag.nodeid, socket.tag.connectTime, 2, 7); // TODO: Right now report power state as "present" (7) until we can poll. obj.parent.SetConnectivityState(socket.tag.meshid, socket.tag.nodeid, socket.tag.connectTime, 2, 7); // TODO: Right now report power state as "present" (7) until we can poll.
SendUserAuthSuccess(socket); // Notify the auth success on the CIRA connection SendUserAuthSuccess(socket); // Notify the auth success on the CIRA connection
}); });
} else { // Unknown mesh type } else if (mesh.mtype == 2) { // If this is a agent mesh, search the mesh for this device UUID
// New CIRA connection for unknown node, disconnect. // Intel AMT GUID (socket.tag.SystemId) will be used to search the node
console.log('CIRA connection to a unknown mesh type. meshid: ' + socket.tag.meshid); obj.db.getAmtUuidNode(mesh._id, socket.tag.SystemId, function (err, nodes) { // TODO: May need to optimize this request with indexes
socket.end(); if (nodes.length == 0) {
return; // New CIRA connection for unknown node, disconnect.
} console.log('CIRA connection for unknown node. meshid: ' + mesh._id + ', uuid: ' + systemid);
}); socket.end();
return;
}
// Node is present
var node = nodes[0];
if ((node.intelamt != undefined) && (node.intelamt.state == 2)) { socket.tag.host = node.intelamt.host; }
socket.tag.nodeid = node._id;
socket.tag.meshid = mesh._id;
socket.tag.connectTime = Date.now();
// Add the connection to the MPS connection list
obj.ciraConnections[socket.tag.nodeid] = socket;
obj.parent.SetConnectivityState(socket.tag.meshid, socket.tag.nodeid, socket.tag.connectTime, 2, 7); // TODO: Right now report power state as "present" (7) until we can poll.
SendUserAuthSuccess(socket); // Notify the auth success on the CIRA connection
});
} else { // Unknown mesh type
// New CIRA connection for unknown node, disconnect.
console.log('CIRA connection to a unknown mesh type. meshid: ' + socket.tag.meshid);
socket.end();
return;
}
return 18 + usernameLen + serviceNameLen + methodNameLen + passwordLen; return 18 + usernameLen + serviceNameLen + methodNameLen + passwordLen;
} }
case APFProtocol.SERVICE_REQUEST: { case APFProtocol.SERVICE_REQUEST: {

View File

@ -1,6 +1,6 @@
{ {
"name": "meshcentral", "name": "meshcentral",
"version": "0.2.8-y", "version": "0.2.8-z",
"keywords": [ "keywords": [
"Remote Management", "Remote Management",
"Intel AMT", "Intel AMT",

View File

@ -39,7 +39,7 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort, au
obj.socket.onopen = obj.xxOnSocketConnected; obj.socket.onopen = obj.xxOnSocketConnected;
obj.socket.onmessage = obj.xxOnMessage; obj.socket.onmessage = obj.xxOnMessage;
//obj.socket.onmessage = function (e) { console.log('Websocket data', e.data); obj.xxOnMessage(e); } //obj.socket.onmessage = function (e) { console.log('Websocket data', e.data); obj.xxOnMessage(e); }
obj.socket.onerror = function (e) { console.error(e); } obj.socket.onerror = function (e) { /* console.error(e); */ }
obj.socket.onclose = obj.xxOnSocketClosed; obj.socket.onclose = obj.xxOnSocketClosed;
obj.xxStateChange(1); obj.xxStateChange(1);
//obj.meshserver.send({ action: 'msg', type: 'tunnel', nodeid: obj.nodeid, value: url2 }); //obj.meshserver.send({ action: 'msg', type: 'tunnel', nodeid: obj.nodeid, value: url2 });

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1803,7 +1803,7 @@
} }
case 'stopped': { // Server is stopping. case 'stopped': { // Server is stopping.
// Disconnect // Disconnect
console.log(message.msg); //console.log(message.msg);
break; break;
} }
default: default:
@ -3391,6 +3391,10 @@
var powerTimeline = null; var powerTimeline = null;
function getCurrentNode() { return currentNode; }; function getCurrentNode() { return currentNode; };
function gotoDevice(nodeid, panel, refresh, event) { function gotoDevice(nodeid, panel, refresh, event) {
// Check if we are allowed to create a new device group
if ((userinfo.emailVerified !== true) && (serverinfo.emailcheck == true) && (userinfo.siteadmin != 0xFFFFFFFF)) { setDialogMode(2, "New Device Group", 1, null, "Unable to create a new device group until a email address is verified. This is required for password recovery. Go to the \"My Account\" tab to change and verify an email address."); return; }
if (event && (event.shiftKey == true)) { if (event && (event.shiftKey == true)) {
// Open the device in a different tab // Open the device in a different tab
window.open(window.location.origin + '?node=' + nodeid.split('/')[2] + '&viewmode=10&hide=16', 'meshcentral:' + nodeid); window.open(window.location.origin + '?node=' + nodeid.split('/')[2] + '&viewmode=10&hide=16', 'meshcentral:' + nodeid);
@ -4266,7 +4270,7 @@
} }
function applyDesktopSettings() { function applyDesktopSettings() {
var r = '', ops = (features & 512)?[90,70,50,40,30,20,10,5,1]:[50,40,30,20,10,5,1]; var r = '', ops = (features & 512)?[90,80,70,60,50,40,30,20,10,5,1]:[60,50,40,30,20,10,5,1];
for (var i in ops) { r += '<option value=' + ops[i] + '>' + ops[i] + '%</option>'; } for (var i in ops) { r += '<option value=' + ops[i] + '>' + ops[i] + '%</option>'; }
QH('d7bitmapquality', r); QH('d7bitmapquality', r);
d7desktopmode.value = desktopsettings.encoding; d7desktopmode.value = desktopsettings.encoding;
@ -5580,7 +5584,7 @@
if (xxdialogMode) return; if (xxdialogMode) return;
// Check if we are allowed to create a new device group // Check if we are allowed to create a new device group
if ((userinfo.emailVerified !== true) && (userinfo.email != null) && (serverinfo.emailcheck == true) && (userinfo.siteadmin != 0xFFFFFFFF)) { setDialogMode(2, "New Device Group", 1, null, "Unable to create a new device group until the email address is verified. Go to the \"My Account\" tab to change and verify an email address."); return; } if ((userinfo.emailVerified !== true) && (serverinfo.emailcheck == true) && (userinfo.siteadmin != 0xFFFFFFFF)) { setDialogMode(2, "New Device Group", 1, null, "Unable to create a new device group until a email address is verified. This is required for password recovery. Go to the \"My Account\" tab to change and verify an email address."); return; }
// We are allowed, let's prompt to information // We are allowed, let's prompt to information
var x = "Create a new device group using the options below.<br /><br />"; var x = "Create a new device group using the options below.<br /><br />";