1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.codec.socks;
17
18 import io.netty.buffer.ByteBuf;
19 import io.netty.buffer.ByteBufUtil;
20 import io.netty.util.CharsetUtil;
21 import io.netty.util.NetUtil;
22 import io.netty.util.internal.ObjectUtil;
23
24 import java.net.IDN;
25
26
27
28
29
30
31
32 public final class SocksCmdRequest extends SocksRequest {
33 private final SocksCmdType cmdType;
34 private final SocksAddressType addressType;
35 private final String host;
36 private final int port;
37
38 public SocksCmdRequest(SocksCmdType cmdType, SocksAddressType addressType, String host, int port) {
39 super(SocksRequestType.CMD);
40 ObjectUtil.checkNotNull(cmdType, "cmdType");
41 ObjectUtil.checkNotNull(addressType, "addressType");
42 ObjectUtil.checkNotNull(host, "host");
43
44 switch (addressType) {
45 case IPv4:
46 if (!NetUtil.isValidIpV4Address(host)) {
47 throw new IllegalArgumentException(host + " is not a valid IPv4 address");
48 }
49 break;
50 case DOMAIN:
51 String asciiHost = IDN.toASCII(host);
52 if (asciiHost.length() > 255) {
53 throw new IllegalArgumentException(host + " IDN: " + asciiHost + " exceeds 255 char limit");
54 }
55 host = asciiHost;
56 break;
57 case IPv6:
58 if (!NetUtil.isValidIpV6Address(host)) {
59 throw new IllegalArgumentException(host + " is not a valid IPv6 address");
60 }
61 break;
62 case UNKNOWN:
63 break;
64 }
65 if (port <= 0 || port >= 65536) {
66 throw new IllegalArgumentException(port + " is not in bounds 0 < x < 65536");
67 }
68 this.cmdType = cmdType;
69 this.addressType = addressType;
70 this.host = host;
71 this.port = port;
72 }
73
74
75
76
77
78
79 public SocksCmdType cmdType() {
80 return cmdType;
81 }
82
83
84
85
86
87
88 public SocksAddressType addressType() {
89 return addressType;
90 }
91
92
93
94
95
96
97 public String host() {
98 return addressType == SocksAddressType.DOMAIN ? IDN.toUnicode(host) : host;
99 }
100
101
102
103
104
105
106 public int port() {
107 return port;
108 }
109
110 @Override
111 public void encodeAsByteBuf(ByteBuf byteBuf) {
112 byteBuf.writeByte(protocolVersion().byteValue());
113 byteBuf.writeByte(cmdType.byteValue());
114 byteBuf.writeByte(0x00);
115 byteBuf.writeByte(addressType.byteValue());
116 switch (addressType) {
117 case IPv4: {
118 byteBuf.writeBytes(NetUtil.createByteArrayFromIpAddressString(host));
119 ByteBufUtil.writeShortBE(byteBuf, port);
120 break;
121 }
122
123 case DOMAIN: {
124 byteBuf.writeByte(host.length());
125 byteBuf.writeCharSequence(host, CharsetUtil.US_ASCII);
126 ByteBufUtil.writeShortBE(byteBuf, port);
127 break;
128 }
129
130 case IPv6: {
131 byteBuf.writeBytes(NetUtil.createByteArrayFromIpAddressString(host));
132 ByteBufUtil.writeShortBE(byteBuf, port);
133 break;
134 }
135 }
136 }
137 }