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: ").append(numberOfDisabled).append("</span></li>");
// **FIXME**
}
+ if (numberOfBursting > 0) {
+ buf.append("<li><span
class=\"peer_never_connected\">Bursting: ").append(numberOfBursting).append("</span></li>");
// **FIXME**
+ }
if (numberOfListening > 0) {
buf.append("<li><span
class=\"peer_never_connected\">Listening: ").append(numberOfListening).append("</span></li>");
// **FIXME**
}
+ if (numberOfListenOnly > 0) {
+ buf.append("<li><span
class=\"peer_never_connected\">Listen
Only: ").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));
}