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;


Reply via email to