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));
}