1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jboss.netty.handler.codec.socks;
17
18 import org.jboss.netty.buffer.ChannelBuffer;
19 import org.jboss.netty.channel.Channel;
20 import org.jboss.netty.channel.ChannelHandlerContext;
21 import org.jboss.netty.handler.codec.replay.ReplayingDecoder;
22 import org.jboss.netty.util.CharsetUtil;
23
24
25
26
27
28 public class SocksCmdResponseDecoder extends ReplayingDecoder<SocksCmdResponseDecoder.State> {
29 private static final String name = "SOCKS_CMD_RESPONSE_DECODER";
30
31
32
33
34 @Deprecated
35 public static String getName() {
36 return name;
37 }
38
39 private SocksMessage.ProtocolVersion version;
40 private int fieldLength;
41 private SocksMessage.CmdStatus cmdStatus;
42 private SocksMessage.AddressType addressType;
43 private byte reserved;
44 private String host;
45 private int port;
46 private SocksResponse msg = SocksCommonUtils.UNKNOWN_SOCKS_RESPONSE;
47
48 public SocksCmdResponseDecoder() {
49 super(State.CHECK_PROTOCOL_VERSION);
50 }
51
52 @Override
53 protected Object decode(ChannelHandlerContext ctx, Channel channel,
54 ChannelBuffer buffer, State state) throws Exception {
55 switch (state) {
56 case CHECK_PROTOCOL_VERSION: {
57 version = SocksMessage.ProtocolVersion.fromByte(buffer.readByte());
58 if (version != SocksMessage.ProtocolVersion.SOCKS5) {
59 break;
60 }
61 checkpoint(State.READ_CMD_HEADER);
62 }
63 case READ_CMD_HEADER: {
64 cmdStatus = SocksMessage.CmdStatus.fromByte(buffer.readByte());
65 reserved = buffer.readByte();
66 addressType = SocksMessage.AddressType.fromByte(buffer.readByte());
67 checkpoint(State.READ_CMD_ADDRESS);
68 }
69 case READ_CMD_ADDRESS: {
70 switch (addressType) {
71 case IPv4: {
72 host = SocksCommonUtils.intToIp(buffer.readInt());
73 port = buffer.readUnsignedShort();
74 msg = new SocksCmdResponse(cmdStatus, addressType);
75 break;
76 }
77 case DOMAIN: {
78 fieldLength = buffer.readByte();
79 host = buffer.readBytes(fieldLength).toString(CharsetUtil.US_ASCII);
80 port = buffer.readUnsignedShort();
81 msg = new SocksCmdResponse(cmdStatus, addressType);
82 break;
83 }
84 case IPv6: {
85 host = SocksCommonUtils.ipv6toStr(buffer.readBytes(16).array());
86 port = buffer.readUnsignedShort();
87 msg = new SocksCmdResponse(cmdStatus, addressType);
88 break;
89 }
90 case UNKNOWN:
91 break;
92 }
93 }
94 }
95 ctx.getPipeline().remove(this);
96 return msg;
97 }
98
99 public enum State {
100 CHECK_PROTOCOL_VERSION,
101 READ_CMD_HEADER,
102 READ_CMD_ADDRESS
103 }
104 }