public static async Task <Greeting> ReadFromAsync(IReadOnlyStream stream, ArrayPool <byte> bufferPool) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } if (bufferPool == null) { throw new ArgumentNullException(nameof(bufferPool)); } // |VER | NMETHODS | METHODS | // | 1 | 1 | 1 to 255 | var buffer = bufferPool.Rent(256); try { await stream.ReadExactlyAsync(buffer, 0, 3).ConfigureAwait(false); if (buffer[0] != 5) { throw new InvalidDataException($"Invalid SOCKS version in greeting: {buffer[0]}"); } var supportedAuthenticationMethodCount = buffer[1]; if (supportedAuthenticationMethodCount < 1) { throw new InvalidDataException("No authentication methods supported."); } var greeting = new Greeting { SupportedAuthenticationMethods = new AuthenticationMethod[supportedAuthenticationMethodCount] }; greeting.SupportedAuthenticationMethods[0] = (AuthenticationMethod)buffer[2]; if (supportedAuthenticationMethodCount > 1) { stream.ReadExactly(buffer, 0, supportedAuthenticationMethodCount - 1); for (int i = 0; i < supportedAuthenticationMethodCount - 1; i++) { greeting.SupportedAuthenticationMethods[i + 1] = (AuthenticationMethod)buffer[i]; } } return(greeting); } finally { bufferPool.Return(buffer); } }
public static async Task <Command> ReadFromAsync(IReadOnlyStream stream, ArrayPool <byte> bufferPool) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } if (bufferPool == null) { throw new ArgumentNullException(nameof(bufferPool)); } // | VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT | // | 1 | 1 | X'00' | 1 | Variable | 2 | var buffer = bufferPool.Rent(byte.MaxValue + sizeof(ushort)); try { await stream.ReadExactlyAsync(buffer, 0, 4).ConfigureAwait(false); if (buffer[0] != 5) { throw new InvalidDataException($"Invalid SOCKS version in greeting: {buffer[0]}"); } var commandType = (CommandType)buffer[1]; if (commandType != CommandType.Bind && commandType != CommandType.Connect && commandType != CommandType.UdpAssociate) { throw new ProtocolException( $"Invalid command type: {commandType}", CommandReplyType.CommandNotSupported); } if (buffer[2] != 0) { throw new InvalidDataException("Invalid command."); } var addressType = (AddressType)buffer[3]; var endPoint = stream.ReadEndPoint(addressType, bufferPool); return(new Command(commandType, endPoint)); } finally { bufferPool.Return(buffer); } }