From 21cec28549587db7e34d0ac455244fe4d73a0ed4 Mon Sep 17 00:00:00 2001 From: jestin Date: Tue, 1 Aug 2006 15:52:16 +0000 Subject: Changes to allow the creation of a tunnel between two (or more) ivy bussssseeeeezzzz --- src/Ghost.java | 39 +++++++++++++ src/Ivy.java | 92 +++++++++++++----------------- src/IvyClient.java | 4 +- src/IvyDaemon.java | 2 +- src/IvyWatcher.java | 3 +- src/Makefile | 2 +- src/ProxyClient.java | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/ProxyMaster.java | 140 ++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 379 insertions(+), 58 deletions(-) create mode 100644 src/Ghost.java create mode 100644 src/ProxyClient.java create mode 100644 src/ProxyMaster.java (limited to 'src') diff --git a/src/Ghost.java b/src/Ghost.java new file mode 100644 index 0000000..ad6e78c --- /dev/null +++ b/src/Ghost.java @@ -0,0 +1,39 @@ +/** + * the Ghost peers on the bus ( Proxy scheme ) + * + * @author Yannick Jestin + * @author http://www.tls.cena.fr/products/ivy/ + * + * CHANGELOG: + * 1.2.12 + */ +package fr.dgac.ivy ; +import java.io.*; +import java.net.*; +import java.util.*; +import org.apache.regexp.*; + +class Ghost extends IvyClient { + + private String id; // given to the Proxy by the Master + private ProxyClient pc; + + Ghost(Ivy bus, Socket socket,int remotePort,boolean incoming,String id,ProxyClient pc) throws IOException { + super(bus,socket,remotePort,incoming); + this.id=id; + this.pc=pc; + } + + protected synchronized void sendBuffer( String buffer ) throws IvyException { + System.out.println("out buffer: "+buffer); + pc.forward(id,buffer); + super.sendBuffer(buffer); + } + + protected boolean newParseMsg(String s) throws IvyException { + System.out.println("in buffer: "+s); + pc.forward(id,buffer); + return super.newParseMsg(s); + } + +} diff --git a/src/Ivy.java b/src/Ivy.java index 7d26dff..2647434 100755 --- a/src/Ivy.java +++ b/src/Ivy.java @@ -13,6 +13,8 @@ * * * CHANGELOG: + * 1.2.12: + * - directMessage goes protected * 1.2.9: * - introducing setFilter() * - introducing IVYRANGE in to allow the bus service socket to start on a @@ -647,14 +649,14 @@ public class Ivy implements Runnable { } /* invokes the direct message callbacks */ - public void directMessage( IvyClient client, int id,String msgarg ){ + protected void directMessage( IvyClient client, int id,String msgarg ){ for ( int i = 0 ; i < ivyApplicationListenerList.size(); i++ ) { ((IvyApplicationListener)ivyApplicationListenerList.elementAt(i)).directMessage(client,id, msgarg); } } /** - * gives the IvyClient() at a given instant + * gives the (Vectored) list of IvyClient at a given instant */ public Vector getIvyClients() { Vector v=new Vector(); @@ -670,7 +672,7 @@ public class Ivy implements Runnable { } /** - * gives a list of IvyClient(s) with the name given in parameter + * gives a list of IvyClient with the name given in parameter * * @param name The name of the Ivy agent you're looking for */ @@ -689,32 +691,7 @@ public class Ivy implements Runnable { return v; } - /////////////////////////////////////////////////////////////////: - // - // Protected methods - // - /////////////////////////////////////////////////////////////////: - private static String[] myTokenize(String s,String separator) { - int index=0, last=0, length=s.length(); - Vector v = new Vector(); - if (length!=0) while (true) { - index=s.indexOf(separator,last); - if (index==-1) { - v.addElement(s.substring(last,length)); - break; - } else if (indexhttp://www.tls.cena.fr/products/ivy/ + * + * (c) ENAC + * + * changelog: + * 1.2.12 + */ +package fr.dgac.ivy ; +import java.io.*; +import java.net.*; +import java.util.* ; +import gnu.getopt.Getopt; +import org.apache.regexp.*; + +public class ProxyClient extends Ivy { + + private Socket clientSocket; + private PrintWriter out; + private BufferedReader in; + private boolean isRunning=false; + private static boolean debug = (System.getProperty("IVY_DEBUG")!=null) ; + private volatile Thread clientThread;// volatile to ensure the quick communication + private Hashtable id=new Hashtable(); + private Vector ghosts = new Vector(); + + public static int DEFAULT_SERVICE_PORT = 3456 ; + public static final String DEFAULTNAME = "ProxyClient"; + public static final String helpmsg = "usage: java fr.dgac.ivy.ProxyClient [options] hostname\n\t-b BUS\tspecifies the Ivy bus domain\n\t-p\tport number, default "+DEFAULT_SERVICE_PORT+"\n\t-n ivyname (default "+DEFAULTNAME+")\n\t-q\tquiet, no tty output\n\t-d\tdebug\n\t-h\thelp\ncontacts the ProxyMaster on hostname\n"; + + private static String name = DEFAULTNAME; + public static void main(String[] args) { + Ivy bus; + Getopt opt = new Getopt("ProxyClient",args,"n:b:dqp:h"); + int c; + int servicePort = DEFAULT_SERVICE_PORT; + boolean quiet = false; + String domain=Ivy.getDomain(null); + while ((c = opt.getopt()) != -1) switch (c) { + case 'n': + name=opt.getOptarg(); + break; + case 'b': + domain=opt.getOptarg(); + break; + case 'q': + quiet=true; + break; + case 'd': + Properties sysProp = System.getProperties(); + sysProp.put("IVY_DEBUG","yes"); + break; + case 'p': + String s=""; + try { + servicePort = Integer.parseInt(s=opt.getOptarg()); + } catch (NumberFormatException nfe) { + System.out.println("Invalid port number: " + s ); + System.exit(0); + } + break; + case 'h': + default: + System.out.println(helpmsg); + System.exit(0); + } + String hostname="localhost"; + try { + ProxyClient pc = new ProxyClient(hostname,servicePort); + if (!quiet) System.out.println("broadcasting on "+pc.domains(domain)); + if (!quiet) System.out.println("contacting tcp:"+hostname+":"+servicePort); + pc.start(domain); + System.out.println("client running..."); + } catch (IvyException ie) { + System.out.println("error, can't connect to Ivy"); + ie.printStackTrace(); + System.exit(-1); + } catch (IOException ioe) { + System.out.println("error, can't connect to the proxy master"); + ioe.printStackTrace(); + System.exit(-1); + } + } + + public ProxyClient(String hostname,int servicePort) throws IOException { + super(name,name+" ready",null); + clientSocket = new Socket(hostname,servicePort) ; + in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); + out = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream())); + clientThread=new Thread(new Servicer()); + clientThread.start(); + } + + RE getId=new RE("^ID id=(.*) value=(.*)"); + RE fwd=new RE("^Forward id=(.*) buffer=(.*)"); + void parseMsg(String msg) { + System.out.println("parsing "+msg); + if (getId.match(msg)) { + id.put(getId.getParen(1),getId.getParen(2)); + } else if (fwd.match(msg)) { + // received a forward request + // TODO give it to the puppet + } else { + System.out.println("unknown message "+msg); + } + } + + class Servicer implements Runnable { + public void run() { + Thread thisThread = Thread.currentThread(); + traceDebug("Thread started"); + String msg = null; + try { + while (true) { + msg=in.readLine(); + if (msg==null) break; + parseMsg(msg); + } + } catch (IOException ioe) { + traceDebug("Subreader exception ..."); + ioe.printStackTrace(); + System.exit(0); + } + traceDebug("Subreader Thread stopped"); + System.out.println("ProxyClient disconnected"); + } + } + + protected IvyClient createIvyClient(Socket s,int port, boolean domachin) throws IOException { + String key = getWBUId(); + System.out.println("asking for a key"); + out.println("GetID id="+key); // asks a centralized ID from ProxyMaster + out.flush(); + try { // waits for the answer + while (id.get(key)==null) { Thread.sleep(200); } + } catch (InterruptedException ie) { + ie.printStackTrace(); + } + System.out.println("key received"); + return new Ghost(this,s,port,domachin,(String)id.get(key),this); + } + + private void forward(String id,String buffer) { + out.println("Forward id="+id+" buffer="+buffer); + out.flush(); + } + + private static void traceDebug(String s){ + if (debug) System.out.println("-->ProxyClient "+name+"<-- "+s); + } + +} diff --git a/src/ProxyMaster.java b/src/ProxyMaster.java new file mode 100644 index 0000000..7ed9460 --- /dev/null +++ b/src/ProxyMaster.java @@ -0,0 +1,140 @@ +/** + * ProxyMaster: Ivy relay, first attempt + * + * @author Yannick Jestin + * @author http://www.tls.cena.fr/products/ivy/ + * + * (c) ENAC + * + * changelog: + * 1.2.12 + */ +package fr.dgac.ivy ; +import java.io.*; +import java.net.*; +import java.util.* ; +import gnu.getopt.Getopt; +import org.apache.regexp.*; + +public class ProxyMaster { + + private ServerSocket serviceSocket; + private boolean isRunning=false; + private static boolean debug=false; + private Vector proxyClients = new Vector(); + private static int serial=0; + + public static int DEFAULT_SERVICE_PORT = 3456 ; + public static final String DEFAULTNAME = "ProxyMaster"; + public static final String helpmsg = "usage: java fr.dgac.ivy.ProxyMaster [options]\n\t-p\tport number, default "+DEFAULT_SERVICE_PORT+"\n\t-q\tquiet, no tty output\n\t-d\tdebug\n\t-h\thelp\nListens on the TCP port for ProxyClients to join.\n"; + + private static String name = DEFAULTNAME; + public static void main(String[] args) { + Ivy bus; + Getopt opt = new Getopt("ProxyMaster",args,"dqp:h"); + int c; + int servicePort = DEFAULT_SERVICE_PORT; + boolean quiet = false; + while ((c = opt.getopt()) != -1) switch (c) { + case 'q': + quiet=true; + break; + case 'd': + Properties sysProp = System.getProperties(); + sysProp.put("IVY_DEBUG","yes"); + break; + case 'p': + String s=""; + try { + servicePort = Integer.parseInt(s=opt.getOptarg()); + } catch (NumberFormatException nfe) { + System.out.println("Invalid port number: " + s ); + System.exit(0); + } + break; + case 'h': + default: + System.out.println(helpmsg); + System.exit(0); + } + try { + if (!quiet) System.out.println("listening on "+servicePort); + ProxyMaster pm = new ProxyMaster(servicePort); + } catch (IOException ioe) { + System.out.println("error, can't set up the proxy master"); + ioe.printStackTrace(); + System.exit(-1); + } + } + + public ProxyMaster(int servicePort) throws IOException { + serviceSocket = new ServerSocket(servicePort) ; + while ( true ) { + try { + new SubReader(serviceSocket.accept()); + } catch( IOException e ) { + traceDebug("TCP socket reader caught an exception " + e.getMessage()); + } + } + } + + class SubReader extends Thread { + BufferedReader in; + PrintWriter out; + SubReader(Socket socket) throws IOException { + proxyClients.addElement(this); + System.out.println("ProxyClient connected"); + in=new BufferedReader(new InputStreamReader(socket.getInputStream())); + out=new PrintWriter(new OutputStreamWriter(socket.getOutputStream())); + start(); + } + public void send(String s) { + out.println(s); + out.flush(); + } + public void run() { + traceDebug("Subreader Thread started"); + String msg = null; + try { + while (true) { + msg=in.readLine(); + if (msg==null) break; + parseMsg(msg); + } + } catch (IOException ioe) { + traceDebug("Subreader exception ..."); + ioe.printStackTrace(); + System.exit(0); + } + traceDebug("Subreader Thread stopped"); + System.out.println("ProxyClient disconnected"); + proxyClients.removeElement(this); + } + + RE getId=new RE("^GetID id=(.*)"); + RE fwd=new RE("^Forward id=(.*) buffer=(.*)"); + void parseMsg(String msg) { + System.out.println("parsing "+msg); + if (getId.match(msg)) { + // a new Ghost has appeared + System.out.println("a new Ghost has appeared"); + int newGhostId = serial++; + out.println("ID id="+getId.getParen(1)+" value="+newGhostId); + out.flush(); + // TODO create Puppets in each other ProxyClient + for (Enumeration e=proxyClients.elements();e.hasMoreElements();) + ((SubReader)e.nextElement()).send("CreatePuppet id="+newGhostId); + } else if (fwd.match(msg)) { + System.out.println("forwarding "+msg); + // TODO forward the message to all relevant puppets + } else { + System.out.println("error unknown message "+msg); + } + } + } // class SubReader + + private static void traceDebug(String s){ + if (debug) System.out.println("-->ProxyMaster "+name+"<-- "+s); + } + +} -- cgit v1.1