Author: toad
Date: 2006-05-31 17:49:26 +0000 (Wed, 31 May 2006)
New Revision: 8957

Modified:
   trunk/freenet/src/freenet/io/xfer/BlockTransmitter.java
   trunk/freenet/src/freenet/node/Node.java
   trunk/freenet/src/freenet/node/NodeDispatcher.java
   trunk/freenet/src/freenet/node/Version.java
Log:
761 (self-mandatory): Fix major bugs in shouldRejectRequest().

Modified: trunk/freenet/src/freenet/io/xfer/BlockTransmitter.java
===================================================================
--- trunk/freenet/src/freenet/io/xfer/BlockTransmitter.java     2006-05-31 
17:03:52 UTC (rev 8956)
+++ trunk/freenet/src/freenet/io/xfer/BlockTransmitter.java     2006-05-31 
17:49:26 UTC (rev 8957)
@@ -493,4 +493,43 @@
        public PeerContext getDestination() {
                return _destination;
        }
+
+       public static boolean isUncontended() {
+               long nowNS = System.currentTimeMillis() * 1000 * 1000;
+               
+               // Synchronize on the static lock, and update
+               synchronized(lastPacketSendTimeSync) {
+                       
+                       // Get the current time
+                       nowNS = System.currentTimeMillis() * 1000 * 1000;
+                       
+                       // Update time if necessary to avoid spurts
+                       if(hardLastPacketSendTimeNSec < (nowNS - 
minPacketDelayNSec)) {
+                               // Can send immediately!
+                       } else {
+                               return false; // is contended.
+                       }
+                       
+                       // What about the soft limit?
+                       
+                       // We can only accumulate burst traffic rights for a 
full period at most.
+                       // If we have a period of 1 hour, and we send no 
traffic in the first 30 minutes,
+                       // then we can use up our whole hour's quota in the 
next 30 minutes if we need to.
+                       // We could even use our entire quota in the last 5 
minutes. After that, we can
+                       // only send at the limit (which may be very low), 
since we have no quota left.
+                       // However, after 1 hour we forget our burst rights.
+                       if(nowNS - softLastPacketSendTimeNSec > 
softLimitPeriodNSec) {
+                               softLastPacketSendTimeNSec = nowNS - 
(softLimitPeriodNSec);
+                       }
+                       
+                       softLastPacketSendTimeNSec += minSoftDelayNSec;
+                       
+                       if(softLastPacketSendTimeNSec > nowNS) {
+                               // Can't send immediately due to soft limit.
+                               return false;
+                       }
+               }
+               
+               return true;
+       }
 }

Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java    2006-05-31 17:03:52 UTC (rev 
8956)
+++ trunk/freenet/src/freenet/node/Node.java    2006-05-31 17:49:26 UTC (rev 
8957)
@@ -1950,22 +1950,30 @@

     long lastAcceptedRequest = -1;

-    public synchronized boolean shouldRejectRequest() {
+    long lastCheckedUncontended = -1;
+    
+    public synchronized boolean shouldRejectRequest(boolean canAcceptAnyway) {
        long now = System.currentTimeMillis();

+       if(lastCheckedUncontended - now > 1000) {
+               lastCheckedUncontended = now;
+               if(BlockTransmitter.isUncontended())
+                       throttledPacketSendAverage.report(0);
+       }
+       
        // Round trip time
        double pingTime = nodePinger.averagePingTime();
        if(pingTime > MAX_PING_TIME) {
-               if(now - lastAcceptedRequest > MAX_INTERREQUEST_TIME) {
+               if(now - lastAcceptedRequest > MAX_INTERREQUEST_TIME && 
canAcceptAnyway) {
                        Logger.minor(this, "Accepting request anyway (take one 
every 10 secs to keep bwlimitDelayTime updated)");
                        lastAcceptedRequest = now;
                        return false;
                }
-               Logger.minor( this, "shouldRejectRequest() == true because 
>MAX_PING_TIME");
+               Logger.minor( this, "shouldRejectRequest("+canAcceptAnyway+") 
== true because >MAX_PING_TIME");
                return true;
        }
        if(pingTime > SUB_MAX_PING_TIME) {
-               double x = (pingTime - SUB_MAX_PING_TIME) / (MAX_PING_TIME - 
SUB_MAX_PING_TIME);
+               double x = ((double)(pingTime - SUB_MAX_PING_TIME)) / 
(MAX_PING_TIME - SUB_MAX_PING_TIME);
                if(random.nextDouble() < x) {
                        Logger.minor( this, "shouldRejectRequest() == true 
because >SUB_MAX_PING_TIME");
                        return true;
@@ -1977,7 +1985,7 @@
        double bwlimitDelayTime = 
this.throttledPacketSendAverage.currentValue();
        Logger.minor(this, "bwlimitDelayTime = "+bwlimitDelayTime);
        if(bwlimitDelayTime > MAX_THROTTLE_DELAY) {
-               if(now - lastAcceptedRequest > MAX_INTERREQUEST_TIME) {
+               if(now - lastAcceptedRequest > MAX_INTERREQUEST_TIME && 
canAcceptAnyway) {
                        Logger.minor(this, "Accepting request anyway (take one 
every 10 secs to keep bwlimitDelayTime updated)");
                        lastAcceptedRequest = now;
                        return false;
@@ -1986,13 +1994,15 @@
                return true;
        }
        if(bwlimitDelayTime > SUB_MAX_THROTTLE_DELAY) {
-               double x = (pingTime - SUB_MAX_THROTTLE_DELAY) / 
(MAX_THROTTLE_DELAY - SUB_MAX_THROTTLE_DELAY);
+               double x = ((double)(bwlimitDelayTime - 
SUB_MAX_THROTTLE_DELAY)) / (MAX_THROTTLE_DELAY - SUB_MAX_THROTTLE_DELAY);
                if(random.nextDouble() < x) {
-                       Logger.minor( this, "shouldRejectRequest() == true 
because >SUB_MAX_THROTTLE_DELAY");
+                       Logger.minor( this, 
"shouldRejectRequest("+canAcceptAnyway+") == true because 
>SUB_MAX_THROTTLE_DELAY");
                        return true;
                }
        }

+       Logger.minor(this, "Accepting request");
+       
        lastAcceptedRequest = now;
        return false;
     }

Modified: trunk/freenet/src/freenet/node/NodeDispatcher.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeDispatcher.java  2006-05-31 17:03:52 UTC 
(rev 8956)
+++ trunk/freenet/src/freenet/node/NodeDispatcher.java  2006-05-31 17:49:26 UTC 
(rev 8957)
@@ -71,10 +71,14 @@
             return handleRoutedReply(m);
         } else if(spec == DMT.FNPRoutedRejected) {
             return handleRoutedRejected(m);
-        } else if(spec == DMT.FNPCHKDataRequest || spec == 
DMT.FNPSSKDataRequest) {
-            return handleDataRequest(m);
-        } else if(spec == DMT.FNPInsertRequest || spec == 
DMT.FNPSSKInsertRequest) {
-            return handleInsertRequest(m);
+        } else if(spec == DMT.FNPCHKDataRequest) {
+               return handleDataRequest(m, false);
+        } else if(spec == DMT.FNPSSKDataRequest) {
+            return handleDataRequest(m, true);
+        } else if(spec == DMT.FNPInsertRequest) {
+               return handleInsertRequest(m, false);
+        } else if(spec == DMT.FNPSSKInsertRequest) {
+            return handleInsertRequest(m, true);
         } else if(spec == DMT.FNPLinkPing) {
                long id = m.getLong(DMT.PING_SEQNO);
                Message msg = DMT.createFNPLinkPong(id);
@@ -104,7 +108,7 @@
     /**
      * Handle an incoming FNPDataRequest.
      */
-    private boolean handleDataRequest(Message m) {
+    private boolean handleDataRequest(Message m, boolean isSSK) {
         long id = m.getLong(DMT.UID);
         if(node.recentlyCompleted(id)) {
             Message rejected = DMT.createFNPRejectedLoop(id);
@@ -115,7 +119,8 @@
             }
             return true;
         }
-        if(node.shouldRejectRequest()) {
+        if(node.shouldRejectRequest(!isSSK)) {
+               // can accept 1 CHK request every so often, but not with SSKs 
because they aren't throttled so won't sort out bwlimitDelayTime, which was the 
whole reason for accepting them when overloaded...
                Logger.normal(this, "Rejecting request from 
"+m.getSource().getPeer()+" preemptively");
                Message rejected = DMT.createFNPRejectedOverload(id, true);
                try {
@@ -146,7 +151,7 @@
         return true;
     }

-    private boolean handleInsertRequest(Message m) {
+    private boolean handleInsertRequest(Message m, boolean isSSK) {
         long now = System.currentTimeMillis();
         long id = m.getLong(DMT.UID);
         if(node.recentlyCompleted(id)) {
@@ -158,7 +163,8 @@
             }
             return true;
         }
-        if(node.shouldRejectRequest()) {
+        // SSKs don't fix bwlimitDelayTime so shouldn't be accepted when 
overloaded.
+        if(node.shouldRejectRequest(!isSSK)) {
                Logger.normal(this, "Rejecting insert from 
"+m.getSource().getPeer()+" preemptively");
                Message rejected = DMT.createFNPRejectedOverload(id, true);
                try {

Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2006-05-31 17:03:52 UTC (rev 
8956)
+++ trunk/freenet/src/freenet/node/Version.java 2006-05-31 17:49:26 UTC (rev 
8957)
@@ -18,10 +18,10 @@
        public static final String protocolVersion = "1.0";

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

        /** Oldest build of Fred we will talk to */
-       private static final int lastGoodBuild = 759;
+       private static final int lastGoodBuild = 761;

        public static final int buildNumber() {
                return buildNumber;


Reply via email to