Author: toad
Date: 2008-04-08 11:17:08 +0000 (Tue, 08 Apr 2008)
New Revision: 19070
Modified:
trunk/freenet/src/freenet/node/LocationManager.java
trunk/freenet/src/freenet/node/PeerNode.java
Log:
Prevent inter-node race condition causing excessive resets:
If our node and one of our peers have the same location, don't reset
immediately but wait until this situation has existed for over 2 minutes on
both sides.
Modified: trunk/freenet/src/freenet/node/LocationManager.java
===================================================================
--- trunk/freenet/src/freenet/node/LocationManager.java 2008-04-08 11:07:17 UTC
(rev 19069)
+++ trunk/freenet/src/freenet/node/LocationManager.java 2008-04-08 11:17:08 UTC
(rev 19070)
@@ -91,6 +91,7 @@
}
private double loc;
+ private long timeLocSet;
private double locChangeSession = 0.0;
int numberOfRemotePeerLocationsSeenInSwaps = 0;
@@ -167,15 +168,24 @@
for(int i=0;i<peers.length;i++) {
PeerNode pn = peers[i];
if(pn.isRoutable()) {
+ synchronized(pn) {
double ploc = pn.getLocation();
if(Math.abs(ploc - myLoc) <=
Double.MIN_VALUE) {
+ // Don't reset location unless
we're SURE there is a problem.
+ // If the node has had its
location equal to ours for at least 2 minutes, and ours has been likewise...
+ long now =
System.currentTimeMillis();
+ if(now - pn.getLocSetTime() >
120*1000 && now - timeLocSet > 120*1000) {
myFlag = true;
// Log an ERROR
// As this is an ERROR, it results
from either a bug or malicious action.
// If it happens very frequently,
it indicates either an attack or a serious bug.
Logger.error(this, "Randomizing
location: my loc="+myLoc+" but loc="+ploc+" for "+pn);
break;
- }
+ } else {
+ Logger.normal(this,
"Node "+pn+" has identical location to us, waiting until this has persisted for
2 minutes...");
+ }
+ }
+ }
}
}
if(myFlag) {
Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java 2008-04-08 11:07:17 UTC
(rev 19069)
+++ trunk/freenet/src/freenet/node/PeerNode.java 2008-04-08 11:17:08 UTC
(rev 19070)
@@ -169,6 +169,8 @@
private static final int MAX_HANDSHAKE_COUNT = 2;
/** Current location in the keyspace, or -1 if it is unknown */
private double currentLocation;
+ /** Time the location was set */
+ private long locSetTime;
/** Node identity; for now a block of data, in future a
* public key (FIXME). Cannot be changed.
*/
@@ -371,6 +373,7 @@
String locationString = fs.get("location");
try {
currentLocation = Location.getLocation(locationString);
+ locSetTime = System.currentTimeMillis();
} catch(FSParseException e) {
// Wait for them to send us an FNPLocChangeNotification
currentLocation = -1.0;
@@ -902,6 +905,10 @@
return currentLocation;
}
+ public synchronized long getLocSetTime() {
+ return locSetTime;
+ }
+
/**
* Returns a unique node identifier (usefull to compare two peernodes).
*/
@@ -1575,6 +1582,7 @@
}
synchronized(this) {
currentLocation = newLoc;
+ locSetTime = System.currentTimeMillis();
}
node.peers.writePeers();
}
@@ -2273,6 +2281,7 @@
if(!Location.equals(newLoc, currentLocation)) {
changedAnything = true;
currentLocation = newLoc;
+ locSetTime = System.currentTimeMillis();
}
} catch(FSParseException e) {
// Location is optional, we will wait for
FNPLocChangeNotification. Until then we will use the last known location (or -1
if we have never known).