diff app/src/main/java/net/sourceforge/jsocks/Socks5Message.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/Socks5Message.java@2bc6805cbc91
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/main/java/net/sourceforge/jsocks/Socks5Message.java	Thu Dec 03 11:23:55 2015 -0800
@@ -0,0 +1,291 @@
+package net.sourceforge.jsocks;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.DataInputStream;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ SOCKS5 request/response message.
+*/
+
+public class Socks5Message extends ProxyMessage{
+   /** Address type of given message*/
+   public int addrType;
+
+   byte[] data;
+
+   /**
+    Server error response.
+    @param cmd Error code.
+   */
+   public Socks5Message(int cmd){
+      super(cmd,null,0);
+      data = new byte[3];
+      data[0] = SOCKS_VERSION; //Version.
+      data[1] = (byte)cmd;     //Reply code for some kind of failure.
+      data[2] = 0;             //Reserved byte.
+   }
+
+   /**
+    Construct client request or server response.
+    @param cmd - Request/Response code.
+    @param ip  - IP field.
+    @paarm port - port field.
+   */
+   public Socks5Message(int cmd,InetAddress ip,int port){
+      super(cmd,ip,port);
+      this.host = ip==null?"0.0.0.0":ip.getHostName();
+      this.version = SOCKS_VERSION;
+
+      byte[] addr;
+
+      if(ip == null){
+         addr = new byte[4];
+         addr[0]=addr[1]=addr[2]=addr[3]=0;
+      }else
+         addr = ip.getAddress();
+
+      addrType = addr.length == 4 ? SOCKS_ATYP_IPV4
+                                  : SOCKS_ATYP_IPV6;
+
+      data = new byte[6+addr.length];
+      data[0] = (byte) SOCKS_VERSION;		//Version
+      data[1] = (byte) command;			//Command
+      data[2] = (byte) 0;			//Reserved byte
+      data[3] = (byte) addrType;		//Address type
+
+      //Put Address
+      System.arraycopy(addr,0,data,4,addr.length);
+      //Put port
+      data[data.length-2] = (byte)(port>>8);
+      data[data.length-1] = (byte)(port);
+   }
+
+
+   /**
+    Construct client request or server response.
+    @param cmd - Request/Response code.
+    @param hostName  - IP field as hostName, uses ADDR_TYPE of HOSTNAME.
+    @paarm port - port field.
+   */
+   public Socks5Message(int cmd,String hostName,int port){
+      super(cmd,null,port);
+      this.host = hostName;
+      this.version = SOCKS_VERSION;
+
+      //System.out.println("Doing ATYP_DOMAINNAME");
+
+      addrType = SOCKS_ATYP_DOMAINNAME;
+      byte addr[] = hostName.getBytes();
+
+      data =new byte[7+addr.length];
+      data[0] = (byte) SOCKS_VERSION;		//Version
+      data[1] = (byte) command;			//Command
+      data[2] = (byte) 0;			//Reserved byte
+      data[3] = (byte) SOCKS_ATYP_DOMAINNAME;	//Address type
+      data[4] = (byte) addr.length;		//Length of the address
+
+      //Put Address
+      System.arraycopy(addr,0,data,5,addr.length);
+      //Put port
+      data[data.length-2] = (byte)(port >>8);
+      data[data.length-1] = (byte)(port);
+   }
+
+   /**
+     Initialises Message from the stream. Reads server response from
+     given stream.
+     @param in Input stream to read response from.
+     @throws SocksException If server response code is not SOCKS_SUCCESS(0), or
+     if any error with protocol occurs.
+     @throws IOException If any error happens with I/O.
+   */
+   public Socks5Message(InputStream in) throws SocksException,
+                                              IOException{
+      this(in,true);
+   }
+
+   /**
+     Initialises Message from the stream. Reads server response or client
+     request from given stream.
+
+     @param in Input stream to read response from.
+     @param clinetMode If true read server response, else read client request.
+     @throws SocksException If server response code is not SOCKS_SUCCESS(0) and
+     reading in client mode, or if any error with protocol occurs.
+     @throws IOException If any error happens with I/O.
+   */
+   public Socks5Message(InputStream in,boolean clientMode)throws SocksException,
+                                              IOException{
+      read(in,clientMode);
+   }
+
+
+   /**
+     Initialises Message from the stream. Reads server response from
+     given stream.
+     @param in Input stream to read response from.
+     @throws SocksException If server response code is not SOCKS_SUCCESS(0), or
+     if any error with protocol occurs.
+     @throws IOException If any error happens with I/O.
+   */
+   public void read(InputStream in) throws SocksException,
+                                           IOException{
+       read(in,true);
+   }
+
+
+   /**
+     Initialises Message from the stream. Reads server response or client
+     request from given stream.
+
+     @param in Input stream to read response from.
+     @param clinetMode If true read server response, else read client request.
+     @throws SocksException If server response code is not SOCKS_SUCCESS(0) and
+     reading in client mode, or if any error with protocol occurs.
+     @throws IOException If any error happens with I/O.
+   */
+   public void read(InputStream in,boolean clientMode) throws SocksException,
+                                           IOException{
+      data = null;
+      ip = null;
+
+      DataInputStream di = new DataInputStream(in);
+
+      version = di.readUnsignedByte();
+      command = di.readUnsignedByte();
+      if(clientMode && command != 0)
+        throw new SocksException(command);
+
+      int reserved = di.readUnsignedByte();
+      addrType = di.readUnsignedByte();
+
+      byte addr[];
+
+      switch(addrType){
+         case SOCKS_ATYP_IPV4:
+            addr = new byte[4];
+            di.readFully(addr);
+            host = bytes2IPV4(addr,0);
+         break;
+         case SOCKS_ATYP_IPV6:
+           addr = new byte[SOCKS_IPV6_LENGTH];//I believe it is 16 bytes,huge!
+           di.readFully(addr);
+           host = bytes2IPV6(addr,0);
+         break;
+         case SOCKS_ATYP_DOMAINNAME:
+           //System.out.println("Reading ATYP_DOMAINNAME");
+           addr = new byte[di.readUnsignedByte()];//Next byte shows the length
+           di.readFully(addr);
+           host = new String(addr);
+         break;
+         default:
+            throw(new SocksException(CProxy.SOCKS_JUST_ERROR));
+      }
+
+      port = di.readUnsignedShort();
+
+      if(addrType != SOCKS_ATYP_DOMAINNAME && doResolveIP){
+         try{
+            ip = InetAddress.getByName(host);
+         }catch(UnknownHostException uh_ex){
+         }
+      }
+   }
+
+   /**
+    Writes the message to the stream.
+    @param out Output stream to which message should be written.
+   */
+   public void write(OutputStream out)throws SocksException,
+                                             IOException{
+     if(data == null){
+       Socks5Message msg;
+
+       if(addrType == SOCKS_ATYP_DOMAINNAME)
+          msg = new Socks5Message(command,host,port);
+       else{
+          if(ip == null){
+             try{
+               ip = InetAddress.getByName(host);
+             }catch(UnknownHostException uh_ex){
+               throw new SocksException(CProxy.SOCKS_JUST_ERROR);
+             }
+          }
+          msg = new Socks5Message(command,ip,port);
+       }
+       data = msg.data;
+     }
+     out.write(data);
+   }
+
+   /**
+    Returns IP field of the message as IP, if the message was created
+    with ATYP of HOSTNAME, it will attempt to resolve the hostname,
+    which might fail.
+    @throws UnknownHostException if host can't be resolved.
+   */
+   public InetAddress getInetAddress() throws UnknownHostException{
+     if(ip!=null) return ip;
+
+     return (ip=InetAddress.getByName(host));
+   }
+
+   /**
+     Returns string representation of the message.
+   */
+   public String toString(){
+      String s=
+        "Socks5Message:"+"\n"+
+        "VN   "+version+"\n"+
+        "CMD  "+command+"\n"+
+        "ATYP "+addrType+"\n"+
+        "ADDR "+host+"\n"+
+        "PORT "+port+"\n";
+      return s;
+   }
+
+
+   /**
+    *Wether to resolve hostIP returned from SOCKS server
+    *that is wether to create InetAddress object from the
+    *hostName string
+    */
+   static public boolean resolveIP(){ return doResolveIP;}
+
+   /**
+    *Wether to resolve hostIP returned from SOCKS server
+    *that is wether to create InetAddress object from the
+    *hostName string
+    *@param doResolve Wether to resolve hostIP from SOCKS server.
+    *@return Previous value.
+    */
+   static public boolean resolveIP(boolean doResolve){
+      boolean old = doResolveIP;
+      doResolveIP = doResolve;
+      return old;
+   }
+
+   /*
+   private static final void debug(String s){
+      if(DEBUG)
+         System.out.print(s);
+   }
+   private static final boolean DEBUG = false;
+   */
+
+   //SOCKS5 constants
+   public static final int SOCKS_VERSION		=5;
+
+   public static final int SOCKS_ATYP_IPV4		=0x1; //Where is 2??
+   public static final int SOCKS_ATYP_DOMAINNAME	=0x3; //!!!!rfc1928
+   public static final int SOCKS_ATYP_IPV6		=0x4;
+
+   public static final int SOCKS_IPV6_LENGTH		=16;
+
+   static boolean doResolveIP = true;
+
+}