connection: fix some edge cases
This commit is contained in:
parent
c43aeb6c3b
commit
bbc5d54158
1 changed files with 35 additions and 7 deletions
|
@ -15,9 +15,13 @@ import { encrypt_bytes, decrypt_bytes } from '../crypto/secretbox.mjs';
|
|||
* Represents a connection to a single endpoint.
|
||||
*/
|
||||
class Connection extends EventEmitter {
|
||||
constructor(secret_join) {
|
||||
constructor(secret_join, socket) {
|
||||
super();
|
||||
|
||||
this.socket = socket;
|
||||
|
||||
this.rekey_last = null;
|
||||
this.rekey_interval = 30 * 60 * 1000; // 30 minutes
|
||||
this.session_key = Buffer.from(secret_join, "base64");
|
||||
}
|
||||
|
||||
|
@ -34,9 +38,14 @@ class Connection extends EventEmitter {
|
|||
address, port
|
||||
});
|
||||
await once(this.socket, "connect");
|
||||
|
||||
await this.init();
|
||||
}
|
||||
|
||||
async init() {
|
||||
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.on("frame", this.handle_frame);
|
||||
|
@ -44,8 +53,13 @@ class Connection extends EventEmitter {
|
|||
this.read_task = read_loop();
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.socket.destroy();
|
||||
async rekey() {
|
||||
this.rekey_last = new Date();
|
||||
this.session_key = await rekey(this.socket, this.session_key);
|
||||
}
|
||||
|
||||
async destroy() {
|
||||
await this.framer.destroy();
|
||||
this.emit("destroy");
|
||||
}
|
||||
|
||||
|
@ -69,14 +83,28 @@ class Connection extends EventEmitter {
|
|||
}
|
||||
|
||||
async send(message) {
|
||||
// TODO: Implement a binary frame-based protocol here instead? It would be 33% more bandwidth efficient.
|
||||
// Perhaps <length> <data>? If messages are too long, we'll have to do something about that though....
|
||||
if(new Date() - this.rekey_last > this.rekey_interval)
|
||||
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
|
||||
let payload = JSON.stringify(message);
|
||||
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;
|
||||
|
|
Loading…
Reference in a new issue