mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2025-01-27 14:43:14 -05:00
Started work on IP-KVM/Power relay thru agent.
This commit is contained in:
parent
2a2e0038c1
commit
aa514534c4
116
meshipkvm.js
116
meshipkvm.js
@ -67,6 +67,7 @@ function CreateIPKVMManager(parent) {
|
|||||||
if (mesh.kvm.model == 1) { // Raritan KX III
|
if (mesh.kvm.model == 1) { // Raritan KX III
|
||||||
const manager = CreateRaritanKX3Manager(obj, host, port, mesh.kvm.user, mesh.kvm.pass);
|
const manager = CreateRaritanKX3Manager(obj, host, port, mesh.kvm.user, mesh.kvm.pass);
|
||||||
manager.meshid = mesh._id;
|
manager.meshid = mesh._id;
|
||||||
|
manager.relayid = mesh.relayid;
|
||||||
manager.domainid = mesh._id.split('/')[1];
|
manager.domainid = mesh._id.split('/')[1];
|
||||||
obj.managedGroups[mesh._id] = manager;
|
obj.managedGroups[mesh._id] = manager;
|
||||||
manager.onStateChanged = onStateChanged;
|
manager.onStateChanged = onStateChanged;
|
||||||
@ -76,6 +77,7 @@ function CreateIPKVMManager(parent) {
|
|||||||
else if (mesh.kvm.model == 2) { // WebPowerSwitch 7
|
else if (mesh.kvm.model == 2) { // WebPowerSwitch 7
|
||||||
const manager = CreateWebPowerSwitch(obj, host, port, mesh.kvm.user, mesh.kvm.pass);
|
const manager = CreateWebPowerSwitch(obj, host, port, mesh.kvm.user, mesh.kvm.pass);
|
||||||
manager.meshid = mesh._id;
|
manager.meshid = mesh._id;
|
||||||
|
manager.relayid = mesh.relayid;
|
||||||
manager.domainid = mesh._id.split('/')[1];
|
manager.domainid = mesh._id.split('/')[1];
|
||||||
obj.managedGroups[mesh._id] = manager;
|
obj.managedGroups[mesh._id] = manager;
|
||||||
manager.onStateChanged = onStateChanged;
|
manager.onStateChanged = onStateChanged;
|
||||||
@ -774,7 +776,14 @@ function CreateWebPowerSwitch(parent, hostname, port, username, password) {
|
|||||||
obj.start = function () {
|
obj.start = function () {
|
||||||
if (obj.started) return;
|
if (obj.started) return;
|
||||||
obj.started = true;
|
obj.started = true;
|
||||||
if (obj.state == 0) connect();
|
if (obj.state == 0) {
|
||||||
|
if (obj.relayid) {
|
||||||
|
obj.router = CreateMiniRouter(parent, obj.relayid, hostname, port);
|
||||||
|
obj.router.start(function () { connect(); });
|
||||||
|
} else {
|
||||||
|
connect();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.stop = function () {
|
obj.stop = function () {
|
||||||
@ -783,6 +792,7 @@ function CreateWebPowerSwitch(parent, hostname, port, username, password) {
|
|||||||
if (retryTimer != null) { clearTimeout(retryTimer); retryTimer = null; }
|
if (retryTimer != null) { clearTimeout(retryTimer); retryTimer = null; }
|
||||||
setState(0);
|
setState(0);
|
||||||
obj.ports = [];
|
obj.ports = [];
|
||||||
|
if (obj.router) { obj.router.stop(); delete obj.router; }
|
||||||
}
|
}
|
||||||
|
|
||||||
function setState(newState) {
|
function setState(newState) {
|
||||||
@ -856,8 +866,8 @@ function CreateWebPowerSwitch(parent, hostname, port, username, password) {
|
|||||||
|
|
||||||
var rdata = [];
|
var rdata = [];
|
||||||
const options = {
|
const options = {
|
||||||
hostname: hostname,
|
hostname: obj.router ? 'localhost' : hostname,
|
||||||
port: port,
|
port: obj.router ? obj.router.tcpServerPort : port,
|
||||||
rejectUnauthorized: false,
|
rejectUnauthorized: false,
|
||||||
checkServerIdentity: onCheckServerIdentity,
|
checkServerIdentity: onCheckServerIdentity,
|
||||||
path: url,
|
path: url,
|
||||||
@ -945,4 +955,104 @@ function CreateWebPowerSwitch(parent, hostname, port, username, password) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Mini TCP port router
|
||||||
|
function CreateMiniRouter(parent, nodeid, targetHost, targetPort) {
|
||||||
|
const Net = require('net');
|
||||||
|
const WebSocket = require('ws');
|
||||||
|
const obj = {};
|
||||||
|
const tcpSockets = {}
|
||||||
|
obj.tcpServerPort = 0;
|
||||||
|
obj.nodeid = nodeid;
|
||||||
|
obj.targetHost = targetHost;
|
||||||
|
obj.targetPort = targetPort;
|
||||||
|
|
||||||
|
parent.parent.debug('relay', 'MiniRouter: Request relay for ' + obj.targetHost + ':' + obj.targetPort + ' thru ' + nodeid + '.');
|
||||||
|
|
||||||
|
// Close a TCP socket and the coresponding web socket.
|
||||||
|
function closeTcpSocket(tcpSocket) {
|
||||||
|
if (tcpSockets[tcpSocket]) {
|
||||||
|
delete tcpSockets[tcpSocket];
|
||||||
|
try { tcpSocket.close(); } catch (ex) { }
|
||||||
|
if (tcpSocket.relaySocket) { try { tcpSocket.relaySocket.close(); } catch (ex) { } }
|
||||||
|
delete tcpSocket.relaySocket.tcpSocket;
|
||||||
|
delete tcpSocket.relaySocket;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close a web socket and the coresponding TCP socket.
|
||||||
|
function closeWebSocket(webSocket) {
|
||||||
|
const tcpSocket = webSocket.tcpSocket;
|
||||||
|
if (tcpSocket) { closeTcpSocket(tcpSocket); }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start the looppback server
|
||||||
|
obj.start = function(onReadyFunc) {
|
||||||
|
obj.tcpServer = new Net.Server();
|
||||||
|
obj.tcpServer.listen(0, 'localhost', function () {
|
||||||
|
obj.tcpServerPort = obj.tcpServer.address().port;
|
||||||
|
parent.parent.debug('relay', 'MiniRouter: Request for relay ' + obj.targetHost + ':' + obj.targetPort + ' started on port ' + obj.tcpServerPort);
|
||||||
|
onReadyFunc(obj.tcpServerPort);
|
||||||
|
});
|
||||||
|
obj.tcpServer.on('connection', function (socket) {
|
||||||
|
tcpSockets[socket] = 1;
|
||||||
|
socket.pause();
|
||||||
|
socket.on('data', function (chunk) { // Make sure to handle flow control.
|
||||||
|
console.log('<-- ' + chunk);
|
||||||
|
const f = function sendDone() { sendDone.tcpSocket.resume(); }
|
||||||
|
f.tcpSocket = this;
|
||||||
|
if (this.relaySocket && this.relaySocket.active) { this.pause(); this.relaySocket.send(chunk, f); }
|
||||||
|
});
|
||||||
|
socket.on('end', function () { close(this); });
|
||||||
|
socket.on('error', function (err) { close(this); });
|
||||||
|
|
||||||
|
// Encode the device relay cookie. Note that there si no userid in this cookie.
|
||||||
|
const domainid = obj.nodeid.split('/')[1];
|
||||||
|
const cookie = parent.parent.encodeCookie({ domainid: domainid, nodeid: obj.nodeid, tcpaddr: obj.targetHost, tcpport: obj.targetPort }, parent.parent.loginCookieEncryptionKey);
|
||||||
|
const domain = parent.parent.config.domains[domainid];
|
||||||
|
|
||||||
|
// Setup the correct URL with domain and use TLS only if needed.
|
||||||
|
const options = { rejectUnauthorized: false };
|
||||||
|
const protocol = (parent.parent.args.tlsoffload) ? 'ws' : 'wss';
|
||||||
|
var domainadd = '';
|
||||||
|
if ((domain.dns == null) && (domain.id != '')) { domainadd = domain.id + '/' }
|
||||||
|
const url = protocol + '://localhost:' + parent.parent.args.port + '/' + domainadd + 'meshrelay.ashx?noping=1&auth=' + cookie; // TODO: &p=10, Protocol 10 is Web-RDP, Specify TCP routing protocol?
|
||||||
|
parent.parent.debug('relay', 'MiniRouter: Connection websocket to ' + url);
|
||||||
|
socket.relaySocket = new WebSocket(url, options);
|
||||||
|
socket.relaySocket.tcpSocket = socket;
|
||||||
|
socket.relaySocket.on('open', function () { parent.parent.debug('relay', 'MiniRouter: Relay websocket open'); });
|
||||||
|
socket.relaySocket.on('message', function (data) { // Make sure to handle flow control.
|
||||||
|
console.log('--> ' + data);
|
||||||
|
if (!this.active) {
|
||||||
|
if (data == 'c') {
|
||||||
|
// Relay Web socket is connected, start data relay
|
||||||
|
this.active = true;
|
||||||
|
this.tcpSocket.resume();
|
||||||
|
} else {
|
||||||
|
// Could not connect web socket, close it
|
||||||
|
console.log('ERR', data);
|
||||||
|
closeWebSocket(this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Relay more data
|
||||||
|
this._socket.pause();
|
||||||
|
const f = function sendDone() { sendDone.webSocket._socket.resume(); }
|
||||||
|
f.webSocket = this;
|
||||||
|
this.tcpSocket.write(data, f);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
socket.relaySocket.on('close', function () { parent.parent.debug('relay', 'MiniRouter: Relay websocket closed'); closeWebSocket(this); });
|
||||||
|
socket.relaySocket.on('error', function (err) { parent.parent.debug('relay', 'MiniRouter: Relay websocket error: ' + err); closeWebSocket(this); });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop the looppback server and all relay sockets
|
||||||
|
obj.stop = function () {
|
||||||
|
for (var tcpSocket in tcpSockets) { closeTcpSocket(tcpSocket); }
|
||||||
|
obj.tcpServer.close();
|
||||||
|
obj.tcpServer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
module.exports.CreateIPKVMManager = CreateIPKVMManager;
|
module.exports.CreateIPKVMManager = CreateIPKVMManager;
|
Loading…
x
Reference in New Issue
Block a user