mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2025-02-12 11:01:52 +00:00
Web relay websocket ping/pong forwarding, #4172
This commit is contained in:
parent
0637412d1b
commit
a383bd1cb3
1 changed files with 43 additions and 59 deletions
102
apprelays.js
102
apprelays.js
|
@ -260,42 +260,48 @@ module.exports.CreateWebRelay = function (parent, db, args, domain) {
|
||||||
// Setup opcode and payload
|
// Setup opcode and payload
|
||||||
var op = 2, payload = data;
|
var op = 2, payload = data;
|
||||||
if (typeof data == 'string') { op = 1; payload = Buffer.from(data, 'binary'); } // Text frame
|
if (typeof data == 'string') { op = 1; payload = Buffer.from(data, 'binary'); } // Text frame
|
||||||
|
sendWebSocketFrameToDevice(op, payload);
|
||||||
// Select a random mask
|
|
||||||
const mask = parent.parent.crypto.randomBytes(4)
|
|
||||||
|
|
||||||
// Setup header and mask
|
|
||||||
var header = null;
|
|
||||||
if (data.length < 126) {
|
|
||||||
header = Buffer.alloc(6); // Header (2) + Mask (4)
|
|
||||||
header[0] = 0x80 + op; // FIN + OP
|
|
||||||
header[1] = 0x80 + data.length; // Mask + Length
|
|
||||||
mask.copy(header, 2, 0, 4); // Copy the mask
|
|
||||||
} else if (data.length <= 0xFFFF) {
|
|
||||||
header = Buffer.alloc(8); // Header (2) + Length (2) + Mask (4)
|
|
||||||
header[0] = 0x80 + op; // FIN + OP
|
|
||||||
header[1] = 0x80 + 126; // Mask + 126
|
|
||||||
header.writeInt16BE(data.length, 2); // Payload size
|
|
||||||
mask.copy(header, 4, 0, 4); // Copy the mask
|
|
||||||
} else {
|
|
||||||
header = Buffer.alloc(14); // Header (2) + Length (8) + Mask (4)
|
|
||||||
header[0] = 0x80 + op; // FIN + OP
|
|
||||||
header[1] = 0x80 + 127; // Mask + 127
|
|
||||||
header.writeInt32BE(data.length, 6); // Payload size
|
|
||||||
mask.copy(header, 10, 0, 4); // Copy the mask
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mask the payload
|
|
||||||
for (var i = 0; i < payload.length; i++) { payload[i] = (payload[i] ^ mask[i % 4]); }
|
|
||||||
|
|
||||||
// Send the frame
|
|
||||||
//console.log(obj.tunnelId, '-->', op, payload.length);
|
|
||||||
send(Buffer.concat([header, payload]));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
obj.ws.on('ping', function (data) { sendWebSocketFrameToDevice(9, data); }); // Forward ping frame
|
||||||
|
obj.ws.on('pong', function (data) { sendWebSocketFrameToDevice(10, data); }); // Forward pong frame
|
||||||
obj.ws.on('close', function () { obj.close(); });
|
obj.ws.on('close', function () { obj.close(); });
|
||||||
obj.ws.on('error', function (err) { obj.close(); });
|
obj.ws.on('error', function (err) { obj.close(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sendWebSocketFrameToDevice(op, payload) {
|
||||||
|
// Select a random mask
|
||||||
|
const mask = parent.parent.crypto.randomBytes(4)
|
||||||
|
|
||||||
|
// Setup header and mask
|
||||||
|
var header = null;
|
||||||
|
if (payload.length < 126) {
|
||||||
|
header = Buffer.alloc(6); // Header (2) + Mask (4)
|
||||||
|
header[0] = 0x80 + op; // FIN + OP
|
||||||
|
header[1] = 0x80 + payload.length; // Mask + Length
|
||||||
|
mask.copy(header, 2, 0, 4); // Copy the mask
|
||||||
|
} else if (payload.length <= 0xFFFF) {
|
||||||
|
header = Buffer.alloc(8); // Header (2) + Length (2) + Mask (4)
|
||||||
|
header[0] = 0x80 + op; // FIN + OP
|
||||||
|
header[1] = 0x80 + 126; // Mask + 126
|
||||||
|
header.writeInt16BE(payload.length, 2); // Payload size
|
||||||
|
mask.copy(header, 4, 0, 4); // Copy the mask
|
||||||
|
} else {
|
||||||
|
header = Buffer.alloc(14); // Header (2) + Length (8) + Mask (4)
|
||||||
|
header[0] = 0x80 + op; // FIN + OP
|
||||||
|
header[1] = 0x80 + 127; // Mask + 127
|
||||||
|
header.writeInt32BE(payload.length, 6); // Payload size
|
||||||
|
mask.copy(header, 10, 0, 4); // Copy the mask
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mask the payload
|
||||||
|
for (var i = 0; i < payload.length; i++) { payload[i] = (payload[i] ^ mask[i % 4]); }
|
||||||
|
|
||||||
|
// Send the frame
|
||||||
|
//console.log(obj.tunnelId, '-->', op, payload.length);
|
||||||
|
send(Buffer.concat([header, payload]));
|
||||||
|
}
|
||||||
|
|
||||||
// Disconnect
|
// Disconnect
|
||||||
obj.close = function (arg) {
|
obj.close = function (arg) {
|
||||||
if (obj.closed == true) return;
|
if (obj.closed == true) return;
|
||||||
|
@ -541,34 +547,12 @@ module.exports.CreateWebRelay = function (parent, db, args, domain) {
|
||||||
|
|
||||||
// Perform operation
|
// Perform operation
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case 0: { // Continue frame
|
case 0: { break; } // Continue frame (TODO)
|
||||||
//console.log('continue', payload.length);
|
case 1: { try { obj.ws.send(payload.toString('binary')); } catch (ex) { } break; } // Text frame
|
||||||
break;
|
case 2: { try { obj.ws.send(payload); } catch (ex) { } break; } // Binary frame
|
||||||
}
|
case 8: { obj.close(); return; } // Connection close
|
||||||
case 1: { // Text frame
|
case 9: { try { obj.ws.ping(payload); } catch (ex) { } break; } // Ping frame
|
||||||
//console.log('text', payload.length);
|
case 10: { try { obj.ws.pong(payload); } catch (ex) { } break; } // Pong frame
|
||||||
try { obj.ws.send(payload.toString('binary')); } catch (ex) { }
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 2: { // Binary frame
|
|
||||||
//console.log('binary', payload.length);
|
|
||||||
try { obj.ws.send(payload); } catch (ex) { }
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 8: { // Connection close
|
|
||||||
obj.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
case 9: { // Ping frame
|
|
||||||
//console.log('ping', payload.length);
|
|
||||||
// TODO
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 10: { // Pong frame
|
|
||||||
//console.log('pong', payload.length);
|
|
||||||
// TODO
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue