diff options
Diffstat (limited to 'src/IvyWatcher.java')
-rwxr-xr-x | src/IvyWatcher.java | 91 |
1 files changed, 59 insertions, 32 deletions
diff --git a/src/IvyWatcher.java b/src/IvyWatcher.java index 98956ea..7698632 100755 --- a/src/IvyWatcher.java +++ b/src/IvyWatcher.java @@ -14,6 +14,17 @@ * thing. * * CHANGELOG: + * 1.2.5: + * - getDomain now sends IvyException for malformed broadcast addresses + * 1.2.4: + * - sends the broadcast before listening to the other's broadcasts. + * TODO wait for all the broadcast to be sent before starting the listen + * mode + * - (REMOVED) allows the connexion from a remote host with the same port number + * it's too complicated to know if the packet is from ourselves... + * - deals with the protocol errors in a more efficient way. The goal is not + * to loose our connectivity because of a rude agent. + * fixes Bug J005 (YJ + JPI) * 1.2.3: * - the packet sending is done in its own thread from now on (PacketSender) * I don't care stopping it, since it can't be blocked. @@ -51,6 +62,7 @@ class IvyWatcher implements Runnable { private boolean isMulticastAddress = false; private Ivy bus; /* master bus controler */ private DatagramSocket broadcast; /* supervision socket */ + private InetAddress localhost,loopback; private String domainaddr; private int port; private volatile Thread listenThread; @@ -75,6 +87,9 @@ class IvyWatcher implements Runnable { ((MulticastSocket)broadcast).joinGroup(group); } broadcast.setSoTimeout(Ivy.TIMEOUTLENGTH); + localhost=InetAddress.getLocalHost(); + loopback=InetAddress.getByName(null); + } catch ( UnknownHostException uhe ) { } catch ( IOException e ) { throw new IvyException("IvyWatcher I/O error" + e ); } @@ -89,9 +104,9 @@ class IvyWatcher implements Runnable { traceDebug("beginning of a watcher Thread"); byte buf[] = new byte[256]; DatagramPacket packet=new DatagramPacket(buf, 256); + InetAddress remotehost=null; try { while( listenThread==thisThread ) { - int port; try { broadcast.receive(packet); if (listenThread!=thisThread) break; // I was summoned to leave during the receive @@ -99,37 +114,43 @@ class IvyWatcher implements Runnable { for (int i=0;i<buf.length;i++) { buf[i]=10; } // clean up the buffer after each message // BUGFIX ? I change 0 to 10 in order to avoid a bug - InetAddress remotehost = packet.getAddress(); - traceDebug("BUSWATCHER Receive Broadcast from "+ remotehost.getHostName()+":"+packet.getPort()); + remotehost = packet.getAddress(); + traceDebug("BUSWATCHER Receive Broadcast from "+remotehost.getHostName()+":"+packet.getPort()); // TODO if ( !isInDomain( remotehost ) ) continue; - // TODO get rid of the StringTokenizer ? - StringTokenizer st = new StringTokenizer(msg); - if ( !st.hasMoreTokens()) { - System.err.println("Bad format "+msg); - continue; - } - int version = Integer.parseInt( st.nextToken() ); - if ( version != bus.PROCOCOLVERSION ) { - System.err.println("Ignoring bad protocol version broadcast"); - continue; - } - if ( ! st.hasMoreTokens()) { - System.err.println("Bad format "+msg); - continue; - } - port = Integer.parseInt( st.nextToken() ); - if ( (bus.applicationPort == port) ) continue; - traceDebug("BUSWATCHER Broadcast de " - +packet.getAddress().getHostName() - +":"+packet.getPort()+" port "+port+" version "+version); try { + RE re = new RE("([0-9]*) ([0-9]*)"); + REMatch result = re.getMatch(msg); + if (result==null) { + System.err.println("Ignoring bad format broadcast from "+remotehost); + continue; + } + int version = Integer.parseInt(result.toString(1)); + if ( version < bus.PROTOCOLMINIMUM ) { + System.err.println("Ignoring bad protocol version "+remotehost+" we need "+ bus.PROTOCOLMINIMUM+" minimum"); + continue; + } + int port = Integer.parseInt(result.toString(2)); + // allows the connexion from a remote host with the same port number + // if ( ( (remotehost.equals(localhost)) || (remotehost.equals(loopback)) ) + // && (bus.applicationPort==port)) { + if (bus.applicationPort==port) { + traceDebug("ignoring my own broadcast. OK"); + continue; // it's me + } + traceDebug("Broadcast de " +packet.getAddress().getHostName() + +":"+packet.getPort()+" port "+port+" version "+version); Socket socket = new Socket( remotehost, port ); - bus.addClient(socket,false); + bus.addClient(socket,false,version); + } catch (REException ree) { + ree.printStackTrace(); + System.exit(-1); + } catch (NumberFormatException nfe) { + System.err.println("Ignoring bad format broadcast from "+remotehost); + continue; } catch ( UnknownHostException e ) { System.err.println("Unkonwn host "+remotehost + e.getMessage()); } catch ( IOException e) { - System.err.println("can't connect to "+remotehost+" port "+ - port+e.getMessage()); + System.err.println("can't connect to "+remotehost+" port "+ port+e.getMessage()); } } catch (InterruptedIOException jii ){ if (thisThread!=listenThread) { break ;} @@ -184,9 +205,9 @@ class IvyWatcher implements Runnable { } synchronized void start() throws IvyException { - String hello = bus.PROCOCOLVERSION + " " + bus.applicationPort + "\n"; - listenThread.start(); + String hello = bus.PROTOCOLVERSION + " " + bus.applicationPort + "\n"; new PacketSender(hello); // notifies our arrival on each domain: protocol version + port + listenThread.start(); } /* @@ -209,18 +230,24 @@ class IvyWatcher implements Runnable { } */ - static String getDomain(String net) { + // TODO this is buggy :-\ try it on a named multicast address just to see + static String getDomain(String net) throws IvyException { + // System.out.println("debug: net=[" + net+ "]"); int sep_index = net.lastIndexOf( ":" ); if ( sep_index != -1 ) { net = net.substring(0,sep_index); } try { net += ".255.255.255"; RE exp = new RE( "^(\\d+\\.\\d+\\.\\d+\\.\\d+).*"); net = exp.substitute( net , "$1" ); + if (net==null) { + System.out.println("Bad broascat addr " + net); + throw new IvyException("bad broadcast addr"); + } } catch ( REException e ){ - System.out.println("Bad broascat addr " + net); - return null; + System.out.println(e); + System.exit(0); } - // System.out.println("net: "+net); + // System.out.println("debug: returning net=[" + net+ "]"); return net; } |