Skip to content

Commit

Permalink
style: Use Microsoft.VisualStudio.Validation
Browse files Browse the repository at this point in the history
  • Loading branch information
HMBSbige committed Aug 10, 2021
1 parent ec0ff33 commit 22645fc
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 115 deletions.
6 changes: 2 additions & 4 deletions HttpProxy/HttpSocks5Service.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Microsoft;
using Microsoft.VisualStudio.Threading;
using Pipelines.Extensions;
using Socks5.Models;
Expand All @@ -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;
Expand Down
7 changes: 3 additions & 4 deletions Pipelines.Extensions/PipeReaderExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Microsoft;
using System;
using System.IO;
using System.IO.Pipelines;
Expand Down Expand Up @@ -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)
{
Expand Down
13 changes: 3 additions & 10 deletions Shadowsocks.Protocol/LocalTcpServices/HttpService.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using HttpProxy;
using Microsoft;
using Socks5.Models;
using System;
using System.Buffers;
using System.IO.Pipelines;
using System.Threading;
Expand All @@ -26,15 +26,8 @@ public bool IsHandle(ReadOnlySequence<byte> 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);
}
Expand Down
18 changes: 4 additions & 14 deletions Shadowsocks.Protocol/LocalTcpServices/Socks5Service.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
using Microsoft;
using Microsoft.Extensions.Logging;
using Pipelines.Extensions;
using Shadowsocks.Protocol.ServersControllers;
using Shadowsocks.Protocol.TcpClients;
using Socks5.Enums;
using Socks5.Models;
using Socks5.Servers;
using System;
using System.Buffers;
using System.IO.Pipelines;
using System.Net;
Expand Down Expand Up @@ -37,15 +37,8 @@ public bool IsHandle(ReadOnlySequence<byte> 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);

Expand Down Expand Up @@ -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);

Expand Down
6 changes: 2 additions & 4 deletions Shadowsocks.Protocol/TcpClients/ShadowsocksTcpClient.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Microsoft;
using Microsoft.Extensions.Logging;
using Pipelines.Extensions;
using Shadowsocks.Protocol.Models;
Expand Down Expand Up @@ -30,10 +31,7 @@ public async ValueTask<bool> 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);
Expand Down
47 changes: 7 additions & 40 deletions Socks5/Clients/Socks5Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
}
Expand Down Expand Up @@ -123,7 +117,7 @@ public async ValueTask<ServerBound> UdpAssociateAsync(IPAddress address, ushort
}
default:
{
throw new ArgumentOutOfRangeException(nameof(bound.Type));
throw Assumes.NotReachable();
}
}

Expand All @@ -135,10 +129,7 @@ public async ValueTask<ServerBound> UdpAssociateAsync(IPAddress address, ushort
//TODO .NET6.0
public async Task<Socks5UdpReceivePacket> 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();

Expand All @@ -159,10 +150,7 @@ private async Task<int> SendUdpAsync(
ReadOnlyMemory<byte> 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<byte>.Shared.Rent(Constants.MaxUdpHandshakeHeaderLength + data.Length);
try
Expand All @@ -183,10 +171,7 @@ private async Task<int> SendUdpAsync(

private async ValueTask<IDuplexPipe> 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);

Expand All @@ -199,25 +184,7 @@ private async ValueTask<IDuplexPipe> 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<Method>(2)
{
Expand Down
26 changes: 6 additions & 20 deletions Socks5/Utils/Pack.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Microsoft;
using Socks5.Enums;
using Socks5.Models;
using System;
Expand All @@ -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);
Expand Down Expand Up @@ -70,10 +65,7 @@ public static int Handshake(IReadOnlyList<Method> clientMethods, Span<byte> 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;
Expand All @@ -99,18 +91,12 @@ public static int UsernamePasswordAuth(UsernamePassword credential, Span<byte> 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;

Expand Down
34 changes: 15 additions & 19 deletions Socks5/Utils/Unpack.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Microsoft;
using Socks5.Enums;
using Socks5.Exceptions;
using Socks5.Models;
Expand Down Expand Up @@ -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(
Expand Down

0 comments on commit 22645fc

Please sign in to comment.