KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > socks > Socks5Message


1 package socks;
2
3 import java.io.IOException JavaDoc;
4 import java.io.InputStream JavaDoc;
5 import java.io.OutputStream JavaDoc;
6 import java.io.DataInputStream JavaDoc;
7 import java.net.InetAddress JavaDoc;
8 import java.net.UnknownHostException JavaDoc;
9
10 /**
11  SOCKS5 request/response message.
12 */

13
14 class 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 JavaDoc 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 JavaDoc 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 JavaDoc in) throws SocksException,
107                                               IOException JavaDoc{
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 JavaDoc in,boolean clientMode)throws SocksException,
122                                               IOException JavaDoc{
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 JavaDoc in) throws SocksException,
136                                            IOException JavaDoc{
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 JavaDoc in,boolean clientMode) throws SocksException,
152                                            IOException JavaDoc{
153       data = null;
154       ip = null;
155
156       DataInputStream JavaDoc di = new DataInputStream JavaDoc(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 JavaDoc(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 JavaDoc 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 JavaDoc out)throws SocksException,
204                                              IOException JavaDoc{
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 JavaDoc 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 JavaDoc getInetAddress() throws UnknownHostException JavaDoc{
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 JavaDoc toString(){
241       String JavaDoc 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 }
292
Popular Tags