Add encrypted managed UDP relay and native voice conformance
This commit is contained in:
@@ -21,6 +21,8 @@ internal sealed class TlsControlConnection : IAsyncDisposable
|
||||
private int prefixBytes;
|
||||
private byte[]? payload;
|
||||
private int payloadBytes;
|
||||
private readonly TaskCompletionSource mediaReady = new(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
private MediaSessionCrypto? mediaCrypto;
|
||||
|
||||
public Task Completion { get; }
|
||||
public CancellationToken CancellationToken => lifetime.Token;
|
||||
@@ -48,6 +50,12 @@ internal sealed class TlsControlConnection : IAsyncDisposable
|
||||
|
||||
public void CompleteWrites() => outgoing.Writer.TryComplete();
|
||||
|
||||
internal async Task<MediaSessionCrypto> TakeMediaCryptoAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
await mediaReady.Task.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||
return Interlocked.Exchange(ref mediaCrypto, null) ?? throw new InvalidOperationException("Media crypto already has an owner.");
|
||||
}
|
||||
|
||||
private async Task RunAsync()
|
||||
{
|
||||
byte[] ciphertext = new byte[16384];
|
||||
@@ -80,6 +88,13 @@ internal sealed class TlsControlConnection : IAsyncDisposable
|
||||
break;
|
||||
}
|
||||
tls.ReceiveCiphertext(ciphertext.AsSpan(0, count));
|
||||
if (tls.IsReady && !mediaReady.Task.IsCompleted)
|
||||
{
|
||||
var encryptor = tls.CreateMediaEncryptor();
|
||||
try { mediaCrypto = new(encryptor, tls.CreateMediaDecryptor()); }
|
||||
catch { encryptor.Dispose(); throw; }
|
||||
mediaReady.SetResult();
|
||||
}
|
||||
if (tls.IsReady) lifetime.CancelAfter(TimeSpan.FromSeconds(60));
|
||||
while ((count = tls.ReadPlaintext(plaintext)) > 0) Parse(plaintext.AsSpan(0, count));
|
||||
await FlushAsync(sendBuffer, cancellationToken).ConfigureAwait(false);
|
||||
@@ -104,6 +119,7 @@ internal sealed class TlsControlConnection : IAsyncDisposable
|
||||
}
|
||||
finally
|
||||
{
|
||||
mediaReady.TrySetCanceled();
|
||||
lifetime.Cancel();
|
||||
socket.Dispose();
|
||||
if (receive is not null)
|
||||
@@ -163,7 +179,7 @@ internal sealed class TlsControlConnection : IAsyncDisposable
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
lifetime.Cancel();
|
||||
await Completion.ConfigureAwait(false);
|
||||
lifetime.Dispose();
|
||||
try { await Completion.ConfigureAwait(false); }
|
||||
finally { Interlocked.Exchange(ref mediaCrypto, null)?.Dispose(); lifetime.Dispose(); }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user