source: branches/2.2/jabberit_messenger/java_source/src/nu/fw/jeti/plugins/filetransfer/socks5/jsocks/SocksSocket.java @ 3102

Revision 3102, 9.8 KB checked in by amuller, 14 years ago (diff)

Ticket #986 - Efetuado merge para o Branch 2.2( atualizacao do modulo)

  • Property svn:executable set to *
Line 
1package nu.fw.jeti.plugins.filetransfer.socks5.jsocks;
2
3import java.net.*;
4import 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
43public class SocksSocket extends Socket{
44   //Data members
45   protected Proxy 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(Proxy,String,int)
59    * @see Socks5Proxy#resolveAddrLocally
60    */
61   public SocksSocket(String 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 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  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 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(Proxy.SOCKS_DIRECT_FAILED,
328                                  "Direct connect failed:"+io_ex);
329      }
330   }
331
332}
Note: See TracBrowser for help on using the repository browser.