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>

Reply via email to