package net.sf.T0rlib4j.controller.network; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; public class TCPForwardServer { protected int SOURCE_PORT; protected String DESTINATION_HOST; protected int DESTINATION_PORT; public TCPForwardServer(int SOURCE_PORT, String DESTINATION_HOST, int DESTINATION_PORT) throws IOException { this.SOURCE_PORT = SOURCE_PORT; this.DESTINATION_HOST = DESTINATION_HOST; this.DESTINATION_PORT = DESTINATION_PORT; ServerSocket serverSocket = new ServerSocket(DESTINATION_PORT); while (true) { Socket clientSocket = serverSocket.accept(); System.out.println("client Accepted with "+clientSocket.getRemoteSocketAddress()); ClientThread clientThread = new ClientThread(clientSocket, DESTINATION_HOST, SOURCE_PORT); clientThread.start(); } } } class ClientThread extends Thread { private Socket mClientSocket; private Socket mServerSocket; protected String DESTINATION_HOST; protected int DESTINATION_PORT; private boolean mForwardingActive = false; public ClientThread(Socket aClientSocket, String DESTINATION_HOST, int DESTINATION_PORT) { mClientSocket = aClientSocket; this.DESTINATION_HOST = DESTINATION_HOST; this.DESTINATION_PORT = DESTINATION_PORT; } public void run() { InputStream clientIn; OutputStream clientOut; InputStream serverIn; OutputStream serverOut; try { // Connect to the destination server mServerSocket = new Socket( DESTINATION_HOST, DESTINATION_PORT); // Turn on keep-alive for both the sockets mServerSocket.setKeepAlive(true); mClientSocket.setKeepAlive(true); // Obtain client & server input & output streams clientIn = mClientSocket.getInputStream(); clientOut = mClientSocket.getOutputStream(); serverIn = mServerSocket.getInputStream(); serverOut = mServerSocket.getOutputStream(); } catch (IOException ioe) { System.err.println("Can not connect to " + DESTINATION_HOST + ":" + DESTINATION_PORT); connectionBroken(); return; } // Start forwarding data between server and client mForwardingActive = true; ForwardThread clientForward = new ForwardThread(this, clientIn, serverOut); clientForward.start(); ForwardThread serverForward = new ForwardThread(this, serverIn, clientOut); serverForward.start(); System.out.println("TCP Forwarding " + mClientSocket.getInetAddress().getHostAddress() + ":" + mClientSocket.getPort() + " <--> " + mServerSocket.getInetAddress().getHostAddress() + ":" + mServerSocket.getPort() + " started."); } public synchronized void connectionBroken() { try { mServerSocket.close(); } catch (Exception e) { } try { mClientSocket.close(); } catch (Exception e) { } if (mForwardingActive) { System.out.println("TCP Forwarding " + mClientSocket.getInetAddress().getHostAddress() + ":" + mClientSocket.getPort() + " <--> " + mServerSocket.getInetAddress().getHostAddress() + ":" + mServerSocket.getPort() + " stopped."); mForwardingActive = false; } } } class ForwardThread extends Thread { private static final int BUFFER_SIZE = 8192; InputStream mInputStream; OutputStream mOutputStream; ClientThread mParent; public ForwardThread(ClientThread aParent, InputStream aInputStream, OutputStream aOutputStream) { mParent = aParent; mInputStream = aInputStream; mOutputStream = aOutputStream; } public void run() { byte[] buffer = new byte[BUFFER_SIZE]; try { while (true) { int bytesRead = mInputStream.read(buffer); if (bytesRead == -1) break; // End of stream is reached --> exit mOutputStream.write(buffer, 0, bytesRead); mOutputStream.flush(); } } catch (IOException e) { // Read/write failed --> connection is broken } // Notify parent thread that the connection is broken mParent.connectionBroken(); } }