connection: fix some edge cases

This commit is contained in:
Starbeamrainbowlabs 2021-10-02 17:00:24 +01:00
parent c43aeb6c3b
commit bbc5d54158
Signed by: sbrl
GPG key ID: 1BE5172E637709C2

View file

@ -15,9 +15,13 @@ import { encrypt_bytes, decrypt_bytes } from '../crypto/secretbox.mjs';
* Represents a connection to a single endpoint. * Represents a connection to a single endpoint.
*/ */
class Connection extends EventEmitter { class Connection extends EventEmitter {
constructor(secret_join) { constructor(secret_join, socket) {
super(); super();
this.socket = socket;
this.rekey_last = null;
this.rekey_interval = 30 * 60 * 1000; // 30 minutes
this.session_key = Buffer.from(secret_join, "base64"); this.session_key = Buffer.from(secret_join, "base64");
} }
@ -34,9 +38,14 @@ class Connection extends EventEmitter {
address, port address, port
}); });
await once(this.socket, "connect"); await once(this.socket, "connect");
await this.init();
}
async init() {
this.socket.setKeepAlive(true); this.socket.setKeepAlive(true);
this.session_key = await rekey(this.socket, this.session_key); await this.rekey();
this.framer = new FramedTransport(this.socket); this.framer = new FramedTransport(this.socket);
this.framer.on("frame", this.handle_frame); this.framer.on("frame", this.handle_frame);
@ -44,8 +53,13 @@ class Connection extends EventEmitter {
this.read_task = read_loop(); this.read_task = read_loop();
} }
destroy() { async rekey() {
this.socket.destroy(); this.rekey_last = new Date();
this.session_key = await rekey(this.socket, this.session_key);
}
async destroy() {
await this.framer.destroy();
this.emit("destroy"); this.emit("destroy");
} }
@ -69,14 +83,28 @@ class Connection extends EventEmitter {
} }
async send(message) { async send(message) {
// TODO: Implement a binary frame-based protocol here instead? It would be 33% more bandwidth efficient. if(new Date() - this.rekey_last > this.rekey_interval)
// Perhaps <length> <data>? If messages are too long, we'll have to do something about that though.... await this.rekey();
// TODO: Consider https://devdocs.io/node/crypto#crypto.createCipheriv() - which lets us use any openssl ciphers we like - e.g. ChaCha20-Poly1305 // TODO: Consider https://devdocs.io/node/crypto#crypto.createCipheriv() - which lets us use any openssl ciphers we like - e.g. ChaCha20-Poly1305
let payload = JSON.stringify(message); let payload = JSON.stringify(message);
payload = encrypt_bytes(this.session_key, payload); payload = encrypt_bytes(this.session_key, payload);
await this., payload);
await this.framer.write(payload);
} }
} }
Connection.Wrap = async function(secret_join, socket) {
const socket = new Connection(secret_join, socket);
await socket.init();
return socket;
}
Connection.Create = async function(secret_join, address, port) {
const socket = new Connection(secret_join);
socket.connect(address, port);
}
export default Connection; export default Connection;