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 }