static async ValueTask <SocketReceiveResult> WaitForReceiveBlockAsync(ValueTask <SocketReceiveResult> t, int count,
                                                                              ManagedTcpSocket managedTcp, Memory <byte> buffer, CancellationToken cancellationToken)
        {
            SocketReceiveResult result = await t.ConfigureAwait(false);

            if (result.BytesReceived > 0 && result.ErrorCode == SocketError.Success)
            {
                // Уменьшить буфер на сколько приняли.
                buffer = buffer.Slice(result.BytesReceived);

                if (buffer.Length == 0)
                {
                    return(new SocketReceiveResult(count, SocketError.Success));
                }
                else
                // Прочитали всё что необходимо.
                {
                    return(await ReceiveBlockAsync(managedTcp, buffer, cancellationToken).ConfigureAwait(false));
                }
            }
            else
            {
                return(result);
            }
        }
    public static ValueTask <SocketReceiveResult> ReceiveBlockAsync(this ManagedTcpSocket managedTcp, Memory <byte> buffer, CancellationToken cancellationToken = default)
    {
        int count = buffer.Length;

        while (buffer.Length > 0)
        {
            ValueTask <SocketReceiveResult> t = managedTcp.ReceiveAsync(buffer, cancellationToken);
            if (t.IsCompletedSuccessfully)
            {
                SocketReceiveResult result = t.Result;

                if (result.BytesReceived > 0 && result.ErrorCode == SocketError.Success)
                {
                    // Уменьшить буфер на столько, сколько приняли.
                    buffer = buffer.Slice(result.BytesReceived);
                }
                else
                {
                    return(new ValueTask <SocketReceiveResult>(result));
                }
            }
            else
            {
                return(WaitForReceiveBlockAsync(t, count, managedTcp, buffer, cancellationToken));
            }
        }

        // Всё выполнено синхронно.
        return(new ValueTask <SocketReceiveResult>(new SocketReceiveResult(count, SocketError.Success)));
Пример #3
0
        public static async Task <Socks5LoginPassword> ReceiveAsync(ManagedTcpSocket managedTcp, Memory <byte> buffer)
        {
            Debug.Assert(buffer.Length >= MaximumSize);

            SocketReceiveResult rcvResult = await managedTcp.ReceiveAsync(buffer).ConfigureAwait(false);

            if (!rcvResult.ReceiveSuccess)
            {
                return(default);
Пример #4
0
        internal static async ValueTask <Socks5Request> ReceiveRequestAsync(ManagedTcpSocket managedTcp, Memory <byte> buffer)
        {
            Debug.Assert(buffer.Length >= MaximumSize);

            // Как минимум должно быть 4 байта.
            SocketReceiveResult rcvResult = await managedTcp.ReceiveBlockAsync(buffer.Slice(0, 4)).ConfigureAwait(false);

            if (!rcvResult.ReceiveSuccess)
            {
                return(default);
Пример #5
0
        public static async ValueTask <Socks5AuthRequest> ReceiveAsync(ManagedTcpSocket managedTcp, Memory <byte> buffer)
        {
            Debug.Assert(buffer.Length >= MaximumSize);

            // Как минимум должно быть 2 байта.
            SocketReceiveResult rcvResult = await managedTcp.ReceiveBlockAsync(buffer.Slice(0, 2)).ConfigureAwait(false);

            if (!rcvResult.ReceiveSuccess)
            {
                return(new Socks5AuthRequest(authMethods: null));
            }

            byte version = buffer.Span[0];

            if (version != 5)
            {
                throw new InvalidOperationException($"Не верный номер версии Socks. Получено {version}, ожидалось 5");
            }

            // Количество поддерживаемых методов аутентификации.
            byte authCount = buffer.Span[1];

            // Номера методов аутентификации, переменная длина, 1 байт для каждого поддерживаемого метода.
            Memory <byte> authSpan = buffer.Slice(2, authCount);

            rcvResult = await managedTcp.ReceiveBlockAsync(authSpan).ConfigureAwait(false);

            if (!rcvResult.ReceiveSuccess)
            {
                return(new Socks5AuthRequest(authMethods: null));
            }

            var authMethods = new Socks5AuthMethod[authSpan.Length];

            for (int i = 0; i < authSpan.Length; i++)
            {
                Socks5AuthMethod a = (Socks5AuthMethod)authSpan.Span[i];
                if (Enum.IsDefined(typeof(Socks5AuthMethod), a))
                {
                    authMethods[i] = a;
                }
                else
                {
                    ThrowHelper.ThrowException(new InvalidOperationException("Ошибка протокола SOCKS 5"));
                }
            }

            return(new Socks5AuthRequest(authMethods));
        }
Пример #6
0
        /// <summary>
        /// Called when [message received].
        /// </summary>
        /// <param name="message">The message.</param>
        private void OnMessageReceived(SocketReceiveResult message)
        {
            if (_isDisposed)
            {
                return;
            }

            if (message.RemoteEndPoint.Port == 0)
            {
                return;
            }

            try
            {
                OnMessageReceived(new GenericEventArgs <SocketReceiveResult>
                {
                    Argument = message
                });
            }
            catch (Exception ex)
            {
                _logger.ErrorException("Error handling UDP message", ex);
            }
        }