Fix voice receiving (#3190)
* Update voice API to version 8 * Fix voice receiving * Reuse RTP Header array during decryption
This commit is contained in:
committed by
GitHub
parent
8883596c31
commit
a468e182eb
@@ -31,7 +31,7 @@ namespace Discord.Audio
|
||||
}
|
||||
}
|
||||
|
||||
public static int Decrypt(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, byte[] header, byte[] nonce, byte[] key)
|
||||
public static int Decrypt(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, byte[] header, int headerSize, byte[] nonce, byte[] key)
|
||||
{
|
||||
fixed (byte* inPtr = input)
|
||||
fixed (byte* outPtr = output)
|
||||
@@ -41,7 +41,7 @@ namespace Discord.Audio
|
||||
outPtr + outputOffset, out ulong plainLen,
|
||||
null,
|
||||
inPtr + inputOffset, (ulong)inputLength,
|
||||
adPtr, (ulong)header.Length,
|
||||
adPtr, (ulong)headerSize,
|
||||
nonce, key
|
||||
);
|
||||
|
||||
|
||||
@@ -10,11 +10,13 @@ namespace Discord.Audio.Streams
|
||||
public class SodiumDecryptStream : AudioOutStream
|
||||
{
|
||||
private const int RtpHeaderSize = 12;
|
||||
private const int ExtendedRtpHeaderSize = RtpHeaderSize + 4;
|
||||
private const int NonceSize = 24;
|
||||
private const int NonceCounterSize = 4;
|
||||
|
||||
private readonly AudioClient _client;
|
||||
private readonly AudioStream _next;
|
||||
private readonly byte[] _rtpHeader;
|
||||
private readonly byte[] _nonce;
|
||||
|
||||
public override bool CanRead => true;
|
||||
@@ -25,6 +27,7 @@ namespace Discord.Audio.Streams
|
||||
{
|
||||
_next = next;
|
||||
_client = (AudioClient)client;
|
||||
_rtpHeader = new byte[ExtendedRtpHeaderSize];
|
||||
_nonce = new byte[NonceSize];
|
||||
}
|
||||
|
||||
@@ -35,26 +38,30 @@ namespace Discord.Audio.Streams
|
||||
if (_client.SecretKey == null)
|
||||
return Task.CompletedTask;
|
||||
|
||||
// Extract nonce from the payload.
|
||||
for (int i = 0; i < NonceCounterSize; i++ )
|
||||
_nonce[i] = buffer[offset + count + NonceCounterSize - i - 1]; // Big-endian to little-endian
|
||||
// Extract nonce counter from the end of the payload.
|
||||
for (int i = 0; i < NonceCounterSize; i++)
|
||||
_nonce[i] = buffer[offset + count - NonceCounterSize + i];
|
||||
|
||||
// Extract RTP header
|
||||
bool hasExtendedHeader = (buffer[0] & 0x10) != 0;
|
||||
int rtpHeaderSize = hasExtendedHeader ? ExtendedRtpHeaderSize : RtpHeaderSize;
|
||||
Buffer.BlockCopy(buffer, offset, _rtpHeader, 0, rtpHeaderSize);
|
||||
|
||||
// Decrypt payload
|
||||
byte[] rtpHeader = new byte[RtpHeaderSize];
|
||||
Buffer.BlockCopy(buffer, offset, rtpHeader, 0, rtpHeader.Length);
|
||||
int payloadOffset = offset + rtpHeader.Length;
|
||||
int payloadLength = count - rtpHeader.Length - NonceCounterSize;
|
||||
int payloadOffset = offset + rtpHeaderSize;
|
||||
int payloadLength = count - offset - rtpHeaderSize - NonceCounterSize;
|
||||
int decryptedLength = SecretBox.Decrypt(
|
||||
buffer,
|
||||
payloadOffset,
|
||||
payloadLength,
|
||||
buffer,
|
||||
payloadOffset,
|
||||
rtpHeader,
|
||||
_rtpHeader,
|
||||
rtpHeaderSize,
|
||||
_nonce,
|
||||
_client.SecretKey);
|
||||
|
||||
int packageLength = rtpHeader.Length + decryptedLength;
|
||||
int packageLength = rtpHeaderSize + decryptedLength;
|
||||
return _next.WriteAsync(buffer, offset, packageLength, cancelToken);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace Discord.Audio.Streams
|
||||
|
||||
private readonly AudioClient _client;
|
||||
private readonly AudioStream _next;
|
||||
private readonly byte[] _rtpHeader;
|
||||
private readonly byte[] _nonce;
|
||||
private bool _hasHeader;
|
||||
private ushort _nextSeq;
|
||||
@@ -24,6 +25,7 @@ namespace Discord.Audio.Streams
|
||||
{
|
||||
_next = next;
|
||||
_client = (AudioClient)client;
|
||||
_rtpHeader = new byte[RtpHeaderSize];
|
||||
_nonce = new byte[NonceSize];
|
||||
_nonceCounter = 0;
|
||||
}
|
||||
@@ -60,23 +62,22 @@ namespace Discord.Audio.Streams
|
||||
_nonceCounter = 0;
|
||||
|
||||
// Encrypt payload
|
||||
byte[] rtpHeader = new byte[RtpHeaderSize];
|
||||
Buffer.BlockCopy(buffer, offset, rtpHeader, 0, rtpHeader.Length);
|
||||
int payloadOffset = offset + rtpHeader.Length;
|
||||
int payloadLength = count - rtpHeader.Length;
|
||||
Buffer.BlockCopy(buffer, offset, _rtpHeader, 0, _rtpHeader.Length);
|
||||
int payloadOffset = offset + _rtpHeader.Length;
|
||||
int payloadLength = count - offset - _rtpHeader.Length;
|
||||
int encryptedLength = SecretBox.Encrypt(
|
||||
buffer,
|
||||
payloadOffset,
|
||||
payloadLength,
|
||||
buffer,
|
||||
payloadOffset,
|
||||
rtpHeader,
|
||||
_rtpHeader,
|
||||
_nonce,
|
||||
_client.SecretKey);
|
||||
|
||||
// Append nonce to encripted payload
|
||||
Buffer.BlockCopy(counterBytes, 0, buffer, payloadOffset + encryptedLength, counterBytes.Length);
|
||||
int packageLength = rtpHeader.Length + encryptedLength + counterBytes.Length;
|
||||
int packageLength = _rtpHeader.Length + encryptedLength + counterBytes.Length;
|
||||
|
||||
_next.WriteHeader(_nextSeq, _nextTimestamp, false);
|
||||
await _next.WriteAsync(buffer, offset, packageLength, cancelToken).ConfigureAwait(false);
|
||||
|
||||
Reference in New Issue
Block a user