mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2025-02-12 11:01:52 +00:00
Started work on traffic accounting.
This commit is contained in:
parent
d17aae0c8f
commit
b6e3b51be2
3 changed files with 57 additions and 2 deletions
35
meshrelay.js
35
meshrelay.js
|
@ -966,6 +966,10 @@ function CreateLocalRelayEx(parent, ws, req, domain, user, cookie) {
|
||||||
obj.ws = ws;
|
obj.ws = ws;
|
||||||
obj.user = user;
|
obj.user = user;
|
||||||
|
|
||||||
|
// Check the protocol in use
|
||||||
|
var protocolInUse = parseInt(req.query.p);
|
||||||
|
if (typeof protocolInUse != 'number') { protocolInUse = 0; }
|
||||||
|
|
||||||
// If there is no authentication, drop this connection
|
// If there is no authentication, drop this connection
|
||||||
if (obj.user == null) { try { ws.close(); parent.parent.debug('relay', 'Relay: Connection with no authentication'); } catch (e) { console.log(e); } return; }
|
if (obj.user == null) { try { ws.close(); parent.parent.debug('relay', 'Relay: Connection with no authentication'); } catch (e) { console.log(e); } return; }
|
||||||
|
|
||||||
|
@ -997,6 +1001,8 @@ function CreateLocalRelayEx(parent, ws, req, domain, user, cookie) {
|
||||||
|
|
||||||
// Hold traffic until we connect to the target
|
// Hold traffic until we connect to the target
|
||||||
ws._socket.pause();
|
ws._socket.pause();
|
||||||
|
ws._socket.bytesReadEx = 0;
|
||||||
|
ws._socket.bytesWrittenEx = 0;
|
||||||
|
|
||||||
// Mesh Rights
|
// Mesh Rights
|
||||||
const MESHRIGHT_EDITMESH = 1;
|
const MESHRIGHT_EDITMESH = 1;
|
||||||
|
@ -1020,11 +1026,28 @@ function CreateLocalRelayEx(parent, ws, req, domain, user, cookie) {
|
||||||
// Clean a IPv6 address that encodes a IPv4 address
|
// Clean a IPv6 address that encodes a IPv4 address
|
||||||
function cleanRemoteAddr(addr) { if (addr.startsWith('::ffff:')) { return addr.substring(7); } else { return addr; } }
|
function cleanRemoteAddr(addr) { if (addr.startsWith('::ffff:')) { return addr.substring(7); } else { return addr; } }
|
||||||
|
|
||||||
|
// Perform data accounting
|
||||||
|
function dataAccounting() {
|
||||||
|
const datain = ((obj.client.bytesRead - obj.client.bytesReadEx) + (ws._socket.bytesRead - ws._socket.bytesReadEx));
|
||||||
|
const dataout = ((obj.client.bytesWritten - obj.client.bytesWrittenEx) + (ws._socket.bytesWritten - ws._socket.bytesWrittenEx));
|
||||||
|
obj.client.bytesReadEx = obj.client.bytesRead;
|
||||||
|
obj.client.bytesWrittenEx = obj.client.bytesWritten;
|
||||||
|
ws._socket.bytesReadEx = ws._socket.bytesRead;
|
||||||
|
ws._socket.bytesWrittenEx = ws._socket.bytesWritten;
|
||||||
|
|
||||||
|
// Add to counters
|
||||||
|
if (parent.trafficStats.localRelayIn[protocolInUse]) { parent.trafficStats.localRelayIn[protocolInUse] += datain; } else { parent.trafficStats.localRelayIn[protocolInUse] = datain; }
|
||||||
|
if (parent.trafficStats.localRelayOut[protocolInUse]) { parent.trafficStats.localRelayOut[protocolInUse] += dataout; } else { parent.trafficStats.localRelayOut[protocolInUse] = dataout; }
|
||||||
|
}
|
||||||
|
|
||||||
// Disconnect
|
// Disconnect
|
||||||
obj.close = function (arg) {
|
obj.close = function (arg) {
|
||||||
// If the web socket is already closed, stop here.
|
// If the web socket is already closed, stop here.
|
||||||
if (obj.ws == null) return;
|
if (obj.ws == null) return;
|
||||||
|
|
||||||
|
// Perform data accounting
|
||||||
|
dataAccounting();
|
||||||
|
|
||||||
// Collect how many raw bytes where received and sent.
|
// Collect how many raw bytes where received and sent.
|
||||||
// We sum both the websocket and TCP client in this case.
|
// We sum both the websocket and TCP client in this case.
|
||||||
var inTraffc = obj.ws._socket.bytesRead, outTraffc = obj.ws._socket.bytesWritten;
|
var inTraffc = obj.ws._socket.bytesRead, outTraffc = obj.ws._socket.bytesWritten;
|
||||||
|
@ -1083,17 +1106,27 @@ function CreateLocalRelayEx(parent, ws, req, domain, user, cookie) {
|
||||||
|
|
||||||
// Setup TCP client
|
// Setup TCP client
|
||||||
obj.client = new net.Socket();
|
obj.client = new net.Socket();
|
||||||
|
obj.client.bytesReadEx = 0;
|
||||||
|
obj.client.bytesWrittenEx = 0;
|
||||||
obj.client.connect(obj.tcpport, node.host, function () {
|
obj.client.connect(obj.tcpport, node.host, function () {
|
||||||
// Log the start of the connection
|
// Log the start of the connection
|
||||||
obj.time = Date.now();
|
obj.time = Date.now();
|
||||||
var event = { etype: 'relay', action: 'relaylog', domain: domain.id, userid: obj.user._id, username: obj.user.name, msgid: 13, msgArgs: [obj.id, obj.req.clientIp, obj.host], msg: 'Started relay session \"' + obj.id + '\" from ' + obj.req.clientIp + ' to ' + obj.host, nodeid: req.query.nodeid, protocol: req.query.p };
|
var event = { etype: 'relay', action: 'relaylog', domain: domain.id, userid: obj.user._id, username: obj.user.name, msgid: 13, msgArgs: [obj.id, obj.req.clientIp, obj.host], msg: 'Started relay session \"' + obj.id + '\" from ' + obj.req.clientIp + ' to ' + obj.host, nodeid: req.query.nodeid, protocol: req.query.p };
|
||||||
parent.parent.DispatchEvent(['*', obj.user._id, obj.meshid, obj.nodeid], obj, event);
|
parent.parent.DispatchEvent(['*', obj.user._id, obj.meshid, obj.nodeid], obj, event);
|
||||||
|
|
||||||
|
// Count the session
|
||||||
|
if (parent.trafficStats.localRelayCount[protocolInUse]) { parent.trafficStats.localRelayCount[protocolInUse] += 1; } else { parent.trafficStats.localRelayCount[protocolInUse] = 1; }
|
||||||
|
|
||||||
// Start the session
|
// Start the session
|
||||||
ws.send('c');
|
ws.send('c');
|
||||||
ws._socket.resume();
|
ws._socket.resume();
|
||||||
});
|
});
|
||||||
obj.client.on('data', function (data) { try { this.pause(); ws.send(data, this.clientResume); } catch (ex) { console.log(ex); } }); // Perform relay
|
obj.client.on('data', function (data) {
|
||||||
|
// Perform data accounting
|
||||||
|
dataAccounting();
|
||||||
|
// Perform relay
|
||||||
|
try { this.pause(); ws.send(data, this.clientResume); } catch (ex) { console.log(ex); }
|
||||||
|
});
|
||||||
obj.client.on('close', function () { obj.close(); });
|
obj.client.on('close', function () { obj.close(); });
|
||||||
obj.client.on('error', function (err) { obj.close(); });
|
obj.client.on('error', function (err) { obj.close(); });
|
||||||
obj.client.clientResume = function () { try { obj.client.resume(); } catch (ex) { console.log(ex); } };
|
obj.client.clientResume = function () { try { obj.client.resume(); } catch (ex) { console.log(ex); } };
|
||||||
|
|
|
@ -905,7 +905,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case 'help': {
|
case 'help': {
|
||||||
var fin = '', f = '', availcommands = 'help,maintenance,info,versions,resetserver,usersessions,closeusersessions,tasklimiter,setmaxtasks,cores,migrationagents,agentstats,agentissues,webstats,mpsstats,swarmstats,acceleratorsstats,updatecheck,serverupdate,nodeconfig,heapdump,relays,autobackup,backupconfig,dupagents,dispatchtable,badlogins,showpaths,le,lecheck,leevents,dbstats,dbcounters,sms,amtacm,certhashes,watchdog,amtmanager,amtpasswords,certexpire';
|
var fin = '', f = '', availcommands = 'help,maintenance,info,versions,resetserver,usersessions,closeusersessions,tasklimiter,setmaxtasks,cores,migrationagents,agentstats,agentissues,webstats,trafficstats,mpsstats,swarmstats,acceleratorsstats,updatecheck,serverupdate,nodeconfig,heapdump,relays,autobackup,backupconfig,dupagents,dispatchtable,badlogins,showpaths,le,lecheck,leevents,dbstats,dbcounters,sms,amtacm,certhashes,watchdog,amtmanager,amtpasswords,certexpire';
|
||||||
if (parent.parent.config.settings.heapdump === true) { availcommands += ',heapdump'; }
|
if (parent.parent.config.settings.heapdump === true) { availcommands += ',heapdump'; }
|
||||||
availcommands = availcommands.split(',').sort();
|
availcommands = availcommands.split(',').sort();
|
||||||
while (availcommands.length > 0) { if (f.length > 80) { fin += (f + ',\r\n'); f = ''; } f += (((f != '') ? ', ' : ' ') + availcommands.shift()); }
|
while (availcommands.length > 0) { if (f.length > 80) { fin += (f + ',\r\n'); f = ''; } f += (((f != '') ? ', ' : ' ') + availcommands.shift()); }
|
||||||
|
@ -1113,6 +1113,13 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'trafficstats': {
|
||||||
|
var stats = parent.getTrafficStats();
|
||||||
|
for (var i in stats) {
|
||||||
|
if (typeof stats[i] == 'object') { r += (i + ': ' + JSON.stringify(stats[i]) + '\r\n'); } else { r += (i + ': ' + stats[i] + '\r\n'); }
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 'watchdog': {
|
case 'watchdog': {
|
||||||
if (parent.parent.watchdog == null) {
|
if (parent.parent.watchdog == null) {
|
||||||
r = 'Server watchdog not active.';
|
r = 'Server watchdog not active.';
|
||||||
|
|
15
webserver.js
15
webserver.js
|
@ -342,6 +342,18 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||||
}
|
}
|
||||||
obj.getAgentStats = function () { return obj.agentStats; }
|
obj.getAgentStats = function () { return obj.agentStats; }
|
||||||
|
|
||||||
|
// Traffic counters
|
||||||
|
obj.trafficStats = {
|
||||||
|
httpRequestCount: 0,
|
||||||
|
relayCount: {},
|
||||||
|
relayIn: {},
|
||||||
|
relayOut: {},
|
||||||
|
localRelayCount: {},
|
||||||
|
localRelayIn: {},
|
||||||
|
localRelayOut: {}
|
||||||
|
}
|
||||||
|
obj.getTrafficStats = function () { return obj.trafficStats; }
|
||||||
|
|
||||||
// Keep a record of the last agent issues.
|
// Keep a record of the last agent issues.
|
||||||
obj.getAgentIssues = function () { return obj.agentIssues; }
|
obj.getAgentIssues = function () { return obj.agentIssues; }
|
||||||
obj.setAgentIssue = function (agent, issue) { obj.agentIssues.push([new Date().toLocaleTimeString(), agent.remoteaddrport, issue]); while (obj.setAgentIssue.length > 50) { obj.agentIssues.shift(); } }
|
obj.setAgentIssue = function (agent, issue) { obj.agentIssues.push([new Date().toLocaleTimeString(), agent.remoteaddrport, issue]); while (obj.setAgentIssue.length > 50) { obj.agentIssues.shift(); } }
|
||||||
|
@ -5327,6 +5339,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||||
// Useful for debugging reverse proxy issues
|
// Useful for debugging reverse proxy issues
|
||||||
parent.debug('httpheaders', req.method, req.url, req.headers);
|
parent.debug('httpheaders', req.method, req.url, req.headers);
|
||||||
|
|
||||||
|
// Count the HTTP request
|
||||||
|
obj.trafficStats.httpRequestCount++;
|
||||||
|
|
||||||
// Set the real IP address of the request
|
// Set the real IP address of the request
|
||||||
// If a trusted reverse-proxy is sending us the remote IP address, use it.
|
// If a trusted reverse-proxy is sending us the remote IP address, use it.
|
||||||
var ipex = '0.0.0.0', xforwardedhost = req.headers.host;
|
var ipex = '0.0.0.0', xforwardedhost = req.headers.host;
|
||||||
|
|
Loading…
Reference in a new issue