Author: toad
Date: 2008-01-31 14:36:48 +0000 (Thu, 31 Jan 2008)
New Revision: 17422

Modified:
   trunk/freenet/src/freenet/io/comm/DMT.java
   trunk/freenet/src/freenet/node/GlobalProbe.java
   trunk/freenet/src/freenet/node/Node.java
   trunk/freenet/src/freenet/node/NodeDispatcher.java
   trunk/freenet/src/freenet/node/PeerNode.java
   trunk/freenet/src/freenet/node/ProbeCallback.java
   trunk/freenet/src/freenet/node/TextModeClientInterface.java
Log:
Simple(ish) threaded probe requests using the current HTL algorithm.
Not tested.
Necessary now so we can identify appropriate HTL settings when we change the 
HTL system.

Modified: trunk/freenet/src/freenet/io/comm/DMT.java
===================================================================
--- trunk/freenet/src/freenet/io/comm/DMT.java  2008-01-31 13:14:57 UTC (rev 
17421)
+++ trunk/freenet/src/freenet/io/comm/DMT.java  2008-01-31 14:36:48 UTC (rev 
17422)
@@ -78,6 +78,7 @@
        public static final String TYPE = "type";
        public static final String PAYLOAD = "payload";
        public static final String COUNTER = "counter";
+       public static final String UNIQUE_COUNTER = "uniqueCounter";
        public static final String LINEAR_COUNTER = "linearCounter";
        public static final String RETURN_LOCATION = "returnLocation";
        public static final String BLOCK_HEADERS = "blockHeaders";
@@ -894,6 +895,105 @@
                return msg;
        }

+       public static final MessageType FNPRHProbeReply = new 
MessageType("FNPRHProbeReply", PRIORITY_HIGH) {{
+               addField(UID, Long.class);
+               addField(NEAREST_LOCATION, Double.class);
+               addField(BEST_LOCATION, Double.class);
+               addField(COUNTER, Short.class);
+               addField(UNIQUE_COUNTER, Short.class);
+               addField(LINEAR_COUNTER, Short.class);
+       }};
+       
+       public static final Message createFNPRHProbeReply(long uid, double 
nearest, double best, short counter, short uniqueCounter, short linearCounter) {
+               Message msg = new Message(FNPRHProbeReply);
+               msg.set(UID, uid);
+               msg.set(NEAREST_LOCATION, nearest);
+               msg.set(BEST_LOCATION, best);
+               msg.set(COUNTER, counter);
+               msg.set(UNIQUE_COUNTER, uniqueCounter);
+               msg.set(LINEAR_COUNTER, linearCounter);
+               return msg;
+       }
+       
+       public static final MessageType FNPRHProbeRequest = new 
MessageType("FNPRHProbeRequest", PRIORITY_HIGH) {{
+               addField(UID, Long.class);
+               addField(TARGET_LOCATION, Double.class);
+               addField(NEAREST_LOCATION, Double.class);
+               addField(BEST_LOCATION, Double.class);
+               addField(HTL, Short.class);
+       }};
+       
+       public static final Message createFNPRHProbeRequest(long uid, double 
target, double nearest, 
+                       double best, short htl) {
+               Message msg = new Message(FNPProbeRequest);
+               msg.set(UID, uid);
+               msg.set(TARGET_LOCATION, target);
+               msg.set(NEAREST_LOCATION, nearest);
+               msg.set(BEST_LOCATION, best);
+               msg.set(HTL, htl);
+               return msg;
+       }
+
+       public static final MessageType FNPRHReturnSubMessage = new 
MessageType("FNPRHReturnSubMessage", PRIORITY_HIGH) {{
+               addField(NEAREST_LOCATION, Double.class);
+               addField(BEST_LOCATION, Double.class);
+               addField(COUNTER, Short.class);
+               addField(UNIQUE_COUNTER, Short.class);
+               addField(LINEAR_COUNTER, Short.class);
+               addField(REASON, String.class);
+       }};
+       
+       public static final Message createFNPRHReturnSubMessage(double nearest, 
double best, short counter, short uniqueCounter, short linearCounter, String 
reason) {
+               Message msg = new Message(FNPRHReturnSubMessage);
+               msg.set(NEAREST_LOCATION, nearest);
+               msg.set(BEST_LOCATION, best);
+               msg.set(COUNTER, counter);
+               msg.set(UNIQUE_COUNTER, uniqueCounter);
+               msg.set(LINEAR_COUNTER, linearCounter);
+               msg.set(REASON, reason);
+               return msg;
+       }
+       
+       public static final MessageType FNPRHProbeTrace = new 
MessageType("FNPRHProbeTrace", PRIORITY_LOW) {{
+               addField(UID, Long.class);
+               addField(NEAREST_LOCATION, Double.class);
+               addField(BEST_LOCATION, Double.class);
+               addField(HTL, Short.class);
+               addField(COUNTER, Short.class);
+               addField(UNIQUE_COUNTER, Short.class);
+               addField(LOCATION, Double.class);
+               addField(MY_UID, Long.class);
+               addField(PEER_LOCATIONS, ShortBuffer.class);
+               addField(PEER_UIDS, ShortBuffer.class);
+               addField(FORK_COUNT, Short.class);
+               addField(LINEAR_COUNTER, Short.class);
+               addField(REASON, String.class);
+               addField(PREV_UID, Long.class);
+       }};
+
+       public static Message createFNPRHProbeTrace(long uid, double nearest, 
double best, short htl, short counter, short uniqueCounter, double myLoc, long 
swapIdentifier, double[] peerLocs, long[] peerUIDs, short forkCount, short 
linearCounter, String reason, long prevUID) {
+               return createFNPRHProbeTrace(uid, nearest, best, htl, counter, 
uniqueCounter, myLoc, swapIdentifier, new 
ShortBuffer(Fields.doublesToBytes(peerLocs)), new 
ShortBuffer(Fields.longsToBytes(peerUIDs)), forkCount, linearCounter, reason, 
prevUID);
+       }
+       
+       public static Message createFNPRHProbeTrace(long uid, double nearest, 
double best, short htl, short counter, short uniqueCounter, double myLoc, long 
swapIdentifier, ShortBuffer peerLocs, ShortBuffer peerUIDs, short forkCount, 
short linearCounter, String reason, long prevUID) {
+               Message msg = new Message(FNPRHProbeTrace);
+               msg.set(UID, uid);
+               msg.set(NEAREST_LOCATION, nearest);
+               msg.set(BEST_LOCATION, best);
+               msg.set(HTL, htl);
+               msg.set(COUNTER, counter);
+               msg.set(UNIQUE_COUNTER, uniqueCounter);
+               msg.set(LOCATION, myLoc);
+               msg.set(MY_UID, swapIdentifier);
+               msg.set(PEER_LOCATIONS, peerLocs);
+               msg.set(PEER_UIDS, peerUIDs);
+               msg.set(FORK_COUNT, forkCount);
+               msg.set(LINEAR_COUNTER, linearCounter);
+               msg.set(REASON, reason);
+               msg.set(PREV_UID, prevUID);
+               return msg;
+       }
+
        public static final MessageType FNPProbeRequest = new 
MessageType("FNPProbeRequest", PRIORITY_HIGH) {{
                addField(UID, Long.class);
                addField(TARGET_LOCATION, Double.class);

Modified: trunk/freenet/src/freenet/node/GlobalProbe.java
===================================================================
--- trunk/freenet/src/freenet/node/GlobalProbe.java     2008-01-31 13:14:57 UTC 
(rev 17421)
+++ trunk/freenet/src/freenet/node/GlobalProbe.java     2008-01-31 14:36:48 UTC 
(rev 17422)
@@ -21,8 +21,8 @@
                this.node = n;
                this.probeType = probeType;
        cb = new ProbeCallback() {
-                       public void onCompleted(String reason, double target, 
double best, double nearest, long id, short counter, short linearCount) {
-                               String msg = "Completed probe request: 
"+target+" -> "+best+"\r\nNearest actually hit "+nearest+", "+counter+" nodes 
("+linearCount+" hops) in "+(System.currentTimeMillis() - lastTime)+", id 
"+id+"\r\n";
+                       public void onCompleted(String reason, double target, 
double best, double nearest, long id, short counter, short uniqueCount, short 
linearCount) {
+                               String msg = "Completed probe request: 
"+target+" -> "+best+"\r\nNearest actually hit "+nearest+", "+counter+" nodes 
("+linearCount+" hops"+uniqueCount+" unique nodes) in 
"+(System.currentTimeMillis() - lastTime)+", id "+id+"\r\n";
                                Logger.error(this, msg);
                                synchronized(GlobalProbe.this) {
                                        doneSomething = true;
@@ -36,6 +36,10 @@
                                String msg = "Probe trace: UID="+uid+" 
target="+target+" nearest="+nearest+" best="+best+" htl="+htl+" 
counter="+counter+" location="+location+" node UID="+nodeUID+" prev 
UID="+prevUID+" peers="+NodeDispatcher.peersUIDsToString(peerUIDs, peerLocs)+" 
locs not visited: "+StringArray.toString(locsNotVisited)+" fork count: 
"+forkCount+" linear count: "+linearCount+" from "+reason;
                                Logger.normal(this, msg);
                        }
+
+                       public void onRejectOverload() {
+                               Logger.normal(this, "Probe trace received 
rejected overload");
+                       }
        };

        }

Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java    2008-01-31 13:14:57 UTC (rev 
17421)
+++ trunk/freenet/src/freenet/node/Node.java    2008-01-31 14:36:48 UTC (rev 
17422)
@@ -244,6 +244,7 @@

        // 900ms
        static final int MIN_INTERVAL_BETWEEN_INCOMING_SWAP_REQUESTS = 900;
+       static final int MIN_INTERVAL_BETWEEN_INCOMING_PROBE_REQUESTS = 1000;
        public static final int SYMMETRIC_KEY_LENGTH = 32; // 256 bits - note 
that this isn't used everywhere to determine it
        /** Minimum space for zipped logfiles on testnet */
        static final long TESTNET_MIN_MAX_ZIPPED_LOGFILES = 512*1024*1024;

Modified: trunk/freenet/src/freenet/node/NodeDispatcher.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeDispatcher.java  2008-01-31 13:14:57 UTC 
(rev 17421)
+++ trunk/freenet/src/freenet/node/NodeDispatcher.java  2008-01-31 14:36:48 UTC 
(rev 17422)
@@ -12,6 +12,7 @@
 import freenet.io.comm.MessageType;
 import freenet.io.comm.NotConnectedException;
 import freenet.io.comm.Peer;
+import freenet.support.Fields;
 import freenet.support.Logger;
 import freenet.support.ShortBuffer;

@@ -134,6 +135,8 @@
                        return handleInsertRequest(m, source, false);
                } else if(spec == DMT.FNPSSKInsertRequest) {
                        return handleInsertRequest(m, source, true);
+               } else if(spec == DMT.FNPRHProbeRequest) {
+                       return handleProbeRequest(m, source);
                } else if(spec == DMT.FNPRoutedPing) {
                        return handleRouted(m, source);
                } else if(spec == DMT.FNPRoutedPong) {
@@ -290,6 +293,34 @@
                if(logMINOR) Logger.minor(this, "Started InsertHandler for 
"+id);
                return true;
        }
+       
+       private boolean handleProbeRequest(Message m, PeerNode source) {
+               long id = m.getLong(DMT.UID);
+               if(node.recentlyCompleted(id)) {
+                       Message rejected = DMT.createFNPRejectedLoop(id);
+                       try {
+                               source.sendAsync(rejected, null, 0, null);
+                       } catch (NotConnectedException e) {
+                               Logger.normal(this, "Rejecting probe request 
from "+source.getPeer()+": "+e);
+                       }
+                       return true;
+               }
+               // Lets not bother with full lockUID, just add it to the 
recently completed list.
+               node.completed(id);
+               // SSKs don't fix bwlimitDelayTime so shouldn't be accepted 
when overloaded.
+               if(source.shouldRejectProbeRequest()) {
+                       Logger.normal(this, "Rejecting probe request from 
"+source.getPeer());
+                       Message rejected = DMT.createFNPRejectedOverload(id, 
true);
+                       try {
+                               source.sendAsync(rejected, null, 0, null);
+                       } catch (NotConnectedException e) {
+                               Logger.normal(this, "Rejecting (overload) 
insert request from "+source.getPeer()+": "+e);
+                       }
+                       return true;
+               }
+               ResettingHTLProbeRequestHandler.start(m, source, node);
+               return true;
+       }

        private boolean handleAnnounceRequest(Message m, PeerNode source) {
                long uid = m.getLong(DMT.UID);
@@ -549,11 +580,37 @@
        // Probe requests

        // FIXME
-       public static final int PROBE_TYPE_DEFAULT = 0;
+       public static final int PROBE_TYPE_RESETTING_HTL = 0;

-       public void startProbe(double d, ProbeCallback cb, int probeType) {
-               long l = node.random.nextLong();
-               // FIXME implement!
-               throw new UnsupportedOperationException();
+       public void startProbe(final double target, final ProbeCallback cb, int 
probeType) {
+               final long uid = node.random.nextLong();
+               if(probeType == PROBE_TYPE_RESETTING_HTL) {
+                       ResettingHTLProbeRequestSender rs = new 
ResettingHTLProbeRequestSender(target, node.maxHTL(), uid, node, 
node.getLocation(), true, null, -1.0);
+                       rs.addListener(new 
ResettingHTLProbeRequestSender.Listener() {
+
+                               public void onCompletion(double nearest, double 
best, short counter, short uniqueCounter, short linearCounter) throws 
NotConnectedException {
+                                       cb.onCompleted("completed", target, 
best, nearest, uid, counter, uniqueCounter, linearCounter);
+                               }
+
+                               public void onRNF(short htl, double nearest, 
double best, short counter, short uniqueCounter, short linearCounter) throws 
NotConnectedException {
+                                       cb.onCompleted("rnf", target, best, 
nearest, uid, counter, uniqueCounter, linearCounter);                           
            
+                               }
+
+                               public void onReceivedRejectOverload() throws 
NotConnectedException {
+                                       cb.onRejectOverload();
+                               }
+
+                               public void onTimeout(double nearest, double 
best, short counter, short uniqueCounter, short linearCounter, String reason) 
throws NotConnectedException {
+                                       cb.onCompleted("timeout", target, best, 
nearest, uid, counter, uniqueCounter, linearCounter);                           
        
+                               }
+
+                               public void onTrace(long uid, double nearest, 
double best, short htl, short counter, short uniqueCounter, double location, 
long myUID, ShortBuffer peerLocs, ShortBuffer peerUIDs, short forkCount, short 
linearCounter, String reason, long prevUID) throws NotConnectedException {
+                                       cb.onTrace(uid, target, nearest, best, 
htl, counter, location, myUID, Fields.bytesToDoubles(peerLocs.getData()), 
Fields.bytesToLongs(peerUIDs.getData()), new double[0], forkCount, 
linearCounter, reason, prevUID);
+                               }
+                               
+                       });
+               } else {
+                       throw new IllegalArgumentException("Unknown probe 
request type");
+               }
        }
 }
\ No newline at end of file

Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java        2008-01-31 13:14:57 UTC 
(rev 17421)
+++ trunk/freenet/src/freenet/node/PeerNode.java        2008-01-31 14:36:48 UTC 
(rev 17422)
@@ -189,6 +189,10 @@
        private long timeLastReceivedSwapRequest;
        /** Average interval between SwapRequest's */
        private final RunningAverage swapRequestsInterval;
+       /** When did we last receive a probe request? */
+       private long timeLastReceivedProbeRequest;
+       /** Average interval between probe requests */
+       private final RunningAverage probeRequestsInterval;
        /** Should we decrement HTL when it is at the maximum? 
        * This decision is made once per node to prevent giving
        * away information that can make correlation attacks much
@@ -533,6 +537,7 @@
                timeAddedOrRestarted = System.currentTimeMillis();

                swapRequestsInterval = new SimpleRunningAverage(50, 
Node.MIN_INTERVAL_BETWEEN_INCOMING_SWAP_REQUESTS);
+               probeRequestsInterval = new SimpleRunningAverage(50, 
Node.MIN_INTERVAL_BETWEEN_INCOMING_PROBE_REQUESTS);

                // Not connected yet; need to handshake
                isConnected = false;
@@ -1557,6 +1562,26 @@
        }

        /**
+       * Should we reject a swap request?
+       */
+       public boolean shouldRejectProbeRequest() {
+               long now = System.currentTimeMillis();
+               synchronized(this) {
+                       if(timeLastReceivedProbeRequest > 0) {
+                               long timeSinceLastTime = now - 
timeLastReceivedProbeRequest;
+                               probeRequestsInterval.report(timeSinceLastTime);
+                               double averageInterval = 
probeRequestsInterval.currentValue();
+                               if(averageInterval >= 
Node.MIN_INTERVAL_BETWEEN_INCOMING_PROBE_REQUESTS) {
+                                       timeLastReceivedProbeRequest = now;
+                                       return false;
+                               } else return true;
+                       }
+                       timeLastReceivedProbeRequest = now;
+               }
+               return false;
+       }
+
+       /**
        * IP on the other side appears to have changed...
        * @param newPeer The new address of the peer.
        */

Modified: trunk/freenet/src/freenet/node/ProbeCallback.java
===================================================================
--- trunk/freenet/src/freenet/node/ProbeCallback.java   2008-01-31 13:14:57 UTC 
(rev 17421)
+++ trunk/freenet/src/freenet/node/ProbeCallback.java   2008-01-31 14:36:48 UTC 
(rev 17422)
@@ -6,8 +6,13 @@
 /** Callback for a locally initiated probe request */
 public interface ProbeCallback {

-       void onCompleted(String reason, double target, double best, double 
nearest, long id, short counter, short linearCount);
+       void onCompleted(String reason, double target, double best, double 
nearest, long id, short counter, short uniqueCounter, short linearCounter);

        void onTrace(long uid, double target, double nearest, double best, 
short htl, short counter, double location, long nodeUID, double[] peerLocs, 
long[] peerUIDs, double[] locsNotVisited, short forkCount, short linearCount, 
String reason, long prevUID);

+       /** Got a RejectedOverload passed down from some upstream node. Note 
that not all probe request
+        * implementations may generate these.
+        */
+       void onRejectOverload();
+
 }

Modified: trunk/freenet/src/freenet/node/TextModeClientInterface.java
===================================================================
--- trunk/freenet/src/freenet/node/TextModeClientInterface.java 2008-01-31 
13:14:57 UTC (rev 17421)
+++ trunk/freenet/src/freenet/node/TextModeClientInterface.java 2008-01-31 
14:36:48 UTC (rev 17422)
@@ -839,8 +839,8 @@
                String s = uline.substring("PROBE:".length()).trim();
                double d = Double.parseDouble(s);
                ProbeCallback cb = new ProbeCallback() {
-                               public void onCompleted(String reason, double 
target, double best, double nearest, long id, short counter, short 
linearCounter) {
-                                       String msg = "Completed probe request: 
"+target+" -> "+best+"\r\nNearest actually hit "+nearest+", "+counter+" nodes 
("+linearCounter+" hops), id "+id+"\r\n";
+                               public void onCompleted(String reason, double 
target, double best, double nearest, long id, short counter, short 
uniqueCounter, short linearCounter) {
+                                       String msg = "Completed probe request: 
"+target+" -> "+best+"\r\nNearest actually hit "+nearest+", "+counter+" nodes 
("+uniqueCounter+" unique, "+linearCounter+" hops), id "+id+"\r\n";
                                        try {
                                                out.write(msg.getBytes());
                                                out.flush();
@@ -862,9 +862,19 @@
                                                // Ignore
                                        }
                                }
+
+                               public void onRejectOverload() {
+                                       String msg = "Probe trace received 
RejectOverload";
+                                       try {
+                                               out.write(msg.getBytes());
+                                               out.flush();
+                                       } catch (IOException e) {
+                                               // Ignore
+                                       }
+                               }
                };
                outsb.append("Probing keyspace around "+d+" ...");
-               n.dispatcher.startProbe(d, cb, 
NodeDispatcher.PROBE_TYPE_DEFAULT);
+               n.dispatcher.startProbe(d, cb, 
NodeDispatcher.PROBE_TYPE_RESETTING_HTL);
                synchronized(this) {
                        while(!doneSomething) {
                                try {
@@ -879,7 +889,7 @@
                uline = uline.substring("PROBEALL".length());
                if(uline.startsWith(":")) uline = uline.substring(1);
                if(uline.length() == 0) {
-                       probeAll(NodeDispatcher.PROBE_TYPE_DEFAULT);
+                       probeAll(NodeDispatcher.PROBE_TYPE_RESETTING_HTL);
                } else {
                        probeAll(Integer.parseInt(uline));
                }


Reply via email to