Skip to content

Commit

Permalink
fix: Large buffer will cause FlushAsync block
Browse files Browse the repository at this point in the history
  • Loading branch information
HMBSbige committed Sep 18, 2021
1 parent 4b05448 commit 52124f0
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 39 deletions.
50 changes: 19 additions & 31 deletions Shadowsocks.Protocol/TcpClients/ShadowsocksPipeReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using Shadowsocks.Crypto;
using Shadowsocks.Protocol.Models;
using System;
using System.Buffers;
using System.IO.Pipelines;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -56,10 +55,25 @@ private Task WrapAsync(IShadowsocksCrypto decryptor, CancellationToken cancellat

try
{
if (ReceiveFromRemote(ref buffer))
while (!buffer.IsEmpty)
{
var writerFlushResult = await Writer.FlushAsync(cancellationToken);
if (writerFlushResult.IsCompleted)
var oldLength = buffer.Length;

var memory = Writer.GetMemory(BufferSize);

var outLength = decryptor.DecryptTCP(ref buffer, memory.Span);

Writer.Advance(outLength);
if (outLength > 0)
{
var writerFlushResult = await Writer.FlushAsync(cancellationToken);
if (writerFlushResult.IsCompleted)
{
goto NoData;
}
}

if (oldLength == buffer.Length)
{
break;
}
Expand All @@ -75,7 +89,7 @@ private Task WrapAsync(IShadowsocksCrypto decryptor, CancellationToken cancellat
InternalReader.AdvanceTo(buffer.Start, buffer.End);
}
}

NoData:
await Writer.CompleteAsync();
}
catch (Exception ex)
Expand All @@ -89,32 +103,6 @@ private Task WrapAsync(IShadowsocksCrypto decryptor, CancellationToken cancellat
},
default
);

bool ReceiveFromRemote(ref ReadOnlySequence<byte> sequence)
{
var result = false;
while (!sequence.IsEmpty)
{
var oldLength = sequence.Length;

var span = Writer.GetSpan(BufferSize);

var outLength = decryptor.DecryptTCP(ref sequence, span);

Writer.Advance(outLength);
if (outLength > 0)
{
result = true;
}

if (oldLength == sequence.Length)
{
break;
}
}

return result;
}
}

public override void AdvanceTo(SequencePosition consumed)
Expand Down
12 changes: 4 additions & 8 deletions Shadowsocks.Protocol/TcpClients/ShadowsocksPipeWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,13 @@ private Task WrapAsync(IShadowsocksCrypto encryptor, CancellationToken cancellat
var result = await Reader.ReadAsync(cancellationToken);
var buffer = result.Buffer;

if (!buffer.IsEmpty)
foreach (var segment in buffer)
{
foreach (var segment in buffer)
{
SendToRemote(segment.Span);
}

SendToRemote(segment.Span);
var flushResult = await InternalWriter.FlushAsync(cancellationToken);
if (flushResult.IsCompleted)
{
break;
goto NoData;
}
}

Expand All @@ -73,7 +69,7 @@ private Task WrapAsync(IShadowsocksCrypto encryptor, CancellationToken cancellat
break;
}
}

NoData:
await Reader.CompleteAsync();
}
catch (Exception ex)
Expand Down

0 comments on commit 52124f0

Please sign in to comment.