Mercurial > 510Connectbot
comparison src/net/sourceforge/jsocks/Socks5Message.java @ 349:205ee2873330
update jsocks to 2011-03-19
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Fri, 01 Aug 2014 11:23:10 -0700 |
parents | 0ce5cc452d02 |
children | 2bc6805cbc91 |
comparison
equal
deleted
inserted
replaced
348:29076621bab0 | 349:205ee2873330 |
---|---|
1 package net.sourceforge.jsocks; | 1 package net.sourceforge.jsocks; |
2 | 2 |
3 import java.io.DataInputStream; | |
4 import java.io.IOException; | 3 import java.io.IOException; |
5 import java.io.InputStream; | 4 import java.io.InputStream; |
6 import java.io.OutputStream; | 5 import java.io.OutputStream; |
6 import java.io.DataInputStream; | |
7 import java.net.InetAddress; | 7 import java.net.InetAddress; |
8 import java.net.UnknownHostException; | 8 import java.net.UnknownHostException; |
9 | 9 |
10 /** | 10 /** |
11 SOCKS5 request/response message. | 11 SOCKS5 request/response message. |
12 */ | 12 */ |
13 | 13 |
14 public class Socks5Message extends ProxyMessage { | 14 class Socks5Message extends ProxyMessage{ |
15 /** Address type of given message*/ | 15 /** Address type of given message*/ |
16 public int addrType; | 16 public int addrType; |
17 | 17 |
18 byte[] data; | 18 byte[] data; |
19 | 19 |
20 /** | 20 /** |
21 Server error response. | 21 Server error response. |
22 @param cmd Error code. | 22 @param cmd Error code. |
23 */ | |
24 public Socks5Message(int cmd){ | |
25 super(cmd,null,0); | |
26 data = new byte[3]; | |
27 data[0] = SOCKS_VERSION; //Version. | |
28 data[1] = (byte)cmd; //Reply code for some kind of failure. | |
29 data[2] = 0; //Reserved byte. | |
30 } | |
31 | |
32 /** | |
33 Construct client request or server response. | |
34 @param cmd - Request/Response code. | |
35 @param ip - IP field. | |
36 @paarm port - port field. | |
37 */ | |
38 public Socks5Message(int cmd,InetAddress ip,int port){ | |
39 super(cmd,ip,port); | |
40 this.host = ip==null?"0.0.0.0":ip.getHostName(); | |
41 this.version = SOCKS_VERSION; | |
42 | |
43 byte[] addr; | |
44 | |
45 if(ip == null){ | |
46 addr = new byte[4]; | |
47 addr[0]=addr[1]=addr[2]=addr[3]=0; | |
48 }else | |
49 addr = ip.getAddress(); | |
50 | |
51 addrType = addr.length == 4 ? SOCKS_ATYP_IPV4 | |
52 : SOCKS_ATYP_IPV6; | |
53 | |
54 data = new byte[6+addr.length]; | |
55 data[0] = (byte) SOCKS_VERSION; //Version | |
56 data[1] = (byte) command; //Command | |
57 data[2] = (byte) 0; //Reserved byte | |
58 data[3] = (byte) addrType; //Address type | |
59 | |
60 //Put Address | |
61 System.arraycopy(addr,0,data,4,addr.length); | |
62 //Put port | |
63 data[data.length-2] = (byte)(port>>8); | |
64 data[data.length-1] = (byte)(port); | |
65 } | |
66 | |
67 | |
68 /** | |
69 Construct client request or server response. | |
70 @param cmd - Request/Response code. | |
71 @param hostName - IP field as hostName, uses ADDR_TYPE of HOSTNAME. | |
72 @paarm port - port field. | |
73 */ | |
74 public Socks5Message(int cmd,String hostName,int port){ | |
75 super(cmd,null,port); | |
76 this.host = hostName; | |
77 this.version = SOCKS_VERSION; | |
78 | |
79 //System.out.println("Doing ATYP_DOMAINNAME"); | |
80 | |
81 addrType = SOCKS_ATYP_DOMAINNAME; | |
82 byte addr[] = hostName.getBytes(); | |
83 | |
84 data =new byte[7+addr.length]; | |
85 data[0] = (byte) SOCKS_VERSION; //Version | |
86 data[1] = (byte) command; //Command | |
87 data[2] = (byte) 0; //Reserved byte | |
88 data[3] = (byte) SOCKS_ATYP_DOMAINNAME; //Address type | |
89 data[4] = (byte) addr.length; //Length of the address | |
90 | |
91 //Put Address | |
92 System.arraycopy(addr,0,data,5,addr.length); | |
93 //Put port | |
94 data[data.length-2] = (byte)(port >>8); | |
95 data[data.length-1] = (byte)(port); | |
96 } | |
97 | |
98 /** | |
99 Initialises Message from the stream. Reads server response from | |
100 given stream. | |
101 @param in Input stream to read response from. | |
102 @throws SocksException If server response code is not SOCKS_SUCCESS(0), or | |
103 if any error with protocol occurs. | |
104 @throws IOException If any error happens with I/O. | |
105 */ | |
106 public Socks5Message(InputStream in) throws SocksException, | |
107 IOException{ | |
108 this(in,true); | |
109 } | |
110 | |
111 /** | |
112 Initialises Message from the stream. Reads server response or client | |
113 request from given stream. | |
114 | |
115 @param in Input stream to read response from. | |
116 @param clinetMode If true read server response, else read client request. | |
117 @throws SocksException If server response code is not SOCKS_SUCCESS(0) and | |
118 reading in client mode, or if any error with protocol occurs. | |
119 @throws IOException If any error happens with I/O. | |
120 */ | |
121 public Socks5Message(InputStream in,boolean clientMode)throws SocksException, | |
122 IOException{ | |
123 read(in,clientMode); | |
124 } | |
125 | |
126 | |
127 /** | |
128 Initialises Message from the stream. Reads server response from | |
129 given stream. | |
130 @param in Input stream to read response from. | |
131 @throws SocksException If server response code is not SOCKS_SUCCESS(0), or | |
132 if any error with protocol occurs. | |
133 @throws IOException If any error happens with I/O. | |
134 */ | |
135 public void read(InputStream in) throws SocksException, | |
136 IOException{ | |
137 read(in,true); | |
138 } | |
139 | |
140 | |
141 /** | |
142 Initialises Message from the stream. Reads server response or client | |
143 request from given stream. | |
144 | |
145 @param in Input stream to read response from. | |
146 @param clinetMode If true read server response, else read client request. | |
147 @throws SocksException If server response code is not SOCKS_SUCCESS(0) and | |
148 reading in client mode, or if any error with protocol occurs. | |
149 @throws IOException If any error happens with I/O. | |
150 */ | |
151 public void read(InputStream in,boolean clientMode) throws SocksException, | |
152 IOException{ | |
153 data = null; | |
154 ip = null; | |
155 | |
156 DataInputStream di = new DataInputStream(in); | |
157 | |
158 version = di.readUnsignedByte(); | |
159 command = di.readUnsignedByte(); | |
160 if(clientMode && command != 0) | |
161 throw new SocksException(command); | |
162 | |
163 int reserved = di.readUnsignedByte(); | |
164 addrType = di.readUnsignedByte(); | |
165 | |
166 byte addr[]; | |
167 | |
168 switch(addrType){ | |
169 case SOCKS_ATYP_IPV4: | |
170 addr = new byte[4]; | |
171 di.readFully(addr); | |
172 host = bytes2IPV4(addr,0); | |
173 break; | |
174 case SOCKS_ATYP_IPV6: | |
175 addr = new byte[SOCKS_IPV6_LENGTH];//I believe it is 16 bytes,huge! | |
176 di.readFully(addr); | |
177 host = bytes2IPV6(addr,0); | |
178 break; | |
179 case SOCKS_ATYP_DOMAINNAME: | |
180 //System.out.println("Reading ATYP_DOMAINNAME"); | |
181 addr = new byte[di.readUnsignedByte()];//Next byte shows the length | |
182 di.readFully(addr); | |
183 host = new String(addr); | |
184 break; | |
185 default: | |
186 throw(new SocksException(CProxy.SOCKS_JUST_ERROR)); | |
187 } | |
188 | |
189 port = di.readUnsignedShort(); | |
190 | |
191 if(addrType != SOCKS_ATYP_DOMAINNAME && doResolveIP){ | |
192 try{ | |
193 ip = InetAddress.getByName(host); | |
194 }catch(UnknownHostException uh_ex){ | |
195 } | |
196 } | |
197 } | |
198 | |
199 /** | |
200 Writes the message to the stream. | |
201 @param out Output stream to which message should be written. | |
202 */ | |
203 public void write(OutputStream out)throws SocksException, | |
204 IOException{ | |
205 if(data == null){ | |
206 Socks5Message msg; | |
207 | |
208 if(addrType == SOCKS_ATYP_DOMAINNAME) | |
209 msg = new Socks5Message(command,host,port); | |
210 else{ | |
211 if(ip == null){ | |
212 try{ | |
213 ip = InetAddress.getByName(host); | |
214 }catch(UnknownHostException uh_ex){ | |
215 throw new SocksException(CProxy.SOCKS_JUST_ERROR); | |
216 } | |
217 } | |
218 msg = new Socks5Message(command,ip,port); | |
219 } | |
220 data = msg.data; | |
221 } | |
222 out.write(data); | |
223 } | |
224 | |
225 /** | |
226 Returns IP field of the message as IP, if the message was created | |
227 with ATYP of HOSTNAME, it will attempt to resolve the hostname, | |
228 which might fail. | |
229 @throws UnknownHostException if host can't be resolved. | |
230 */ | |
231 public InetAddress getInetAddress() throws UnknownHostException{ | |
232 if(ip!=null) return ip; | |
233 | |
234 return (ip=InetAddress.getByName(host)); | |
235 } | |
236 | |
237 /** | |
238 Returns string representation of the message. | |
239 */ | |
240 public String toString(){ | |
241 String s= | |
242 "Socks5Message:"+"\n"+ | |
243 "VN "+version+"\n"+ | |
244 "CMD "+command+"\n"+ | |
245 "ATYP "+addrType+"\n"+ | |
246 "ADDR "+host+"\n"+ | |
247 "PORT "+port+"\n"; | |
248 return s; | |
249 } | |
250 | |
251 | |
252 /** | |
253 *Wether to resolve hostIP returned from SOCKS server | |
254 *that is wether to create InetAddress object from the | |
255 *hostName string | |
23 */ | 256 */ |
24 public Socks5Message(int cmd) { | 257 static public boolean resolveIP(){ return doResolveIP;} |
25 super(cmd, null, 0); | 258 |
26 data = new byte[3]; | 259 /** |
27 data[0] = SOCKS_VERSION; //Version. | 260 *Wether to resolve hostIP returned from SOCKS server |
28 data[1] = (byte)cmd; //Reply code for some kind of failure. | 261 *that is wether to create InetAddress object from the |
29 data[2] = 0; //Reserved byte. | 262 *hostName string |
30 } | 263 *@param doResolve Wether to resolve hostIP from SOCKS server. |
31 | 264 *@return Previous value. |
32 /** | |
33 Construct client request or server response. | |
34 @param cmd - Request/Response code. | |
35 @param ip - IP field. | |
36 @paarm port - port field. | |
37 */ | 265 */ |
38 public Socks5Message(int cmd, InetAddress ip, int port) { | 266 static public boolean resolveIP(boolean doResolve){ |
39 super(cmd, ip, port); | 267 boolean old = doResolveIP; |
40 this.host = ip == null ? "0.0.0.0" : ip.getHostName(); | 268 doResolveIP = doResolve; |
41 this.version = SOCKS_VERSION; | 269 return old; |
42 byte[] addr; | 270 } |
43 | 271 |
44 if (ip == null) { | 272 /* |
45 addr = new byte[4]; | 273 private static final void debug(String s){ |
46 addr[0] = addr[1] = addr[2] = addr[3] = 0; | 274 if(DEBUG) |
47 } | 275 System.out.print(s); |
48 else | 276 } |
49 addr = ip.getAddress(); | 277 private static final boolean DEBUG = false; |
50 | 278 */ |
51 addrType = addr.length == 4 ? SOCKS_ATYP_IPV4 | 279 |
52 : SOCKS_ATYP_IPV6; | 280 //SOCKS5 constants |
53 data = new byte[6 + addr.length]; | 281 public static final int SOCKS_VERSION =5; |
54 data[0] = (byte) SOCKS_VERSION; //Version | 282 |
55 data[1] = (byte) command; //Command | 283 public static final int SOCKS_ATYP_IPV4 =0x1; //Where is 2?? |
56 data[2] = (byte) 0; //Reserved byte | 284 public static final int SOCKS_ATYP_DOMAINNAME =0x3; //!!!!rfc1928 |
57 data[3] = (byte) addrType; //Address type | 285 public static final int SOCKS_ATYP_IPV6 =0x4; |
58 //Put Address | 286 |
59 System.arraycopy(addr, 0, data, 4, addr.length); | 287 public static final int SOCKS_IPV6_LENGTH =16; |
60 //Put port | 288 |
61 data[data.length - 2] = (byte)(port >> 8); | 289 static boolean doResolveIP = true; |
62 data[data.length - 1] = (byte)(port); | |
63 } | |
64 | |
65 | |
66 /** | |
67 Construct client request or server response. | |
68 @param cmd - Request/Response code. | |
69 @param hostName - IP field as hostName, uses ADDR_TYPE of HOSTNAME. | |
70 @paarm port - port field. | |
71 */ | |
72 public Socks5Message(int cmd, String hostName, int port) { | |
73 super(cmd, null, port); | |
74 this.host = hostName; | |
75 this.version = SOCKS_VERSION; | |
76 //System.out.println("Doing ATYP_DOMAINNAME"); | |
77 addrType = SOCKS_ATYP_DOMAINNAME; | |
78 byte addr[] = hostName.getBytes(); | |
79 data = new byte[7 + addr.length]; | |
80 data[0] = (byte) SOCKS_VERSION; //Version | |
81 data[1] = (byte) command; //Command | |
82 data[2] = (byte) 0; //Reserved byte | |
83 data[3] = (byte) SOCKS_ATYP_DOMAINNAME; //Address type | |
84 data[4] = (byte) addr.length; //Length of the address | |
85 //Put Address | |
86 System.arraycopy(addr, 0, data, 5, addr.length); | |
87 //Put port | |
88 data[data.length - 2] = (byte)(port >> 8); | |
89 data[data.length - 1] = (byte)(port); | |
90 } | |
91 | |
92 /** | |
93 Initialises Message from the stream. Reads server response from | |
94 given stream. | |
95 @param in Input stream to read response from. | |
96 @throws SocksException If server response code is not SOCKS_SUCCESS(0), or | |
97 if any error with protocol occurs. | |
98 @throws IOException If any error happens with I/O. | |
99 */ | |
100 public Socks5Message(InputStream in) throws SocksException, | |
101 IOException { | |
102 this(in, true); | |
103 } | |
104 | |
105 /** | |
106 Initialises Message from the stream. Reads server response or client | |
107 request from given stream. | |
108 | |
109 @param in Input stream to read response from. | |
110 @param clinetMode If true read server response, else read client request. | |
111 @throws SocksException If server response code is not SOCKS_SUCCESS(0) and | |
112 reading in client mode, or if any error with protocol occurs. | |
113 @throws IOException If any error happens with I/O. | |
114 */ | |
115 public Socks5Message(InputStream in, boolean clientMode)throws SocksException, | |
116 IOException { | |
117 read(in, clientMode); | |
118 } | |
119 | |
120 | |
121 /** | |
122 Initialises Message from the stream. Reads server response from | |
123 given stream. | |
124 @param in Input stream to read response from. | |
125 @throws SocksException If server response code is not SOCKS_SUCCESS(0), or | |
126 if any error with protocol occurs. | |
127 @throws IOException If any error happens with I/O. | |
128 */ | |
129 public void read(InputStream in) throws SocksException, | |
130 IOException { | |
131 read(in, true); | |
132 } | |
133 | |
134 | |
135 /** | |
136 Initialises Message from the stream. Reads server response or client | |
137 request from given stream. | |
138 | |
139 @param in Input stream to read response from. | |
140 @param clinetMode If true read server response, else read client request. | |
141 @throws SocksException If server response code is not SOCKS_SUCCESS(0) and | |
142 reading in client mode, or if any error with protocol occurs. | |
143 @throws IOException If any error happens with I/O. | |
144 */ | |
145 public void read(InputStream in, boolean clientMode) throws SocksException, | |
146 IOException { | |
147 data = null; | |
148 ip = null; | |
149 DataInputStream di = new DataInputStream(in); | |
150 version = di.readUnsignedByte(); | |
151 command = di.readUnsignedByte(); | |
152 | |
153 if (clientMode && command != 0) | |
154 throw new SocksException(command); | |
155 | |
156 @SuppressWarnings("unused") | |
157 int reserved = di.readUnsignedByte(); | |
158 addrType = di.readUnsignedByte(); | |
159 byte addr[]; | |
160 | |
161 switch (addrType) { | |
162 case SOCKS_ATYP_IPV4: | |
163 addr = new byte[4]; | |
164 di.readFully(addr); | |
165 host = bytes2IPV4(addr, 0); | |
166 break; | |
167 | |
168 case SOCKS_ATYP_IPV6: | |
169 addr = new byte[SOCKS_IPV6_LENGTH];//I believe it is 16 bytes,huge! | |
170 di.readFully(addr); | |
171 host = bytes2IPV6(addr, 0); | |
172 break; | |
173 | |
174 case SOCKS_ATYP_DOMAINNAME: | |
175 //System.out.println("Reading ATYP_DOMAINNAME"); | |
176 addr = new byte[di.readUnsignedByte()];//Next byte shows the length | |
177 di.readFully(addr); | |
178 host = new String(addr); | |
179 break; | |
180 | |
181 default: | |
182 throw(new SocksException(Proxy.SOCKS_JUST_ERROR)); | |
183 } | |
184 | |
185 port = di.readUnsignedShort(); | |
186 | |
187 if (addrType != SOCKS_ATYP_DOMAINNAME && doResolveIP) { | |
188 try { | |
189 ip = InetAddress.getByName(host); | |
190 } | |
191 catch (UnknownHostException uh_ex) { | |
192 } | |
193 } | |
194 } | |
195 | |
196 /** | |
197 Writes the message to the stream. | |
198 @param out Output stream to which message should be written. | |
199 */ | |
200 public void write(OutputStream out)throws SocksException, | |
201 IOException { | |
202 if (data == null) { | |
203 Socks5Message msg; | |
204 | |
205 if (addrType == SOCKS_ATYP_DOMAINNAME) | |
206 msg = new Socks5Message(command, host, port); | |
207 else { | |
208 if (ip == null) { | |
209 try { | |
210 ip = InetAddress.getByName(host); | |
211 } | |
212 catch (UnknownHostException uh_ex) { | |
213 throw new SocksException(Proxy.SOCKS_JUST_ERROR); | |
214 } | |
215 } | |
216 | |
217 msg = new Socks5Message(command, ip, port); | |
218 } | |
219 | |
220 data = msg.data; | |
221 } | |
222 | |
223 out.write(data); | |
224 } | |
225 | |
226 /** | |
227 Returns IP field of the message as IP, if the message was created | |
228 with ATYP of HOSTNAME, it will attempt to resolve the hostname, | |
229 which might fail. | |
230 @throws UnknownHostException if host can't be resolved. | |
231 */ | |
232 public InetAddress getInetAddress() throws UnknownHostException { | |
233 if (ip != null) return ip; | |
234 | |
235 return (ip = InetAddress.getByName(host)); | |
236 } | |
237 | |
238 /** | |
239 Returns string representation of the message. | |
240 */ | |
241 public String toString() { | |
242 String s = | |
243 "Socks5Message:" + "\n" + | |
244 "VN " + version + "\n" + | |
245 "CMD " + command + "\n" + | |
246 "ATYP " + addrType + "\n" + | |
247 "ADDR " + host + "\n" + | |
248 "PORT " + port + "\n"; | |
249 return s; | |
250 } | |
251 | |
252 | |
253 /** | |
254 *Wether to resolve hostIP returned from SOCKS server | |
255 *that is wether to create InetAddress object from the | |
256 *hostName string | |
257 */ | |
258 static public boolean resolveIP() { return doResolveIP;} | |
259 | |
260 /** | |
261 *Wether to resolve hostIP returned from SOCKS server | |
262 *that is wether to create InetAddress object from the | |
263 *hostName string | |
264 *@param doResolve Wether to resolve hostIP from SOCKS server. | |
265 *@return Previous value. | |
266 */ | |
267 static public boolean resolveIP(boolean doResolve) { | |
268 boolean old = doResolveIP; | |
269 doResolveIP = doResolve; | |
270 return old; | |
271 } | |
272 | |
273 /* | |
274 private static final void debug(String s){ | |
275 if(DEBUG) | |
276 System.out.print(s); | |
277 } | |
278 private static final boolean DEBUG = false; | |
279 */ | |
280 | |
281 //SOCKS5 constants | |
282 public static final int SOCKS_VERSION = 5; | |
283 | |
284 public static final int SOCKS_ATYP_IPV4 = 0x1; //Where is 2?? | |
285 public static final int SOCKS_ATYP_DOMAINNAME = 0x3; //!!!!rfc1928 | |
286 public static final int SOCKS_ATYP_IPV6 = 0x4; | |
287 | |
288 public static final int SOCKS_IPV6_LENGTH = 16; | |
289 | |
290 static boolean doResolveIP = true; | |
291 | 290 |
292 } | 291 } |