Author: zothar
Date: 2006-05-18 03:33:53 +0000 (Thu, 18 May 2006)
New Revision: 8754

Added:
   trunk/freenet/src/freenet/node/BuildOldAgeUserAlert.java
Modified:
   trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
   trunk/freenet/src/freenet/clients/http/staticfiles/themes/clean/theme.css
   trunk/freenet/src/freenet/node/Node.java
   trunk/freenet/src/freenet/node/PeerNode.java
   trunk/freenet/src/freenet/node/Version.java
Log:
Prepare for alerting the user when their build is older than the current 
lastGoodVersion advertised by their peers.  This commit should not change any 
behavior.

Modified: trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java       
2006-05-18 00:15:09 UTC (rev 8753)
+++ trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java       
2006-05-18 03:33:53 UTC (rev 8754)
@@ -100,12 +100,14 @@

                final Integer CONNECTED = new Integer(0);
                final Integer BACKED_OFF = new Integer(1);
-               final Integer INCOMPATIBLE = new Integer(2);
-               final Integer DISCONNECTED = new Integer(3);
+               final Integer TOO_NEW = new Integer(2);
+               final Integer INCOMPATIBLE = new Integer(3);
+               final Integer DISCONNECTED = new Integer(4);

                int numberOfConnected = 0;
                int numberOfBackedOff = 0;
                int numberOfIncompatible = 0;
+               int numberOfTooNew = 0;
                int numberOfDisconnected = 0;

                // Create array
@@ -129,6 +131,8 @@
                                if(routingBackedOffNow) {
                                        status = BACKED_OFF;
                                }
+                       } else if(pn.hasCompletedHandshake() && 
pn.isVerifiedIncompatibleNewerVersion()) {
+                               status = TOO_NEW;
                        } else if(pn.hasCompletedHandshake() && 
!Version.checkGoodVersion(pn.getVersion())) {
                                status = INCOMPATIBLE;
                        } else {
@@ -162,6 +166,10 @@
                                row[1] = "<span class=\"peer_backedoff\">BACKED 
OFF</span>";
                                numberOfBackedOff++;
                        }
+                       else if(x == TOO_NEW) {
+                               row[1] = "<span class=\"peer_too_new\">TOO 
NEW</span>";
+                               numberOfTooNew++;
+                       }
                        else if(x == INCOMPATIBLE) {
                                row[1] = "<span 
class=\"peer_incompatible\">INCOMPATIBLE</span>";
                                numberOfIncompatible++;
@@ -228,6 +236,12 @@
                                buf.append("<span 
class=\"peer_backedoff\">BACKED OFF: " + numberOfBackedOff + "</span>");
                                separatorNeeded = true;
                        }
+                       if (numberOfTooNew != 0) {
+                               if (separatorNeeded)
+                                       buf.append(" | ");
+                               buf.append("<span class=\"peer_too_new\">TOO 
NEW: " + numberOfTooNew + "</span>");
+                               separatorNeeded = true;
+                       }
                        if (numberOfIncompatible != 0) {
                                if (separatorNeeded)
                                        buf.append(" | ");

Modified: 
trunk/freenet/src/freenet/clients/http/staticfiles/themes/clean/theme.css
===================================================================
--- trunk/freenet/src/freenet/clients/http/staticfiles/themes/clean/theme.css   
2006-05-18 00:15:09 UTC (rev 8753)
+++ trunk/freenet/src/freenet/clients/http/staticfiles/themes/clean/theme.css   
2006-05-18 03:33:53 UTC (rev 8754)
@@ -270,6 +270,10 @@
        color: #ff0000;
 }

+table.darknet_connections span.peer_too_new {
+       color: #d0a0a0;
+}
+
 table.darknet_connections span.peer_incompatible {
        color: #d0a0d0;
 }

Added: trunk/freenet/src/freenet/node/BuildOldAgeUserAlert.java
===================================================================
--- trunk/freenet/src/freenet/node/BuildOldAgeUserAlert.java    2006-05-18 
00:15:09 UTC (rev 8753)
+++ trunk/freenet/src/freenet/node/BuildOldAgeUserAlert.java    2006-05-18 
03:33:53 UTC (rev 8754)
@@ -0,0 +1,39 @@
+package freenet.node;
+
+public class BuildOldAgeUserAlert implements UserAlert {
+       private boolean isValid=true;
+       int lastGoodVersion = 0;
+       
+       public boolean userCanDismiss() {
+               return false;
+       }
+
+       public String getTitle() {
+               return "Build too old";
+       }
+       
+       public String getText() {
+         if(lastGoodVersion == 0)
+                 throw new IllegalArgumentException("Not valid");
+               String s;
+               s = "This node's software is older than the oldest version 
(Build #"+lastGoodVersion+") allowed by the newest peers we " +
+                               "try to connect to.  Please update your node as 
soon as possible as you will not be " +
+                               "able to connect to peers labeled \"TOO NEW\" 
until you do.  " +
+                               "(Freenet may leave your node in the dust of 
the past if you don't upgrade.)";
+               return s;
+       }
+
+       public short getPriorityClass() {
+               return UserAlert.ERROR;
+       }
+
+       public boolean isValid() {
+         if(lastGoodVersion == 0)
+           return false;
+               return isValid;
+       }
+       
+       public void isValid(boolean b){
+               if(userCanDismiss()) isValid=b;
+       }
+}

Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java    2006-05-18 00:15:09 UTC (rev 
8753)
+++ trunk/freenet/src/freenet/node/Node.java    2006-05-18 03:33:53 UTC (rev 
8754)
@@ -297,6 +297,7 @@

        private static IPUndetectedUserAlert primaryIPUndetectedAlert;
        private static MeaningfulNodeNameUserAlert nodeNameUserAlert;
+       private static BuildOldAgeUserAlert buildOldAgeUserAlert;

        public class NodeNameCallback implements StringCallback{
                        Node node;
@@ -390,6 +391,8 @@
     public static final int RANDOMIZED_TIME_BETWEEN_HANDSHAKE_SENDS = 
HANDSHAKE_TIMEOUT;
     public static final int MIN_TIME_BETWEEN_VERSION_PROBES = 
HANDSHAKE_TIMEOUT*4;
     public static final int RANDOMIZED_TIME_BETWEEN_VERSION_PROBES = 
HANDSHAKE_TIMEOUT*2; // 20-30 secs
+    public static final int MIN_TIME_BETWEEN_VERSION_SENDS = 
HANDSHAKE_TIMEOUT*9;
+    public static final int RANDOMIZED_TIME_BETWEEN_VERSION_SENDS = 
HANDSHAKE_TIMEOUT*2; // 45-55 secs
     // If we don't receive any packets at all in this period, from any node, 
tell the user
     public static final long ALARM_TIME = 60*1000;
     /** Sub-max ping time. If ping is greater than this, we reject some 
requests. */
@@ -1072,6 +1075,8 @@

         usm.setDispatcher(dispatcher=new NodeDispatcher(this));
         usm.setLowLevelFilter(packetMangler = new FNPPacketMangler(this));
+        
+        buildOldAgeUserAlert = new BuildOldAgeUserAlert();

         // Temp files

@@ -2595,4 +2600,15 @@
        public String getBindTo(){
                return this.bindto;
        }
+       
+       public boolean setNewestPeerLastGoodVersion( int version ) {
+               if( version > buildOldAgeUserAlert.lastGoodVersion ) {
+                       if( buildOldAgeUserAlert.lastGoodVersion == 0 ) {
+                               alerts.register(buildOldAgeUserAlert);
+                       }
+                       buildOldAgeUserAlert.lastGoodVersion = version;
+                       return true;
+               }
+               return false;
+       }
 }

Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java        2006-05-18 00:15:09 UTC 
(rev 8753)
+++ trunk/freenet/src/freenet/node/PeerNode.java        2006-05-18 03:33:53 UTC 
(rev 8754)
@@ -63,6 +63,11 @@

        private String lastGoodVersion; 

+    /** Set to true based on a relevant incoming handshake from this peer
+        Set true if this peer has a incompatible newer build than we are
+     */
+       private boolean verifiedIncompatibleNewerVersion = false;
+       
     /** For debugging/testing, set this to true to stop the
      * probabilistic decrement at the edges of the HTLs.
      */
@@ -466,6 +471,14 @@
     }

     /**
+     * Is this node too new for us? (i.e. our version if older than it's 
lastGoodVersion)
+     * 
+     */
+    public boolean isVerifiedIncompatibleNewerVersion() {
+        return verifiedIncompatibleNewerVersion;
+    }
+    
+    /**
      * Is this node currently connected?
      * 
      * Note possible deadlocks! PeerManager calls this, we call
@@ -607,7 +620,12 @@
     public synchronized void sentHandshake() {
         Logger.debug(this, "sentHandshake(): "+this);
         long now = System.currentTimeMillis();
-        if(invalidVersion() && !firstHandshake) {
+        if(verifiedIncompatibleNewerVersion) { 
+            // Let them know we're here, but have no hope of connecting
+            sendHandshakeTime = now + Node.MIN_TIME_BETWEEN_VERSION_SENDS
+              + node.random.nextInt(Node.RANDOMIZED_TIME_BETWEEN_VERSION_SENDS)
+              + 
node.random.nextInt(Node.RANDOMIZED_TIME_BETWEEN_VERSION_SENDS);
+        } else if(invalidVersion() && !firstHandshake) {
             sendHandshakeTime = now + Node.MIN_TIME_BETWEEN_VERSION_PROBES
                + 
node.random.nextInt(Node.RANDOMIZED_TIME_BETWEEN_VERSION_PROBES);
         } else {
@@ -628,7 +646,12 @@
     public synchronized void couldNotSendHandshake() {
         Logger.minor(this, "couldNotSendHandshake(): "+this);
         long now = System.currentTimeMillis();
-        if(invalidVersion() && !firstHandshake) {
+        if(verifiedIncompatibleNewerVersion) {
+            // Let them know we're here, but have no hope of connecting
+            sendHandshakeTime = now + Node.MIN_TIME_BETWEEN_VERSION_SENDS
+              + node.random.nextInt(Node.RANDOMIZED_TIME_BETWEEN_VERSION_SENDS)
+              + 
node.random.nextInt(Node.RANDOMIZED_TIME_BETWEEN_VERSION_SENDS);
+        } else if(invalidVersion() && !firstHandshake) {
             sendHandshakeTime = now + Node.MIN_TIME_BETWEEN_VERSION_PROBES
               + 
node.random.nextInt(Node.RANDOMIZED_TIME_BETWEEN_VERSION_PROBES)
               + 
node.random.nextInt(Node.RANDOMIZED_TIME_BETWEEN_VERSION_PROBES);
@@ -943,6 +966,10 @@
     private synchronized boolean invalidVersion() {
         return bogusNoderef || (!Version.checkGoodVersion(version));
     }
+    
+    private synchronized boolean reverseInvalidVersion() {
+        return bogusNoderef || 
(!Version.checkArbitraryGoodVersion(Version.getVersionString(),lastGoodVersion));
+    }

     /**
      * Process a new nodereference, in compressed form.

Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2006-05-18 00:15:09 UTC (rev 
8753)
+++ trunk/freenet/src/freenet/node/Version.java 2006-05-18 03:33:53 UTC (rev 
8754)
@@ -152,6 +152,77 @@
        }

        /**
+        * @return true if requests should be accepted from nodes brandishing 
this
+        *         version string, given an arbitrary lastGoodVersion
+        */
+       public static final boolean checkArbitraryGoodVersion(
+               String version, String lastGoodVersion) {
+           if(version == null) {
+               Logger.error(Version.class, "version == null!",
+                       new Exception("error"));
+               return false;
+           }
+           if(lastGoodVersion == null) {
+               Logger.error(Version.class, "lastGoodVersion == null!",
+                       new Exception("error"));
+               return false;
+           }
+               String[] v = Fields.commaList(version);
+               String[] lgv = Fields.commaList(lastGoodVersion);
+
+               if (v.length < 3 || !goodProtocol(v[2])) {
+                       return false;
+               }
+               if (lgv.length < 3 || !goodProtocol(lgv[2])) {
+                       return false;
+               }
+               if (sameArbitraryVersion(v,lgv)) {
+                       try {
+                               int build = Integer.parseInt(v[3]);
+                               int min_build = Integer.parseInt(lgv[3]);
+                               if (build < min_build) {
+                                       if(logDEBUG) Logger.debug(
+                                               Version.class,
+                                               "Not accepting unstable from 
version: "
+                                                       + version
+                                                       + "(lastGoodVersion="
+                                                       + lastGoodVersion
+                                                       + ")");
+                                       return false;
+                               }
+                       } catch (NumberFormatException e) {
+                               Logger.minor(
+                                       Version.class,
+                                       "Not accepting (" + e + ") from " + 
version + " and/or " + lastGoodVersion);
+                               return false;
+                       }
+               }
+               if (stableVersion(v)) {
+                       try {
+                               int build = Integer.parseInt(v[3]);
+                               if(build < lastGoodStableBuild) {
+                                       if(logDEBUG) Logger.debug(
+                                               Version.class,
+                                               "Not accepting stable from 
version"
+                                                       + version
+                                                       + 
"(lastGoodStableBuild="
+                                                       + lastGoodStableBuild
+                                                       + ")");
+                                       return false;
+                               }
+                       } catch (NumberFormatException e) {
+                               Logger.minor(
+                                       Version.class,
+                                       "Not accepting (" + e + ") from " + 
version);
+                               return false;
+                       }
+               }
+               if(logDEBUG)
+                       Logger.minor(Version.class, "Accepting: " + version);
+               return true;
+       }
+
+       /**
         * @return string explaining why a version string is rejected
         */
        public static final String explainBadVersion(String version) {
@@ -186,6 +257,24 @@
        }

        /**
+        * @return the build number of an arbitrary version string
+        */
+       public static final int getArbitraryBuildNumber(
+               String version ) throws NumberFormatException {
+           if(version == null) {
+               Logger.error(Version.class, "version == null!",
+                       new Exception("error"));
+               throw new NumberFormatException();
+           }
+               String[] v = Fields.commaList(version);
+
+               if (v.length < 3 || !goodProtocol(v[2])) {
+               throw new NumberFormatException();
+               }
+               return Integer.parseInt(v[3]);
+       }
+
+       /**
         * Update static variable highestSeenBuild anytime we encounter
         * a new node with a higher version than we've seen before
         */
@@ -225,6 +314,17 @@
        }

        /**
+        * @return true if the string describes the same node version as an 
arbitrary one.
+        * Note that the build number may be different, and is ignored.
+        */
+       public static boolean sameArbitraryVersion(String[] v, String[] lgv) {
+               return v[0].equals(lgv[0])
+                       && v[1].equals(lgv[1])
+                       && v.length >= 4
+                       && lgv.length >= 4;
+       }
+
+       /**
         * @return true if the string describes a stable node version
         */
        private static boolean stableVersion(String[] v) {


Reply via email to