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

Revision 3102, 8.5 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.io.IOException;
4import java.io.InputStream;
5import java.io.OutputStream;
6import java.io.DataInputStream;
7import java.net.InetAddress;
8import java.net.UnknownHostException;
9
10/**
11 SOCKS5 request/response message.
12*/
13
14class Socks5Message extends ProxyMessage{
15   /** Address type of given message*/
16   public int addrType;
17
18   byte[] data;
19
20   /**
21    Server error response.
22    @param cmd Error code.
23   */
24   public Socks5Message(int cmd){
25      super(cmd,null,0);
26      data = new byte[3];
27      data[0] = SOCKS_VERSION; //Version.
28      data[1] = (byte)cmd;     //Reply code for some kind of failure.
29      data[2] = 0;             //Reserved byte.
30   }
31
32   /**
33    Construct client request or server response.
34    @param cmd - Request/Response code.
35    @param ip  - IP field.
36    @paarm port - port field.
37   */
38   public Socks5Message(int cmd,InetAddress ip,int port){
39      super(cmd,ip,port);
40      this.host = ip==null?"0.0.0.0":ip.getHostName();
41      this.version = SOCKS_VERSION;
42
43      byte[] addr;
44
45      if(ip == null){
46         addr = new byte[4];
47         addr[0]=addr[1]=addr[2]=addr[3]=0;
48      }else
49         addr = ip.getAddress();
50
51      addrType = addr.length == 4 ? SOCKS_ATYP_IPV4
52                                  : SOCKS_ATYP_IPV6;
53 
54      data = new byte[6+addr.length];
55      data[0] = (byte) SOCKS_VERSION;           //Version
56      data[1] = (byte) command;                 //Command
57      data[2] = (byte) 0;                       //Reserved byte
58      data[3] = (byte) addrType;                //Address type
59 
60      //Put Address
61      System.arraycopy(addr,0,data,4,addr.length);
62      //Put port
63      data[data.length-2] = (byte)(port>>8);
64      data[data.length-1] = (byte)(port);
65   }
66
67
68   /**
69    Construct client request or server response.
70    @param cmd - Request/Response code.
71    @param hostName  - IP field as hostName, uses ADDR_TYPE of HOSTNAME.
72    @paarm port - port field.
73   */
74   public Socks5Message(int cmd,String hostName,int port){
75      super(cmd,null,port);
76      this.host = hostName;
77      this.version = SOCKS_VERSION;
78
79      //System.out.println("Doing ATYP_DOMAINNAME");
80
81      addrType = SOCKS_ATYP_DOMAINNAME;
82      byte addr[] = hostName.getBytes();
83 
84      data =new byte[7+addr.length];
85      data[0] = (byte) SOCKS_VERSION;           //Version
86      data[1] = (byte) command;                 //Command
87      data[2] = (byte) 0;                       //Reserved byte
88      data[3] = (byte) SOCKS_ATYP_DOMAINNAME;   //Address type
89      data[4] = (byte) addr.length;             //Length of the address
90
91      //Put Address
92      System.arraycopy(addr,0,data,5,addr.length);
93      //Put port
94      data[data.length-2] = (byte)(port >>8);
95      data[data.length-1] = (byte)(port);
96   }
97
98   /**
99     Initialises Message from the stream. Reads server response from
100     given stream.
101     @param in Input stream to read response from.
102     @throws SocksException If server response code is not SOCKS_SUCCESS(0), or
103     if any error with protocol occurs.
104     @throws IOException If any error happens with I/O.
105   */
106   public Socks5Message(InputStream in) throws SocksException,
107                                              IOException{
108      this(in,true);
109   }
110
111   /**
112     Initialises Message from the stream. Reads server response or client
113     request from given stream.
114     
115     @param in Input stream to read response from.
116     @param clinetMode If true read server response, else read client request.
117     @throws SocksException If server response code is not SOCKS_SUCCESS(0) and
118     reading in client mode, or if any error with protocol occurs.
119     @throws IOException If any error happens with I/O.
120   */
121   public Socks5Message(InputStream in,boolean clientMode)throws SocksException,
122                                              IOException{
123      read(in,clientMode);
124   }
125
126
127   /**
128     Initialises Message from the stream. Reads server response from
129     given stream.
130     @param in Input stream to read response from.
131     @throws SocksException If server response code is not SOCKS_SUCCESS(0), or
132     if any error with protocol occurs.
133     @throws IOException If any error happens with I/O.
134   */
135   public void read(InputStream in) throws SocksException,
136                                           IOException{
137       read(in,true);
138   }
139
140
141   /**
142     Initialises Message from the stream. Reads server response or client
143     request from given stream.
144     
145     @param in Input stream to read response from.
146     @param clinetMode If true read server response, else read client request.
147     @throws SocksException If server response code is not SOCKS_SUCCESS(0) and
148     reading in client mode, or if any error with protocol occurs.
149     @throws IOException If any error happens with I/O.
150   */
151   public void read(InputStream in,boolean clientMode) throws SocksException,
152                                           IOException{
153      data = null;
154      ip = null;
155
156      DataInputStream di = new DataInputStream(in);
157
158      version = di.readUnsignedByte();
159      command = di.readUnsignedByte();
160      if(clientMode && command != 0)
161        throw new SocksException(command);
162
163      int reserved = di.readUnsignedByte();
164      addrType = di.readUnsignedByte();
165
166      byte addr[];
167
168      switch(addrType){
169         case SOCKS_ATYP_IPV4:
170            addr = new byte[4];
171            di.readFully(addr);
172            host = bytes2IPV4(addr,0);
173         break;
174         case SOCKS_ATYP_IPV6:
175           addr = new byte[SOCKS_IPV6_LENGTH];//I believe it is 16 bytes,huge!
176           di.readFully(addr);
177           host = bytes2IPV6(addr,0);
178         break;
179         case SOCKS_ATYP_DOMAINNAME:
180           //System.out.println("Reading ATYP_DOMAINNAME");
181           addr = new byte[di.readUnsignedByte()];//Next byte shows the length
182           di.readFully(addr);
183           host = new String(addr);
184         break;
185         default:
186            throw(new SocksException(Proxy.SOCKS_JUST_ERROR));
187      }
188
189      port = di.readUnsignedShort();
190
191      if(addrType != SOCKS_ATYP_DOMAINNAME && doResolveIP){
192         try{
193            ip = InetAddress.getByName(host);
194         }catch(UnknownHostException uh_ex){
195         }
196      }
197   }
198
199   /**
200    Writes the message to the stream.
201    @param out Output stream to which message should be written.
202   */
203   public void write(OutputStream out)throws SocksException,
204                                             IOException{
205     if(data == null){
206       Socks5Message msg;
207
208       if(addrType == SOCKS_ATYP_DOMAINNAME)
209          msg = new Socks5Message(command,host,port);
210       else{
211          if(ip == null){
212             try{
213               ip = InetAddress.getByName(host);
214             }catch(UnknownHostException uh_ex){
215               throw new SocksException(Proxy.SOCKS_JUST_ERROR);
216             }
217          }
218          msg = new Socks5Message(command,ip,port);
219       }
220       data = msg.data;
221     }
222     out.write(data);
223   }
224
225   /**
226    Returns IP field of the message as IP, if the message was created
227    with ATYP of HOSTNAME, it will attempt to resolve the hostname,
228    which might fail.
229    @throws UnknownHostException if host can't be resolved.
230   */
231   public InetAddress getInetAddress() throws UnknownHostException{
232     if(ip!=null) return ip;
233
234     return (ip=InetAddress.getByName(host));
235   }
236
237   /**
238     Returns string representation of the message.
239   */
240   public String toString(){
241      String s=
242        "Socks5Message:"+"\n"+
243        "VN   "+version+"\n"+
244        "CMD  "+command+"\n"+
245        "ATYP "+addrType+"\n"+
246        "ADDR "+host+"\n"+
247        "PORT "+port+"\n";
248      return s;
249   }
250           
251
252   /**
253    *Wether to resolve hostIP returned from SOCKS server
254    *that is wether to create InetAddress object from the
255    *hostName string
256    */
257   static public boolean resolveIP(){ return doResolveIP;}
258
259   /**
260    *Wether to resolve hostIP returned from SOCKS server
261    *that is wether to create InetAddress object from the
262    *hostName string
263    *@param doResolve Wether to resolve hostIP from SOCKS server.
264    *@return Previous value.
265    */
266   static public boolean resolveIP(boolean doResolve){
267      boolean old = doResolveIP;
268      doResolveIP = doResolve;
269      return old;
270   }
271
272   /*
273   private static final void debug(String s){
274      if(DEBUG)
275         System.out.print(s);
276   }
277   private static final boolean DEBUG = false;
278   */
279
280   //SOCKS5 constants
281   public static final int SOCKS_VERSION                =5;
282
283   public static final int SOCKS_ATYP_IPV4              =0x1; //Where is 2??
284   public static final int SOCKS_ATYP_DOMAINNAME        =0x3; //!!!!rfc1928
285   public static final int SOCKS_ATYP_IPV6              =0x4;
286
287   public static final int SOCKS_IPV6_LENGTH            =16;
288
289   static boolean doResolveIP = true;
290
291}
Note: See TracBrowser for help on using the repository browser.