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