diff src/net/sourceforge/jsocks/SocksServerSocket.java @ 0:0ce5cc452d02

initial version
author Carl Byington <carl@five-ten-sg.com>
date Thu, 22 May 2014 10:41:19 -0700
parents
children 205ee2873330
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/net/sourceforge/jsocks/SocksServerSocket.java	Thu May 22 10:41:19 2014 -0700
@@ -0,0 +1,170 @@
+package net.sourceforge.jsocks;
+
+import java.net.*;
+import java.io.*;
+
+/**
+   SocksServerSocket allows to accept connections from one particular
+   host through the SOCKS4 or SOCKS5 proxy.
+*/
+public class SocksServerSocket extends ServerSocket {
+    //Data members
+    protected Proxy proxy;
+    protected String localHost;
+    protected InetAddress localIP;
+    protected int localPort;
+
+    boolean doing_direct = false;
+    InetAddress  remoteAddr;
+
+    /**
+     *Creates ServerSocket capable of accepting one connection
+     *through the firewall, uses given proxy.
+     *@param host Host from which the connection should be recieved.
+     *@param port Port number of the primary connection.
+     */
+    public SocksServerSocket(String host, int port) throws SocksException,
+        UnknownHostException, IOException {
+        super(0);
+        remoteAddr = InetAddress.getByName(host);
+        doDirect();
+    }
+
+    /**
+     * Creates ServerSocket capable of accepting one connection
+     * through the firewall, uses default Proxy.
+     *@param ip Host from which the connection should be recieved.
+     *@param port Port number of the primary connection.
+     */
+    public SocksServerSocket(InetAddress ip, int port) throws SocksException,
+        IOException {
+        this(Proxy.defaultProxy, ip, port);
+    }
+
+    /**
+     *Creates ServerSocket capable of accepting one connection
+     *through the firewall, uses given proxy.
+     *@param ip   Host from which the connection should be recieved.
+     *@param port Port number of the primary connection.
+     */
+    public SocksServerSocket(Proxy p, InetAddress ip, int port)
+    throws SocksException, IOException {
+        super(0);
+        remoteAddr = ip;
+        doDirect();
+    }
+
+
+    /**
+     * Accepts the incoming connection.
+     */
+    public Socket accept() throws IOException {
+        Socket s;
+
+        if (!doing_direct) {
+            if (proxy == null) return null;
+
+            ProxyMessage msg = proxy.accept();
+            s = msg.ip == null ? new SocksSocket(msg.host, msg.port, proxy)
+                : new SocksSocket(msg.ip, msg.port, proxy);
+            //Set timeout back to 0
+            proxy.proxySocket.setSoTimeout(0);
+        }
+        else { //Direct Connection
+
+            //Mimic the proxy behaviour,
+            //only accept connections from the speciefed host.
+            while (true) {
+                s = super.accept();
+
+                if (s.getInetAddress().equals(remoteAddr)) {
+                    //got the connection from the right host
+                    //Close listenning socket.
+                    break;
+                }
+                else
+                    s.close(); //Drop all connections from other hosts
+            }
+        }
+
+        proxy = null;
+        //Return accepted socket
+        return s;
+    }
+
+    /**
+     * Closes the connection to proxy if socket have not been accepted, if
+     * the direct connection is used, closes direct ServerSocket. If the
+     * client socket have been allready accepted, does nothing.
+     */
+    public void close() throws IOException {
+        super.close();
+
+        if (proxy != null) proxy.endSession();
+
+        proxy = null;
+    }
+
+    /**
+      Get the name of the host proxy is using to listen for incoming
+      connection.
+      <P>
+      Usefull when address is returned by proxy as the hostname.
+      @return the hostname of the address proxy is using to listen
+      for incoming connection.
+     */
+    public String getHost() {
+        return localHost;
+    }
+
+    /**
+     * Get address assigned by proxy to listen for incomming
+     * connections, or the local machine address if doing direct
+     * connection.
+     */
+    public InetAddress getInetAddress() {
+        if (localIP == null) {
+            try {
+                localIP = InetAddress.getByName(localHost);
+            }
+            catch (UnknownHostException e) {
+                return null;
+            }
+        }
+
+        return localIP;
+    }
+
+    /**
+     *  Get port assigned by proxy to listen for incoming connections, or
+        the port chosen by local system, if accepting directly.
+     */
+    public int getLocalPort() {
+        return localPort;
+    }
+
+    /**
+     Set Timeout.
+
+     @param timeout Amount of time in milliseconds, accept should wait for
+                    incoming connection before failing with exception.
+                    Zero timeout implies infinity.
+    */
+    public void setSoTimeout(int timeout) throws SocketException {
+        super.setSoTimeout(timeout);
+
+        if (!doing_direct) proxy.proxySocket.setSoTimeout(timeout);
+    }
+
+
+//Private Methods
+//////////////////
+
+    private void doDirect() {
+        doing_direct = true;
+        localPort = super.getLocalPort();
+        localIP = super.getInetAddress();
+        localHost = localIP.getHostName();
+    }
+
+}