Mercurial > 510Connectbot
comparison app/src/main/java/net/sourceforge/jsocks/SocksSocket.java @ 438:d29cce60f393
migrate from Eclipse to Android Studio
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Thu, 03 Dec 2015 11:23:55 -0800 |
parents | src/net/sourceforge/jsocks/SocksSocket.java@205ee2873330 |
children |
comparison
equal
deleted
inserted
replaced
437:208b31032318 | 438:d29cce60f393 |
---|---|
1 package net.sourceforge.jsocks; | |
2 | |
3 import java.net.*; | |
4 import java.io.*; | |
5 | |
6 /** | |
7 * SocksSocket tryies to look very similar to normal Socket, | |
8 * while allowing connections through the SOCKS4 or 5 proxy. | |
9 * To use this class you will have to identify proxy you need | |
10 * to use, CProxy class allows you to set default proxy, which | |
11 * will be used by all Socks aware sockets. You can also create | |
12 * either Socks4Proxy or Socks5Proxy, and use them by passing to the | |
13 * appropriate constructors. | |
14 * <P> | |
15 * Using Socks package can be as easy as that: | |
16 * | |
17 * <pre><tt> | |
18 * | |
19 * import Socks.*; | |
20 * .... | |
21 * | |
22 * try{ | |
23 * //Specify SOCKS5 proxy | |
24 * CProxy.setDefaultProxy("socks-proxy",1080); | |
25 * | |
26 * //OR you still use SOCKS4 | |
27 * //Code below uses SOCKS4 proxy | |
28 * //CProxy.setDefaultProxy("socks-proxy",1080,userName); | |
29 * | |
30 * Socket s = SocksSocket("some.host.of.mine",13); | |
31 * readTimeFromSock(s); | |
32 * }catch(SocksException sock_ex){ | |
33 * //Usually it will turn in more or less meaningfull message | |
34 * System.err.println("SocksException:"+sock_ex); | |
35 * } | |
36 * | |
37 * </tt></pre> | |
38 *<P> | |
39 * However if the need exist for more control, like resolving addresses | |
40 * remotely, or using some non-trivial authentication schemes, it can be done. | |
41 */ | |
42 | |
43 public class SocksSocket extends Socket{ | |
44 //Data members | |
45 protected CProxy proxy; | |
46 protected String localHost, remoteHost; | |
47 protected InetAddress localIP, remoteIP; | |
48 protected int localPort,remotePort; | |
49 | |
50 private Socket directSock = null; | |
51 | |
52 /** | |
53 * Tryies to connect to given host and port | |
54 * using default proxy. If no default proxy speciefied | |
55 * it throws SocksException with error code SOCKS_NO_PROXY. | |
56 @param host Machine to connect to. | |
57 @param port Port to which to connect. | |
58 * @see SocksSocket#SocksSocket(CProxy,String,int) | |
59 * @see Socks5Proxy#resolveAddrLocally | |
60 */ | |
61 public SocksSocket(String host,int port) | |
62 throws SocksException,UnknownHostException{ | |
63 this(CProxy.defaultProxy,host,port); | |
64 } | |
65 /** | |
66 * Connects to host port using given proxy server. | |
67 @param p CProxy to use. | |
68 @param host Machine to connect to. | |
69 @param port Port to which to connect. | |
70 @throws UnknownHostException | |
71 If one of the following happens: | |
72 <ol> | |
73 | |
74 <li> CProxy settings say that address should be resolved locally, but | |
75 this fails. | |
76 <li> CProxy settings say that the host should be contacted directly but | |
77 host name can't be resolved. | |
78 </ol> | |
79 @throws SocksException | |
80 If one of the following happens: | |
81 <ul> | |
82 <li> CProxy is is null. | |
83 <li> CProxy settings say that the host should be contacted directly but | |
84 this fails. | |
85 <li> Socks Server can't be contacted. | |
86 <li> Authentication fails. | |
87 <li> Connection is not allowed by the SOCKS proxy. | |
88 <li> SOCKS proxy can't establish the connection. | |
89 <li> Any IO error occured. | |
90 <li> Any protocol error occured. | |
91 </ul> | |
92 @throws IOexception if anything is wrong with I/O. | |
93 @see Socks5Proxy#resolveAddrLocally | |
94 */ | |
95 public SocksSocket(CProxy p,String host,int port) | |
96 throws SocksException,UnknownHostException{ | |
97 | |
98 | |
99 if(p == null) throw new SocksException(CProxy.SOCKS_NO_PROXY); | |
100 //proxy=p; | |
101 proxy = p.copy(); | |
102 remoteHost = host; | |
103 remotePort = port; | |
104 if(proxy.isDirect(host)){ | |
105 remoteIP = InetAddress.getByName(host); | |
106 doDirect(); | |
107 } | |
108 else | |
109 processReply(proxy.connect(host,port)); | |
110 } | |
111 | |
112 | |
113 /** | |
114 * Tryies to connect to given ip and port | |
115 * using default proxy. If no default proxy speciefied | |
116 * it throws SocksException with error code SOCKS_NO_PROXY. | |
117 @param ip Machine to connect to. | |
118 @param port Port to which to connect. | |
119 * @see SocksSocket#SocksSocket(CProxy,String,int) | |
120 */ | |
121 public SocksSocket(InetAddress ip, int port) throws SocksException{ | |
122 this(CProxy.defaultProxy,ip,port); | |
123 } | |
124 | |
125 /** | |
126 Connects to given ip and port using given CProxy server. | |
127 @param p CProxy to use. | |
128 @param ip Machine to connect to. | |
129 @param port Port to which to connect. | |
130 | |
131 */ | |
132 public SocksSocket(CProxy p,InetAddress ip, int port) throws SocksException{ | |
133 if(p == null) throw new SocksException(CProxy.SOCKS_NO_PROXY); | |
134 this.proxy = p.copy(); | |
135 this.remoteIP = ip; | |
136 this.remotePort = port; | |
137 this.remoteHost = ip.getHostName(); | |
138 if(proxy.isDirect(remoteIP)) | |
139 doDirect(); | |
140 else | |
141 processReply(proxy.connect(ip,port)); | |
142 } | |
143 | |
144 | |
145 /** | |
146 * These 2 constructors are used by the SocksServerSocket. | |
147 * This socket simply overrides remoteHost, remotePort | |
148 */ | |
149 protected SocksSocket(String host,int port,CProxy proxy){ | |
150 this.remotePort = port; | |
151 this.proxy = proxy; | |
152 this.localIP = proxy.proxySocket.getLocalAddress(); | |
153 this.localPort = proxy.proxySocket.getLocalPort(); | |
154 this.remoteHost = host; | |
155 } | |
156 protected SocksSocket(InetAddress ip,int port,CProxy proxy){ | |
157 remoteIP = ip; | |
158 remotePort = port; | |
159 this.proxy = proxy; | |
160 this.localIP = proxy.proxySocket.getLocalAddress(); | |
161 this.localPort = proxy.proxySocket.getLocalPort(); | |
162 remoteHost = remoteIP.getHostName(); | |
163 } | |
164 | |
165 /** | |
166 * Same as Socket | |
167 */ | |
168 public void close() throws IOException{ | |
169 if(proxy!= null)proxy.endSession(); | |
170 proxy = null; | |
171 } | |
172 /** | |
173 * Same as Socket | |
174 */ | |
175 public InputStream getInputStream(){ | |
176 return proxy.in; | |
177 } | |
178 /** | |
179 * Same as Socket | |
180 */ | |
181 public OutputStream getOutputStream(){ | |
182 return proxy.out; | |
183 } | |
184 /** | |
185 * Same as Socket | |
186 */ | |
187 public int getPort(){ | |
188 return remotePort; | |
189 } | |
190 /** | |
191 * Returns remote host name, it is usefull in cases when addresses | |
192 * are resolved by proxy, and we can't create InetAddress object. | |
193 @return The name of the host this socket is connected to. | |
194 */ | |
195 public String getHost(){ | |
196 return remoteHost; | |
197 } | |
198 /** | |
199 * Get remote host as InetAddress object, might return null if | |
200 * addresses are resolved by proxy, and it is not possible to resolve | |
201 * it locally | |
202 @return Ip address of the host this socket is connected to, or null | |
203 if address was returned by the proxy as DOMAINNAME and can't be | |
204 resolved locally. | |
205 */ | |
206 public InetAddress getInetAddress(){ | |
207 if(remoteIP == null){ | |
208 try{ | |
209 remoteIP = InetAddress.getByName(remoteHost); | |
210 }catch(UnknownHostException e){ | |
211 return null; | |
212 } | |
213 } | |
214 return remoteIP; | |
215 } | |
216 | |
217 /** | |
218 * Get the port assigned by the proxy for the socket, not | |
219 * the port on locall machine as in Socket. | |
220 @return Port of the socket used on the proxy server. | |
221 */ | |
222 public int getLocalPort(){ | |
223 return localPort; | |
224 } | |
225 | |
226 /** | |
227 * Get address assigned by proxy to make a remote connection, | |
228 * it might be different from the host specified for the proxy. | |
229 * Can return null if socks server returned this address as hostname | |
230 * and it can't be resolved locally, use getLocalHost() then. | |
231 @return Address proxy is using to make a connection. | |
232 */ | |
233 public InetAddress getLocalAddress(){ | |
234 if(localIP == null){ | |
235 try{ | |
236 localIP = InetAddress.getByName(localHost); | |
237 }catch(UnknownHostException e){ | |
238 return null; | |
239 } | |
240 } | |
241 return localIP; | |
242 } | |
243 /** | |
244 Get name of the host, proxy has assigned to make a remote connection | |
245 for this socket. This method is usefull when proxy have returned | |
246 address as hostname, and we can't resolve it on this machine. | |
247 @return The name of the host proxy is using to make a connection. | |
248 */ | |
249 public String getLocalHost(){ | |
250 return localHost; | |
251 } | |
252 | |
253 /** | |
254 Same as socket. | |
255 */ | |
256 public void setSoLinger(boolean on,int val) throws SocketException{ | |
257 proxy.proxySocket.setSoLinger(on,val); | |
258 } | |
259 /** | |
260 Same as socket. | |
261 */ | |
262 public int getSoLinger(int timeout) throws SocketException{ | |
263 return proxy.proxySocket.getSoLinger(); | |
264 } | |
265 /** | |
266 Same as socket. | |
267 */ | |
268 public void setSoTimeout(int timeout) throws SocketException{ | |
269 proxy.proxySocket.setSoTimeout(timeout); | |
270 } | |
271 /** | |
272 Same as socket. | |
273 */ | |
274 public int getSoTimeout(int timeout) throws SocketException{ | |
275 return proxy.proxySocket.getSoTimeout(); | |
276 } | |
277 /** | |
278 Same as socket. | |
279 */ | |
280 public void setTcpNoDelay(boolean on) throws SocketException{ | |
281 proxy.proxySocket.setTcpNoDelay(on); | |
282 } | |
283 /** | |
284 Same as socket. | |
285 */ | |
286 public boolean getTcpNoDelay() throws SocketException{ | |
287 return proxy.proxySocket.getTcpNoDelay(); | |
288 } | |
289 | |
290 /** | |
291 Get string representation of the socket. | |
292 */ | |
293 public String toString(){ | |
294 if(directSock!=null) return "Direct connection:"+directSock; | |
295 return ("Proxy:"+proxy+";"+"addr:"+remoteHost+",port:"+remotePort | |
296 +",localport:"+localPort); | |
297 | |
298 } | |
299 | |
300 //Private Methods | |
301 ////////////////// | |
302 | |
303 private void processReply(ProxyMessage reply)throws SocksException{ | |
304 localPort = reply.port; | |
305 /* | |
306 * If the server have assigned same host as it was contacted on | |
307 * it might return an address of all zeros | |
308 */ | |
309 if(reply.host.equals("0.0.0.0")){ | |
310 localIP = proxy.proxyIP; | |
311 localHost = localIP.getHostName(); | |
312 }else{ | |
313 localHost = reply.host; | |
314 localIP = reply.ip; | |
315 } | |
316 } | |
317 private void doDirect()throws SocksException{ | |
318 try{ | |
319 //System.out.println("IP:"+remoteIP+":"+remotePort); | |
320 directSock = new Socket(remoteIP,remotePort); | |
321 proxy.out = directSock.getOutputStream(); | |
322 proxy.in = directSock.getInputStream(); | |
323 proxy.proxySocket = directSock; | |
324 localIP = directSock.getLocalAddress(); | |
325 localPort = directSock.getLocalPort(); | |
326 }catch(IOException io_ex){ | |
327 throw new SocksException(CProxy.SOCKS_DIRECT_FAILED, | |
328 "Direct connect failed:"+io_ex); | |
329 } | |
330 } | |
331 | |
332 } |