mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2025-03-09 15:40:18 +00:00
Completed server load-balancing support
This commit is contained in:
parent
1031eca853
commit
453383f851
19 changed files with 305 additions and 56 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -26,7 +26,7 @@ function createMeshCore(agent) {
|
|||
var lastNetworkInfo = null;
|
||||
var lastPublicLocationInfo = null;
|
||||
var selfInfoUpdateTimer = null;
|
||||
obj.useNativePipes = (process.platform == 'win32');
|
||||
obj.useNativePipes = true; //(process.platform == 'win32');
|
||||
|
||||
var http = require('http');
|
||||
var fs = require('fs');
|
||||
|
@ -158,7 +158,7 @@ function createMeshCore(agent) {
|
|||
};
|
||||
|
||||
// Replace a string with a number if the string is an exact number
|
||||
function toNumberIfNumber(x) { if ((typeof x == 'string') && (+parseInt(x) == x)) { x = parseInt(x); } return x; }
|
||||
function toNumberIfNumber(x) { if ((typeof x == 'string') && (+parseInt(x) === x)) { x = parseInt(x); } return x; }
|
||||
|
||||
// Convert decimal to hex
|
||||
function char2hex(i) { return (i + 0x100).toString(16).substr(-2).toUpperCase(); }
|
||||
|
@ -218,16 +218,48 @@ function createMeshCore(agent) {
|
|||
return results;
|
||||
}
|
||||
|
||||
// Parge a URL string into an options object
|
||||
function parseUrl(url) {
|
||||
var x = url.split('/');
|
||||
if (x.length < 4) return null;
|
||||
var y = x[2].split(':');
|
||||
var options = {};
|
||||
var options = { protocol: x[0], hostname: y[0], path: '/' + x.splice(3).join('/') };
|
||||
if (y.length == 1) { options.port = ((x[0] == 'https:') || (x[0] == 'wss:')) ? 443 : 80; } else { options.port = parseInt(y[1]); }
|
||||
if (isNaN(options.port) == true) return null;
|
||||
return options;
|
||||
// Get server target url with a custom path
|
||||
function getServerTargetUrl(path) {
|
||||
var x = mesh.ServerUrl;
|
||||
//sendConsoleText("mesh.ServerUrl: " + mesh.ServerUrl);
|
||||
if (x == null) { return null; }
|
||||
if (path == null) { path = ''; }
|
||||
x = http.parseUri(x);
|
||||
if (x == null) return null;
|
||||
return x.protocol + '//' + x.host + ':' + x.port + '/' + path;
|
||||
}
|
||||
|
||||
// Get server url. If the url starts with "*/..." change it, it not use the url as is.
|
||||
function getServerTargetUrlEx(url) {
|
||||
if (url.substring(0, 2) == '*/') { return getServerTargetUrl(url.substring(2)); }
|
||||
return url;
|
||||
}
|
||||
|
||||
// Send a wake-on-lan packet
|
||||
function sendWakeOnLan(hexMac) {
|
||||
var count = 0;
|
||||
try {
|
||||
var interfaces = require('os').networkInterfaces();
|
||||
var magic = 'FFFFFFFFFFFF';
|
||||
for (var x = 1; x <= 16; ++x) { magic += hexMac; }
|
||||
var magicbin = Buffer.from(magic, 'hex');
|
||||
|
||||
for (var adapter in interfaces) {
|
||||
if (interfaces.hasOwnProperty(adapter)) {
|
||||
for (var i = 0; i < interfaces[adapter].length; ++i) {
|
||||
var addr = interfaces[adapter][i];
|
||||
if ((addr.family == 'IPv4') && (addr.mac != '00:00:00:00:00:00')) {
|
||||
var socket = require('dgram').createSocket({ type: "udp4" });
|
||||
socket.bind({ address: addr.address });
|
||||
socket.setBroadcast(true);
|
||||
socket.send(magicbin, 7, "255.255.255.255");
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) { }
|
||||
return count;
|
||||
}
|
||||
|
||||
// Handle a mesh agent command
|
||||
|
@ -245,21 +277,26 @@ function createMeshCore(agent) {
|
|||
else if (data.type == 'tunnel') { // Process a new tunnel connection request
|
||||
if (data.value && data.sessionid) {
|
||||
// Create a new tunnel object
|
||||
var tunnel = http.request(parseUrl(data.value));
|
||||
tunnel.upgrade = onTunnelUpgrade;
|
||||
tunnel.sessionid = data.sessionid;
|
||||
tunnel.rights = data.rights;
|
||||
tunnel.state = 0;
|
||||
tunnel.url = data.value;
|
||||
tunnel.protocol = 0;
|
||||
//sendConsoleText(data.value);
|
||||
var xurl = getServerTargetUrlEx(data.value);
|
||||
//sendConsoleText(xurl);
|
||||
if (xurl != null) {
|
||||
var tunnel = http.request(http.parseUri(xurl));
|
||||
tunnel.upgrade = onTunnelUpgrade;
|
||||
tunnel.sessionid = data.sessionid;
|
||||
tunnel.rights = data.rights;
|
||||
tunnel.state = 0;
|
||||
tunnel.url = xurl;
|
||||
tunnel.protocol = 0;
|
||||
|
||||
// Put the tunnel in the tunnels list
|
||||
var index = 1;
|
||||
while (tunnels[index]) { index++; }
|
||||
tunnel.index = index;
|
||||
tunnels[index] = tunnel;
|
||||
// Put the tunnel in the tunnels list
|
||||
var index = 1;
|
||||
while (tunnels[index]) { index++; }
|
||||
tunnel.index = index;
|
||||
tunnels[index] = tunnel;
|
||||
|
||||
sendConsoleText('New tunnel connection #' + index + ': ' + tunnel.url + ', rights: ' + tunnel.rights, data.sessionid);
|
||||
sendConsoleText('New tunnel connection #' + index + ': ' + tunnel.url + ', rights: ' + tunnel.rights, data.sessionid);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -267,7 +304,7 @@ function createMeshCore(agent) {
|
|||
case 'wakeonlan': {
|
||||
// Send wake-on-lan on all interfaces for all MAC addresses in data.macs array. The array is a list of HEX MAC addresses.
|
||||
sendConsoleText('Server requesting wake-on-lan for: ' + data.macs.join(', '));
|
||||
// TODO!!!!
|
||||
for (var i in data.macs) { sendWakeOnLan(data.macs[i]); }
|
||||
break;
|
||||
}
|
||||
case 'poweraction': {
|
||||
|
@ -554,7 +591,7 @@ function createMeshCore(agent) {
|
|||
var response = null;
|
||||
switch (cmd) {
|
||||
case 'help': { // Displays available commands
|
||||
response = 'Available commands: help, info, args, print, type, dbget, dbset, dbcompact, parseurl, httpget, wslist, wsconnect, wssend, wsclose, notify, ls, amt, netinfo, location, power.';
|
||||
response = 'Available commands: help, info, args, print, type, dbget, dbset, dbcompact, parseuri, httpget, wslist, wsconnect, wssend, wsclose, notify, ls, amt, netinfo, location, power, wakeonlan.';
|
||||
break;
|
||||
}
|
||||
case 'notify': { // Send a notification message to the mesh
|
||||
|
@ -569,7 +606,7 @@ function createMeshCore(agent) {
|
|||
break;
|
||||
}
|
||||
case 'info': { // Return information about the agent and agent core module
|
||||
response = 'Current Core: ' + obj.meshCoreInfo + '.\r\nAgent Time: ' + Date() + '.\r\nUser Rights: 0x' + rights.toString(16) + '.\r\nPlatform Info: ' + process.platform + '.\r\nCapabilities: ' + obj.meshCoreCapabilities + '.\r\nNative Pipes: ' + obj.useNativePipes + '.';
|
||||
response = 'Current Core: ' + obj.meshCoreInfo + '.\r\nAgent Time: ' + Date() + '.\r\nUser Rights: 0x' + rights.toString(16) + '.\r\nPlatform Info: ' + process.platform + '.\r\nCapabilities: ' + obj.meshCoreCapabilities + '.\r\nNative Pipes: ' + obj.useNativePipes + '.\r\nServer URL: ' + mesh.ServerUrl + '.';
|
||||
break;
|
||||
}
|
||||
case 'selfinfo': { // Return self information block
|
||||
|
@ -628,10 +665,6 @@ function createMeshCore(agent) {
|
|||
response = 'Database compacted: ' + r;
|
||||
break;
|
||||
}
|
||||
case 'parseurl': {
|
||||
response = objToString(parseUrl(args['_'][0]));
|
||||
break;
|
||||
}
|
||||
case 'httpget': {
|
||||
if (consoleHttpRequest != null) {
|
||||
response = 'HTTP operation already in progress.';
|
||||
|
@ -639,7 +672,7 @@ function createMeshCore(agent) {
|
|||
if (args['_'].length != 1) {
|
||||
response = 'Proper usage: httpget (url)';
|
||||
} else {
|
||||
var options = parseUrl(args['_'][0]);
|
||||
var options = http.parseUri(args['_'][0]);
|
||||
options.method = 'GET';
|
||||
if (options == null) {
|
||||
response = 'Invalid url.';
|
||||
|
@ -648,7 +681,7 @@ function createMeshCore(agent) {
|
|||
consoleHttpRequest.sessionid = sessionid;
|
||||
if (consoleHttpRequest != null) {
|
||||
consoleHttpRequest.end();
|
||||
response = 'HTTPGET ' + options.protocol + '//' + options.hostname + ':' + options.port + options.path;
|
||||
response = 'HTTPGET ' + options.protocol + '//' + options.host + ':' + options.port + options.path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -670,7 +703,7 @@ function createMeshCore(agent) {
|
|||
} else {
|
||||
var httprequest = null;
|
||||
try {
|
||||
httprequest = http.request(parseUrl(args['_'][0]));
|
||||
httprequest = http.request(http.parseUri(args['_'][0]));
|
||||
} catch (e) { response = 'Invalid HTTP websocket request'; }
|
||||
if (httprequest != null) {
|
||||
httprequest.upgrade = onWebSocketUpgrade;
|
||||
|
@ -756,7 +789,18 @@ function createMeshCore(agent) {
|
|||
break;
|
||||
}
|
||||
case 'netinfo': { // Show network interface information
|
||||
response = objToString(mesh.NetInfo, 0, '.');
|
||||
//response = objToString(mesh.NetInfo, 0, '.');
|
||||
var interfaces = require('os').networkInterfaces();
|
||||
response = objToString(interfaces, 0, '.');
|
||||
break;
|
||||
}
|
||||
case 'wakeonlan': { // Send wake-on-lan
|
||||
if ((args['_'].length != 1) || (args['_'][0].length != 12)) {
|
||||
response = 'Proper usage: wakeonlan [mac], for example "wakeonlan 010203040506".';
|
||||
} else {
|
||||
var count = sendWakeOnLan(args['_'][0]);
|
||||
response = 'Sent wake-on-lan on ' + count + ' interface(s).';
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'sendall': { // Send a message to all consoles on this mesh
|
||||
|
@ -782,6 +826,10 @@ function createMeshCore(agent) {
|
|||
});
|
||||
break;
|
||||
}
|
||||
case 'parseuri': {
|
||||
response = JSON.stringify(http.parseUri(args['_'][0]));
|
||||
break;
|
||||
}
|
||||
default: { // This is an unknown command, return an error message
|
||||
response = 'Unknown command \"' + cmd + '\", type \"help\" for list of avaialble commands.';
|
||||
break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue