mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2024-11-25 10:03:01 +03:00
AMT interceptor performance improvement.
This commit is contained in:
parent
e42816ab97
commit
d1ab4e508a
@ -37,14 +37,11 @@ module.exports.CreateHttpInterceptor = function (args) {
|
|||||||
|
|
||||||
// Process data coming from Intel AMT
|
// Process data coming from Intel AMT
|
||||||
obj.processAmtData = function (data) {
|
obj.processAmtData = function (data) {
|
||||||
obj.amt.acc += data; // Add data to accumulator
|
obj.amt.acc += data.toString('binary'); // Add data to accumulator
|
||||||
data = '';
|
data = '';
|
||||||
var datalen = 0;
|
var datalen = 0;
|
||||||
do {
|
do { datalen = data.length; data += obj.processAmtDataEx(); } while (datalen != data.length); // Process as much data as possible
|
||||||
datalen = data.length;
|
return Buffer.from(data, 'binary');
|
||||||
data += obj.processAmtDataEx();
|
|
||||||
} while (datalen != data.length); // Process as much data as possible
|
|
||||||
return data;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Process data coming from AMT in the accumulator
|
// Process data coming from AMT in the accumulator
|
||||||
@ -122,14 +119,11 @@ module.exports.CreateHttpInterceptor = function (args) {
|
|||||||
|
|
||||||
// Process data coming from the Browser
|
// Process data coming from the Browser
|
||||||
obj.processBrowserData = function (data) {
|
obj.processBrowserData = function (data) {
|
||||||
obj.ws.acc += data; // Add data to accumulator
|
obj.ws.acc += data.toString('binary'); // Add data to accumulator
|
||||||
data = '';
|
data = '';
|
||||||
var datalen = 0;
|
var datalen = 0;
|
||||||
do {
|
do { datalen = data.length; data += obj.processBrowserDataEx(); } while (datalen != data.length); // Process as much data as possible
|
||||||
datalen = data.length;
|
return Buffer.from(data, 'binary');
|
||||||
data += obj.processBrowserDataEx();
|
|
||||||
} while (datalen != data.length); // Process as much data as possible
|
|
||||||
return data;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Process data coming from the Browser in the accumulator
|
// Process data coming from the Browser in the accumulator
|
||||||
@ -279,20 +273,21 @@ module.exports.CreateRedirInterceptor = function (args) {
|
|||||||
|
|
||||||
// Process data coming from Intel AMT
|
// Process data coming from Intel AMT
|
||||||
obj.processAmtData = function (data) {
|
obj.processAmtData = function (data) {
|
||||||
obj.amt.acc += data; // Add data to accumulator
|
if ((obj.amt.direct == true) && (obj.amt.acc == '')) { return data; } // Interceptor fast path
|
||||||
|
obj.amt.acc += data.toString('binary'); // Add data to accumulator
|
||||||
data = '';
|
data = '';
|
||||||
var datalen = 0;
|
var datalen = 0;
|
||||||
do { datalen = data.length; data += obj.processAmtDataEx(); } while (datalen != data.length); // Process as much data as possible
|
do { datalen = data.length; data += obj.processAmtDataEx(); } while (datalen != data.length); // Process as much data as possible
|
||||||
return data;
|
return Buffer.from(data, 'binary');
|
||||||
};
|
};
|
||||||
|
|
||||||
// Process data coming from AMT in the accumulator
|
// Process data coming from AMT in the accumulator
|
||||||
obj.processAmtDataEx = function () {
|
obj.processAmtDataEx = function () {
|
||||||
var r;
|
var r;
|
||||||
if (obj.amt.acc.length == 0) return "";
|
if (obj.amt.acc.length == 0) return '';
|
||||||
if (obj.amt.direct == true) {
|
if (obj.amt.direct == true) {
|
||||||
var data = obj.amt.acc;
|
var data = obj.amt.acc;
|
||||||
obj.amt.acc = "";
|
obj.amt.acc = '';
|
||||||
return data;
|
return data;
|
||||||
} else {
|
} else {
|
||||||
//console.log(obj.amt.acc.charCodeAt(0));
|
//console.log(obj.amt.acc.charCodeAt(0));
|
||||||
@ -346,11 +341,12 @@ module.exports.CreateRedirInterceptor = function (args) {
|
|||||||
|
|
||||||
// Process data coming from the Browser
|
// Process data coming from the Browser
|
||||||
obj.processBrowserData = function (data) {
|
obj.processBrowserData = function (data) {
|
||||||
obj.ws.acc += data; // Add data to accumulator
|
if ((obj.ws.direct == true) && (obj.ws.acc == '')) { return data; } // Interceptor fast path
|
||||||
|
obj.ws.acc += data.toString('binary'); // Add data to accumulator
|
||||||
data = '';
|
data = '';
|
||||||
var datalen = 0;
|
var datalen = 0;
|
||||||
do { datalen = data.length; data += obj.processBrowserDataEx(); } while (datalen != data.length); // Process as much data as possible
|
do { datalen = data.length; data += obj.processBrowserDataEx(); } while (datalen != data.length); // Process as much data as possible
|
||||||
return data;
|
return Buffer.from(data, 'binary');
|
||||||
};
|
};
|
||||||
|
|
||||||
// Process data coming from the Browser in the accumulator
|
// Process data coming from the Browser in the accumulator
|
||||||
@ -434,7 +430,6 @@ module.exports.CreateRedirInterceptor = function (args) {
|
|||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
obj.ws.error = true;
|
obj.ws.error = true;
|
||||||
return '';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
71
webserver.js
71
webserver.js
@ -13,17 +13,7 @@
|
|||||||
/*jshint esversion: 6 */
|
/*jshint esversion: 6 */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/*
|
// SerialTunnel object is used to embed TLS within another connection.
|
||||||
class SerialTunnel extends require('stream').Duplex {
|
|
||||||
constructor(options) { super(options); this.forwardwrite = null; }
|
|
||||||
updateBuffer(chunk) { this.push(chunk); }
|
|
||||||
_write(chunk, encoding, callback) { if (this.forwardwrite != null) { this.forwardwrite(chunk); } else { console.err("Failed to fwd _write."); } if (callback) callback(); } // Pass data written to forward
|
|
||||||
_read(size) { } // Push nothing, anything to read should be pushed from updateBuffer()
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Older NodeJS does not support the keyword "class", so we do without using this syntax
|
|
||||||
// TODO: Validate that it's the same as above and that it works.
|
|
||||||
function SerialTunnel(options) {
|
function SerialTunnel(options) {
|
||||||
var obj = new require('stream').Duplex(options);
|
var obj = new require('stream').Duplex(options);
|
||||||
obj.forwardwrite = null;
|
obj.forwardwrite = null;
|
||||||
@ -3388,7 +3378,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||||||
|
|
||||||
// Setup a new CIRA channel
|
// Setup a new CIRA channel
|
||||||
if ((port == 16993) || (port == 16995)) {
|
if ((port == 16993) || (port == 16995)) {
|
||||||
// Perform TLS - ( TODO: THIS IS BROKEN on Intel AMT v7 but works on v10, Not sure why. Well, could be broken TLS 1.0 in firmware )
|
// Perform TLS
|
||||||
var ser = new SerialTunnel();
|
var ser = new SerialTunnel();
|
||||||
var chnl = parent.mpsserver.SetupChannel(ciraconn, port);
|
var chnl = parent.mpsserver.SetupChannel(ciraconn, port);
|
||||||
|
|
||||||
@ -3415,7 +3405,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||||||
// Decrypted tunnel from TLS communcation to be forwarded to websocket
|
// Decrypted tunnel from TLS communcation to be forwarded to websocket
|
||||||
tlsock.on('data', function (data) {
|
tlsock.on('data', function (data) {
|
||||||
// AMT/TLS ---> WS
|
// AMT/TLS ---> WS
|
||||||
if (ws.interceptor) { data = Buffer.from(ws.interceptor.processAmtData(data.toString('binary')), 'binary'); } // Run data thru interceptor
|
if (ws.interceptor) { data = ws.interceptor.processAmtData(data); } // Run data thru interceptor
|
||||||
try { ws.send(data); } catch (ex) { }
|
try { ws.send(data); } catch (ex) { }
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -3430,11 +3420,11 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||||||
|
|
||||||
ws.forwardclient.onData = function (ciraconn, data) {
|
ws.forwardclient.onData = function (ciraconn, data) {
|
||||||
// Run data thru interceptor
|
// Run data thru interceptor
|
||||||
if (ws.interceptor) { data = Buffer.from(ws.interceptor.processAmtData(data.toString('binary')), 'binary'); }
|
if (ws.interceptor) { data = ws.interceptor.processAmtData(data); }
|
||||||
|
|
||||||
if (data.length > 0) {
|
if (data.length > 0) {
|
||||||
if (ws.logfile == null) {
|
if (ws.logfile == null) {
|
||||||
try { ws.send(data); } catch (e) { } // TODO: Add TLS support
|
try { ws.send(data); } catch (e) { }
|
||||||
} else {
|
} else {
|
||||||
// Log to recording file
|
// Log to recording file
|
||||||
recordingEntry(ws.logfile.fd, 2, 0, data, function () { try { ws.send(data); } catch (ex) { console.log(ex); } }); // TODO: Add TLS support
|
recordingEntry(ws.logfile.fd, 2, 0, data, function () { try { ws.send(data); } catch (ex) { console.log(ex); } }); // TODO: Add TLS support
|
||||||
@ -3442,10 +3432,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ws.forwardclient.onSendOk = function (ciraconn) {
|
// TODO: Flow control? (Dont' really need it with AMT, but would be nice)
|
||||||
// TODO: Flow control? (Dont' really need it with AMT, but would be nice)
|
ws.forwardclient.onSendOk = function (ciraconn) { };
|
||||||
//console.log('onSendOk');
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
@ -3462,24 +3450,22 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||||||
ws.forwardclient.onData = function (ciraconn, data) {
|
ws.forwardclient.onData = function (ciraconn, data) {
|
||||||
//parent.debug('webrelaydata', 'Relay CIRA data to WS', data.length);
|
//parent.debug('webrelaydata', 'Relay CIRA data to WS', data.length);
|
||||||
|
|
||||||
// Run data thru interceptor
|
// Run data thru interceptorp
|
||||||
if (ws.interceptor) { data = Buffer.from(ws.interceptor.processAmtData(data.toString('binary')), 'binary'); }
|
if (ws.interceptor) { data = ws.interceptor.processAmtData(data); }
|
||||||
|
|
||||||
//console.log('AMT --> WS', Buffer.from(data, 'binary').toString('hex'));
|
//console.log('AMT --> WS', Buffer.from(data, 'binary').toString('hex'));
|
||||||
if (data.length > 0) {
|
if (data.length > 0) {
|
||||||
if (ws.logfile == null) {
|
if (ws.logfile == null) {
|
||||||
try { ws.send(data); } catch (e) { } // TODO: Add TLS support
|
try { ws.send(data); } catch (e) { }
|
||||||
} else {
|
} else {
|
||||||
// Log to recording file
|
// Log to recording file
|
||||||
recordingEntry(ws.logfile.fd, 2, 0, data, function () { try { ws.send(data); } catch (ex) { console.log(ex); } }); // TODO: Add TLS support
|
recordingEntry(ws.logfile.fd, 2, 0, data, function () { try { ws.send(data); } catch (ex) { console.log(ex); } });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ws.forwardclient.onSendOk = function (ciraconn) {
|
// TODO: Flow control? (Dont' really need it with AMT, but would be nice)
|
||||||
// TODO: Flow control? (Dont' really need it with AMT, but would be nice)
|
ws.forwardclient.onSendOk = function (ciraconn) { };
|
||||||
//console.log('onSendOk');
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// When data is received from the web socket, forward the data into the associated CIRA cahnnel.
|
// When data is received from the web socket, forward the data into the associated CIRA cahnnel.
|
||||||
@ -3489,7 +3475,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||||||
if (typeof data == 'string') { data = Buffer.from(data, 'binary'); }
|
if (typeof data == 'string') { data = Buffer.from(data, 'binary'); }
|
||||||
|
|
||||||
// WS ---> AMT/TLS
|
// WS ---> AMT/TLS
|
||||||
if (ws.interceptor) { data = Buffer.from(ws.interceptor.processBrowserData(data.toString('binary')), 'binary'); } // Run data thru interceptor
|
if (ws.interceptor) { data = ws.interceptor.processBrowserData(data); } // Run data thru interceptor
|
||||||
|
|
||||||
// Log to recording file
|
// Log to recording file
|
||||||
if (ws.logfile == null) {
|
if (ws.logfile == null) {
|
||||||
@ -3505,10 +3491,17 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||||||
ws.on('error', function (err) {
|
ws.on('error', function (err) {
|
||||||
console.log('CIRA server websocket error from ' + req.clientIp + ', ' + err.toString().split('\r')[0] + '.');
|
console.log('CIRA server websocket error from ' + req.clientIp + ', ' + err.toString().split('\r')[0] + '.');
|
||||||
parent.debug('webrelay', 'Websocket relay closed on error.');
|
parent.debug('webrelay', 'Websocket relay closed on error.');
|
||||||
if (ws.forwardclient && ws.forwardclient.close) { ws.forwardclient.close(); } // TODO: If TLS is used, we need to close the socket that is wrapped by TLS
|
|
||||||
|
// Websocket closed, close the CIRA channel and TLS session.
|
||||||
|
if (ws.forwardclient) {
|
||||||
|
if (ws.forwardclient.close) { ws.forwardclient.close(); } // NonTLS, close the CIRA channel
|
||||||
|
if (ws.forwardclient.end) { ws.forwardclient.end(); } // TLS, close the TLS session
|
||||||
|
if (ws.forwardclient.chnl) { ws.forwardclient.chnl.close(); } // TLS, close the CIRA channel
|
||||||
|
delete ws.forwardclient;
|
||||||
|
}
|
||||||
|
|
||||||
// Close the recording file
|
// Close the recording file
|
||||||
if (ws.logfile != null) { recordingEntry(ws.logfile.fd, 3, 0, 'MeshCentralMCREC', function (fd, ws) { obj.fs.close(fd); ws.logfile = null; }, ws); }
|
if (ws.logfile != null) { recordingEntry(ws.logfile.fd, 3, 0, 'MeshCentralMCREC', function (fd, ws) { obj.fs.close(fd); delete ws.logfile; }, ws); }
|
||||||
});
|
});
|
||||||
|
|
||||||
// If the web socket is closed, close the associated TCP connection.
|
// If the web socket is closed, close the associated TCP connection.
|
||||||
@ -3520,10 +3513,11 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||||||
if (ws.forwardclient.close) { ws.forwardclient.close(); } // NonTLS, close the CIRA channel
|
if (ws.forwardclient.close) { ws.forwardclient.close(); } // NonTLS, close the CIRA channel
|
||||||
if (ws.forwardclient.end) { ws.forwardclient.end(); } // TLS, close the TLS session
|
if (ws.forwardclient.end) { ws.forwardclient.end(); } // TLS, close the TLS session
|
||||||
if (ws.forwardclient.chnl) { ws.forwardclient.chnl.close(); } // TLS, close the CIRA channel
|
if (ws.forwardclient.chnl) { ws.forwardclient.chnl.close(); } // TLS, close the CIRA channel
|
||||||
|
delete ws.forwardclient;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close the recording file
|
// Close the recording file
|
||||||
if (ws.logfile != null) { recordingEntry(ws.logfile.fd, 3, 0, 'MeshCentralMCREC', function (fd, ws) { obj.fs.close(fd); ws.logfile = null; }, ws); }
|
if (ws.logfile != null) { recordingEntry(ws.logfile.fd, 3, 0, 'MeshCentralMCREC', function (fd, ws) { obj.fs.close(fd); delete ws.logfile; }, ws); }
|
||||||
});
|
});
|
||||||
|
|
||||||
// Fetch Intel AMT credentials & Setup interceptor
|
// Fetch Intel AMT credentials & Setup interceptor
|
||||||
@ -3546,20 +3540,17 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||||||
|
|
||||||
// When data is received from the web socket, forward the data into the associated TCP connection.
|
// When data is received from the web socket, forward the data into the associated TCP connection.
|
||||||
ws.on('message', function (msg) {
|
ws.on('message', function (msg) {
|
||||||
if (obj.parent.debugLevel >= 1) { // DEBUG
|
//parent.debug('webrelaydata', 'TCP relay data to ' + node.host + ', ' + msg.length + ' bytes');
|
||||||
parent.debug('webrelaydata', 'TCP relay data to ' + node.host + ', ' + msg.length + ' bytes');
|
|
||||||
//if (obj.parent.debugLevel >= 4) { parent.debug('webrelaydatahex', ' ' + msg.toString('hex')); }
|
if (typeof msg == 'string') { msg = Buffer.from(msg, 'binary'); }
|
||||||
}
|
|
||||||
msg = msg.toString('binary');
|
|
||||||
if (ws.interceptor) { msg = ws.interceptor.processBrowserData(msg); } // Run data thru interceptor
|
if (ws.interceptor) { msg = ws.interceptor.processBrowserData(msg); } // Run data thru interceptor
|
||||||
|
|
||||||
// Log to recording file
|
// Log to recording file
|
||||||
if (ws.logfile == null) {
|
if (ws.logfile == null) {
|
||||||
// Forward data to the associated TCP connection.
|
// Forward data to the associated TCP connection.
|
||||||
try { ws.forwardclient.write(Buffer.from(msg, 'binary')); } catch (ex) { }
|
try { ws.forwardclient.write(msg); } catch (ex) { }
|
||||||
} else {
|
} else {
|
||||||
// Log to recording file
|
// Log to recording file
|
||||||
msg = Buffer.from(msg, 'binary');
|
|
||||||
recordingEntry(ws.logfile.fd, 2, 2, msg, function () { try { ws.forwardclient.write(msg); } catch (ex) { } });
|
recordingEntry(ws.logfile.fd, 2, 2, msg, function () { try { ws.forwardclient.write(msg); } catch (ex) { } });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -3622,6 +3613,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||||||
|
|
||||||
// When we receive data on the TCP connection, forward it back into the web socket connection.
|
// When we receive data on the TCP connection, forward it back into the web socket connection.
|
||||||
ws.forwardclient.on('data', function (data) {
|
ws.forwardclient.on('data', function (data) {
|
||||||
|
if (typeof data == 'string') { data = Buffer.from(data, 'binary'); }
|
||||||
if (obj.parent.debugLevel >= 1) { // DEBUG
|
if (obj.parent.debugLevel >= 1) { // DEBUG
|
||||||
parent.debug('webrelaydata', 'TCP relay data from ' + node.host + ', ' + data.length + ' bytes.');
|
parent.debug('webrelaydata', 'TCP relay data from ' + node.host + ', ' + data.length + ' bytes.');
|
||||||
//if (obj.parent.debugLevel >= 4) { Debug(4, ' ' + Buffer.from(data, 'binary').toString('hex')); }
|
//if (obj.parent.debugLevel >= 4) { Debug(4, ' ' + Buffer.from(data, 'binary').toString('hex')); }
|
||||||
@ -3629,10 +3621,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||||||
if (ws.interceptor) { data = ws.interceptor.processAmtData(data); } // Run data thru interceptor
|
if (ws.interceptor) { data = ws.interceptor.processAmtData(data); } // Run data thru interceptor
|
||||||
if (ws.logfile == null) {
|
if (ws.logfile == null) {
|
||||||
// No logging
|
// No logging
|
||||||
try { ws.send(Buffer.from(data, 'binary')); } catch (e) { }
|
try { ws.send(data); } catch (e) { }
|
||||||
} else {
|
} else {
|
||||||
// Log to recording file
|
// Log to recording file
|
||||||
data = Buffer.from(data, 'binary');
|
|
||||||
recordingEntry(ws.logfile.fd, 2, 0, data, function () { try { ws.send(data); } catch (e) { } });
|
recordingEntry(ws.logfile.fd, 2, 0, data, function () { try { ws.send(data); } catch (e) { } });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user