Skip to content

Commit 4b05448

Browse files
committed
refactor: Better ShadowsocksPipe
1 parent 5d4f9c6 commit 4b05448

File tree

8 files changed

+358
-226
lines changed

8 files changed

+358
-226
lines changed

Shadowsocks.Protocol/ListenServices/TcpListenService.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using Microsoft.Extensions.Logging;
22
using Microsoft.VisualStudio.Threading;
33
using Pipelines.Extensions;
4-
using Pipelines.Extensions.SocketPipe;
54
using Shadowsocks.Protocol.LocalTcpServices;
65
using System;
76
using System.Collections.Generic;
@@ -11,6 +10,7 @@
1110
using System.Net.Sockets;
1211
using System.Threading;
1312
using System.Threading.Tasks;
13+
using static Shadowsocks.Protocol.ShadowsocksProtocolConstants;
1414

1515
namespace Shadowsocks.Protocol.ListenServices
1616
{
@@ -24,8 +24,6 @@ public class TcpListenService : IListenService
2424
private readonly CancellationTokenSource _cts;
2525

2626
private const string LoggerHeader = @"[TcpListenService]";
27-
private const int FirstBufferSize = 8192;
28-
private static readonly SocketPipeReaderOptions LocalPipeReaderOptions = new(sizeHint: FirstBufferSize);
2927

3028
public TcpListenService(ILogger<TcpListenService> logger, IPEndPoint local, IEnumerable<ILocalTcpService> services)
3129
{
@@ -64,7 +62,7 @@ private async Task HandleAsync(Socket socket, CancellationToken token)
6462
var remoteEndPoint = socket.RemoteEndPoint;
6563
try
6664
{
67-
var pipe = socket.AsDuplexPipe(LocalPipeReaderOptions);
65+
var pipe = socket.AsDuplexPipe(SocketPipeReaderOptions, SocketPipeWriterOptions);
6866
var result = await pipe.Input.ReadAsync(token);
6967
var buffer = result.Buffer;
7068

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using Pipelines.Extensions.SocketPipe;
2+
using System.IO.Pipelines;
3+
4+
namespace Shadowsocks.Protocol
5+
{
6+
internal static class ShadowsocksProtocolConstants
7+
{
8+
private const int BlockSize = 4096; // 4K
9+
public const int ReceiveBufferSize = 20 * BlockSize; // 80K, must < 85000 LOH
10+
public const int SendBufferSize = 5 * BlockSize; // 20K, must < 85000 LOH
11+
12+
private const int SegmentPoolSize = 16;
13+
private const int MinimumSegmentSize = BlockSize;
14+
private const int ResumeWriterThreshold = PauseWriterThreshold / 2;
15+
private const int PauseWriterThreshold = MinimumSegmentSize * SegmentPoolSize;
16+
public static readonly PipeOptions DefaultPipeOptions = new(
17+
pauseWriterThreshold: PauseWriterThreshold,
18+
resumeWriterThreshold: ResumeWriterThreshold,
19+
minimumSegmentSize: MinimumSegmentSize);
20+
21+
public static readonly SocketPipeReaderOptions SocketPipeReaderOptions = new(DefaultPipeOptions, sizeHint: ReceiveBufferSize);
22+
public static readonly SocketPipeWriterOptions SocketPipeWriterOptions = new(DefaultPipeOptions);
23+
}
24+
}

Shadowsocks.Protocol/TcpClients/IPipeClient.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace Shadowsocks.Protocol.TcpClients
77
{
88
public interface IPipeClient : IAsyncDisposable
99
{
10-
ValueTask ConnectAsync(CancellationToken token);
10+
ValueTask ConnectAsync(CancellationToken cancellationToken = default);
1111

1212
IDuplexPipe GetPipe(string targetAddress, ushort targetPort);
1313
}

Shadowsocks.Protocol/TcpClients/ShadowsocksDuplexPipe.cs

Lines changed: 0 additions & 207 deletions
This file was deleted.
Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1+
using Pipelines.Extensions;
12
using Shadowsocks.Protocol.Models;
23
using Socks5.Utils;
34
using System.IO.Pipelines;
45
using System.Runtime.CompilerServices;
5-
using System.Threading;
66

77
namespace Shadowsocks.Protocol.TcpClients
88
{
@@ -13,17 +13,14 @@ public static IDuplexPipe AsShadowsocksPipe(
1313
this IDuplexPipe pipe,
1414
ShadowsocksServerInfo serverInfo,
1515
string targetAddress, ushort targetPort,
16-
PipeOptions? pipeOptions = null,
17-
CancellationToken cancellationToken = default)
16+
PipeOptions? readerOptions = null,
17+
PipeOptions? writerOptions = null)
1818
{
19-
return new ShadowsocksDuplexPipe(
20-
pipe,
21-
serverInfo,
22-
targetAddress,
23-
targetPort,
24-
pipeOptions,
25-
cancellationToken
26-
);
19+
var reader = pipe.Input.AsShadowsocksPipeReader(serverInfo, readerOptions);
20+
var writer = pipe.Output.AsShadowsocksPipeWriter(serverInfo, writerOptions);
21+
writer.WriteShadowsocksHeader(targetAddress, targetPort);
22+
23+
return DefaultDuplexPipe.Create(reader, writer);
2724
}
2825

2926
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -35,5 +32,23 @@ public static void WriteShadowsocksHeader(
3532
var addressLength = Pack.DestinationAddressAndPort(targetAddress, default, targetPort, span);
3633
writer.Advance(addressLength);
3734
}
35+
36+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
37+
public static PipeWriter AsShadowsocksPipeWriter(
38+
this PipeWriter writer,
39+
ShadowsocksServerInfo serverInfo,
40+
PipeOptions? pipeOptions = null)
41+
{
42+
return new ShadowsocksPipeWriter(writer, serverInfo, pipeOptions);
43+
}
44+
45+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
46+
public static PipeReader AsShadowsocksPipeReader(
47+
this PipeReader reader,
48+
ShadowsocksServerInfo serverInfo,
49+
PipeOptions? pipeOptions = null)
50+
{
51+
return new ShadowsocksPipeReader(reader, serverInfo, pipeOptions);
52+
}
3853
}
3954
}

0 commit comments

Comments
 (0)