Beispiel #1
0
        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);
            }
        }