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