protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List <object> output) { try { switch (State) { case Socks5CommandResponseDecoderState.Init: var version = input.ReadByte(); if (version != (byte)SocksVersion.Socks5) { throw new DecoderException( "unsupported version: " + version + " (expected: " + SocksVersion.Socks5 + ')'); } var status = Socks5CommandStatus.ValueOf(input.ReadByte()); input.SkipBytes(1); // Reserved var addrType = Socks5AddressType.ValueOf(input.ReadByte()); var addr = _addressDecoder.DecodeAddress(addrType, input); int port = input.ReadUnsignedShort(); output.Add(new DefaultSocks5CommandResponse(status, addrType, addr, port)); Checkpoint(Socks5CommandResponseDecoderState.Success); break; case Socks5CommandResponseDecoderState.Success: var readableBytes = ActualReadableBytes; if (readableBytes > 0) { output.Add(input.ReadRetainedSlice(readableBytes)); } break; case Socks5CommandResponseDecoderState.Failure: input.SkipBytes(ActualReadableBytes); break; } } catch (Exception e) { Fail(output, e); } }
public DefaultSocks5CommandResponse( Socks5CommandStatus status, Socks5AddressType bndAddrType, string bndAddr = null, int bndPort = 0) { if (bndAddr != null) { if (bndAddrType == Socks5AddressType.Pv4) { if (!IPAddress.TryParse(bndAddr, out _)) { throw new ArgumentException("bndAddr: " + bndAddr + " (expected: a valid IPv4 address)"); } } else if (bndAddrType == Socks5AddressType.Domain) { bndAddr = Idn.GetAscii(bndAddr); if (bndAddr.Length > 255) { throw new ArgumentException("bndAddr: " + bndAddr + " (expected: less than 256 chars)"); } } else if (bndAddrType == Socks5AddressType.Pv6) { if (!IPAddress.TryParse(bndAddr, out _)) { throw new ArgumentException("bndAddr: " + bndAddr + " (expected: a valid IPv6 address)"); } } } if (bndPort < 0 || bndPort > 65535) { throw new ArgumentException("bndPort: " + bndPort + " (expected: 0~65535)"); } Status = status; BndAddrType = bndAddrType; BndAddr = bndAddr; BndPort = bndPort; }