Author: nextgens
Date: 2007-12-04 22:20:15 +0000 (Tue, 04 Dec 2007)
New Revision: 16288
Modified:
trunk/freenet/src/freenet/clients/http/ConnectionsToadlet.java
trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
trunk/freenet/src/freenet/clients/http/staticfiles/themes/clean/theme.css
trunk/freenet/src/freenet/io/comm/DMT.java
trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties
trunk/freenet/src/freenet/node/DarknetPeerNode.java
trunk/freenet/src/freenet/node/NodeDispatcher.java
trunk/freenet/src/freenet/node/PeerManager.java
trunk/freenet/src/freenet/node/PeerNode.java
trunk/freenet/src/freenet/node/PeerNodeStatus.java
Log:
Implement a feature requested by pheenode: the ability to prevent a link to a
remote node to serve routing purposes
Modified: trunk/freenet/src/freenet/clients/http/ConnectionsToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/ConnectionsToadlet.java
2007-12-04 20:08:01 UTC (rev 16287)
+++ trunk/freenet/src/freenet/clients/http/ConnectionsToadlet.java
2007-12-04 22:20:15 UTC (rev 16288)
@@ -183,12 +183,13 @@
int numberOfClockProblem =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_CLOCK_PROBLEM);
int numberOfConnError =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_CONN_ERROR);
int numberOfDisconnecting =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_DISCONNECTING);
+ int numberOfRoutingDisabled =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_ROUTING_DISABLED);
int numberOfSimpleConnected = numberOfConnected +
numberOfRoutingBackedOff;
int numberOfNotConnected = numberOfTooNew + numberOfTooOld +
numberOfDisconnected + numberOfNeverConnected + numberOfDisabled +
numberOfBursting + numberOfListening + numberOfListenOnly +
numberOfClockProblem + numberOfConnError;
String titleCountString = null;
if(advancedModeEnabled) {
- titleCountString = "(" + numberOfConnected + '/' +
numberOfRoutingBackedOff + '/' + numberOfTooNew + '/' + numberOfTooOld + '/' +
numberOfNotConnected + ')';
+ titleCountString = "(" + numberOfConnected + '/' +
numberOfRoutingBackedOff + '/' + numberOfTooNew + '/' + numberOfTooOld + '/' +
numberOfRoutingDisabled + '/' + numberOfNotConnected + ')';
} else {
titleCountString = (numberOfNotConnected +
numberOfSimpleConnected)>0 ? String.valueOf(numberOfSimpleConnected) : "";
}
@@ -328,6 +329,12 @@
peerStatsListenOnlyListItem.addChild("span",
new String[] { "class", "title", "style" }, new String[] {
"peer_disconnecting", l10n("disconnecting"), "border-bottom: 1px dotted;
cursor: help;" }, l10n("disconnectingShort"));
peerStatsListenOnlyListItem.addChild("span",
":\u00a0" + numberOfDisconnecting);
}
+
+ if (numberOfRoutingDisabled > 0) {
+ HTMLNode peerStatsListenOnlyListItem =
peerStatsList.addChild("li").addChild("span");
+ peerStatsListenOnlyListItem.addChild("span",
new String[] { "class", "title", "style" }, new String[] {
"peer_routing_disabled", l10n("routingDisabled"), "border-bottom: 1px dotted;
cursor: help;" }, l10n("routingDisabledShort"));
+ peerStatsListenOnlyListItem.addChild("span",
":\u00a0" + numberOfRoutingDisabled);
+ }
// Peer routing backoff reason box
if(advancedModeEnabled) {
Modified: trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
2007-12-04 20:08:01 UTC (rev 16287)
+++ trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
2007-12-04 22:20:15 UTC (rev 16288)
@@ -118,6 +118,8 @@
actionSelect.addChild("option", "value",
"clear_allow_local", "On selected peers, clear allowLocalAddresses");
actionSelect.addChild("option", "value",
"set_ignore_source_port", "On selected peers, set ignoreSourcePort (try this if
behind an evil corporate firewall; otherwise not recommended)");
actionSelect.addChild("option", "value",
"clear_ignore_source_port", "On selected peers, clear ignoreSourcePort");
+ actionSelect.addChild("option", "value",
"set_dont_route", "On selected peers, set dontRoute (you shouldn't use that
unless you know what you're doing, really!)");
+ actionSelect.addChild("option", "value",
"clear_dont_route", "On selected peers, clear dontRoute");
}
actionSelect.addChild("option", "value", "", l10n("separator"));
actionSelect.addChild("option", "value", "remove",
l10n("removePeers"));
@@ -254,6 +256,28 @@
headers.put("Location", "/friends/");
ctx.sendReplyHeaders(302, "Found", headers, null, 0);
return;
+ } else if (request.isPartSet("doAction") &&
request.getPartAsString("action",25).equals("clear_dont_route")) {
+ DarknetPeerNode[] peerNodes =
node.getDarknetConnections();
+ for(int i = 0; i < peerNodes.length; i++) {
+ if
(request.isPartSet("node_"+peerNodes[i].hashCode())) {
+ peerNodes[i].setRoutingStatus(true,
true);
+ }
+ }
+ MultiValueTable headers = new MultiValueTable();
+ headers.put("Location", "/friends/");
+ ctx.sendReplyHeaders(302, "Found", headers, null, 0);
+ return;
+ } else if (request.isPartSet("doAction") &&
request.getPartAsString("action",25).equals("set_dont_route")) {
+ DarknetPeerNode[] peerNodes =
node.getDarknetConnections();
+ for(int i = 0; i < peerNodes.length; i++) {
+ if(request.isPartSet("node_" +
peerNodes[i].hashCode())) {
+ peerNodes[i].setRoutingStatus(false,
true);
+ }
+ }
+ MultiValueTable headers = new MultiValueTable();
+ headers.put("Location", "/friends/");
+ ctx.sendReplyHeaders(302, "Found", headers, null, 0);
+ return;
} else if (request.isPartSet("doAction") &&
request.getPartAsString("action",25).equals("set_listen_only")) {
//int hashcode =
Integer.decode(request.getParam("node")).intValue();
Modified:
trunk/freenet/src/freenet/clients/http/staticfiles/themes/clean/theme.css
===================================================================
--- trunk/freenet/src/freenet/clients/http/staticfiles/themes/clean/theme.css
2007-12-04 20:08:01 UTC (rev 16287)
+++ trunk/freenet/src/freenet/clients/http/staticfiles/themes/clean/theme.css
2007-12-04 22:20:15 UTC (rev 16288)
@@ -321,6 +321,10 @@
color: #d0d0d0;
}
+span.peer_routing_disabled {
+ color: #7b68ee;
+}
+
span.peer_never_connected {
color: #a0a0a0;
}
Modified: trunk/freenet/src/freenet/io/comm/DMT.java
===================================================================
--- trunk/freenet/src/freenet/io/comm/DMT.java 2007-12-04 20:08:01 UTC (rev
16287)
+++ trunk/freenet/src/freenet/io/comm/DMT.java 2007-12-04 22:20:15 UTC (rev
16288)
@@ -124,6 +124,7 @@
public static final String TIME_DELTAS = "timeDeltas";
public static final String HASHES = "hashes";
public static final String REJECT_CODE = "rejectCode";
+ public static final String ROUTING_ENABLED = "routingEnabled";
//Diagnostic
public static final MessageType ping = new MessageType("ping") {{
@@ -1386,6 +1387,17 @@
for(int i=0;i<locs.length;i++) locs[i] =
doubles[i].doubleValue();
return createFNPBestRoutesNotTaken(locs);
}
+
+ public static final MessageType FNPRoutingStatus = new
MessageType("FNPRoutingStatus") {{
+ addField(ROUTING_ENABLED, Boolean.class);
+ }};
+
+ public static final Message createRoutingStatus(boolean routeRequests) {
+ Message msg = new Message(FNPRoutingStatus);
+ msg.set(ROUTING_ENABLED, routeRequests);
+
+ return msg;
+ }
public static void init() { }
Modified: trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties
===================================================================
--- trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties 2007-12-04
20:08:01 UTC (rev 16287)
+++ trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties 2007-12-04
22:20:15 UTC (rev 16288)
@@ -117,6 +117,7 @@
ConnectionsToadlet.nodeStatus.DISCONNECTING=DISCONNECTING
ConnectionsToadlet.nodeStatus.UNKNOWN STATUS=UNKNOWN STATUS
ConnectionsToadlet.nodeStatus.BUSY=BUSY
+ConnectionsToadlet.nodeStatus.ROUTINGDISABLED=NOT ROUTING TRAFFIC
ContentDataFilter.unknownCharset=The page you are about to display has an
unknown character set. This means that we are not able to filter the page, and
it may compromize your anonymity.
ContentDataFilter.unknownCharsetTitle=Unknown character set!
ContentDataFilter.warningUnknownCharsetTitle=Warning: Unknown character set
(${charset})
@@ -161,6 +162,8 @@
DarknetConnectionsToadlet.disabledShort=Disabled
DarknetConnectionsToadlet.enterDescription=Enter description:
DarknetConnectionsToadlet.connError=Connection failed (buggy node?)
+DarknetConnectionsToadlet.routingDisabled=Not routing traffic (we are
currently connected to the node but we or it refuses to route traffic)
+DarknetConnectionsToadlet.routingDisabledShort=Not routing traffic
DarknetConnectionsToadlet.disconnectingShort=Disconnecting
DarknetConnectionsToadlet.disconnecting=Disconnecting (we are currently
removing the node, we need to tell it to go away and this can take a short time)
DarknetConnectionsToadlet.connErrorShort=Connection Error
@@ -526,7 +529,7 @@
N2NTMToadlet.noSuchFileOrCannotRead=Unable to send the file: Either it does
not exist or it can't be read.
N2NTMToadlet.peerName=Peer Name
N2NTMToadlet.peerNotFoundTitle=Peer not found
-N2NTMToadlet.peerNotFoundWithHash=The peer with the hash code
\u201c${hash}\u201d could not be found.
+N2NTMToadlet.peerNotFoundWithHash=The peer with the hash code
\u201C${hash}\u201D could not be found.
N2NTMToadlet.processingSend=Send Node to Node Text Message Processing
N2NTMToadlet.queued=Queued: Peer not connected, so message queued for when it
connects
N2NTMToadlet.queuedTitle=Queued
Modified: trunk/freenet/src/freenet/node/DarknetPeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/DarknetPeerNode.java 2007-12-04 20:08:01 UTC
(rev 16287)
+++ trunk/freenet/src/freenet/node/DarknetPeerNode.java 2007-12-04 22:20:15 UTC
(rev 16288)
@@ -105,13 +105,14 @@
String name = fs.get("myName");
if(name == null) throw new FSParseException("No name");
myName = name;
-
+
if(fromLocal) {
SimpleFieldSet metadata = fs.subset("metadata");
isDisabled = Fields.stringToBool(metadata.get("isDisabled"),
false);
isListenOnly =
Fields.stringToBool(metadata.get("isListenOnly"), false);
isBurstOnly = Fields.stringToBool(metadata.get("isBurstOnly"),
false);
+ disableRouting = disableRoutingHasBeenSetLocally =
Fields.stringToBool(metadata.get("disableRoutingHasBeenSetLocally"), false);
ignoreSourcePort =
Fields.stringToBool(metadata.get("ignoreSourcePort"), false);
allowLocalAddresses =
Fields.stringToBool(metadata.get("allowLocalAddresses"), false);
}
@@ -205,6 +206,8 @@
fs.putSingle("ignoreSourcePort", "true");
if(allowLocalAddresses)
fs.putSingle("allowLocalAddresses", "true");
+ if(disableRoutingHasBeenSetLocally)
+ fs.putSingle("disableRoutingHasBeenSetLocally", "true");
return fs;
}
@@ -299,7 +302,36 @@
}
}
+ /**
+ * Change the routing status of a peer
+ *
+ * @param shouldRoute
+ * @param localRequest (true everywhere but in NodeDispatcher)
+ */
+
+ public void setRoutingStatus(boolean shouldRoute, boolean localRequest)
{
+ synchronized(this) {
+ if(localRequest)
+ disableRoutingHasBeenSetLocally = !shouldRoute;
+ else
+ isRoutingDisabledRemotely = !shouldRoute;
+ disableRouting = disableRoutingHasBeenSetLocally ||
isRoutingDisabledRemotely;
+ }
+
+ if(localRequest) {
+ Message msg = DMT.createRoutingStatus(shouldRoute);
+ try {
+ sendAsync(msg, null, 0, null);
+ } catch(NotConnectedException e) {
+ // ok
+ }
+ }
+ setPeerNodeStatus(System.currentTimeMillis());
+ node.peers.writePeers();
+
+ }
+
public boolean isIgnoreSourcePort() {
return ignoreSourcePort;
}
Modified: trunk/freenet/src/freenet/node/NodeDispatcher.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeDispatcher.java 2007-12-04 20:08:01 UTC
(rev 16287)
+++ trunk/freenet/src/freenet/node/NodeDispatcher.java 2007-12-04 22:20:15 UTC
(rev 16288)
@@ -99,6 +99,15 @@
return node.nodeUpdater.uom.handleSendingMain(m,
source);
} else if(spec == DMT.FNPOpennetAnnounceRequest) {
return handleAnnounceRequest(m, source);
+ } else if(spec == DMT.FNPRoutingStatus) {
+ if(source instanceof DarknetPeerNode) {
+ boolean value =
m.getBoolean(DMT.ROUTING_ENABLED);
+ if(logMINOR)
+ Logger.minor(this, "The peer
("+source+") asked us to set routing="+value);
+
((DarknetPeerNode)source).setRoutingStatus(value, false);
+ }
+ // We claim it in any case
+ return true;
}
if(!source.isRoutable()) return false;
Modified: trunk/freenet/src/freenet/node/PeerManager.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerManager.java 2007-12-04 20:08:01 UTC
(rev 16287)
+++ trunk/freenet/src/freenet/node/PeerManager.java 2007-12-04 22:20:15 UTC
(rev 16288)
@@ -97,6 +97,7 @@
public static final int PEER_NODE_STATUS_CLOCK_PROBLEM = 11;
public static final int PEER_NODE_STATUS_CONN_ERROR = 12;
public static final int PEER_NODE_STATUS_DISCONNECTING = 13;
+ public static final int PEER_NODE_STATUS_ROUTING_DISABLED = 14;
/**
* Create a PeerManager by reading a list of peers from
Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java 2007-12-04 20:08:01 UTC
(rev 16287)
+++ trunk/freenet/src/freenet/node/PeerNode.java 2007-12-04 22:20:15 UTC
(rev 16288)
@@ -88,6 +88,9 @@
* Set true if this peer has a incompatible newer build than we are
*/
protected boolean verifiedIncompatibleNewerVersion;
+ protected boolean disableRouting;
+ protected boolean disableRoutingHasBeenSetLocally;
+ protected boolean isRoutingDisabledRemotely;
/*
* Buffer of Ni,Nr,g^i,g^r,ID
*/
@@ -330,9 +333,11 @@
currentLocation = -1.0;
}
+ disableRouting = disableRoutingHasBeenSetLocally = false;
+ isRoutingDisabledRemotely = false; // Assume so
+
// FIXME make mandatory once everyone has upgraded
lastGoodVersion = fs.get("lastGoodVersion");
-
updateShouldDisconnectNow();
String testnet = fs.get("testnet");
@@ -842,7 +847,7 @@
public boolean isRoutingCompatible() {
long now = System.currentTimeMillis();
synchronized(this) {
- if(isRoutable) {
+ if(isRoutable && !disableRouting) {
timeLastRoutable = now;
return true;
}
@@ -1154,7 +1159,7 @@
* Set sendHandshakeTime, and return whether to fetch the ARK.
*/
protected synchronized boolean innerCalcNextHandshake(boolean
successfulHandshakeSend, boolean dontFetchARK, long now) {
- if(verifiedIncompatibleOlderVersion ||
verifiedIncompatibleNewerVersion) {
+ if(verifiedIncompatibleOlderVersion ||
verifiedIncompatibleNewerVersion || disableRouting) {
// 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) {
@@ -1552,6 +1557,7 @@
} else
wasARekey = true;
isConnected = true;
+ disableRouting = disableRoutingHasBeenSetLocally ||
isRoutingDisabledRemotely;
isRoutable = routable;
verifiedIncompatibleNewerVersion = newer;
verifiedIncompatibleOlderVersion = older;
@@ -1674,6 +1680,7 @@
Message ipMsg = DMT.createFNPDetectedIPAddress(detectedPeer);
Message timeMsg = DMT.createFNPTime(System.currentTimeMillis());
Message packetsMsg = createSentPacketsMessage();
+ Message dRouting =
DMT.createRoutingStatus(!disableRoutingHasBeenSetLocally);
try {
if(isRoutable())
@@ -1681,6 +1688,7 @@
sendAsync(ipMsg, null, 0, null);
sendAsync(timeMsg, null, 0, null);
sendAsync(packetsMsg, null, 0, null);
+ sendAsync(dRouting, null, 0, null);
} catch(NotConnectedException e) {
Logger.error(this, "Completed handshake with " +
getPeer() + " but disconnected (" + isConnected + ':' + currentTracker + "!!!:
" + e, e);
}
@@ -1775,6 +1783,10 @@
public synchronized boolean publicReverseInvalidVersion() {
return verifiedIncompatibleNewerVersion;
}
+
+ public synchronized boolean dontRoute() {
+ return disableRouting;
+ }
/**
* Process a new nodereference, in compressed form.
@@ -2512,6 +2524,8 @@
return "CLOCK PROBLEM";
if(status == PeerManager.PEER_NODE_STATUS_CONN_ERROR)
return "CONNECTION ERROR";
+ if(status == PeerManager.PEER_NODE_STATUS_ROUTING_DISABLED)
+ return "ROUTINGDISABLED";
if(status == PeerManager.PEER_NODE_STATUS_DISCONNECTING)
return "DISCONNECTING";
return "UNKNOWN STATUS";
@@ -2545,6 +2559,8 @@
return "peer_listen_only";
if(status == PeerManager.PEER_NODE_STATUS_CLOCK_PROBLEM)
return "peer_clock_problem";
+ if(status == PeerManager.PEER_NODE_STATUS_ROUTING_DISABLED)
+ return "peer_routing_disabled";
if(status == PeerManager.PEER_NODE_STATUS_DISCONNECTING)
return "peer_disconnecting";
return "peer_unknown_status";
@@ -2577,6 +2593,8 @@
peerNodeStatus = PeerManager.PEER_NODE_STATUS_TOO_NEW;
else if(isConnected && verifiedIncompatibleOlderVersion)
peerNodeStatus = PeerManager.PEER_NODE_STATUS_TOO_OLD;
+ else if(isConnected && disableRouting)
+ peerNodeStatus =
PeerManager.PEER_NODE_STATUS_ROUTING_DISABLED;
else if(isConnected && Math.abs(clockDelta) > MAX_CLOCK_DELTA)
peerNodeStatus =
PeerManager.PEER_NODE_STATUS_CLOCK_PROBLEM;
else if(neverConnected)
@@ -2659,7 +2677,7 @@
public synchronized boolean noLongerRoutable() {
// TODO: We should disconnect here if "protocol version
mismatch", maybe throwing an exception
// TODO: shouldDisconnectNow() is hopefully only called when
we're connected, otherwise we're breaking the meaning of
verifiedIncompable[Older|Newer]Version
- if(verifiedIncompatibleNewerVersion ||
verifiedIncompatibleOlderVersion)
+ if(verifiedIncompatibleNewerVersion ||
verifiedIncompatibleOlderVersion || disableRouting)
return true;
return false;
}
Modified: trunk/freenet/src/freenet/node/PeerNodeStatus.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNodeStatus.java 2007-12-04 20:08:01 UTC
(rev 16287)
+++ trunk/freenet/src/freenet/node/PeerNodeStatus.java 2007-12-04 22:20:15 UTC
(rev 16288)
@@ -5,7 +5,6 @@
import java.util.Map;
-import freenet.clients.http.DarknetConnectionsToadlet;
import freenet.io.comm.Peer;
import freenet.io.xfer.PacketThrottle;
@@ -52,7 +51,7 @@
private final boolean publicInvalidVersion;
private final boolean publicReverseInvalidVersion;
-
+
private final double backedOffPercent;
private String lastBackoffReason;