Author: zothar
Date: 2006-07-16 17:50:43 +0000 (Sun, 16 Jul 2006)
New Revision: 9636

Modified:
   trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
   trunk/freenet/src/freenet/node/Node.java
   trunk/freenet/src/freenet/node/PeerNode.java
   trunk/freenet/src/freenet/node/Version.java
   trunk/freenet/src/freenet/node/fcp/ModifyPeer.java
Log:
883: Added BurstOnly functionality, which send handshake requests in bursts of 
1-4 requests at the normal rate and then waits 2-5 minutes before sending 
again.  Setting BurstOnly clears ListenOnly and vice-versa.  The former 
LISTENING is now LISTEN ONLY and LISTENING and BURSTING are now used by 
BurstOnly when the peer is being listen for or handshake burst to respectively. 
 A BurstOnly peer should connect with a ListenOnly peer.

Modified: trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java       
2006-07-16 17:43:03 UTC (rev 9635)
+++ trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java       
2006-07-16 17:50:43 UTC (rev 9636)
@@ -75,10 +75,12 @@
                int numberOfDisconnected = 
node.getPeerNodeStatusSize(Node.PEER_NODE_STATUS_DISCONNECTED);
                int numberOfNeverConnected = 
node.getPeerNodeStatusSize(Node.PEER_NODE_STATUS_NEVER_CONNECTED);
                int numberOfDisabled = 
node.getPeerNodeStatusSize(Node.PEER_NODE_STATUS_DISABLED);
+               int numberOfBursting = 
node.getPeerNodeStatusSize(Node.PEER_NODE_STATUS_BURSTING);
                int numberOfListening = 
node.getPeerNodeStatusSize(Node.PEER_NODE_STATUS_LISTENING);
+               int numberOfListenOnly = 
node.getPeerNodeStatusSize(Node.PEER_NODE_STATUS_LISTEN_ONLY);

                int numberOfSimpleConnected = numberOfConnected + 
numberOfRoutingBackedOff;
-               int numberOfNotConnected = numberOfTooNew + numberOfTooOld + 
numberOfDisconnected + numberOfNeverConnected + numberOfDisabled + 
numberOfListening;
+               int numberOfNotConnected = numberOfTooNew + numberOfTooOld + 
numberOfDisconnected + numberOfNeverConnected + numberOfDisabled + 
numberOfBursting + numberOfListening + numberOfListenOnly;
                String titleCountString = null;
                if(advancedEnabled) {
                        titleCountString = "(" + numberOfConnected + "/" + 
numberOfRoutingBackedOff + "/" + numberOfTooNew + "/" + numberOfTooOld + "/" + 
numberOfNotConnected + ")";
@@ -192,9 +194,15 @@
                if (numberOfDisabled > 0) {
                        buf.append("<li><span 
class=\"peer_never_connected\">Disabled:&nbsp;").append(numberOfDisabled).append("</span></li>");
  // **FIXME**
                }
+               if (numberOfBursting > 0) {
+                       buf.append("<li><span 
class=\"peer_never_connected\">Bursting:&nbsp;").append(numberOfBursting).append("</span></li>");
  // **FIXME**
+               }
                if (numberOfListening > 0) {
                        buf.append("<li><span 
class=\"peer_never_connected\">Listening:&nbsp;").append(numberOfListening).append("</span></li>");
  // **FIXME**
                }
+               if (numberOfListenOnly > 0) {
+                       buf.append("<li><span 
class=\"peer_never_connected\">Listen 
Only:&nbsp;").append(numberOfListenOnly).append("</span></li>");  // **FIXME**
+               }
                buf.append("</ul>");
                buf.append("</div>");
                buf.append("</div>\n");
@@ -404,6 +412,8 @@
                                buf.append(" <option value=\"\">-- Select 
Action --</option>\n");
                                buf.append(" <option value=\"enable\">Enable 
Selected Peers</option>\n");
                                buf.append(" <option value=\"disable\">Disable 
Selected Peers</option>\n");
+                               buf.append(" <option 
value=\"set_burst_only\">On Selected Peers, Set BurstOnly</option>\n");
+                               buf.append(" <option 
value=\"clear_burst_only\">On Selected Peers, Clear BurstOnly</option>\n");
                                buf.append(" <option 
value=\"set_listen_only\">On Selected Peers, Set ListenOnly</option>\n");
                                buf.append(" <option 
value=\"clear_listen_only\">On Selected Peers, Clear ListenOnly</option>\n");
                                buf.append(" <option value=\"\">-- -- 
--</option>\n");
@@ -574,6 +584,32 @@
                        headers.put("Location", "/darknet/");
                        ctx.sendReplyHeaders(302, "Found", headers, null, 0);
                        return;
+               } else if (request.isPartSet("submit") && 
request.getPartAsString("action",25).equals("set_burst_only")) {
+                       //int hashcode = 
Integer.decode(request.getParam("node")).intValue();
+                       
+                       PeerNode[] peerNodes = node.getDarknetConnections();
+                       for(int i = 0; i < peerNodes.length; i++) {
+                               if 
(request.isPartSet("node_"+peerNodes[i].hashCode())) {
+                                       peerNodes[i].setBurstOnly(true);
+                               }
+                       }
+                       MultiValueTable headers = new MultiValueTable();
+                       headers.put("Location", "/darknet/");
+                       ctx.sendReplyHeaders(302, "Found", headers, null, 0);
+                       return;
+               } else if (request.isPartSet("submit") && 
request.getPartAsString("action",25).equals("clear_burst_only")) {
+                       //int hashcode = 
Integer.decode(request.getParam("node")).intValue();
+                       
+                       PeerNode[] peerNodes = node.getDarknetConnections();
+                       for(int i = 0; i < peerNodes.length; i++) {
+                               if 
(request.isPartSet("node_"+peerNodes[i].hashCode())) {
+                                       peerNodes[i].setBurstOnly(false);
+                               }
+                       }
+                       MultiValueTable headers = new MultiValueTable();
+                       headers.put("Location", "/darknet/");
+                       ctx.sendReplyHeaders(302, "Found", headers, null, 0);
+                       return;
                } else if (request.isPartSet("submit") && 
request.getPartAsString("action",25).equals("set_listen_only")) {
                        //int hashcode = 
Integer.decode(request.getParam("node")).intValue();


Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java    2006-07-16 17:43:03 UTC (rev 
9635)
+++ trunk/freenet/src/freenet/node/Node.java    2006-07-16 17:50:43 UTC (rev 
9636)
@@ -449,6 +449,10 @@
        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*4;
        public static final int RANDOMIZED_TIME_BETWEEN_VERSION_SENDS = 
HANDSHAKE_TIMEOUT*2; // 20-30 secs
+       public static final int MIN_TIME_BETWEEN_BURSTING_HANDSHAKE_BURSTS = 
HANDSHAKE_TIMEOUT*24; // 2-5 minutes
+       public static final int 
RANDOMIZED_TIME_BETWEEN_BURSTING_HANDSHAKE_BURSTS = HANDSHAKE_TIMEOUT*36;
+       public static final int MIN_BURSTING_HANDSHAKE_BURST_SIZE = 1; // 1-4 
handshake sends per burst
+       public static final int RANDOMIZED_BURSTING_HANDSHAKE_BURST_SIZE = 3;
        // 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. */
@@ -623,7 +627,9 @@
        public static final int PEER_NODE_STATUS_DISCONNECTED = 5;
        public static final int PEER_NODE_STATUS_NEVER_CONNECTED = 6;
        public static final int PEER_NODE_STATUS_DISABLED = 7;
-       public static final int PEER_NODE_STATUS_LISTENING = 8;
+       public static final int PEER_NODE_STATUS_BURSTING = 8;
+       public static final int PEER_NODE_STATUS_LISTENING = 9;
+       public static final int PEER_NODE_STATUS_LISTEN_ONLY = 10;
        public static final int N2N_TEXT_MESSAGE_TYPE_USERALERT = 1;

        public final long bootID;
@@ -3429,8 +3435,10 @@
                int numberOfDisconnected = 
getPeerNodeStatusSize(PEER_NODE_STATUS_DISCONNECTED);
                int numberOfNeverConnected = 
getPeerNodeStatusSize(PEER_NODE_STATUS_NEVER_CONNECTED);
                int numberOfDisabled = 
getPeerNodeStatusSize(PEER_NODE_STATUS_DISABLED);
+               int numberOfListenOnly = 
getPeerNodeStatusSize(PEER_NODE_STATUS_LISTEN_ONLY);
                int numberOfListening = 
getPeerNodeStatusSize(PEER_NODE_STATUS_LISTENING);
-               Logger.normal(this, "Connected: "+numberOfConnected+"  Routing 
Backed Off: "+numberOfRoutingBackedOff+"  Too New: "+numberOfTooNew+"  Too Old: 
"+numberOfTooOld+"  Disconnected: "+numberOfDisconnected+"  Never Connected: 
"+numberOfNeverConnected+"  Disabled: "+numberOfDisabled+"  Listening: 
"+numberOfListening);
+               int numberOfBursting = 
getPeerNodeStatusSize(PEER_NODE_STATUS_BURSTING);
+               Logger.normal(this, "Connected: "+numberOfConnected+"  Routing 
Backed Off: "+numberOfRoutingBackedOff+"  Too New: "+numberOfTooNew+"  Too Old: 
"+numberOfTooOld+"  Disconnected: "+numberOfDisconnected+"  Never Connected: 
"+numberOfNeverConnected+"  Disabled: "+numberOfDisabled+"  Bursting: 
"+numberOfBursting+"  Listening: "+numberOfListening+"  Listen Only: 
"+numberOfListenOnly);
                nextPeerNodeStatusLogTime = now + peerNodeStatusLogInterval;
          }
        }

Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java        2006-07-16 17:43:03 UTC 
(rev 9635)
+++ trunk/freenet/src/freenet/node/PeerNode.java        2006-07-16 17:50:43 UTC 
(rev 9636)
@@ -129,6 +129,12 @@
     /** After this many failed handshakes, we start the ARK fetcher. */
     private static final int MAX_HANDSHAKE_COUNT = 2;

+    /** Number of handshake attempts (while in ListenOnly mode) since the 
beginning of this burst */
+    private int listeningHandshakeBurstCount;
+    
+    /** Total number of handshake attempts (while in ListenOnly mode) to be in 
this burst */
+    private int listeningHandshakeBurstSize;
+    
     /** Current location in the keyspace */
     private Location currentLocation;

@@ -237,6 +243,12 @@
     /** True if we don't send handshake requests to this peer, but will 
connect if we receive one */
     private boolean isListenOnly;

+    /** True if we send handshake requests to this peer in infrequent bursts */
+    private boolean isBurstOnly;
+    
+    /** True if we are currently sending this peer a burst of handshake 
requests */
+    private boolean isBursting;
+    
     /** True if we want to allow LAN/localhost addresses. */
     private boolean allowLocalAddresses;

@@ -440,6 +452,7 @@
                }
                isDisabled = Fields.stringToBool(metadata.get("isDisabled"), 
false);
                isListenOnly = 
Fields.stringToBool(metadata.get("isListenOnly"), false);
+               isBurstOnly = Fields.stringToBool(metadata.get("isBurstOnly"), 
false);
                allowLocalAddresses = 
Fields.stringToBool(metadata.get("allowLocalAddresses"), false);
                }
         } else {
@@ -448,7 +461,16 @@
         }
         // populate handshakeIPs so handshakes can start ASAP
         maybeUpdateHandshakeIPs(true);
+        
+        sendHandshakeTime = now;  // Be sure we're ready to handshake right 
away

+               listeningHandshakeBurstCount = 0;
+               listeningHandshakeBurstSize = 
Node.MIN_BURSTING_HANDSHAKE_BURST_SIZE
+                               + 
node.random.nextInt(Node.RANDOMIZED_BURSTING_HANDSHAKE_BURST_SIZE);
+               if(isBurstOnly) {
+                       Logger.minor(this, "First BurstOnly mode handshake in 
"+(sendHandshakeTime - now)+"ms for "+getName()+" (count: 
"+listeningHandshakeBurstCount+", size: "+listeningHandshakeBurstSize+")");
+               }
+
         // status may have changed from PEER_NODE_STATUS_DISCONNECTED to 
PEER_NODE_STATUS_NEVER_CONNECTED
         setPeerNodeStatus(now);
     }
@@ -856,10 +878,16 @@
                 (handshakeIPs != null) &&
                 (now > sendHandshakeTime);
                }
-               if(tempShouldSendHandshake && !(hasLiveHandshake(now))) {
-                       return true;
+               if(tempShouldSendHandshake && (hasLiveHandshake(now))) {
+                       tempShouldSendHandshake = false;
                }
-               return false;
+               if(tempShouldSendHandshake && isBurstOnly()) {
+                       synchronized(this) {
+                               isBursting = true;
+                       }
+                       setPeerNodeStatus(now);
+               }
+               return tempShouldSendHandshake;
     }

     /**
@@ -882,25 +910,51 @@
         long now = System.currentTimeMillis();
         boolean fetchARKFlag = false;
         synchronized(this) {
-            if(verifiedIncompatibleOlderVersion || 
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);
-            } else if(invalidVersion() && !firstHandshake) {
-                sendHandshakeTime = now + Node.MIN_TIME_BETWEEN_VERSION_PROBES
-                  + 
node.random.nextInt(Node.RANDOMIZED_TIME_BETWEEN_VERSION_PROBES);
-            } else {
-                sendHandshakeTime = now + Node.MIN_TIME_BETWEEN_HANDSHAKE_SENDS
-                  + 
node.random.nextInt(Node.RANDOMIZED_TIME_BETWEEN_HANDSHAKE_SENDS);
-            }
-            if(couldSendHandshake) {
-                firstHandshake = false;
-            } else {
-                handshakeIPs = null;
-            }
-            this.handshakeCount++;
-               fetchARKFlag = ((handshakeCount == MAX_HANDSHAKE_COUNT) && 
!(verifiedIncompatibleOlderVersion || verifiedIncompatibleNewerVersion));
+                       if(!isBurstOnly) {
+                               if(verifiedIncompatibleOlderVersion || 
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);
+                               } else if(invalidVersion() && !firstHandshake) {
+                                       sendHandshakeTime = now + 
Node.MIN_TIME_BETWEEN_VERSION_PROBES
+                                               + 
node.random.nextInt(Node.RANDOMIZED_TIME_BETWEEN_VERSION_PROBES);
+                               } else {
+                                       sendHandshakeTime = now + 
Node.MIN_TIME_BETWEEN_HANDSHAKE_SENDS
+                                               + 
node.random.nextInt(Node.RANDOMIZED_TIME_BETWEEN_HANDSHAKE_SENDS);
+                               }
+                               if(couldSendHandshake) {
+                                       firstHandshake = false;
+                               } else {
+                                       handshakeIPs = null;
+                               }
+                               handshakeCount++;
+                               fetchARKFlag = ((handshakeCount == 
MAX_HANDSHAKE_COUNT) && !(verifiedIncompatibleOlderVersion || 
verifiedIncompatibleNewerVersion));
+                       } else {
+                               listeningHandshakeBurstCount++;
+                               if(verifiedIncompatibleOlderVersion || 
verifiedIncompatibleNewerVersion) { 
+                                       // Let them know we're here, but have 
no hope of connecting
+                                       listeningHandshakeBurstCount = 0;
+                               } else if(listeningHandshakeBurstCount >= 
listeningHandshakeBurstSize) {
+                                       listeningHandshakeBurstCount = 0;
+                                       fetchARKFlag = true;
+                               }
+                               if(listeningHandshakeBurstCount == 0) {  // 0 
only if we just reset it above
+                                       sendHandshakeTime = now + 
Node.MIN_TIME_BETWEEN_BURSTING_HANDSHAKE_BURSTS
+                                               + 
node.random.nextInt(Node.RANDOMIZED_TIME_BETWEEN_BURSTING_HANDSHAKE_BURSTS);
+                                       listeningHandshakeBurstSize = 
Node.MIN_BURSTING_HANDSHAKE_BURST_SIZE
+                                                       + 
node.random.nextInt(Node.RANDOMIZED_BURSTING_HANDSHAKE_BURST_SIZE);
+                                       isBursting = false;
+                               } else {
+                                       sendHandshakeTime = now + 
Node.MIN_TIME_BETWEEN_HANDSHAKE_SENDS
+                                               + 
node.random.nextInt(Node.RANDOMIZED_TIME_BETWEEN_HANDSHAKE_SENDS);
+                               }
+                               if(!couldSendHandshake) {
+                                       handshakeIPs = null;
+                               }
+                               Logger.minor(this, "Next BurstOnly mode 
handshake in "+(sendHandshakeTime - now)+"ms for "+getName()+" (count: 
"+listeningHandshakeBurstCount+", size: "+listeningHandshakeBurstSize+")", new 
Exception("double-called debug"));
+                       }
         }
+               setPeerNodeStatus(now);  // Because of isBursting being set 
above and it can't hurt others
         // Don't fetch ARKs for peers we have verified (through handshake) to 
be incompatible with us
         if(fetchARKFlag) {
                        long arkFetcherStartTime1 = System.currentTimeMillis();
@@ -1613,6 +1667,8 @@
                fs.put("isDisabled", "true");
        if(isListenOnly())
                fs.put("isListenOnly", "true");
+       if(isBurstOnly())
+               fs.put("isBurstOnly", "true");
        if(allowLocalAddresses())
                fs.put("allowLocalAddresses", "true");
        return fs;
@@ -2068,8 +2124,12 @@
                return "NEVER CONNECTED";
        if(status == Node.PEER_NODE_STATUS_DISABLED)
                return "DISABLED";
+       if(status == Node.PEER_NODE_STATUS_LISTEN_ONLY)
+               return "LISTEN ONLY";
        if(status == Node.PEER_NODE_STATUS_LISTENING)
                return "LISTENING";
+       if(status == Node.PEER_NODE_STATUS_BURSTING)
+               return "BURSTING";
        return "UNKNOWN STATUS";
   }

@@ -2089,8 +2149,12 @@
                return "peer_never_connected";
        if(status == Node.PEER_NODE_STATUS_DISABLED)
                return "peer_disconnected";  // **FIXME**
+       if(status == Node.PEER_NODE_STATUS_LISTEN_ONLY)
+               return "peer_disconnected";  // **FIXME**
        if(status == Node.PEER_NODE_STATUS_LISTENING)
                return "peer_disconnected";  // **FIXME**
+       if(status == Node.PEER_NODE_STATUS_BURSTING)
+               return "peer_disconnected";  // **FIXME**
        return "peer_unknown_status";
   }

@@ -2124,6 +2188,10 @@
                        } else if(neverConnected) {
                                peerNodeStatus = 
Node.PEER_NODE_STATUS_NEVER_CONNECTED;
                        } else if(isListenOnly) {
+                               peerNodeStatus = 
Node.PEER_NODE_STATUS_LISTEN_ONLY;
+                       } else if(isBursting) {
+                               peerNodeStatus = Node.PEER_NODE_STATUS_BURSTING;
+                       } else if(isBurstOnly) {
                                peerNodeStatus = 
Node.PEER_NODE_STATUS_LISTENING;
                        } else {
                                peerNodeStatus = 
Node.PEER_NODE_STATUS_DISCONNECTED;
@@ -2179,6 +2247,9 @@
                synchronized(this) {
                        isListenOnly = setting;
                }
+               if(setting && isBurstOnly()) {
+                       setBurstOnly(false);
+               }
                setPeerNodeStatus(System.currentTimeMillis());
         node.peers.writePeers();
        }
@@ -2186,7 +2257,28 @@
        public synchronized boolean isListenOnly() {
                return isListenOnly;
        }
+       
+       public void setBurstOnly(boolean setting) {
+               synchronized(this) {
+                       isBurstOnly = setting;
+               }
+               if(setting && isListenOnly()) {
+                       setListenOnly(false);
+               }
+               long now = System.currentTimeMillis();
+               if(!setting) {
+                       synchronized(this) {
+                               sendHandshakeTime = now;  // don't keep any 
long handshake delays we might have had under BurstOnly
+                       }
+               }
+               setPeerNodeStatus(now);
+               node.peers.writePeers();
+       }

+       public synchronized boolean isBurstOnly() {
+               return isBurstOnly;
+       }
+
        /**
         * Should the node be disconnected from immediately?
         * This will return true if our lastGoodBuild has changed due to a 
timed mandatory.
@@ -2201,7 +2293,7 @@

        protected synchronized void invalidate() {
                isRoutable = false;
-        Logger.normal(this, "Invalidated "+this);
+               Logger.normal(this, "Invalidated "+this);
        }

        public synchronized boolean allowLocalAddresses() {

Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2006-07-16 17:43:03 UTC (rev 
9635)
+++ trunk/freenet/src/freenet/node/Version.java 2006-07-16 17:50:43 UTC (rev 
9636)
@@ -18,7 +18,7 @@
        public static final String protocolVersion = "1.0";

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

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

Modified: trunk/freenet/src/freenet/node/fcp/ModifyPeer.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ModifyPeer.java  2006-07-16 17:43:03 UTC 
(rev 9635)
+++ trunk/freenet/src/freenet/node/fcp/ModifyPeer.java  2006-07-16 17:50:43 UTC 
(rev 9636)
@@ -55,6 +55,16 @@
                                return;
                        }
                }
+               String isBurstOnlyString = fs.get("IsBurstOnly");
+               if(isBurstOnlyString != null) {
+                       if(!isBurstOnlyString.equals("")) {
+                               
pn.setBurstOnly(Fields.stringToBool(isBurstOnlyString, false));
+                       } else {
+                               ProtocolErrorMessage msg = new 
ProtocolErrorMessage(ProtocolErrorMessage.MESSAGE_PARSE_ERROR, false, 
"IsBurstOnly had no value", nodeIdentifier);
+                               handler.outputHandler.queue(msg);
+                               return;
+                       }
+               }
                handler.outputHandler.queue(new Peer(pn, true, true));
        }



Reply via email to