From: erik Date: Thu, 16 Mar 2006 18:59:11 +0000 (+0000) Subject: (no commit message) X-Git-Tag: BEFORE_MAVEN_MIGRATION~215 X-Git-Url: http://wamblee.org/gitweb/?a=commitdiff_plain;h=658e27f9556fff0b7417faa8bd29b539e3c8524c;p=utils --- diff --git a/socketproxy/build.xml b/socketproxy/build.xml new file mode 100644 index 00000000..ec298d33 --- /dev/null +++ b/socketproxy/build.xml @@ -0,0 +1,32 @@ + + + + +]> + + + + + + + + + + + &header; + + + + + + + + + &trailer; + + + diff --git a/socketproxy/src/org/wamblee/socketproxy/Barrier.java b/socketproxy/src/org/wamblee/socketproxy/Barrier.java new file mode 100644 index 00000000..e8f9f814 --- /dev/null +++ b/socketproxy/src/org/wamblee/socketproxy/Barrier.java @@ -0,0 +1,36 @@ +package org.wamblee.socketproxy; + +/** + * Copyright (c) 2005 UPS_SCS NL + * + */ + +public class Barrier { + + private int _countLeft; + + public Barrier( int aCount ) { + _countLeft = aCount; + } + + public synchronized void block( ) { + _countLeft--; + if ( _countLeft < 0 ) { + throw new IllegalStateException( + "Barrier count became negative, programming error" ); + } + notifyAll( ); + while ( _countLeft > 0 ) { + waitUninterruptable( ); + } + } + + private void waitUninterruptable( ) { + try { + wait( ); + } catch ( InterruptedException e ) { + // ignore. + } + } + +} diff --git a/socketproxy/src/org/wamblee/socketproxy/ForwarderThread.java b/socketproxy/src/org/wamblee/socketproxy/ForwarderThread.java new file mode 100644 index 00000000..53988b1f --- /dev/null +++ b/socketproxy/src/org/wamblee/socketproxy/ForwarderThread.java @@ -0,0 +1,86 @@ +package org.wamblee.socketproxy; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Forwarder thread which handles forwarding of an input stream to + * an output stream. + */ + +public class ForwarderThread extends Thread { + + private String _prefix; + + private Barrier _barrier; + + private InputStream _is; + + private OutputStream _os; + + /** + * Constructs the forwarder thread. + * @param aPrefix Prefix to use in the output. + * @param aBarrier Barrier to block on before actually closing the stream. + * This is done to make sure that connections are only closed in th e + * proxy when the forwarders in both directions are ready to close. + * @param aIs Input stream to read from. + * @param aOs Output stream to forward to. + */ + public ForwarderThread( String aPrefix, Barrier aBarrier, + InputStream aIs, OutputStream aOs ) { + _prefix = aPrefix; + _is = aIs; + _os = aOs; + _barrier = aBarrier; + } + + public void run( ) { + boolean firstChar = true; + try { + int c = _is.read( ); + while ( c > 0 ) { + try { + _os.write( c ); + _os.flush( ); + if ( firstChar ) { + System.out.print( _prefix ); + firstChar = false; + } + System.out.print( (char) c ); + if ( c == '\n' ) { + firstChar = true; + } + } catch ( IOException e ) { + } + + c = _is.read( ); + } + } catch ( IOException e ) { + } + closeStreams(); + } + + /** + * @param is + * @param os + */ + private void closeStreams( ) { + _barrier.block( ); // wait until the other forwarder for the other direction + // is also closed. + try { + _is.close( ); + } catch ( IOException e1 ) { + // Empty. + } + try { + _os.flush( ); + _os.close( ); + } catch ( IOException e1 ) { + // Empty + } + System.out.println(_prefix + " closed"); + } + +} diff --git a/socketproxy/src/org/wamblee/socketproxy/SocketProxy.java b/socketproxy/src/org/wamblee/socketproxy/SocketProxy.java new file mode 100644 index 00000000..25d350fd --- /dev/null +++ b/socketproxy/src/org/wamblee/socketproxy/SocketProxy.java @@ -0,0 +1,101 @@ +package org.wamblee.socketproxy; + +/* + * Created on Apr 5, 2005 + */ + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.ServerSocket; +import java.net.Socket; + +/** + * @author erik + * + * TODO To change the template for this generated type comment go to Window - + * Preferences - Java - Code Style - Code Templates + */ +public class SocketProxy { + + public static void main( final String[] args ) throws IOException { + for ( int i = 0; i < args.length; i++ ) { + // System.out.println(i + " " + args[i]); + String[] fields = args[i].split( ":" ); + final int localPort = Integer.parseInt( fields[0] ); + final String host = fields[1]; + final int remotePort = Integer.parseInt( fields[2] ); + runSocketProxy( localPort, host, remotePort ); + } + } + + /** + * @param localPort + * @param host + * @param remotePort + */ + private static void runSocketProxy( final int localPort, + final String host, final int remotePort ) { + new Thread( new Runnable( ) { + public void run( ) { + try { + new SocketProxy( localPort, host, remotePort ); + } catch ( IOException e ) { + System.out.println( "Problem with socket " + localPort + + ":" + host + ":" + remotePort ); + e.printStackTrace( ); + } + } + } ).start( ); + } + + public SocketProxy( int localPort, String remoteHost, int remotePort ) + throws IOException { + System.out.println( "Listening on port " + localPort ); + ServerSocket server = new ServerSocket( localPort ); + for ( ;; ) { + Socket socket = server.accept( ); + System.out.println( "Got local connection on port " + + localPort ); + InputStream localIs = socket.getInputStream( ); + OutputStream localOs = socket.getOutputStream( ); + Socket clientSocket = new Socket( remoteHost, remotePort ); + final String description = "Port forwarding: " + localPort + + " -> " + remoteHost + ":" + remotePort; + System.out.println( description + " established." ); + InputStream serverIs = clientSocket.getInputStream( ); + OutputStream serverOs = clientSocket.getOutputStream( ); + Barrier barrier = new Barrier(2); + final Thread t1 = runForwarder( barrier, "> ", localIs, serverOs ); + final Thread t2 = runForwarder( barrier, "< ", serverIs, localOs ); + waitForConnectionClose( description, t1, t2 ); + } + } + + /** + * @param description + * @param t1 + * @param t2 + */ + private void waitForConnectionClose( final String description, + final Thread t1, final Thread t2 ) { + new Thread( new Runnable( ) { + public void run( ) { + try { + t1.join( ); + t2.join( ); + } catch ( InterruptedException e ) { + e.printStackTrace( ); + } + System.out.println( description + " closed" ); + } + } ).start( ); + } + + private Thread runForwarder( final Barrier barrier, final String prefix, + final InputStream is, final OutputStream os ) { + Thread t = new ForwarderThread(prefix, barrier, is, os); + t.start( ); + return t; + } +}