public Socks5AuthResponse(Memory <byte> outputBuffer, Socks5AuthMethod method) { if (outputBuffer.Length < 2) { ThrowHelper.ThrowArgumentOutOfRange(nameof(outputBuffer), "Размер буфера должен быть больше или равен 2."); } outputBuffer.Span[0] = 0x05; // Версия SOCKS. outputBuffer.Span[1] = (byte)method; BufferSlice = outputBuffer.Slice(0, 2); }
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)); }
static Socks5ParseResult Parse(byte[] request, int requestLength, out Socks5AuthMethod[] methods) { methods = new Socks5AuthMethod[0]; // +-----+----------+----------+ // | VER | NMETHODS | METHODS | // +-----+----------+----------+ // | 1 | 1 | 1 to 255 | // +-----+----------+----------+ if (requestLength < 1) { return(Socks5ParseResult.NotEnoughData); } if (request[0] != 0x05) { return(Socks5ParseResult.InvalidRequest); } if (requestLength < 2) { return(Socks5ParseResult.NotEnoughData); } int n = request[1]; if (requestLength < 2 + n) { return(Socks5ParseResult.NotEnoughData); } methods = new Socks5AuthMethod[n]; for (int i = 0; i < n; i++) { methods[i] = (Socks5AuthMethod)request[2 + i]; } return(Socks5ParseResult.Success); }
public void AddMethod(Socks5AuthMethod method) { AddMethod((byte)method); }