Author: toad
Date: 2007-12-08 18:43:54 +0000 (Sat, 08 Dec 2007)
New Revision: 16417

Modified:
   trunk/freenet/src/freenet/node/FNPPacketMangler.java
   trunk/freenet/src/freenet/node/OutgoingPacketMangler.java
   trunk/freenet/src/freenet/node/PeerNode.java
Log:
Divide the inter-handshake interval by the number of peers to send it to, and 
alternate between them.
Hopefully this will fix the problems we've been having with multi-homing.
It's either this, or some major refactoring to properly support multiple 
connections to the same peer...

Modified: trunk/freenet/src/freenet/node/FNPPacketMangler.java
===================================================================
--- trunk/freenet/src/freenet/node/FNPPacketMangler.java        2007-12-08 
18:30:23 UTC (rev 16416)
+++ trunk/freenet/src/freenet/node/FNPPacketMangler.java        2007-12-08 
18:43:54 UTC (rev 16417)
@@ -2471,52 +2471,16 @@
                        Logger.normal(this, "Cannot send handshake to "+pn+" 
because no common negTypes, choosing random negType of "+negType);
                }
                if(logMINOR) Logger.minor(this, "Possibly sending handshake to 
"+pn+" negotiation type "+negType);
-               Peer[] handshakeIPs;
-               if(!pn.shouldSendHandshake()) {
-                       if(logMINOR) Logger.minor(this, "Not sending handshake 
to "+pn.getPeer()+" because pn.shouldSendHandshake() returned false");
-                       return;
-               }
-               long firstTime = System.currentTimeMillis();
-               handshakeIPs = pn.getHandshakeIPs();
-               long secondTime = System.currentTimeMillis();
-               if((secondTime - firstTime) > 1000)
-                       Logger.error(this, "getHandshakeIPs() took more than a 
second to execute ("+(secondTime - firstTime)+") working on 
"+pn.userToString());
-               if(handshakeIPs.length == 0) {
+               
+               Peer peer = pn.getHandshakeIP();
+               if(peer == null) {
                        pn.couldNotSendHandshake();
-                       long thirdTime = System.currentTimeMillis();
-                       if((thirdTime - secondTime) > 1000)
-                               Logger.error(this, "couldNotSendHandshake() 
(after getHandshakeIPs()) took more than a second to execute ("+(thirdTime - 
secondTime)+") working on "+pn.userToString());
                        return;
                }
-               int sentCount = 0;
-               long loopTime1 = System.currentTimeMillis();
-               for(int i=0;i<handshakeIPs.length;i++){
-                       Peer peer = handshakeIPs[i];
-                       FreenetInetAddress addr = peer.getFreenetAddress();
-                       if(!crypto.allowConnection(pn, addr)) {
-                               if(logMINOR)
-                                       Logger.minor(this, "Not sending 
handshake packet to "+peer+" for "+pn);
-                       }
-                       if(peer.getAddress(false) == null) {
-                               if(logMINOR) Logger.minor(this, "Not sending 
handshake to "+handshakeIPs[i]+" for "+pn.getPeer()+" because the DNS lookup 
failed or it's a currently unsupported IPv6 address");
-                               continue;
-                       }
-                       if((!pn.allowLocalAddresses()) && 
(!peer.isRealInternetAddress(false, false))) {
-                               if(logMINOR) Logger.minor(this, "Not sending 
handshake to "+handshakeIPs[i]+" for "+pn.getPeer()+" because it's not a real 
Internet address and metadata.allowLocalAddresses is not true");
-                               continue;
-                       }
-                       sendJFKMessage1(pn, peer, 
pn.handshakeUnknownInitiator(), pn.handshakeSetupType());
-                       if(logMINOR)
-                               Logger.minor(this, "Sending handshake to 
"+peer+" for "+pn+" ("+i+" of "+handshakeIPs.length);
-                       pn.sentHandshake();
-                       sentCount += 1;
-               }
-               long loopTime2 = System.currentTimeMillis();
-               if((loopTime2 - loopTime1) > 1000)
-                       Logger.normal(this, "loopTime2 is more than a second 
after loopTime1 ("+(loopTime2 - loopTime1)+") working on "+pn.userToString());
-               if(sentCount==0) {
-                       pn.couldNotSendHandshake();
-               }
+               sendJFKMessage1(pn, peer, pn.handshakeUnknownInitiator(), 
pn.handshakeSetupType());
+               if(logMINOR)
+                       Logger.minor(this, "Sending handshake to "+peer+" for 
"+pn);
+               pn.sentHandshake();
        }

        /* (non-Javadoc)
@@ -2764,4 +2728,8 @@
                return sock.getDetectedConnectivityStatus();
        }

+       public boolean allowConnection(PeerNode pn, FreenetInetAddress addr) {
+               return crypto.allowConnection(pn, addr);
+       }
+
 }

Modified: trunk/freenet/src/freenet/node/OutgoingPacketMangler.java
===================================================================
--- trunk/freenet/src/freenet/node/OutgoingPacketMangler.java   2007-12-08 
18:30:23 UTC (rev 16416)
+++ trunk/freenet/src/freenet/node/OutgoingPacketMangler.java   2007-12-08 
18:43:54 UTC (rev 16417)
@@ -4,6 +4,7 @@
 package freenet.node;

 import freenet.io.comm.AsyncMessageCallback;
+import freenet.io.comm.FreenetInetAddress;
 import freenet.io.comm.NotConnectedException;
 import freenet.io.comm.Peer;
 import freenet.io.comm.PeerContext;
@@ -111,4 +112,10 @@
         * @return A status code from AddressTracker. FIXME make this more 
generic when we need to.
         */
        public int getConnectivityStatus();
+
+       /**
+        * Is there any reason not to allow this connection? E.g. limits on the 
number of nodes on
+        * a specific IP address?
+        */
+       public boolean allowConnection(PeerNode node, FreenetInetAddress addr);
 }

Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java        2007-12-08 18:30:23 UTC 
(rev 16416)
+++ trunk/freenet/src/freenet/node/PeerNode.java        2007-12-08 18:43:54 UTC 
(rev 16417)
@@ -1204,6 +1204,9 @@
                        delay = Node.MIN_TIME_BETWEEN_HANDSHAKE_SENDS + 
node.random.nextInt(Node.RANDOMIZED_TIME_BETWEEN_HANDSHAKE_SENDS);
                }
                sendHandshakeTime = now + delay;
+               // FIXME proper multi-homing support!
+               delay /= (handshakeIPs == null ? 1 : handshakeIPs.length);
+               if(delay < 3000) delay = 3000;

                if(successfulHandshakeSend)
                        firstHandshake = false;
@@ -1231,6 +1234,10 @@
                        delay = Node.MIN_TIME_BETWEEN_HANDSHAKE_SENDS
                                + 
node.random.nextInt(Node.RANDOMIZED_TIME_BETWEEN_HANDSHAKE_SENDS);
                }
+               // FIXME proper multi-homing support!
+               delay /= (handshakeIPs == null ? 1 : handshakeIPs.length);
+               if(delay < 3000) delay = 3000;
+               
                sendHandshakeTime = now + delay;
                if(logMINOR) Logger.minor(this, "Next BurstOnly mode handshake 
in "+(sendHandshakeTime - now)+"ms for "+shortToString()+" (count: 
"+listeningHandshakeBurstCount+", size: "+listeningHandshakeBurstSize+ ')', new 
Exception("double-called debug"));
                return fetchARKFlag;
@@ -3284,5 +3291,65 @@
        public WeakReference getWeakRef() {
                return myRef;
        }
+
+       /**
+        * Get a single address to send a handshake to.
+        * The current code doesn't work well with multiple simulataneous 
handshakes.
+        * Alternates between valid values.
+        * (FIXME!)
+        */
+       public Peer getHandshakeIP() {
+               Peer[] handshakeIPs;
+               if(!shouldSendHandshake()) {
+                       if(logMINOR) Logger.minor(this, "Not sending handshake 
to "+getPeer()+" because pn.shouldSendHandshake() returned false");
+                       return null;
+               }
+               long firstTime = System.currentTimeMillis();
+               handshakeIPs = getHandshakeIPs();
+               long secondTime = System.currentTimeMillis();
+               if((secondTime - firstTime) > 1000)
+                       Logger.error(this, "getHandshakeIPs() took more than a 
second to execute ("+(secondTime - firstTime)+") working on "+userToString());
+               if(handshakeIPs.length == 0) {
+                       long thirdTime = System.currentTimeMillis();
+                       if((thirdTime - secondTime) > 1000)
+                               Logger.error(this, "couldNotSendHandshake() 
(after getHandshakeIPs()) took more than a second to execute ("+(thirdTime - 
secondTime)+") working on "+userToString());
+                       return null;
+               }
+               long loopTime1 = System.currentTimeMillis();
+               Vector validIPs = new Vector();
+               for(int i=0;i<handshakeIPs.length;i++){
+                       Peer peer = handshakeIPs[i];
+                       FreenetInetAddress addr = peer.getFreenetAddress();
+                       if(!outgoingMangler.allowConnection(this, addr)) {
+                               if(logMINOR)
+                                       Logger.minor(this, "Not sending 
handshake packet to "+peer+" for "+this);
+                       }
+                       if(peer.getAddress(false) == null) {
+                               if(logMINOR) Logger.minor(this, "Not sending 
handshake to "+handshakeIPs[i]+" for "+getPeer()+" because the DNS lookup 
failed or it's a currently unsupported IPv6 address");
+                               continue;
+                       }
+                       if((!allowLocalAddresses()) && 
(!peer.isRealInternetAddress(false, false))) {
+                               if(logMINOR) Logger.minor(this, "Not sending 
handshake to "+handshakeIPs[i]+" for "+getPeer()+" because it's not a real 
Internet address and metadata.allowLocalAddresses is not true");
+                               continue;
+                       }
+                       validIPs.add(peer);
+               }
+               Peer ret;
+               if(validIPs.size() > 1) {
+                       synchronized(this) {
+                               if(handshakeIPAlternator > validIPs.size())
+                                       handshakeIPAlternator = 0;
+                               ret = (Peer) 
validIPs.get(handshakeIPAlternator);
+                               handshakeIPAlternator++;
+                       }
+               } else {
+                       ret = (Peer) validIPs.get(0);
+               }
+               long loopTime2 = System.currentTimeMillis();
+               if((loopTime2 - loopTime1) > 1000)
+                       Logger.normal(this, "loopTime2 is more than a second 
after loopTime1 ("+(loopTime2 - loopTime1)+") working on "+userToString());
+               return ret;
+       }

+       private int handshakeIPAlternator;
 }


Reply via email to