private Task WrapAsync(IShadowsocksCrypto encryptor, CancellationToken cancellationToken)
    {
        return(Task.Run(
                   async() =>
        {
            try
            {
                while (true)
                {
                    ReadResult result = await Reader.ReadAsync(cancellationToken);
                    ReadOnlySequence <byte> buffer = result.Buffer;

                    foreach (ReadOnlyMemory <byte> segment in buffer)
                    {
                        SendToRemote(segment.Span);
                        FlushResult flushResult = await InternalWriter.FlushAsync(cancellationToken);
                        if (flushResult.IsCompleted)
                        {
                            goto NoData;
                        }
                    }

                    Reader.AdvanceTo(buffer.End);

                    if (result.IsCompleted)
                    {
                        break;
                    }
                }
                NoData:
                await Reader.CompleteAsync();
            }
            catch (Exception ex)
            {
                await Reader.CompleteAsync(ex);
            }
            finally
            {
                encryptor.Dispose();
            }
        },
                   default
                   ));

        void SendToRemote(ReadOnlySpan <byte> buffer)
        {
            while (!buffer.IsEmpty)
            {
                Span <byte> span = InternalWriter.GetSpan(BufferSize);

                encryptor.EncryptTCP(buffer, span, out int p, out int outLength);

                InternalWriter.Advance(outLength);

                if (p == buffer.Length)
                {
                    break;
                }

                buffer = buffer[p..];
示例#2
0
    public async ValueTask <int> SendAsync(ReadOnlyMemory <byte> buffer, CancellationToken cancellationToken = default)
    {
        byte[] encBuffer = ArrayPool <byte> .Shared.Rent(MaxUdpSize);

        try
        {
            using IShadowsocksCrypto encryptor = ShadowsocksCrypto.Create(_serverInfo.Method !, _serverInfo.Password !);
            int length = encryptor.EncryptUDP(buffer.Span, encBuffer);

            int sendLength = await _client.SendAsync(encBuffer.AsMemory(0, length), SocketFlags.None, cancellationToken);

            Report.IfNot(sendLength == length, @"Send Udp {0}/{1}", sendLength, length);
            return(sendLength == length ? buffer.Length : default);
示例#3
0
    public async ValueTask <int> ReceiveAsync(Memory <byte> buffer, CancellationToken cancellationToken = default)
    {
        byte[] encBuffer = ArrayPool <byte> .Shared.Rent(MaxUdpSize);

        try
        {
            int res = await _client.ReceiveAsync(encBuffer, SocketFlags.None, cancellationToken);

            using IShadowsocksCrypto decryptor = ShadowsocksCrypto.Create(_serverInfo.Method !, _serverInfo.Password !);

            return(decryptor.DecryptUDP(encBuffer.AsSpan(0, res), buffer.Span));
        }
        finally
        {
            ArrayPool <byte> .Shared.Return(encBuffer);
        }
    }
    public ShadowsocksPipeReader(
        PipeReader reader,
        ShadowsocksServerInfo serverInfo,
        PipeOptions?pipeOptions = null)
    {
        Requires.NotNull(reader, nameof(reader));
        Requires.NotNull(serverInfo, nameof(serverInfo));
        Requires.NotNullAllowStructs(serverInfo.Method, nameof(serverInfo));
        Requires.NotNullAllowStructs(serverInfo.Password, nameof(serverInfo));

        IShadowsocksCrypto decryptor = ShadowsocksCrypto.Create(serverInfo.Method, serverInfo.Password);

        InternalReader           = reader;
        _pipe                    = new Pipe(pipeOptions ?? PipeOptions.Default);
        _cancellationTokenSource = new CancellationTokenSource();

        WrapAsync(decryptor, _cancellationTokenSource.Token).Forget();
    }
示例#5
0
    public static void Test(string method)
    {
        Console.Write($@"Testing {method}: ");

        ReadOnlySpan <byte> i = new byte[Step];
        Span <byte>         o = new byte[AEADShadowsocksCrypto.GetBufferSize(i.Length)];

        using IShadowsocksCrypto crypto = ShadowsocksCrypto.Create(method, Password);
        ulong     length = 0ul;
        Stopwatch sw     = Stopwatch.StartNew();

        do
        {
            crypto.EncryptTCP(i, o, out int pLength, out _);
            length += (uint)pLength;
        } while (sw.ElapsedMilliseconds < 2000);

        sw.Stop();
        double result = length / sw.Elapsed.TotalSeconds / 1024.0 / 1024.0;

        Console.WriteLine($@"{result:F2} MB/s");
    }
    private Task WrapAsync(IShadowsocksCrypto decryptor, CancellationToken cancellationToken)
    {
        return(Task.Run(
                   async() =>
        {
            try
            {
                while (true)
                {
                    ReadResult result = await InternalReader.ReadAndCheckIsCanceledAsync(cancellationToken);
                    ReadOnlySequence <byte> buffer = result.Buffer;

                    try
                    {
                        while (!buffer.IsEmpty)
                        {
                            long oldLength = buffer.Length;

                            Memory <byte> memory = Writer.GetMemory(BufferSize);

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

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

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

                        if (result.IsCompleted)
                        {
                            break;
                        }
                    }
                    finally
                    {
                        InternalReader.AdvanceTo(buffer.Start, buffer.End);
                    }
                }
                NoData:
                await Writer.CompleteAsync();
            }
            catch (Exception ex)
            {
                await Writer.CompleteAsync(ex);
            }
            finally
            {
                decryptor.Dispose();
            }
        },
                   default
                   ));
    }