On Wednesday 06 February 2008 20:04, robert at freenetproject.org wrote:
> Author: robert
> Date: 2008-02-06 20:04:55 +0000 (Wed, 06 Feb 2008)
> New Revision: 17609
>
> Added:
> trunk/freenet/src/freenet/node/NetworkIDManager.java
> Modified:
> trunk/freenet/src/freenet/node/Node.java
> trunk/freenet/src/freenet/node/NodeDispatcher.java
> Log:
> initial SecretPing implementation (for discussion; untested & disabled)
>
>
> Added: trunk/freenet/src/freenet/node/NetworkIDManager.java
> ===================================================================
> --- trunk/freenet/src/freenet/node/NetworkIDManager.java
>
(rev 0)
> +++ trunk/freenet/src/freenet/node/NetworkIDManager.java 2008-02-06
> 20:04:55
UTC (rev 17609)
...
> + if (disableSecretPings || node.recentlyCompleted(uid)) {
> + source.sendAsync(DMT.createFNPRejectedLoop(uid), null,
> 0, null);
> + } else {
> + StoredSecret match;
> + //Yes, I know... it looks really weird sync.ing on a
> separate map...
> + synchronized (secretsByPeer) {
> + match=(StoredSecret)secretsByUID.get(new
> Long(uid));
> + }
> + if (match!=null) {
> + //This is the node that the ping intends to
> reach, we will *not*
forward it; but we might not respond positively either.
> + //don't set the completed flag, we might reject
> it from one peer (too
short a path) and accept it from another.
> + if (htl > dawnHtl) {
> +
> source.sendAsync(DMT.createFNPRejectedLoop(uid), null, 0, null);
> + } else {
> + Logger.error(this, "Responding to
> "+source+" with "+match+"
from "+match.peer);
> +
> source.sendAsync(match.getSecretPong(counter+1), null, 0, null);
> + }
It's very likely that the long path to a node includes the short path, and if
we try the short path and get rejected, we won't be able to use the long
path.
So it's essential that on this path we don't add the UID to the
recentlyCompleted set.
> + } else {
> + //Set the completed flag immediately for
> determining reject loops
rather than locking the uid.
> + node.completed(uid);
Now, this is dangerous. If to get to node A you have to go through node B, and
you go through node B with a short path, then you won't be able to go through
node B with a longer path later on because the UID will be rejected.
IMHO if you want to find long paths you're going to have to start a few hops
out by random routing for a while.
I'm still not entirely sure I understand what's going on here: are you
attempting to show that you can connect to a specific node via a specific
subnetwork?
> +
> + //Not a local match... forward
> + double target=m.getDouble(DMT.TARGET_LOCATION);
> + HashSet routedTo=new HashSet();
> + HashSet notIgnored=new HashSet();
> + while (true) {
> + PeerNode next;
> +
> + if (htl > dawnHtl &&
> routedTo.isEmpty()) {
> +
> next=node.peers.getRandomPeer(source);
> + } else {
> +
> next=node.peers.closerPeer(source, routedTo, notIgnored, target,
true, node.isAdvancedModeEnabled(), -1, null);
> + }
> +
> + if (next==null) {
> + //would be rnf... but this is a
> more exhaustive and lightweight
search I suppose.
> +
> source.sendAsync(DMT.createFNPRejectedLoop(uid), null, 0, null);
> + break;
> + }
> +
> + htl=next.decrementHTL(htl);
> +
> + if (htl<=0) {
> + //would be dnf if we were
> looking for data.
> +
> source.sendAsync(DMT.createFNPRejectedLoop(uid), null, 0, null);
> + break;
> + }
> +
> + if (!source.isConnected()) {
> + throw new
> NotConnectedException("source gone away while forwarding");
> + }
> +
> + counter++;
> + routedTo.add(next);
> + try {
> +
> next.sendAsync(DMT.createFNPSecretPing(uid, target, htl, dawnHtl,
counter), null, 0, null);
> + } catch (NotConnectedException e) {
> + Logger.normal(this, next+"
> disconnected before secret-ping-forward");
> + continue;
> + }
> +
> + //wait for a reject or pong
> + MessageFilter mfPong =
MessageFilter.create().setSource(next).setField(DMT.UID,
uid).setTimeout(SECRETPONG_TIMEOUT).setType(DMT.FNPSecretPong);
> + MessageFilter mfRejectLoop =
MessageFilter.create().setSource(next).setField(DMT.UID,
uid).setTimeout(SECRETPONG_TIMEOUT).setType(DMT.FNPRejectedLoop);
> + Message msg;
> +
> + try {
> + msg =
> node.usm.waitFor(mfPong.or(mfRejectLoop), null);
> + } catch (DisconnectedException e) {
> + Logger.normal(this, next+"
> disconnected while waiting for a
secret-pong");
> + continue;
> + }
> +
> + if (msg==null) {
> + Logger.error(this, "fatal
> timeout in waiting for secretpong
from "+next);
> + //backoff?
> + break;
> + }
> +
> + if (msg.getSpec() == DMT.FNPSecretPong)
> {
> + int
> suppliedCounter=msg.getInt(DMT.COUNTER);
> + if (suppliedCounter>counter)
> + counter=suppliedCounter;
> + long
> secret=msg.getLong(DMT.SECRET);
> + Logger.error(this, node+"
> forwarding apparently-successful secretpong
response: "+counter+"/"+secret+" from "+next+" to "+source);
> +
> source.sendAsync(DMT.createFNPSecretPong(uid, counter, secret), null,
0, null);
> + break;
> + }
> +
> + if (msg.getSpec() ==
> DMT.FNPRejectedLoop) {
> + if (logMINOR)
> Logger.minor(this, "secret ping
(reject/loop): "+source+" -> "+next);
> + continue;
> + }
> +
> + Logger.error(this, "unexpected message
> type: "+msg);
> + break;
> + }
> + }
> + //unlockUID()
> + }
> + return true;
> + }
> +
> + //FIXME: This needs to be wired in.
> + public void onDisconnect(PeerNode pn) {
> + synchronized (secretsByPeer) {
> + StoredSecret s=(StoredSecret)secretsByPeer.get(pn);
> + if (s!=null) {
> + //???: Might it still be valid to respond to
> secret pings when the
neighbor requesting it has disconnected? (super-secret ping?)
> + Logger.error(this, "Removing on disconnect:
> "+s);
> + removeSecret(s);
> + }
> + }
> + }
> +
> + private void addOrReplaceSecret(StoredSecret s) {
> + synchronized (secretsByPeer) {
> + StoredSecret
> prev=(StoredSecret)secretsByPeer.get(s.peer);
> + if (prev!=null) {
> + Logger.normal(this, "Removing on replacement:
> "+s);
> + removeSecret(prev);
> + }
> + //Need to remember by peer (so we can remove it on
> disconnect)
> + //Need to remember by uid (so we can respond quickly to
> arbitrary
requests).
> + secretsByPeer.put(s.peer, s);
> + secretsByUID.put(new Long(s.uid), s);
> + }
> + }
> +
> + private void removeSecret(StoredSecret s) {
> + //synchronized (secretsByPeer) in calling functions
> + secretsByPeer.remove(s);
> + secretsByUID.remove(s);
> + }
> +
> + private static final class StoredSecret {
> + PeerNode peer;
> + long uid;
> + long secret;
> + StoredSecret(PeerNode peer, long uid, long secret) {
> + this.peer=peer;
> + this.uid=uid;
> + this.secret=secret;
> + }
> + public String toString() {
> + return "Secret("+uid+"/"+secret+")";
> + }
> + Message getSecretPong(int counter) {
> + return DMT.createFNPSecretPong(uid, counter, secret);
> + }
> + }
> +}
> \ No newline at end of file
>
> Modified: trunk/freenet/src/freenet/node/Node.java
> ===================================================================
> --- trunk/freenet/src/freenet/node/Node.java 2008-02-06 19:43:39 UTC (rev
17608)
> +++ trunk/freenet/src/freenet/node/Node.java 2008-02-06 20:04:55 UTC (rev
17609)
> @@ -189,6 +189,7 @@
>
> /** Stats */
> public final NodeStats nodeStats;
> + public final NetworkIDManager netid;
>
> /** Config object for the whole node. */
> public final PersistentConfig config;
> @@ -1445,6 +1446,8 @@
>
> clientCore = new NodeClientCore(this, config, nodeConfig,
> nodeDir,
getDarknetPortNumber(), sortOrder, oldThrottleFS == null ? null :
oldThrottleFS.subset("RequestStarters"), oldConfig, fproxyConfig, toadlets);
>
> + netid = new NetworkIDManager(this);
> +
> nodeConfig.register("disableHangCheckers", false, sortOrder++,
> true,
false, "Node.disableHangCheckers", "Node.disableHangCheckersLong", new
BooleanCallback() {
>
> public boolean get() {
>
> Modified: trunk/freenet/src/freenet/node/NodeDispatcher.java
> ===================================================================
> --- trunk/freenet/src/freenet/node/NodeDispatcher.java 2008-02-06
> 19:43:39
UTC (rev 17608)
> +++ trunk/freenet/src/freenet/node/NodeDispatcher.java 2008-02-06
> 20:04:55
UTC (rev 17609)
> @@ -74,6 +74,10 @@
> // Ignore
> }
> return true;
> + } else if (spec == DMT.FNPStoreSecret) {
> + return node.netid.handleStoreSecret(m);
> + } else if(spec == DMT.FNPSecretPing) {
> + return node.netid.handleSecretPing(m);
> } else if(spec == DMT.FNPDetectedIPAddress) {
> Peer p = (Peer) m.getObject(DMT.EXTERNAL_ADDRESS);
> source.setRemoteDetectedPeer(p);
> @@ -441,6 +445,7 @@
> }
> }
>
> + //FIXME: PLEASE! When are these contexts ever cleaned up!!!
Memory-leak-per-ping!
> final Hashtable routedContexts = new Hashtable();
>
> static class RoutedContext {
>
> _______________________________________________
> cvs mailing list
> cvs at freenetproject.org
> http://emu.freenetproject.org/cgi-bin/mailman/listinfo/cvs
>
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL:
<https://emu.freenetproject.org/pipermail/devl/attachments/20080208/c7db0e90/attachment.pgp>