Mercurial > 510Connectbot
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(); + } + +}