mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-16 11:33:30 +01:00
voice: support xsalsa20_poly1305_lite and xsalsa20_poly1305_suffix
This commit is contained in:
@@ -8,6 +8,12 @@ const EventEmitter = require('events');
|
|||||||
const { Error } = require('../../errors');
|
const { Error } = require('../../errors');
|
||||||
const PlayInterface = require('./util/PlayInterface');
|
const PlayInterface = require('./util/PlayInterface');
|
||||||
|
|
||||||
|
const SUPPORTED_MODES = [
|
||||||
|
'xsalsa20_poly1305_lite',
|
||||||
|
'xsalsa20_poly1305_suffix',
|
||||||
|
'xsalsa20_poly1305',
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a connection to a guild's voice server.
|
* Represents a connection to a guild's voice server.
|
||||||
* ```js
|
* ```js
|
||||||
@@ -382,9 +388,16 @@ class VoiceConnection extends EventEmitter {
|
|||||||
* @param {Object} data The received data
|
* @param {Object} data The received data
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
onReady({ port, ssrc, ip }) {
|
onReady({ port, ssrc, ip, modes }) {
|
||||||
this.authentication.port = port;
|
this.authentication.port = port;
|
||||||
this.authentication.ssrc = ssrc;
|
this.authentication.ssrc = ssrc;
|
||||||
|
for (let mode of modes) {
|
||||||
|
if (SUPPORTED_MODES.includes(mode)) {
|
||||||
|
this.authentication.encryptionMode = mode;
|
||||||
|
this.emit('debug', `Selecting the ${mode} mode`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
this.sockets.udp.createUDPSocket(ip);
|
this.sockets.udp.createUDPSocket(ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ const FRAME_LENGTH = 20;
|
|||||||
const CHANNELS = 2;
|
const CHANNELS = 2;
|
||||||
const TIMESTAMP_INC = (48000 / 100) * CHANNELS;
|
const TIMESTAMP_INC = (48000 / 100) * CHANNELS;
|
||||||
|
|
||||||
|
const MAX_NONCE_SIZE = (2 ** 32) - 1;
|
||||||
const nonce = Buffer.alloc(24);
|
const nonce = Buffer.alloc(24);
|
||||||
nonce.fill(0);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @external WritableStream
|
* @external WritableStream
|
||||||
@@ -42,6 +42,9 @@ class StreamDispatcher extends Writable {
|
|||||||
this.streamOptions = streamOptions;
|
this.streamOptions = streamOptions;
|
||||||
this.streams = streams;
|
this.streams = streams;
|
||||||
|
|
||||||
|
this._nonce = 0;
|
||||||
|
this._nonceBuffer = Buffer.alloc(24);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The time that the stream was paused at (null if not paused)
|
* The time that the stream was paused at (null if not paused)
|
||||||
* @type {?number}
|
* @type {?number}
|
||||||
@@ -217,9 +220,26 @@ class StreamDispatcher extends Writable {
|
|||||||
this._sendPacket(this._createPacket(this._sdata.sequence, this._sdata.timestamp, chunk));
|
this._sendPacket(this._createPacket(this._sdata.sequence, this._sdata.timestamp, chunk));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_encrypt(buffer) {
|
||||||
|
const { secretKey, encryptionMode } = this.player.voiceConnection.authentication;
|
||||||
|
if (encryptionMode === 'xsalsa20_poly1305_lite') {
|
||||||
|
this._nonce++;
|
||||||
|
if (this._nonce > MAX_NONCE_SIZE) this._nonce = 0;
|
||||||
|
this._nonceBuffer.writeUInt32BE(this._nonce, 0);
|
||||||
|
return [
|
||||||
|
secretbox.methods.close(buffer, this._nonceBuffer, secretKey),
|
||||||
|
this._nonceBuffer.slice(0, 4),
|
||||||
|
];
|
||||||
|
} else if (encryptionMode === 'xsalsa20_poly1305_suffix') {
|
||||||
|
const random = secretbox.methods.random(24);
|
||||||
|
return [secretbox.methods.close(buffer, random, secretKey), random];
|
||||||
|
} else {
|
||||||
|
return [secretbox.methods.close(buffer, nonce, secretKey)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_createPacket(sequence, timestamp, buffer) {
|
_createPacket(sequence, timestamp, buffer) {
|
||||||
const packetBuffer = Buffer.alloc(buffer.length + 28);
|
const packetBuffer = Buffer.alloc(12);
|
||||||
packetBuffer.fill(0);
|
|
||||||
packetBuffer[0] = 0x80;
|
packetBuffer[0] = 0x80;
|
||||||
packetBuffer[1] = 0x78;
|
packetBuffer[1] = 0x78;
|
||||||
|
|
||||||
@@ -228,10 +248,7 @@ class StreamDispatcher extends Writable {
|
|||||||
packetBuffer.writeUIntBE(this.player.voiceConnection.authentication.ssrc, 8, 4);
|
packetBuffer.writeUIntBE(this.player.voiceConnection.authentication.ssrc, 8, 4);
|
||||||
|
|
||||||
packetBuffer.copy(nonce, 0, 0, 12);
|
packetBuffer.copy(nonce, 0, 0, 12);
|
||||||
buffer = secretbox.methods.close(buffer, nonce, this.player.voiceConnection.authentication.secretKey);
|
return Buffer.concat([packetBuffer, ...this._encrypt(buffer, sequence)]);
|
||||||
for (let i = 0; i < buffer.length; i++) packetBuffer[i + 12] = buffer[i];
|
|
||||||
|
|
||||||
return packetBuffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_sendPacket(packet) {
|
_sendPacket(packet) {
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ class VoiceConnectionUDPClient extends EventEmitter {
|
|||||||
data: {
|
data: {
|
||||||
address: packet.address,
|
address: packet.address,
|
||||||
port: packet.port,
|
port: packet.port,
|
||||||
mode: 'xsalsa20_poly1305',
|
mode: this.voiceConnection.authentication.encryptionMode,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,14 +2,17 @@ const libs = {
|
|||||||
sodium: sodium => ({
|
sodium: sodium => ({
|
||||||
open: sodium.api.crypto_secretbox_open_easy,
|
open: sodium.api.crypto_secretbox_open_easy,
|
||||||
close: sodium.api.crypto_secretbox_easy,
|
close: sodium.api.crypto_secretbox_easy,
|
||||||
|
random: n => sodium.randombytes_buf(n),
|
||||||
}),
|
}),
|
||||||
'libsodium-wrappers': sodium => ({
|
'libsodium-wrappers': sodium => ({
|
||||||
open: sodium.crypto_secretbox_open_easy,
|
open: sodium.crypto_secretbox_open_easy,
|
||||||
close: sodium.crypto_secretbox_easy,
|
close: sodium.crypto_secretbox_easy,
|
||||||
|
random: n => sodium.randombytes_buf(n),
|
||||||
}),
|
}),
|
||||||
tweetnacl: tweetnacl => ({
|
tweetnacl: tweetnacl => ({
|
||||||
open: tweetnacl.secretbox.open,
|
open: tweetnacl.secretbox.open,
|
||||||
close: tweetnacl.secretbox,
|
close: tweetnacl.secretbox,
|
||||||
|
random: n => tweetnacl.randomBytes(n),
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user