voice: clean up packet handling

This commit is contained in:
Amish Shah
2018-08-16 11:28:28 +01:00
parent 64832abfdb
commit 97c34b5b6f
5 changed files with 23 additions and 29 deletions

View File

@@ -396,29 +396,25 @@ class VoiceConnection extends EventEmitter {
* @param {Object} data The received data * @param {Object} data The received data
* @private * @private
*/ */
onReady({ port, ssrc, ip, modes }) { onReady(data) {
this.authentication.port = port; this.authentication = data;
this.authentication.ssrc = ssrc; for (let mode of data.modes) {
for (let mode of modes) {
if (SUPPORTED_MODES.includes(mode)) { if (SUPPORTED_MODES.includes(mode)) {
this.authentication.encryptionMode = mode; this.authentication.mode = mode;
this.emit('debug', `Selecting the ${mode} mode`); this.emit('debug', `Selecting the ${mode} mode`);
break; break;
} }
} }
this.sockets.udp.createUDPSocket(ip); this.sockets.udp.createUDPSocket(data.ip);
} }
/** /**
* Invoked when a session description is received. * Invoked when a session description is received.
* @param {string} mode The encryption mode * @param {Object} data The received data
* @param {string} secret The secret key
* @private * @private
*/ */
onSessionDescription(mode, secret) { onSessionDescription(data) {
this.authentication.encryptionMode = mode; Object.assign(this.authentication, data);
this.authentication.secretKey = secret;
this.status = VoiceStatus.CONNECTED; this.status = VoiceStatus.CONNECTED;
clearTimeout(this.connectTimeout); clearTimeout(this.connectTimeout);
/** /**

View File

@@ -242,26 +242,26 @@ class StreamDispatcher extends Writable {
} }
_playChunk(chunk) { _playChunk(chunk) {
if (this.player.dispatcher !== this || !this.player.voiceConnection.authentication.secretKey) return; if (this.player.dispatcher !== this || !this.player.voiceConnection.authentication.secret_key) return;
this._setSpeaking(true); this._setSpeaking(true);
this._sendPacket(this._createPacket(this._sdata.sequence, this._sdata.timestamp, chunk)); this._sendPacket(this._createPacket(this._sdata.sequence, this._sdata.timestamp, chunk));
} }
_encrypt(buffer) { _encrypt(buffer) {
const { secretKey, encryptionMode } = this.player.voiceConnection.authentication; const { secret_key, mode } = this.player.voiceConnection.authentication;
if (encryptionMode === 'xsalsa20_poly1305_lite') { if (mode === 'xsalsa20_poly1305_lite') {
this._nonce++; this._nonce++;
if (this._nonce > MAX_NONCE_SIZE) this._nonce = 0; if (this._nonce > MAX_NONCE_SIZE) this._nonce = 0;
this._nonceBuffer.writeUInt32BE(this._nonce, 0); this._nonceBuffer.writeUInt32BE(this._nonce, 0);
return [ return [
secretbox.methods.close(buffer, this._nonceBuffer, secretKey), secretbox.methods.close(buffer, this._nonceBuffer, secret_key),
this._nonceBuffer.slice(0, 4), this._nonceBuffer.slice(0, 4),
]; ];
} else if (encryptionMode === 'xsalsa20_poly1305_suffix') { } else if (mode === 'xsalsa20_poly1305_suffix') {
const random = secretbox.methods.random(24); const random = secretbox.methods.random(24);
return [secretbox.methods.close(buffer, random, secretKey), random]; return [secretbox.methods.close(buffer, random, secret_key), random];
} else { } else {
return [secretbox.methods.close(buffer, nonce, secretKey)]; return [secretbox.methods.close(buffer, nonce, secret_key)];
} }
} }

View File

@@ -104,7 +104,7 @@ class VoiceConnectionUDPClient extends EventEmitter {
data: { data: {
address: packet.address, address: packet.address,
port: packet.port, port: packet.port,
mode: this.voiceConnection.authentication.encryptionMode, mode: this.voiceConnection.authentication.mode,
}, },
}, },
}); });

View File

@@ -168,15 +168,13 @@ class VoiceWebSocket extends EventEmitter {
break; break;
/* eslint-disable no-case-declarations */ /* eslint-disable no-case-declarations */
case VoiceOPCodes.SESSION_DESCRIPTION: case VoiceOPCodes.SESSION_DESCRIPTION:
const key = new Uint8Array(new ArrayBuffer(packet.d.secret_key.length)); packet.d.secret_key = new Uint8Array(packet.d.secret_key);
for (const i in packet.d.secret_key) key[i] = packet.d.secret_key[i];
/** /**
* Emitted once the Voice Websocket receives a description of this voice session. * Emitted once the Voice Websocket receives a description of this voice session.
* @param {string} encryptionMode The type of encryption being used * @param {Object} packet The received packet
* @param {Uint8Array} secretKey The secret key used for encryption
* @event VoiceWebSocket#sessionDescription * @event VoiceWebSocket#sessionDescription
*/ */
this.emit('sessionDescription', packet.d.mode, key); this.emit('sessionDescription', packet.d);
break; break;
case VoiceOPCodes.CLIENT_CONNECT: case VoiceOPCodes.CLIENT_CONNECT:
this.connection.ssrcMap.set(+packet.d.audio_ssrc, packet.d.user_id); this.connection.ssrcMap.set(+packet.d.audio_ssrc, packet.d.user_id);

View File

@@ -32,14 +32,14 @@ class PacketHandler extends EventEmitter {
} }
parseBuffer(buffer) { parseBuffer(buffer) {
const { secretKey, encryptionMode } = this.receiver.connection.authentication; const { secret_key, mode } = this.receiver.connection.authentication;
// Choose correct nonce depending on encryption // Choose correct nonce depending on encryption
let end; let end;
if (encryptionMode === 'xsalsa20_poly1305_lite') { if (mode === 'xsalsa20_poly1305_lite') {
buffer.copy(this.nonce, 0, buffer.length - 4); buffer.copy(this.nonce, 0, buffer.length - 4);
end = buffer.length - 4; end = buffer.length - 4;
} else if (encryptionMode === 'xsalsa20_poly1305_suffix') { } else if (mode === 'xsalsa20_poly1305_suffix') {
buffer.copy(this.nonce, 0, buffer.length - 24); buffer.copy(this.nonce, 0, buffer.length - 24);
end = buffer.length - 24; end = buffer.length - 24;
} else { } else {
@@ -47,7 +47,7 @@ class PacketHandler extends EventEmitter {
} }
// Open packet // Open packet
let packet = secretbox.methods.open(buffer.slice(12, end), this.nonce, secretKey); let packet = secretbox.methods.open(buffer.slice(12, end), this.nonce, secret_key);
if (!packet) return new Error('Failed to decrypt voice packet'); if (!packet) return new Error('Failed to decrypt voice packet');
packet = Buffer.from(packet); packet = Buffer.from(packet);