From 22645fcb6581c74eb6a77888cce2b2aa2f0822a9 Mon Sep 17 00:00:00 2001 From: Bruce Wayne Date: Tue, 10 Aug 2021 11:22:04 +0800 Subject: [PATCH] style: Use Microsoft.VisualStudio.Validation --- HttpProxy/HttpSocks5Service.cs | 6 +-- Pipelines.Extensions/PipeReaderExtensions.cs | 7 ++- .../LocalTcpServices/HttpService.cs | 13 ++--- .../LocalTcpServices/Socks5Service.cs | 18 ++----- .../TcpClients/ShadowsocksTcpClient.cs | 6 +-- Socks5/Clients/Socks5Client.cs | 47 +++---------------- Socks5/Utils/Pack.cs | 26 +++------- Socks5/Utils/Unpack.cs | 34 ++++++-------- 8 files changed, 42 insertions(+), 115 deletions(-) diff --git a/HttpProxy/HttpSocks5Service.cs b/HttpProxy/HttpSocks5Service.cs index d3a83c8..a2d9e87 100644 --- a/HttpProxy/HttpSocks5Service.cs +++ b/HttpProxy/HttpSocks5Service.cs @@ -1,3 +1,4 @@ +using Microsoft; using Microsoft.VisualStudio.Threading; using Pipelines.Extensions; using Socks5.Models; @@ -20,10 +21,7 @@ public class HttpSocks5Service public HttpSocks5Service(IPEndPoint local, HttpToSocks5 httpToSocks5, Socks5CreateOption socks5CreateOption) { - if (socks5CreateOption.Address is null) - { - throw new ArgumentNullException(nameof(socks5CreateOption.Address)); - } + Requires.NotNullAllowStructs(socks5CreateOption.Address, nameof(socks5CreateOption.Address)); TcpListener = new TcpListener(local); _httpToSocks5 = httpToSocks5; diff --git a/Pipelines.Extensions/PipeReaderExtensions.cs b/Pipelines.Extensions/PipeReaderExtensions.cs index 98dc576..79657cb 100644 --- a/Pipelines.Extensions/PipeReaderExtensions.cs +++ b/Pipelines.Extensions/PipeReaderExtensions.cs @@ -1,3 +1,4 @@ +using Microsoft; using System; using System.IO; using System.IO.Pipelines; @@ -46,11 +47,9 @@ public static async ValueTask CopyToAsync( CancellationToken cancellationToken = default) { //TODO .NET6.0 ReadAtLeastAsync + //TODO CancelPendingRead - if (size < 0) - { - throw new ArgumentOutOfRangeException(nameof(size), @"size must >0."); - } + Requires.Range(size >= 0, nameof(size), @"size must >=0."); while (true) { diff --git a/Shadowsocks.Protocol/LocalTcpServices/HttpService.cs b/Shadowsocks.Protocol/LocalTcpServices/HttpService.cs index 00dfbba..350ed52 100644 --- a/Shadowsocks.Protocol/LocalTcpServices/HttpService.cs +++ b/Shadowsocks.Protocol/LocalTcpServices/HttpService.cs @@ -1,6 +1,6 @@ using HttpProxy; +using Microsoft; using Socks5.Models; -using System; using System.Buffers; using System.IO.Pipelines; using System.Threading; @@ -26,15 +26,8 @@ public bool IsHandle(ReadOnlySequence buffer) public async ValueTask HandleAsync(IDuplexPipe pipe, CancellationToken token = default) { - if (Socks5CreateOption is null) - { - throw new InvalidOperationException($@"You must set {nameof(Socks5CreateOption)}"); - } - - if (Socks5CreateOption.Address is null) - { - throw new InvalidOperationException(@"You must set socks5 address"); - } + Verify.Operation(Socks5CreateOption is not null, @"You must set {0}", nameof(Socks5CreateOption)); + Verify.Operation(Socks5CreateOption.Address is not null, @"You must set socks5 address"); await _httpToSocks5.ForwardToSocks5Async(pipe, Socks5CreateOption, token); } diff --git a/Shadowsocks.Protocol/LocalTcpServices/Socks5Service.cs b/Shadowsocks.Protocol/LocalTcpServices/Socks5Service.cs index 1fa7304..43bd1e8 100644 --- a/Shadowsocks.Protocol/LocalTcpServices/Socks5Service.cs +++ b/Shadowsocks.Protocol/LocalTcpServices/Socks5Service.cs @@ -1,3 +1,4 @@ +using Microsoft; using Microsoft.Extensions.Logging; using Pipelines.Extensions; using Shadowsocks.Protocol.ServersControllers; @@ -5,7 +6,6 @@ using Socks5.Enums; using Socks5.Models; using Socks5.Servers; -using System; using System.Buffers; using System.IO.Pipelines; using System.Net; @@ -37,15 +37,8 @@ public bool IsHandle(ReadOnlySequence buffer) public async ValueTask HandleAsync(IDuplexPipe pipe, CancellationToken token = default) { - if (Socks5CreateOption is null) - { - throw new ArgumentNullException(nameof(Socks5CreateOption)); - } - - if (Socks5CreateOption.Address is null) - { - throw new ArgumentNullException(nameof(Socks5CreateOption.Address)); - } + Verify.Operation(Socks5CreateOption is not null, @"You must set {0}", nameof(Socks5CreateOption)); + Verify.Operation(Socks5CreateOption.Address is not null, @"You must set socks5 address"); var socks5 = new Socks5ServerConnection(pipe, Socks5CreateOption.UsernamePassword); @@ -77,10 +70,7 @@ public async ValueTask HandleAsync(IDuplexPipe pipe, CancellationToken token = d }; await socks5.SendReplyAsync(Socks5Reply.Succeeded, bound, token); - if (client.Pipe is null) - { - throw new InvalidOperationException(@"You should TryConnect successfully first!"); - } + Verify.Operation(client.Pipe is not null, @"You should TryConnect successfully first!"); await client.Pipe.Output.SendShadowsocksHeaderAsync(target, socks5.Target.Port, token); diff --git a/Shadowsocks.Protocol/TcpClients/ShadowsocksTcpClient.cs b/Shadowsocks.Protocol/TcpClients/ShadowsocksTcpClient.cs index 09eadac..9775863 100644 --- a/Shadowsocks.Protocol/TcpClients/ShadowsocksTcpClient.cs +++ b/Shadowsocks.Protocol/TcpClients/ShadowsocksTcpClient.cs @@ -1,3 +1,4 @@ +using Microsoft; using Microsoft.Extensions.Logging; using Pipelines.Extensions; using Shadowsocks.Protocol.Models; @@ -30,10 +31,7 @@ public async ValueTask TryConnectAsync(CancellationToken token) { try { - if (_serverInfo.Address is null) - { - throw new ArgumentNullException(nameof(_serverInfo.Address)); - } + Requires.NotNullAllowStructs(_serverInfo.Address, nameof(_serverInfo.Address)); _client = new TcpClient { NoDelay = true }; await _client.ConnectAsync(_serverInfo.Address, _serverInfo.Port, token); diff --git a/Socks5/Clients/Socks5Client.cs b/Socks5/Clients/Socks5Client.cs index 67ccfef..e642264 100644 --- a/Socks5/Clients/Socks5Client.cs +++ b/Socks5/Clients/Socks5Client.cs @@ -39,10 +39,7 @@ public sealed class Socks5Client : IDisposable, IAsyncDisposable public Socks5Client(Socks5CreateOption option) { Requires.NotNull(option, nameof(option)); - if (option.Address is null) - { - throw new ArgumentNullException(nameof(option.Address)); - } + Requires.NotNullAllowStructs(option.Address, nameof(option.Address)); _option = option; _tcpClient = new TcpClient(option.Address.AddressFamily); @@ -54,10 +51,7 @@ public Socks5Client(Socks5CreateOption option) public IDuplexPipe GetPipe() { - if (Status is not Status.Established || _pipe is null) - { - throw new InvalidOperationException(@"Socks5 is not established."); - } + Verify.Operation(Status is Status.Established && _pipe is not null, @"Socks5 is not established."); return _pipe; } @@ -123,7 +117,7 @@ public async ValueTask UdpAssociateAsync(IPAddress address, ushort } default: { - throw new ArgumentOutOfRangeException(nameof(bound.Type)); + throw Assumes.NotReachable(); } } @@ -135,10 +129,7 @@ public async ValueTask UdpAssociateAsync(IPAddress address, ushort //TODO .NET6.0 public async Task ReceiveAsync() { - if (Status is not Status.Established || _udpClient is null) - { - throw new InvalidOperationException(@"Socks5 is not established."); - } + Verify.Operation(Status is Status.Established && _udpClient is not null, @"Socks5 is not established."); var res = await _udpClient.ReceiveAsync(); @@ -159,10 +150,7 @@ private async Task SendUdpAsync( ReadOnlyMemory data, string? dst, IPAddress? dstAddress, ushort dstPort) { - if (Status is not Status.Established || _udpClient is null) - { - throw new InvalidOperationException(@"Socks5 is not established."); - } + Verify.Operation(Status is Status.Established && _udpClient is not null, @"Socks5 is not established."); var buffer = ArrayPool.Shared.Rent(Constants.MaxUdpHandshakeHeaderLength + data.Length); try @@ -183,10 +171,7 @@ private async Task SendUdpAsync( private async ValueTask HandshakeAsync(CancellationToken token) { - if (Status is not Status.Initial) - { - throw new InvalidOperationException(@"Socks5 already connected."); - } + Verify.Operation(Status is Status.Initial, @"Socks5 already connected."); await _tcpClient.ConnectAsync(_option.Address!, _option.Port, token); @@ -199,25 +184,7 @@ private async ValueTask HandshakeAsync(CancellationToken token) private async ValueTask HandshakeWithAuthAsync(IDuplexPipe pipe, CancellationToken token) { - switch (Status) - { - case Status.Established: - { - throw new InvalidOperationException(@"Socks5 has been initialized."); - } - case Status.Closed: - { - throw new InvalidOperationException(@"Socks5 closed."); - } - case Status.Initial: - { - break; - } - default: - { - throw new ArgumentOutOfRangeException(); - } - } + Verify.Operation(Status is Status.Initial, @"Socks5 has been initialized."); var clientMethods = new List(2) { diff --git a/Socks5/Utils/Pack.cs b/Socks5/Utils/Pack.cs index 418b429..360f2d4 100644 --- a/Socks5/Utils/Pack.cs +++ b/Socks5/Utils/Pack.cs @@ -1,3 +1,4 @@ +using Microsoft; using Socks5.Enums; using Socks5.Models; using System; @@ -23,19 +24,13 @@ public static int DestinationAddressAndPort(string? hostName, IPAddress? ip, ush { destination[0] = Convert.ToByte(AddressType.Domain); var length = Encoding.UTF8.GetBytes(hostName, destination[2..]); - if (length > byte.MaxValue) - { - throw new ArgumentException($@"Domain Length > {byte.MaxValue}"); - } + Requires.Argument(length <= byte.MaxValue, nameof(hostName), @"Domain Length > {0}", byte.MaxValue); destination[1] = (byte)length; outLength = 1 + 1 + length; } else { - if (!ip.TryWriteBytes(destination[1..], out var length)) - { - throw new ArgumentOutOfRangeException(nameof(destination)); - } + Requires.Argument(ip.TryWriteBytes(destination[1..], out var length), nameof(destination), @"buffer is too small"); var type = length == 4 ? AddressType.IPv4 : AddressType.IPv6; destination[0] = Convert.ToByte(type); @@ -70,10 +65,7 @@ public static int Handshake(IReadOnlyList clientMethods, Span buff // | 1 | 1 | 1 to 255 | // +----+----------+----------+ - if (clientMethods.Count > byte.MaxValue) - { - throw new ArgumentException($@"{nameof(clientMethods)}.Count > {byte.MaxValue}"); - } + Requires.Argument(clientMethods.Count <= byte.MaxValue, nameof(clientMethods), @"{0}.Count > {1}", nameof(clientMethods), byte.MaxValue); buffer[0] = Constants.ProtocolVersion; buffer[1] = (byte)clientMethods.Count; @@ -99,18 +91,12 @@ public static int UsernamePasswordAuth(UsernamePassword credential, Span b var offset = 1; var usernameLength = Encoding.UTF8.GetBytes(credential.UserName, buffer[(offset + 1)..]); - if (usernameLength > byte.MaxValue) - { - throw new ArgumentException($@"{nameof(credential.UserName)} too long."); - } + Requires.Argument(usernameLength <= byte.MaxValue, nameof(credential), @"{0} too long.", nameof(credential.UserName)); buffer[offset++] = (byte)usernameLength; offset += usernameLength; var passwordLength = Encoding.UTF8.GetBytes(credential.Password, buffer[(offset + 1)..]); - if (passwordLength > byte.MaxValue) - { - throw new ArgumentException($@"{nameof(credential.Password)} too long."); - } + Requires.Argument(passwordLength <= byte.MaxValue, nameof(credential), @"{0} too long.", nameof(credential.Password)); buffer[offset++] = (byte)passwordLength; offset += passwordLength; diff --git a/Socks5/Utils/Unpack.cs b/Socks5/Utils/Unpack.cs index 5567b23..b461f55 100644 --- a/Socks5/Utils/Unpack.cs +++ b/Socks5/Utils/Unpack.cs @@ -1,3 +1,4 @@ +using Microsoft; using Socks5.Enums; using Socks5.Exceptions; using Socks5.Models; @@ -124,31 +125,26 @@ public static Socks5UdpReceivePacket Udp(byte[] buffer) // | 2 | 1 | 1 | Variable | 2 | Variable | // +----+------+------+----------+----------+----------+ - try - { - var res = new Socks5UdpReceivePacket(); + Requires.Range(buffer.LongLength >= 7, nameof(buffer)); - if (buffer[0] != Constants.Rsv || buffer[1] != Constants.Rsv) - { - throw new ProtocolErrorException($@"Protocol failed, RESERVED is not 0x0000: 0x{buffer[0]:X2}{buffer[1]:X2}."); - } + var res = new Socks5UdpReceivePacket(); - res.Fragment = buffer[2]; + if (buffer[0] != Constants.Rsv || buffer[1] != Constants.Rsv) + { + throw new ProtocolErrorException($@"Protocol failed, RESERVED is not 0x0000: 0x{buffer[0]:X2}{buffer[1]:X2}."); + } - res.Type = (AddressType)buffer[3]; + res.Fragment = buffer[2]; - var offset = 4; - offset += DestinationAddress(res.Type, buffer.AsSpan(offset), out res.Address, out res.Domain); + res.Type = (AddressType)buffer[3]; - res.Port = BinaryPrimitives.ReadUInt16BigEndian(buffer.AsSpan(offset)); - res.Data = buffer.AsMemory(offset + 2); + var offset = 4; + offset += DestinationAddress(res.Type, buffer.AsSpan(offset), out res.Address, out res.Domain); - return res; - } - catch (Exception ex) when (ex is not ProtocolErrorException) - { - throw new ProtocolErrorException($@"Server sent an unknown message: {BitConverter.ToString(buffer)}."); - } + res.Port = BinaryPrimitives.ReadUInt16BigEndian(buffer.AsSpan(offset)); + res.Data = buffer.AsMemory(offset + 2); + + return res; } public static bool ReadDestinationAddress(