This repository has been archived on 2023-11-14. You can view files and clone it, but cannot push or open issues/pull-requests.
valnet/lib/STP/packets.js

111 lines
2.2 KiB
JavaScript

const md5 = require('md5');
// #region === [ private lib functions ] ===
class STPPacket {
cmd = 'NOOP';
data = {};
meta = {};
toBuffer() {
return Buffer.from(`\x02${JSON.stringify({
cmd: this.cmd,
data: this.data,
meta: this.meta
})}\x03`);
}
}
function basicPacket(commandName) {
return class extends STPPacket {
constructor() {
super();
this.cmd = commandName;
}
}
}
// #endregion
// #region === [ exotic packet classes ] ===
class KeyExchangePacket extends STPPacket {
constructor(key, type = 'pkcs8-pem') {
super();
this.cmd = 'KEY';
this.data.key = key;
this.meta.type = type;
}
}
class ClientsPacket extends STPPacket {
constructor(clients) {
super();
this.cmd = 'NODES'
this.data.clients = clients;
}
}
class PingPacket extends STPPacket {
constructor() {
super();
this.cmd = 'PING';
this.data.id = md5(Date());
}
}
class PongPacket extends STPPacket {
constructor(id) {
super();
this.cmd = 'PONG';
this.data.id = id;
}
}
// #endregion
// #region === [ ordinary packet classes ] ===
const AckPacket = basicPacket('ACK');
const GetClientsPacket = basicPacket('QNODES');
// #endregion
// #region === [ public lib functions ] ===
function reconstructPacket(packet) {
if(packet.startsWith('\02'))
return reconstructPacket(packet.substr(1));
if(packet.endsWith('\x03'))
return reconstructPacket(packet.substr(0, packet.length - 1));
const obj = JSON.parse(packet);
switch(obj.cmd) {
case 'KEY': return new KeyExchangePacket(obj.data.key, obj.meta.type);
case 'NODES': return new ClientsPacket(obj.data.clients);
case 'QNODES': return new GetClientsPacket();
case 'ACK': return new AckPacket();
case 'NOOP': return new STPPacket();
default: throw new TypeError(`Unknown command ${obj.cmd}`);
}
}
// #endregion
// #region === [ exports ] ===
module.exports.KeyExchangePacket = KeyExchangePacket;
module.exports.ClientsPacket = ClientsPacket;
module.exports.PingPacket = PingPacket;
module.exports.PongPacket = PongPacket;
module.exports.AckPacket = AckPacket;
module.exports.GetClientsPacket = GetClientsPacket;
module.exports.reconstructPacket = reconstructPacket;
// #endregion