Author: toad
Date: 2006-07-04 00:54:36 +0000 (Tue, 04 Jul 2006)
New Revision: 9461

Modified:
   trunk/freenet/src/freenet/node/Node.java
   trunk/freenet/src/freenet/node/PeerNode.java
   trunk/freenet/src/freenet/node/Version.java
Log:
856: Basic multi-homing support (does not support actual multi-homed machines; 
but we will sometimes include more than one IP from our various possible 
sources).

Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java    2006-07-03 23:37:40 UTC (rev 
9460)
+++ trunk/freenet/src/freenet/node/Node.java    2006-07-04 00:54:36 UTC (rev 
9461)
@@ -25,6 +25,8 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.TreeMap;
+import java.util.Vector;
 import java.util.zip.DeflaterOutputStream;

 import org.tanukisoftware.wrapper.WrapperManager;
@@ -156,20 +158,12 @@

                private ClientPutter inserter;
                private boolean shouldInsert;
-               private Peer lastInsertedAddress;
+               private Peer[] lastInsertedPeers;

                public void update() {
                        Logger.minor(this, "update()");
-                       if(lastIPAddress == null) {
-                               Logger.minor(this, "Not inserting because no IP 
address");
-                               return; // no point inserting
-                       }
-                       Peer p = new Peer(lastIPAddress, Node.this.portNumber);
-                       if(p.strictEquals(lastInsertedAddress)) {
-                               Logger.minor(this, "Not inserting ARK because 
"+p+" equals "+lastInsertedAddress);
-                               return;
-                       }
-                       Logger.minor(this, "Inserting ARK because "+p+" != 
"+lastInsertedAddress);
+                       if(!checkIPUpdated()) return;
+                       Logger.minor(this, "Inserting ARK because peers list 
changed");
                        synchronized(this) {
                                if(inserter != null) {
                                        // Already inserting.
@@ -187,6 +181,21 @@
                        }
                }

+               private boolean checkIPUpdated() {
+                       if(lastIPAddress == null) {
+                               Logger.minor(this, "Not inserting because no IP 
address");
+                               return true; // no point inserting
+                       }
+                       Peer[] p = getPrimaryIPAddress();
+                       if(lastInsertedPeers != null) {
+                               if(p.length != lastInsertedPeers.length) return 
true;
+                               for(int i=0;i<p.length;i++)
+                                       
if(!p[i].strictEquals(lastInsertedPeers[i]))
+                                               return true;
+                       }
+                       return false;
+               }
+
                private void startInserter() {

                        Logger.minor(this, "starting inserter");
@@ -223,10 +232,14 @@
                        try {
                                inserter.start();
                                if(fs.get("physical.udp") == null)
-                                       lastInsertedAddress = null;
+                                       lastInsertedPeers = null;
                                else {
                                        try {
-                                               lastInsertedAddress = new 
Peer(fs.get("physical.udp"), false);
+                                               String[] all = 
fs.getAll("physical.udp");
+                                               Peer[] peers = new 
Peer[all.length];
+                                               for(int i=0;i<all.length;i++)
+                                                       peers[i] = new 
Peer(all[i], false);
+                                               lastInsertedPeers = peers;
                                        } catch (PeerParseException e1) {
                                                Logger.error(this, "Error 
parsing own ref: "+e1+" : "+fs.get("physical.udp"), e1);
                                        } catch (UnknownHostException e1) {
@@ -259,7 +272,7 @@

                public void onFailure(InserterException e, BaseClientPutter 
state) {
                        Logger.minor(this, "ARK insert failed: "+e);
-                       lastInsertedAddress = null;
+                       lastInsertedPeers = null;
                        // :(
                        // Better try again
                        try {
@@ -285,8 +298,7 @@
                }

                public void onConnectedPeer() {
-                       Peer p = new Peer(Node.this.getPrimaryIPAddress(), 
Node.this.portNumber);
-                       if(p.equals(lastInsertedAddress)) return;
+                       if(!checkIPUpdated()) return;
                        synchronized(this) {
                                if(!shouldInsert) return;
                                if(inserter != null) {
@@ -660,11 +672,12 @@
                SimpleFieldSet fs = new SimpleFieldSet(br, true);
                br.close();
                // Read contents
-               String physical = fs.get("physical.udp");
-               if(physical != null) {
+               String[] udp = fs.getAll("physical.udp");
+               if(udp != null && udp.length > 0) {
+                       // Just keep the first one.
                        Peer myOldPeer;
                        try {
-                               myOldPeer = new Peer(physical, false);
+                               myOldPeer = new Peer(udp[0], false);
                        } catch (PeerParseException e) {
                                IOException e1 = new IOException();
                                e1.initCause(e);
@@ -2200,10 +2213,12 @@
         */
        public SimpleFieldSet exportPublicFieldSet() {
                SimpleFieldSet fs = new SimpleFieldSet(true);
-               FreenetInetAddress ip = getPrimaryIPAddress();
+               Peer[] ips = getPrimaryIPAddress();
                fs.put("base64", "true");
-               if(ip != null)
-                       fs.put("physical.udp", ip.toString()+":"+portNumber);
+               if(ips != null) {
+                       for(int i=0;i<ips.length;i++)
+                               fs.put("physical.udp", ips[i].toString());
+               }
                fs.put("identity", Base64.encode(myIdentity));
                fs.put("location", 
Double.toString(lm.getLocation().getValue()));
                fs.put("version", Version.getVersionString());
@@ -2225,7 +2240,7 @@
        /** IP address from last time */
        FreenetInetAddress oldIPAddress;
        /** Last detected IP address */
-       FreenetInetAddress lastIPAddress;
+       Peer[] lastIPAddress;

        /**
         * @return Our current main IP address.
@@ -2233,19 +2248,20 @@
         * detection properly with NetworkInterface, and we should use
         * third parties if available and UP&P if available.
         */
-       FreenetInetAddress detectPrimaryIPAddress() {
+       Peer[] detectPrimaryIPAddress() {
+               Vector addresses = new Vector();
                if(overrideIPAddress != null) {
-                       Logger.minor(this, "Returning overridden address: 
"+overrideIPAddress);
-                       lastIPAddress = overrideIPAddress;
-                       return overrideIPAddress;
+                       // If the IP is overridden, the override has to be the 
first element.
+                       addresses.add(new Peer(overrideIPAddress, portNumber));
                }
-               Logger.minor(this, "IP address not overridden");
-               InetAddress addr = ipDetector.getAddress();
-               if(addr != null) {
-                       FreenetInetAddress a = new FreenetInetAddress(addr);
-                       lastIPAddress = a;
-                       return a;
+               InetAddress detectedAddr = ipDetector.getAddress();
+               if(detectedAddr != null) {
+                       Peer a = new Peer(new FreenetInetAddress(detectedAddr), 
portNumber);
+                       if(!addresses.contains(a))
+                               addresses.add(a);
                }
+               if(detectedAddr == null && oldIPAddress != null && 
!oldIPAddress.equals(overrideIPAddress))
+                       addresses.add(new Peer(oldIPAddress, portNumber));
                // Try to pick it up from our connections
                if(peers != null) {
                        PeerNode[] peerList = peers.connectedPeers;
@@ -2258,47 +2274,56 @@
                                InetAddress ip = p.getAddress(true);
                                if(!IPUtil.checkAddress(ip)) continue;
                                if(countsByPeer.containsKey(ip)) {
-                                       Integer count = (Integer) 
countsByPeer.get(ip);
+                                       Integer count = (Integer) 
countsByPeer.get(p);
                                        Integer newCount = new 
Integer(count.intValue()+1);
-                                       countsByPeer.put(ip, newCount);
+                                       countsByPeer.put(p, newCount);
                                } else {
-                                       countsByPeer.put(ip, new Integer(1));
+                                       countsByPeer.put(p, new Integer(1));
                                }
                        }
                        if(countsByPeer.size() == 1) {
                                Iterator it = countsByPeer.keySet().iterator();
-                               FreenetInetAddress a = new 
FreenetInetAddress((InetAddress)(it.next()));
-                               lastIPAddress = a;
-                               return a;
+                               Peer p = (Peer) (it.next());
+                               if(!addresses.contains(p)) addresses.add(p);
                        } else if(countsByPeer.size() > 1) {
-                               Iterator it = countsByPeer.keySet().iterator();
-                               // Pick most popular address
-                               // FIXME use multi-homing here
-                               InetAddress best = null;
+                               Iterator it = countsByPeer.keySet().iterator();
+                               // Take two most popular addresses.
+                               Peer best = null;
+                               Peer secondBest = null;
                                int bestPopularity = 0;
+                               int secondBestPopularity = 0;
                                while(it.hasNext()) {
-                                       InetAddress cur = (InetAddress) 
it.next();
+                                       Peer cur = (Peer) (it.next());
                                        int curPop = ((Integer) 
(countsByPeer.get(cur))).intValue();
                                        if(curPop > bestPopularity) {
                                                bestPopularity = curPop;
+                                               secondBest = best;
                                                best = cur;
+                                               secondBestPopularity = 
bestPopularity;
                                        }
                                }
-                               lastIPAddress = best == null ? null : new 
FreenetInetAddress(best);
+                               if(best != null) {
+                                       if(bestPopularity > 2 || detectedAddr 
== null) {
+                                               if(!addresses.contains(best))
+                                                       addresses.add(best);
+                                               if(secondBest != null && 
secondBestPopularity > 2) {
+                                                       
if(!addresses.contains(secondBest))
+                                                               
addresses.add(secondBest);
+                                               }
+                                       }
+                               }
                        }
                }
-               if(lastIPAddress == null) {
-                       if(oldIPAddress != null) lastIPAddress = oldIPAddress;
-               }
-               if (lastIPAddress == null) {
+               if (addresses.isEmpty()) {
                        this.alerts.register(primaryIPUndetectedAlert);
                } else {
                        this.alerts.unregister(primaryIPUndetectedAlert);
                }
+               lastIPAddress = (Peer[]) addresses.toArray(new 
Peer[addresses.size()]);
                return lastIPAddress;
        }

-       FreenetInetAddress getPrimaryIPAddress() {
+       Peer[] getPrimaryIPAddress() {
                if(lastIPAddress == null) return detectPrimaryIPAddress();
                return lastIPAddress;
        }
@@ -2819,13 +2844,13 @@
                return sskInsertThrottle;
        }

-       FreenetInetAddress lastIP;
+       Peer[] lastIP;
        public BookmarkManager bookmarkManager;

        public void redetectAddress() {
-               FreenetInetAddress newIP = detectPrimaryIPAddress();
+               Peer[] newIP = detectPrimaryIPAddress();
+               if(Arrays.equals(newIP, lastIP)) return;
                shouldInsertARK();
-               if(newIP == null || newIP.equals(lastIP)) return;
                lastIP = newIP;
                writeNodeFile();
        }

Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java        2006-07-03 23:37:40 UTC 
(rev 9460)
+++ trunk/freenet/src/freenet/node/PeerNode.java        2006-07-04 00:54:36 UTC 
(rev 9461)
@@ -594,7 +594,8 @@

        // Hack for two nodes on the same IP that can't talk over inet for 
routing reasons
        FreenetInetAddress localhost = node.fLocalhostAddress;
-       FreenetInetAddress nodeAddr = node.getPrimaryIPAddress();
+       Peer[] nodePeers = node.getPrimaryIPAddress();
+//     FreenetInetAddress nodeAddr = node.getPrimaryIPAddress();

        Vector peers = new Vector(nominalPeer);

@@ -614,9 +615,12 @@
                        if(addedLocalhost) continue;
                        addedLocalhost = true;
                }
-               if(addr.equals(nodeAddr)) {
-                       if(!addedLocalhost)
-                               peers.add(new Peer(localhost, p.getPort()));
+               for(int j=0;j<nodePeers.length;j++) {
+                       if(nodePeers[j].getFreenetAddress().equals(addr)) {
+                               if(!addedLocalhost)
+                                       peers.add(new Peer(localhost, 
p.getPort()));
+                               addedLocalhost = true;
+                       }
                }
                if(peers.contains(p)) continue;
                peers.add(p);

Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2006-07-03 23:37:40 UTC (rev 
9460)
+++ trunk/freenet/src/freenet/node/Version.java 2006-07-04 00:54:36 UTC (rev 
9461)
@@ -18,7 +18,7 @@
        public static final String protocolVersion = "1.0";

        /** The build number of the current revision */
-       private static final int buildNumber = 855;
+       private static final int buildNumber = 856;

        /** Oldest build of Fred we will talk to */
        private static final int oldLastGoodBuild = 839;


Reply via email to