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* inPtr = input)
|
||||||
fixed (byte* outPtr = output)
|
fixed (byte* outPtr = output)
|
||||||
@@ -41,7 +41,7 @@ namespace Discord.Audio
|
|||||||
outPtr + outputOffset, out ulong plainLen,
|
outPtr + outputOffset, out ulong plainLen,
|
||||||
null,
|
null,
|
||||||
inPtr + inputOffset, (ulong)inputLength,
|
inPtr + inputOffset, (ulong)inputLength,
|
||||||
adPtr, (ulong)header.Length,
|
adPtr, (ulong)headerSize,
|
||||||
nonce, key
|
nonce, key
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -10,11 +10,13 @@ namespace Discord.Audio.Streams
|
|||||||
public class SodiumDecryptStream : AudioOutStream
|
public class SodiumDecryptStream : AudioOutStream
|
||||||
{
|
{
|
||||||
private const int RtpHeaderSize = 12;
|
private const int RtpHeaderSize = 12;
|
||||||
|
private const int ExtendedRtpHeaderSize = RtpHeaderSize + 4;
|
||||||
private const int NonceSize = 24;
|
private const int NonceSize = 24;
|
||||||
private const int NonceCounterSize = 4;
|
private const int NonceCounterSize = 4;
|
||||||
|
|
||||||
private readonly AudioClient _client;
|
private readonly AudioClient _client;
|
||||||
private readonly AudioStream _next;
|
private readonly AudioStream _next;
|
||||||
|
private readonly byte[] _rtpHeader;
|
||||||
private readonly byte[] _nonce;
|
private readonly byte[] _nonce;
|
||||||
|
|
||||||
public override bool CanRead => true;
|
public override bool CanRead => true;
|
||||||
@@ -25,6 +27,7 @@ namespace Discord.Audio.Streams
|
|||||||
{
|
{
|
||||||
_next = next;
|
_next = next;
|
||||||
_client = (AudioClient)client;
|
_client = (AudioClient)client;
|
||||||
|
_rtpHeader = new byte[ExtendedRtpHeaderSize];
|
||||||
_nonce = new byte[NonceSize];
|
_nonce = new byte[NonceSize];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,26 +38,30 @@ namespace Discord.Audio.Streams
|
|||||||
if (_client.SecretKey == null)
|
if (_client.SecretKey == null)
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|
||||||
// Extract nonce from the payload.
|
// Extract nonce counter from the end of the payload.
|
||||||
for (int i = 0; i < NonceCounterSize; i++ )
|
for (int i = 0; i < NonceCounterSize; i++)
|
||||||
_nonce[i] = buffer[offset + count + NonceCounterSize - i - 1]; // Big-endian to little-endian
|
_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
|
// Decrypt payload
|
||||||
byte[] rtpHeader = new byte[RtpHeaderSize];
|
int payloadOffset = offset + rtpHeaderSize;
|
||||||
Buffer.BlockCopy(buffer, offset, rtpHeader, 0, rtpHeader.Length);
|
int payloadLength = count - offset - rtpHeaderSize - NonceCounterSize;
|
||||||
int payloadOffset = offset + rtpHeader.Length;
|
|
||||||
int payloadLength = count - rtpHeader.Length - NonceCounterSize;
|
|
||||||
int decryptedLength = SecretBox.Decrypt(
|
int decryptedLength = SecretBox.Decrypt(
|
||||||
buffer,
|
buffer,
|
||||||
payloadOffset,
|
payloadOffset,
|
||||||
payloadLength,
|
payloadLength,
|
||||||
buffer,
|
buffer,
|
||||||
payloadOffset,
|
payloadOffset,
|
||||||
rtpHeader,
|
_rtpHeader,
|
||||||
|
rtpHeaderSize,
|
||||||
_nonce,
|
_nonce,
|
||||||
_client.SecretKey);
|
_client.SecretKey);
|
||||||
|
|
||||||
int packageLength = rtpHeader.Length + decryptedLength;
|
int packageLength = rtpHeaderSize + decryptedLength;
|
||||||
return _next.WriteAsync(buffer, offset, packageLength, cancelToken);
|
return _next.WriteAsync(buffer, offset, packageLength, cancelToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ namespace Discord.Audio.Streams
|
|||||||
|
|
||||||
private readonly AudioClient _client;
|
private readonly AudioClient _client;
|
||||||
private readonly AudioStream _next;
|
private readonly AudioStream _next;
|
||||||
|
private readonly byte[] _rtpHeader;
|
||||||
private readonly byte[] _nonce;
|
private readonly byte[] _nonce;
|
||||||
private bool _hasHeader;
|
private bool _hasHeader;
|
||||||
private ushort _nextSeq;
|
private ushort _nextSeq;
|
||||||
@@ -24,6 +25,7 @@ namespace Discord.Audio.Streams
|
|||||||
{
|
{
|
||||||
_next = next;
|
_next = next;
|
||||||
_client = (AudioClient)client;
|
_client = (AudioClient)client;
|
||||||
|
_rtpHeader = new byte[RtpHeaderSize];
|
||||||
_nonce = new byte[NonceSize];
|
_nonce = new byte[NonceSize];
|
||||||
_nonceCounter = 0;
|
_nonceCounter = 0;
|
||||||
}
|
}
|
||||||
@@ -60,23 +62,22 @@ namespace Discord.Audio.Streams
|
|||||||
_nonceCounter = 0;
|
_nonceCounter = 0;
|
||||||
|
|
||||||
// Encrypt payload
|
// Encrypt payload
|
||||||
byte[] rtpHeader = new byte[RtpHeaderSize];
|
Buffer.BlockCopy(buffer, offset, _rtpHeader, 0, _rtpHeader.Length);
|
||||||
Buffer.BlockCopy(buffer, offset, rtpHeader, 0, rtpHeader.Length);
|
int payloadOffset = offset + _rtpHeader.Length;
|
||||||
int payloadOffset = offset + rtpHeader.Length;
|
int payloadLength = count - offset - _rtpHeader.Length;
|
||||||
int payloadLength = count - rtpHeader.Length;
|
|
||||||
int encryptedLength = SecretBox.Encrypt(
|
int encryptedLength = SecretBox.Encrypt(
|
||||||
buffer,
|
buffer,
|
||||||
payloadOffset,
|
payloadOffset,
|
||||||
payloadLength,
|
payloadLength,
|
||||||
buffer,
|
buffer,
|
||||||
payloadOffset,
|
payloadOffset,
|
||||||
rtpHeader,
|
_rtpHeader,
|
||||||
_nonce,
|
_nonce,
|
||||||
_client.SecretKey);
|
_client.SecretKey);
|
||||||
|
|
||||||
// Append nonce to encripted payload
|
// Append nonce to encripted payload
|
||||||
Buffer.BlockCopy(counterBytes, 0, buffer, payloadOffset + encryptedLength, counterBytes.Length);
|
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);
|
_next.WriteHeader(_nextSeq, _nextTimestamp, false);
|
||||||
await _next.WriteAsync(buffer, offset, packageLength, cancelToken).ConfigureAwait(false);
|
await _next.WriteAsync(buffer, offset, packageLength, cancelToken).ConfigureAwait(false);
|
||||||
|
|||||||
Reference in New Issue
Block a user