Mercurial > 510Connectbot
comparison src/net/sourceforge/jsocks/Socks5DatagramSocket.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 |
comparison
equal
deleted
inserted
replaced
348:29076621bab0 | 349:205ee2873330 |
---|---|
14 <li> IPV6, version 6 ip address (not supported by Java as for now). | 14 <li> IPV6, version 6 ip address (not supported by Java as for now). |
15 22 bytes header size. | 15 22 bytes header size. |
16 <li> Host name,(7+length of the host name bytes header size). | 16 <li> Host name,(7+length of the host name bytes header size). |
17 </ul> | 17 </ul> |
18 As with other Socks equivalents, direct addresses are handled | 18 As with other Socks equivalents, direct addresses are handled |
19 transparently, that is data will be send directly when required | 19 transparently, that is data will be send directly when required |
20 by the proxy settings. | 20 by the proxy settings. |
21 <p> | 21 <p> |
22 <b>NOTE:</b><br> | 22 <b>NOTE:</b><br> |
23 Unlike other SOCKS Sockets, it <b>does not</b> support proxy chaining, | 23 Unlike other SOCKS Sockets, it <b>does not</b> support proxy chaining, |
24 and will throw an exception if proxy has a chain proxy attached. The | 24 and will throw an exception if proxy has a chain proxy attached. The |
27 which host:port datagrams will be send for association, and returns address | 27 which host:port datagrams will be send for association, and returns address |
28 to which datagrams should be send by the client, but it does not | 28 to which datagrams should be send by the client, but it does not |
29 inform client from which host:port it is going to send datagrams, in fact | 29 inform client from which host:port it is going to send datagrams, in fact |
30 there is even no guarantee they will be send at all and from the same address | 30 there is even no guarantee they will be send at all and from the same address |
31 each time. | 31 each time. |
32 | 32 |
33 */ | 33 */ |
34 public class Socks5DatagramSocket extends DatagramSocket { | 34 public class Socks5DatagramSocket extends DatagramSocket{ |
35 | 35 |
36 InetAddress relayIP; | 36 InetAddress relayIP; |
37 int relayPort; | 37 int relayPort; |
38 Socks5Proxy proxy; | 38 Socks5Proxy proxy; |
39 private boolean server_mode = false; | 39 private boolean server_mode = false; |
40 UDPEncapsulation encapsulation; | 40 UDPEncapsulation encapsulation; |
41 | 41 |
42 | 42 |
43 /** | 43 /** |
44 Construct Datagram socket for communication over SOCKS5 proxy | 44 Construct Datagram socket for communication over SOCKS5 proxy |
45 server. This constructor uses default proxy, the one set with | 45 server. This constructor uses default proxy, the one set with |
46 Proxy.setDefaultProxy() method. If default proxy is not set or | 46 CProxy.setDefaultProxy() method. If default proxy is not set or |
47 it is set to version4 proxy, which does not support datagram | 47 it is set to version4 proxy, which does not support datagram |
48 forwarding, throws SocksException. | 48 forwarding, throws SocksException. |
49 | 49 |
50 */ | 50 */ |
51 public Socks5DatagramSocket() throws SocksException, | 51 public Socks5DatagramSocket() throws SocksException, |
52 IOException { | 52 IOException{ |
53 this(Proxy.defaultProxy, 0, null); | 53 this(CProxy.defaultProxy,0,null); |
54 } | 54 } |
55 /** | 55 /** |
56 Construct Datagram socket for communication over SOCKS5 proxy | 56 Construct Datagram socket for communication over SOCKS5 proxy |
57 server. And binds it to the specified local port. | 57 server. And binds it to the specified local port. |
58 This constructor uses default proxy, the one set with | 58 This constructor uses default proxy, the one set with |
59 Proxy.setDefaultProxy() method. If default proxy is not set or | 59 CProxy.setDefaultProxy() method. If default proxy is not set or |
60 it is set to version4 proxy, which does not support datagram | 60 it is set to version4 proxy, which does not support datagram |
61 forwarding, throws SocksException. | 61 forwarding, throws SocksException. |
62 */ | 62 */ |
63 public Socks5DatagramSocket(int port) throws SocksException, | 63 public Socks5DatagramSocket(int port) throws SocksException, |
64 IOException { | 64 IOException{ |
65 this(Proxy.defaultProxy, port, null); | 65 this(CProxy.defaultProxy,port,null); |
66 } | 66 } |
67 /** | 67 /** |
68 Construct Datagram socket for communication over SOCKS5 proxy | 68 Construct Datagram socket for communication over SOCKS5 proxy |
69 server. And binds it to the specified local port and address. | 69 server. And binds it to the specified local port and address. |
70 This constructor uses default proxy, the one set with | 70 This constructor uses default proxy, the one set with |
71 Proxy.setDefaultProxy() method. If default proxy is not set or | 71 CProxy.setDefaultProxy() method. If default proxy is not set or |
72 it is set to version4 proxy, which does not support datagram | 72 it is set to version4 proxy, which does not support datagram |
73 forwarding, throws SocksException. | 73 forwarding, throws SocksException. |
74 */ | 74 */ |
75 public Socks5DatagramSocket(int port, InetAddress ip) throws SocksException, | 75 public Socks5DatagramSocket(int port,InetAddress ip) throws SocksException, |
76 IOException { | 76 IOException{ |
77 this(Proxy.defaultProxy, port, ip); | 77 this(CProxy.defaultProxy,port,ip); |
78 } | 78 } |
79 | 79 |
80 /** | 80 /** |
81 Constructs datagram socket for communication over specified proxy. | 81 Constructs datagram socket for communication over specified proxy. |
82 And binds it to the given local address and port. Address of null | 82 And binds it to the given local address and port. Address of null |
83 and port of 0, signify any availabale port/address. | 83 and port of 0, signify any availabale port/address. |
84 Might throw SocksException, if: | 84 Might throw SocksException, if: |
85 <ol> | 85 <ol> |
86 <li> Given version of proxy does not support UDP_ASSOCIATE. | 86 <li> Given version of proxy does not support UDP_ASSOCIATE. |
87 <li> Proxy can't be reached. | 87 <li> CProxy can't be reached. |
88 <li> Authorization fails. | 88 <li> Authorization fails. |
89 <li> Proxy does not want to perform udp forwarding, for any reason. | 89 <li> CProxy does not want to perform udp forwarding, for any reason. |
90 </ol> | 90 </ol> |
91 Might throw IOException if binding dtagram socket to given address/port | 91 Might throw IOException if binding dtagram socket to given address/port |
92 fails. | 92 fails. |
93 See java.net.DatagramSocket for more details. | 93 See java.net.DatagramSocket for more details. |
94 */ | 94 */ |
95 public Socks5DatagramSocket(Proxy p, int port, InetAddress ip) | 95 public Socks5DatagramSocket(CProxy p,int port,InetAddress ip) |
96 throws SocksException, | 96 throws SocksException, |
97 IOException { | 97 IOException{ |
98 super(port, ip); | 98 super(port,ip); |
99 | 99 if(p == null) throw new SocksException(CProxy.SOCKS_NO_PROXY); |
100 if (p == null) throw new SocksException(Proxy.SOCKS_NO_PROXY); | 100 if(!(p instanceof Socks5Proxy)) |
101 | 101 throw new SocksException(-1,"Datagram Socket needs Proxy version 5"); |
102 if (!(p instanceof Socks5Proxy)) | 102 |
103 throw new SocksException(-1, "Datagram Socket needs Proxy version 5"); | 103 if(p.chainProxy != null) |
104 | 104 throw new SocksException(CProxy.SOCKS_JUST_ERROR, |
105 if (p.chainProxy != null) | 105 "Datagram Sockets do not support proxy chaining."); |
106 throw new SocksException(Proxy.SOCKS_JUST_ERROR, | 106 |
107 "Datagram Sockets do not support proxy chaining."); | 107 proxy =(Socks5Proxy) p.copy(); |
108 | 108 |
109 proxy = (Socks5Proxy) p.copy(); | 109 ProxyMessage msg = proxy.udpAssociate(super.getLocalAddress(), |
110 ProxyMessage msg = proxy.udpAssociate(super.getLocalAddress(), | 110 super.getLocalPort()); |
111 super.getLocalPort()); | 111 relayIP = msg.ip; |
112 relayIP = msg.ip; | 112 if(relayIP.getHostAddress().equals("0.0.0.0")) relayIP = proxy.proxyIP; |
113 | 113 relayPort = msg.port; |
114 if (relayIP.getHostAddress().equals("0.0.0.0")) relayIP = proxy.proxyIP; | 114 |
115 | 115 encapsulation = proxy.udp_encapsulation; |
116 relayPort = msg.port; | 116 |
117 encapsulation = proxy.udp_encapsulation; | 117 //debug("Datagram Socket:"+getLocalAddress()+":"+getLocalPort()+"\n"); |
118 //debug("Datagram Socket:"+getLocalAddress()+":"+getLocalPort()+"\n"); | 118 //debug("Socks5Datagram: "+relayIP+":"+relayPort+"\n"); |
119 //debug("Socks5Datagram: "+relayIP+":"+relayPort+"\n"); | 119 } |
120 } | 120 |
121 | 121 /** |
122 /** | 122 Used by UDPRelayServer. |
123 Used by UDPRelayServer. | 123 */ |
124 */ | 124 Socks5DatagramSocket(boolean server_mode,UDPEncapsulation encapsulation, |
125 Socks5DatagramSocket(boolean server_mode, UDPEncapsulation encapsulation, | 125 InetAddress relayIP,int relayPort) |
126 InetAddress relayIP, int relayPort) | 126 throws IOException{ |
127 throws IOException { | 127 super(); |
128 super(); | 128 this.server_mode = server_mode; |
129 this.server_mode = server_mode; | 129 this.relayIP = relayIP; |
130 this.relayIP = relayIP; | 130 this.relayPort = relayPort; |
131 this.relayPort = relayPort; | 131 this.encapsulation = encapsulation; |
132 this.encapsulation = encapsulation; | 132 this.proxy = null; |
133 this.proxy = null; | 133 } |
134 } | 134 |
135 | 135 /** |
136 /** | 136 Sends the Datagram either through the proxy or directly depending |
137 Sends the Datagram either through the proxy or directly depending | 137 on current proxy settings and destination address. <BR> |
138 on current proxy settings and destination address. <BR> | 138 |
139 | 139 <B> NOTE: </B> DatagramPacket size should be at least 10 bytes less |
140 <B> NOTE: </B> DatagramPacket size should be at least 10 bytes less | 140 than the systems limit. |
141 than the systems limit. | 141 |
142 | 142 <P> |
143 <P> | 143 See documentation on java.net.DatagramSocket |
144 See documentation on java.net.DatagramSocket | 144 for full details on how to use this method. |
145 for full details on how to use this method. | 145 @param dp Datagram to send. |
146 @param dp Datagram to send. | 146 @throws IOException If error happens with I/O. |
147 @throws IOException If error happens with I/O. | 147 */ |
148 */ | 148 public void send(DatagramPacket dp) throws IOException{ |
149 public void send(DatagramPacket dp) throws IOException { | 149 //If the host should be accessed directly, send it as is. |
150 //If the host should be accessed directly, send it as is. | 150 if(!server_mode && proxy.isDirect(dp.getAddress())){ |
151 if (!server_mode) { | 151 super.send(dp); |
152 super.send(dp); | 152 //debug("Sending directly:"); |
153 //debug("Sending directly:"); | 153 return; |
154 return; | 154 } |
155 } | 155 |
156 | 156 byte[] head = formHeader(dp.getAddress(),dp.getPort()); |
157 byte[] head = formHeader(dp.getAddress(), dp.getPort()); | 157 byte[] buf = new byte[head.length + dp.getLength()]; |
158 byte[] buf = new byte[head.length + dp.getLength()]; | 158 byte[] data = dp.getData(); |
159 byte[] data = dp.getData(); | 159 //Merge head and data |
160 //Merge head and data | 160 System.arraycopy(head,0,buf,0,head.length); |
161 System.arraycopy(head, 0, buf, 0, head.length); | 161 //System.arraycopy(data,dp.getOffset(),buf,head.length,dp.getLength()); |
162 //System.arraycopy(data,dp.getOffset(),buf,head.length,dp.getLength()); | 162 System.arraycopy(data,0,buf,head.length,dp.getLength()); |
163 System.arraycopy(data, 0, buf, head.length, dp.getLength()); | 163 |
164 | 164 if(encapsulation != null) |
165 if (encapsulation != null) | 165 buf = encapsulation.udpEncapsulate(buf,true); |
166 buf = encapsulation.udpEncapsulate(buf, true); | 166 |
167 | 167 super.send(new DatagramPacket(buf,buf.length,relayIP,relayPort)); |
168 super.send(new DatagramPacket(buf, buf.length, relayIP, relayPort)); | 168 } |
169 } | 169 /** |
170 /** | 170 This method allows to send datagram packets with address type DOMAINNAME. |
171 This method allows to send datagram packets with address type DOMAINNAME. | 171 SOCKS5 allows to specify host as names rather than ip addresses.Using |
172 SOCKS5 allows to specify host as names rather than ip addresses.Using | 172 this method one can send udp datagrams through the proxy, without having |
173 this method one can send udp datagrams through the proxy, without having | 173 to know the ip address of the destination host. |
174 to know the ip address of the destination host. | 174 <p> |
175 <p> | 175 If proxy specified for that socket has an option resolveAddrLocally set |
176 If proxy specified for that socket has an option resolveAddrLocally set | 176 to true host will be resolved, and the datagram will be send with address |
177 to true host will be resolved, and the datagram will be send with address | 177 type IPV4, if resolve fails, UnknownHostException is thrown. |
178 type IPV4, if resolve fails, UnknownHostException is thrown. | 178 @param dp Datagram to send, it should contain valid port and data |
179 @param dp Datagram to send, it should contain valid port and data | 179 @param host Host name to which datagram should be send. |
180 @param host Host name to which datagram should be send. | 180 @throws IOException If error happens with I/O, or the host can't be |
181 @throws IOException If error happens with I/O, or the host can't be | 181 resolved when proxy settings say that hosts should be resolved locally. |
182 resolved when proxy settings say that hosts should be resolved locally. | 182 @see Socks5Proxy#resolveAddrLocally(boolean) |
183 @see Socks5Proxy#resolveAddrLocally(boolean) | 183 */ |
184 */ | 184 public void send(DatagramPacket dp, String host) throws IOException{ |
185 public void send(DatagramPacket dp, String host) throws IOException { | 185 if(proxy.isDirect(host)){ |
186 dp.setAddress(InetAddress.getByName(host)); | 186 dp.setAddress(InetAddress.getByName(host)); |
187 super.send(dp); | 187 super.send(dp); |
188 } | 188 return; |
189 | 189 } |
190 /** | 190 |
191 * Receives udp packet. If packet have arrived from the proxy relay server, | 191 if(((Socks5Proxy)proxy).resolveAddrLocally){ |
192 * it is processed and address and port of the packet are set to the | 192 dp.setAddress(InetAddress.getByName(host)); |
193 * address and port of sending host.<BR> | 193 } |
194 * If the packet arrived from anywhere else it is not changed.<br> | 194 |
195 * <B> NOTE: </B> DatagramPacket size should be at least 10 bytes bigger | 195 byte[] head = formHeader(host,dp.getPort()); |
196 * than the largest packet you expect (this is for IPV4 addresses). | 196 byte[] buf = new byte[head.length + dp.getLength()]; |
197 * For hostnames and IPV6 it is even more. | 197 byte[] data = dp.getData(); |
198 @param dp Datagram in which all relevent information will be copied. | 198 //Merge head and data |
199 */ | 199 System.arraycopy(head,0,buf,0,head.length); |
200 public void receive(DatagramPacket dp) throws IOException { | 200 //System.arraycopy(data,dp.getOffset(),buf,head.length,dp.getLength()); |
201 super.receive(dp); | 201 System.arraycopy(data,0,buf,head.length,dp.getLength()); |
202 | 202 |
203 if (server_mode) { | 203 if(encapsulation != null) |
204 //Drop all datagrams not from relayIP/relayPort | 204 buf = encapsulation.udpEncapsulate(buf,true); |
205 int init_length = dp.getLength(); | 205 |
206 int initTimeout = getSoTimeout(); | 206 super.send(new DatagramPacket(buf,buf.length,relayIP,relayPort)); |
207 long startTime = System.currentTimeMillis(); | 207 } |
208 | 208 |
209 while (!relayIP.equals(dp.getAddress()) || | 209 /** |
210 relayPort != dp.getPort()) { | 210 * Receives udp packet. If packet have arrived from the proxy relay server, |
211 //Restore datagram size | 211 * it is processed and address and port of the packet are set to the |
212 dp.setLength(init_length); | 212 * address and port of sending host.<BR> |
213 | 213 * If the packet arrived from anywhere else it is not changed.<br> |
214 //If there is a non-infinit timeout on this socket | 214 * <B> NOTE: </B> DatagramPacket size should be at least 10 bytes bigger |
215 //Make sure that it happens no matter how often unexpected | 215 * than the largest packet you expect (this is for IPV4 addresses). |
216 //packets arrive. | 216 * For hostnames and IPV6 it is even more. |
217 if (initTimeout != 0) { | 217 @param dp Datagram in which all relevent information will be copied. |
218 int newTimeout = initTimeout - (int)(System.currentTimeMillis() - | 218 */ |
219 startTime); | 219 public void receive(DatagramPacket dp) throws IOException{ |
220 | 220 super.receive(dp); |
221 if (newTimeout <= 0) throw new InterruptedIOException( | 221 |
222 "In Socks5DatagramSocket->receive()"); | 222 if(server_mode){ |
223 | 223 //Drop all datagrams not from relayIP/relayPort |
224 setSoTimeout(newTimeout); | 224 int init_length = dp.getLength(); |
225 } | 225 int initTimeout = getSoTimeout(); |
226 | 226 long startTime = System.currentTimeMillis(); |
227 super.receive(dp); | 227 |
228 } | 228 while(!relayIP.equals(dp.getAddress()) || |
229 | 229 relayPort != dp.getPort()){ |
230 //Restore timeout settings | 230 |
231 if (initTimeout != 0) setSoTimeout(initTimeout); | 231 //Restore datagram size |
232 } | 232 dp.setLength(init_length); |
233 else if (!relayIP.equals(dp.getAddress()) || | 233 |
234 relayPort != dp.getPort()) | 234 //If there is a non-infinit timeout on this socket |
235 return; // Recieved direct packet | 235 //Make sure that it happens no matter how often unexpected |
236 | 236 //packets arrive. |
237 //If the datagram is not from the relay server, return it it as is. | 237 if(initTimeout != 0){ |
238 byte[] data; | 238 int newTimeout = initTimeout - (int)(System.currentTimeMillis() - |
239 data = dp.getData(); | 239 startTime); |
240 | 240 if(newTimeout <= 0) throw new InterruptedIOException( |
241 if (encapsulation != null) | 241 "In Socks5DatagramSocket->receive()"); |
242 data = encapsulation.udpEncapsulate(data, false); | 242 setSoTimeout(newTimeout); |
243 | 243 } |
244 int offset = 0; //Java 1.1 | 244 |
245 //int offset = dp.getOffset(); //Java 1.2 | 245 super.receive(dp); |
246 ByteArrayInputStream bIn = new ByteArrayInputStream(data, offset, | 246 } |
247 dp.getLength()); | 247 |
248 ProxyMessage msg = new Socks5Message(bIn); | 248 //Restore timeout settings |
249 dp.setPort(msg.port); | 249 if(initTimeout != 0) setSoTimeout(initTimeout); |
250 dp.setAddress(msg.getInetAddress()); | 250 |
251 //what wasn't read by the Message is the data | 251 }else if(!relayIP.equals(dp.getAddress()) || |
252 int data_length = bIn.available(); | 252 relayPort != dp.getPort()) |
253 //Shift data to the left | 253 return; // Recieved direct packet |
254 System.arraycopy(data, offset + dp.getLength() - data_length, | 254 //If the datagram is not from the relay server, return it it as is. |
255 data, offset, data_length); | 255 |
256 dp.setLength(data_length); | 256 byte[] data; |
257 } | 257 data = dp.getData(); |
258 | 258 |
259 /** | 259 if(encapsulation != null) |
260 * Returns port assigned by the proxy, to which datagrams are relayed. | 260 data = encapsulation.udpEncapsulate(data,false); |
261 * It is not the same port to which other party should send datagrams. | 261 |
262 @return Port assigned by socks server to which datagrams are send | 262 int offset = 0; //Java 1.1 |
263 for association. | 263 //int offset = dp.getOffset(); //Java 1.2 |
264 */ | 264 |
265 public int getLocalPort() { | 265 ByteArrayInputStream bIn = new ByteArrayInputStream(data,offset, |
266 if (server_mode) return super.getLocalPort(); | 266 dp.getLength()); |
267 | 267 |
268 return relayPort; | 268 |
269 } | 269 ProxyMessage msg = new Socks5Message(bIn); |
270 /** | 270 dp.setPort(msg.port); |
271 * Address assigned by the proxy, to which datagrams are send for relay. | 271 dp.setAddress(msg.getInetAddress()); |
272 * It is not necesseraly the same address, to which other party should send | 272 |
273 * datagrams. | 273 //what wasn't read by the Message is the data |
274 @return Address to which datagrams are send for association. | 274 int data_length = bIn.available(); |
275 */ | 275 //Shift data to the left |
276 public InetAddress getLocalAddress() { | 276 System.arraycopy(data,offset+dp.getLength()-data_length, |
277 if (server_mode) return super.getLocalAddress(); | 277 data,offset,data_length); |
278 | 278 |
279 return relayIP; | 279 |
280 } | 280 dp.setLength(data_length); |
281 | 281 } |
282 /** | 282 |
283 * Closes datagram socket, and proxy connection. | 283 /** |
284 */ | 284 * Returns port assigned by the proxy, to which datagrams are relayed. |
285 public void close() { | 285 * It is not the same port to which other party should send datagrams. |
286 if (!server_mode) proxy.endSession(); | 286 @return Port assigned by socks server to which datagrams are send |
287 | 287 for association. |
288 super.close(); | 288 */ |
289 } | 289 public int getLocalPort(){ |
290 | 290 if(server_mode) return super.getLocalPort(); |
291 /** | 291 return relayPort; |
292 This method checks wether proxy still runs udp forwarding service | 292 } |
293 for this socket. | 293 /** |
294 <p> | 294 * Address assigned by the proxy, to which datagrams are send for relay. |
295 This methods checks wether the primary connection to proxy server | 295 * It is not necesseraly the same address, to which other party should send |
296 is active. If it is, chances are that proxy continues to forward | 296 * datagrams. |
297 datagrams being send from this socket. If it was closed, most likely | 297 @return Address to which datagrams are send for association. |
298 datagrams are no longer being forwarded by the server. | 298 */ |
299 <p> | 299 public InetAddress getLocalAddress(){ |
300 Proxy might decide to stop forwarding datagrams, in which case it | 300 if(server_mode) return super.getLocalAddress(); |
301 should close primary connection. This method allows to check, wether | 301 return relayIP; |
302 this have been done. | 302 } |
303 <p> | 303 |
304 You can specify timeout for which we should be checking EOF condition | 304 /** |
305 on the primary connection. Timeout is in milliseconds. Specifying 0 as | 305 * Closes datagram socket, and proxy connection. |
306 timeout implies infinity, in which case method will block, until | 306 */ |
307 connection to proxy is closed or an error happens, and then return false. | 307 public void close(){ |
308 <p> | 308 if(!server_mode) proxy.endSession(); |
309 One possible scenario is to call isProxyactive(0) in separate thread, | 309 super.close(); |
310 and once it returned notify other threads about this event. | 310 } |
311 | 311 |
312 @param timeout For how long this method should block, before returning. | 312 /** |
313 @return true if connection to proxy is active, false if eof or error | 313 This method checks wether proxy still runs udp forwarding service |
314 condition have been encountered on the connection. | 314 for this socket. |
315 */ | 315 <p> |
316 public boolean isProxyAlive(int timeout) { | 316 This methods checks wether the primary connection to proxy server |
317 if (server_mode) return false; | 317 is active. If it is, chances are that proxy continues to forward |
318 | 318 datagrams being send from this socket. If it was closed, most likely |
319 if (proxy != null) { | 319 datagrams are no longer being forwarded by the server. |
320 try { | 320 <p> |
321 proxy.proxySocket.setSoTimeout(timeout); | 321 CProxy might decide to stop forwarding datagrams, in which case it |
322 int eof = proxy.in.read(); | 322 should close primary connection. This method allows to check, wether |
323 | 323 this have been done. |
324 if (eof < 0) return false; // EOF encountered. | 324 <p> |
325 else return true; // This really should not happen | 325 You can specify timeout for which we should be checking EOF condition |
326 } | 326 on the primary connection. Timeout is in milliseconds. Specifying 0 as |
327 catch (InterruptedIOException iioe) { | 327 timeout implies infinity, in which case method will block, until |
328 return true; // read timed out. | 328 connection to proxy is closed or an error happens, and then return false. |
329 } | 329 <p> |
330 catch (IOException ioe) { | 330 One possible scenario is to call isProxyactive(0) in separate thread, |
331 return false; | 331 and once it returned notify other threads about this event. |
332 } | 332 |
333 } | 333 @param timeout For how long this method should block, before returning. |
334 | 334 @return true if connection to proxy is active, false if eof or error |
335 return false; | 335 condition have been encountered on the connection. |
336 } | 336 */ |
337 public boolean isProxyAlive(int timeout){ | |
338 if(server_mode) return false; | |
339 if(proxy != null){ | |
340 try{ | |
341 proxy.proxySocket.setSoTimeout(timeout); | |
342 | |
343 int eof = proxy.in.read(); | |
344 if(eof < 0) return false; // EOF encountered. | |
345 else return true; // This really should not happen | |
346 | |
347 }catch(InterruptedIOException iioe){ | |
348 return true; // read timed out. | |
349 }catch(IOException ioe){ | |
350 return false; | |
351 } | |
352 } | |
353 return false; | |
354 } | |
337 | 355 |
338 //PRIVATE METHODS | 356 //PRIVATE METHODS |
339 ////////////////// | 357 ////////////////// |
340 | 358 |
341 | 359 |
342 private byte[] formHeader(InetAddress ip, int port) { | 360 private byte[] formHeader(InetAddress ip, int port){ |
343 Socks5Message request = new Socks5Message(0, ip, port); | 361 Socks5Message request = new Socks5Message(0,ip,port); |
344 request.data[0] = 0; | 362 request.data[0] = 0; |
345 return request.data; | 363 return request.data; |
346 } | 364 } |
347 | 365 |
348 | 366 |
349 /*====================================================================== | 367 private byte[] formHeader(String host,int port){ |
350 | 368 Socks5Message request = new Socks5Message(0,host,port); |
351 //Mainly Test functions | 369 request.data[0] = 0; |
352 ////////////////////// | 370 return request.data; |
353 | 371 } |
354 private String bytes2String(byte[] b){ | 372 |
355 String s=""; | 373 |
356 char[] hex_digit = { '0','1','2','3','4','5','6','7','8','9', | 374 /*====================================================================== |
357 'A','B','C','D','E','F'}; | 375 |
358 for(int i=0;i<b.length;++i){ | 376 //Mainly Test functions |
359 int i1 = (b[i] & 0xF0) >> 4; | 377 ////////////////////// |
360 int i2 = b[i] & 0xF; | 378 |
361 s+=hex_digit[i1]; | 379 private String bytes2String(byte[] b){ |
362 s+=hex_digit[i2]; | 380 String s=""; |
363 s+=" "; | 381 char[] hex_digit = { '0','1','2','3','4','5','6','7','8','9', |
364 } | 382 'A','B','C','D','E','F'}; |
365 return s; | 383 for(int i=0;i<b.length;++i){ |
366 } | 384 int i1 = (b[i] & 0xF0) >> 4; |
367 private static final void debug(String s){ | 385 int i2 = b[i] & 0xF; |
368 if(DEBUG) | 386 s+=hex_digit[i1]; |
369 System.out.print(s); | 387 s+=hex_digit[i2]; |
370 } | 388 s+=" "; |
371 | 389 } |
372 private static final boolean DEBUG = true; | 390 return s; |
373 | 391 } |
374 | 392 private static final void debug(String s){ |
375 public static void usage(){ | 393 if(DEBUG) |
376 System.err.print( | 394 System.out.print(s); |
377 "Usage: java Socks.SocksDatagramSocket host port [socksHost socksPort]\n"); | 395 } |
378 } | 396 |
379 | 397 private static final boolean DEBUG = true; |
380 static final int defaultProxyPort = 1080; //Default Port | 398 |
381 static final String defaultProxyHost = "www-proxy"; //Default proxy | 399 |
382 | 400 public static void usage(){ |
383 public static void main(String args[]){ | 401 System.err.print( |
384 int port; | 402 "Usage: java Socks.SocksDatagramSocket host port [socksHost socksPort]\n"); |
385 String host; | 403 } |
386 int proxyPort; | 404 |
387 String proxyHost; | 405 static final int defaultProxyPort = 1080; //Default Port |
388 InetAddress ip; | 406 static final String defaultProxyHost = "www-proxy"; //Default proxy |
389 | 407 |
390 if(args.length > 1 && args.length < 5){ | 408 public static void main(String args[]){ |
391 try{ | 409 int port; |
392 | 410 String host; |
393 host = args[0]; | 411 int proxyPort; |
394 port = Integer.parseInt(args[1]); | 412 String proxyHost; |
395 | 413 InetAddress ip; |
396 proxyPort =(args.length > 3)? Integer.parseInt(args[3]) | 414 |
397 : defaultProxyPort; | 415 if(args.length > 1 && args.length < 5){ |
398 | 416 try{ |
399 host = args[0]; | 417 |
400 ip = InetAddress.getByName(host); | 418 host = args[0]; |
401 | 419 port = Integer.parseInt(args[1]); |
402 proxyHost =(args.length > 2)? args[2] | 420 |
403 : defaultProxyHost; | 421 proxyPort =(args.length > 3)? Integer.parseInt(args[3]) |
404 | 422 : defaultProxyPort; |
405 Proxy.setDefaultProxy(proxyHost,proxyPort); | 423 |
406 Proxy p = Proxy.getDefaultProxy(); | 424 host = args[0]; |
407 p.addDirect("lux"); | 425 ip = InetAddress.getByName(host); |
408 | 426 |
409 | 427 proxyHost =(args.length > 2)? args[2] |
410 DatagramSocket ds = new Socks5DatagramSocket(); | 428 : defaultProxyHost; |
411 | 429 |
412 | 430 CProxy.setDefaultProxy(proxyHost,proxyPort); |
413 BufferedReader in = new BufferedReader( | 431 CProxy p = CProxy.getDefaultProxy(); |
414 new InputStreamReader(System.in)); | 432 p.addDirect("lux"); |
415 String s; | 433 |
416 | 434 |
417 System.out.print("Enter line:"); | 435 DatagramSocket ds = new Socks5DatagramSocket(); |
418 s = in.readLine(); | 436 |
419 | 437 |
420 while(s != null){ | 438 BufferedReader in = new BufferedReader( |
421 byte[] data = (s+"\r\n").getBytes(); | 439 new InputStreamReader(System.in)); |
422 DatagramPacket dp = new DatagramPacket(data,0,data.length, | 440 String s; |
423 ip,port); | 441 |
424 System.out.println("Sending to: "+ip+":"+port); | 442 System.out.print("Enter line:"); |
425 ds.send(dp); | 443 s = in.readLine(); |
426 dp = new DatagramPacket(new byte[1024],1024); | 444 |
427 | 445 while(s != null){ |
428 System.out.println("Trying to recieve on port:"+ | 446 byte[] data = (s+"\r\n").getBytes(); |
429 ds.getLocalPort()); | 447 DatagramPacket dp = new DatagramPacket(data,0,data.length, |
430 ds.receive(dp); | 448 ip,port); |
431 System.out.print("Recieved:\n"+ | 449 System.out.println("Sending to: "+ip+":"+port); |
432 "From:"+dp.getAddress()+":"+dp.getPort()+ | 450 ds.send(dp); |
433 "\n\n"+ | 451 dp = new DatagramPacket(new byte[1024],1024); |
434 new String(dp.getData(),dp.getOffset(),dp.getLength())+"\n" | 452 |
435 ); | 453 System.out.println("Trying to recieve on port:"+ |
436 System.out.print("Enter line:"); | 454 ds.getLocalPort()); |
437 s = in.readLine(); | 455 ds.receive(dp); |
438 | 456 System.out.print("Recieved:\n"+ |
439 } | 457 "From:"+dp.getAddress()+":"+dp.getPort()+ |
440 ds.close(); | 458 "\n\n"+ |
441 System.exit(1); | 459 new String(dp.getData(),dp.getOffset(),dp.getLength())+"\n" |
442 | 460 ); |
443 }catch(SocksException s_ex){ | 461 System.out.print("Enter line:"); |
444 System.err.println("SocksException:"+s_ex); | 462 s = in.readLine(); |
445 s_ex.printStackTrace(); | 463 |
446 System.exit(1); | 464 } |
447 }catch(IOException io_ex){ | 465 ds.close(); |
448 io_ex.printStackTrace(); | 466 System.exit(1); |
449 System.exit(1); | 467 |
450 }catch(NumberFormatException num_ex){ | 468 }catch(SocksException s_ex){ |
451 usage(); | 469 System.err.println("SocksException:"+s_ex); |
452 num_ex.printStackTrace(); | 470 s_ex.printStackTrace(); |
453 System.exit(1); | 471 System.exit(1); |
454 } | 472 }catch(IOException io_ex){ |
455 | 473 io_ex.printStackTrace(); |
456 }else{ | 474 System.exit(1); |
457 usage(); | 475 }catch(NumberFormatException num_ex){ |
458 } | 476 usage(); |
459 } | 477 num_ex.printStackTrace(); |
460 */ | 478 System.exit(1); |
479 } | |
480 | |
481 }else{ | |
482 usage(); | |
483 } | |
484 } | |
485 */ | |
461 | 486 |
462 } | 487 } |