protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List <object> output) { try { switch (State) { case Socks5CommandRequestDecoderState.Init: var version = input.ReadByte(); if (version != (byte)SocksVersion.Socks5) { throw new DecoderException( "unsupported version: " + version + " (expected: " + SocksVersion.Socks5 + ')'); } var type = Socks5CommandType.ValueOf(input.ReadByte()); input.SkipBytes(1); // RSV var dstAddrType = Socks5AddressType.ValueOf(input.ReadByte()); var dstAddr = _addressDecoder.DecodeAddress(dstAddrType, input); int dstPort = input.ReadUnsignedShort(); output.Add(new DefaultSocks5CommandRequest(type, dstAddrType, dstAddr, dstPort)); Checkpoint(Socks5CommandRequestDecoderState.Success); break; case Socks5CommandRequestDecoderState.Success: { var readableBytes = ActualReadableBytes; if (readableBytes > 0) { output.Add(input.ReadRetainedSlice(readableBytes)); } break; } case Socks5CommandRequestDecoderState.Failure: { input.SkipBytes(ActualReadableBytes); break; } } } catch (Exception e) { Fail(output, e); } }
public DefaultSocks5CommandRequest( Socks5CommandType type, Socks5AddressType dstAddrType, string dstAddr, int dstPort) { if (Equals(dstAddrType, Socks5AddressType.Pv4)) { if (!IPAddress.TryParse(dstAddr, out _)) { throw new ArgumentException("dstAddr: " + dstAddr + " (expected: a valid IPv4 address)"); } } else if (dstAddrType == Socks5AddressType.Domain) { dstAddr = Idn.GetAscii(dstAddr); if (dstAddr.Length > 255) { throw new ArgumentException("dstAddr: " + dstAddr + " (expected: less than 256 chars)"); } } else if (dstAddrType == Socks5AddressType.Pv6) { if (!IPAddress.TryParse(dstAddr, out _)) { throw new ArgumentException("dstAddr: " + dstAddr + " (expected: a valid IPv6 address"); } } if (dstPort < 0 || dstPort > 65535) { throw new ArgumentException("dstPort: " + dstPort + " (expected: 0~65535)"); } Type = type; DstAddrType = dstAddrType; DstAddr = dstAddr; DstPort = dstPort; }