KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > socks > SocksSocket


1 package socks;
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, Proxy 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  * Proxy.setDefaultProxy("socks-proxy",1080);
25  *
26  * //OR you still use SOCKS4
27  * //Code below uses SOCKS4 proxy
28  * //Proxy.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 Proxy proxy;
46    protected String JavaDoc 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(Proxy,String,int)
59     * @see Socks5Proxy#resolveAddrLocally
60     */

61    public SocksSocket(String JavaDoc host,int port)
62       throws SocksException,UnknownHostException{
63       this(Proxy.defaultProxy,host,port);
64    }
65    /**
66     * Connects to host port using given proxy server.
67       @param p Proxy 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> Proxy settings say that address should be resolved locally, but
75            this fails.
76       <li> Proxy 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> Proxy is is null.
83        <li> Proxy 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(Proxy p,String JavaDoc host,int port)
96       throws SocksException,UnknownHostException{
97
98
99       if(p == null) throw new SocksException(Proxy.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(Proxy,String,int)
120     */

121    public SocksSocket(InetAddress ip, int port) throws SocksException{
122       this(Proxy.defaultProxy,ip,port);
123    }
124
125    /**
126       Connects to given ip and port using given Proxy server.
127       @param p Proxy to use.
128       @param ip Machine to connect to.
129       @param port Port to which to connect.
130
131     */

132    public SocksSocket(Proxy p,InetAddress ip, int port) throws SocksException{
133       if(p == null) throw new SocksException(Proxy.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 JavaDoc host,int port,Proxy 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,Proxy 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 JavaDoc 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 JavaDoc 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 JavaDoc 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(Proxy.SOCKS_DIRECT_FAILED,
328                                   "Direct connect failed:"+io_ex);
329       }
330    }
331
332 }
333
Popular Tags