diff --git a/Socks5/Utils/Socks5TestUtils.cs b/Socks5/Utils/Socks5TestUtils.cs index f219955..07a3be3 100644 --- a/Socks5/Utils/Socks5TestUtils.cs +++ b/Socks5/Utils/Socks5TestUtils.cs @@ -21,7 +21,7 @@ public static class Socks5TestUtils /// /// 使用 HTTP1.1 204 测试 SOCKS5 CONNECT /// Example: - /// https://www.google.com/generate_204 + /// http://www.google.com/generate_204 /// http://connectivitycheck.gstatic.com/generate_204 /// http://connect.rom.miui.com/generate_204 /// http://cp.cloudflare.com diff --git a/UnitTest/AEADShadowsocksCryptoTest.cs b/UnitTest/AEADShadowsocksCryptoTest.cs index 56ec4c5..c132922 100644 --- a/UnitTest/AEADShadowsocksCryptoTest.cs +++ b/UnitTest/AEADShadowsocksCryptoTest.cs @@ -29,25 +29,24 @@ private static void TestAEAD(string method, string password, string str, string private static void TestTcpDecrypt(string method, string password, string str, string encHex) { Span origin = Encoding.UTF8.GetBytes(str); - var enc = new ReadOnlySequence(encHex.FromHex()); + var encBuffer = encHex.FromHex(); - Span buffer = new byte[enc.Length]; + Span buffer = new byte[encBuffer.Length]; using var crypto = (AEADShadowsocksCrypto)ShadowsocksCrypto.Create(method, password); - var e0 = enc.Slice(0, crypto.SaltLength); + var secondIndex = RandomNumberGenerator.GetInt32(crypto.SaltLength, encBuffer.Length); + var multiSequence = TestUtils.GetMultiSegmentSequence(encBuffer, crypto.SaltLength, secondIndex); + Assert.IsFalse(multiSequence.IsSingleSegment); + Assert.AreEqual(encBuffer.LongLength, multiSequence.Length); + + var e0 = multiSequence.Slice(0, crypto.SaltLength); var o2 = crypto.DecryptTCP(ref e0, buffer); Assert.AreEqual(crypto.SaltLength, e0.Length); Assert.AreEqual(0, o2); - var e1Length = crypto.SaltLength + AEADShadowsocksCrypto.ChunkOverheadSize + 1; - var e1 = enc.Slice(0, e1Length); - var o0 = crypto.DecryptTCP(ref e1, buffer); - Assert.AreEqual(e1Length - crypto.SaltLength, e1.Length); - Assert.AreEqual(0, o0); - - var remain = enc.Slice(crypto.SaltLength); - var o1 = crypto.DecryptTCP(ref remain, buffer[o0..]); + var remain = multiSequence; + var o1 = crypto.DecryptTCP(ref remain, buffer); Assert.AreEqual(0, remain.Length); Assert.AreEqual(origin.Length, o1); diff --git a/UnitTest/BufferSegment.cs b/UnitTest/BufferSegment.cs new file mode 100644 index 0000000..baecd98 --- /dev/null +++ b/UnitTest/BufferSegment.cs @@ -0,0 +1,23 @@ +using System; +using System.Buffers; + +namespace UnitTest +{ + internal class BufferSegment : ReadOnlySequenceSegment + { + public BufferSegment(Memory memory) + { + Memory = memory; + } + + public BufferSegment Append(Memory memory) + { + var segment = new BufferSegment(memory) + { + RunningIndex = RunningIndex + Memory.Length + }; + Next = segment; + return segment; + } + } +} diff --git a/UnitTest/TestUtils.cs b/UnitTest/TestUtils.cs new file mode 100644 index 0000000..26c204e --- /dev/null +++ b/UnitTest/TestUtils.cs @@ -0,0 +1,33 @@ +using Microsoft; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Buffers; +using System.Linq; + +namespace UnitTest +{ + internal static class TestUtils + { + public static ReadOnlySequence GetMultiSegmentSequence(Memory source, params int[] index) + { + Requires.Argument(index.LongLength > 1, nameof(index), @"index length must >1"); + var orderedIndex = index.OrderBy(x => x); + var first = new BufferSegment(source[..orderedIndex.First()]); + + var last = first; + var length = index[0]; + + foreach (var i in index.Skip(1)) + { + last = last.Append(source.Slice(length, i - length)); + length = i; + } + + last = last.Append(source[length..]); + + var sequence = new ReadOnlySequence(first, 0, last, last.Memory.Length); + Assert.AreEqual(source.Length, sequence.Length); + return sequence; + } + } +}