Author: zothar
Date: 2006-05-11 04:24:24 +0000 (Thu, 11 May 2006)
New Revision: 8652

Modified:
   trunk/freenet/src/freenet/io/NetworkInterface.java
   trunk/freenet/src/freenet/io/comm/Peer.java
   trunk/freenet/src/freenet/node/FNPPacketMangler.java
   trunk/freenet/src/freenet/node/Node.java
   trunk/freenet/src/freenet/node/PeerNode.java
Log:
When no IP addresses are available for handshake, reset the handshake timer.  
Only do DNS lookups during handshake and store the result.  Explicitly set 
Java's negative DNS cache TTL.  Factored out the repeated use of some address 
lookup methods within a few lines of each other.  Fixed an NPE caused by trying 
to call the canGetCipher() method on a null DHContext.  Added another 
short-circuit to getHandshakeIPs().

Modified: trunk/freenet/src/freenet/io/NetworkInterface.java
===================================================================
--- trunk/freenet/src/freenet/io/NetworkInterface.java  2006-05-11 01:07:59 UTC 
(rev 8651)
+++ trunk/freenet/src/freenet/io/NetworkInterface.java  2006-05-11 04:24:24 UTC 
(rev 8652)
@@ -257,6 +257,7 @@
                                try {
                                        Socket clientSocket = 
serverSocket.accept();
                                        InetAddress clientAddress = 
clientSocket.getInetAddress();
+                                       Logger.minor(Acceptor.class, 
"Connection from " + clientAddress);
                                        String clientHostName = 
clientAddress.getHostName();

                                        /* check if the ip address is allowed */

Modified: trunk/freenet/src/freenet/io/comm/Peer.java
===================================================================
--- trunk/freenet/src/freenet/io/comm/Peer.java 2006-05-11 01:07:59 UTC (rev 
8651)
+++ trunk/freenet/src/freenet/io/comm/Peer.java 2006-05-11 04:24:24 UTC (rev 
8652)
@@ -39,7 +39,7 @@
        // hostname - only set if we were created with a hostname
        // and not an address
        private final String hostname;
-       private final InetAddress _address;
+       private InetAddress _address;
        private final int _port;

        // Create a null peer
@@ -135,22 +135,49 @@
                if (_address != null) {
                        return _address;
                } else {
-                        Logger.minor(this, "Looking up '"+hostname+"' in DNS");
-                       /* 
-                        * Peers are constructed from an address once
-                        * a handshake has been completed, so this
-                        * lookup will only be performed during a 
-                        * handshake - it doesn't mean we perform
-                        * a DNS lookup with every packet we send.
-                        */
-                       try {
-                               return InetAddress.getByName(hostname);
-                       } catch (UnknownHostException e) {
-                               return null;
-                       }
+                       InetAddress addr = getHandshakeAddress();
+                       if( addr != null ) {
+                               this._address = addr;
+                       }
+                       return addr;
                }
        }

+       public InetAddress getHandshakeAddress() {
+           // Since we're handshaking, hostname-to-IP may have changed
+           if (_address != null && hostname == null) {
+               return _address;
+           } else {
+                Logger.minor(this, "Looking up '"+hostname+"' in DNS");
+               /* 
+                * Peers are constructed from an address once a
+                * handshake has been completed, so this lookup
+                * will only be performed during a handshake
+                * (this method should normally only be called
+                * from PeerNode.getHandshakeIPs() and once
+                * each connection from this.getAddress()
+                * otherwise) - it doesn't mean we perform a
+                * DNS lookup with every packet we send.
+                */
+               try {
+                    InetAddress addr = InetAddress.getByName(hostname);
+                    //Logger.normal(this, "Look up got '"+addr+"'");
+                    if( addr != null ) {
+                        /*
+                         * cache the answer since getHandshakeAddress()
+                         * doesn't use the cached value, thus
+                         * getHandshakeIPs() should always get the
+                         * latest value from DNS (minus Java's caching)
+                         */
+                        this._address = addr;
+                    }
+                    return addr;
+               } catch (UnknownHostException e) {
+                   return null;
+               }
+           }
+       }
+
        public int hashCode() {
                if (_address != null) {
                        return _address.hashCode() + _port;

Modified: trunk/freenet/src/freenet/node/FNPPacketMangler.java
===================================================================
--- trunk/freenet/src/freenet/node/FNPPacketMangler.java        2006-05-11 
01:07:59 UTC (rev 8651)
+++ trunk/freenet/src/freenet/node/FNPPacketMangler.java        2006-05-11 
04:24:24 UTC (rev 8652)
@@ -381,7 +381,7 @@
      */
     private DiffieHellmanContext processDHTwoOrThree(int i, byte[] payload, 
PeerNode pn, Peer replyTo, boolean sendCompletion) {
         DiffieHellmanContext ctx = pn.getDHContext();
-        if(!ctx.canGetCipher()) {
+        if(ctx == null || !ctx.canGetCipher()) {
             if(shouldLogErrorInHandshake()) {
                 Logger.error(this, "Cannot get cipher");
             }
@@ -1286,20 +1286,28 @@
     public void sendHandshake(PeerNode pn) {
         Logger.minor(this, "Possibly sending handshake to "+pn);
         DiffieHellmanContext ctx;
+        Peer[] handshakeIPs;
         synchronized(pn) {
-            if((!pn.shouldSendHandshake()) || pn.getHandshakeIPs().length == 
0) {
+            if(!pn.shouldSendHandshake()) return;
+            handshakeIPs = pn.getHandshakeIPs();
+            if(handshakeIPs.length == 0) {
+                pn.couldNotSendHandshake();
                 return;
             } else {
                 ctx = DiffieHellman.generateContext();
                 pn.setDHContext(ctx);
             }
         }
-
-        for(int i=0;i<pn.getHandshakeIPs().length;i++){
-          if( pn.getHandshakeIPs()[i].getAddress() == null ) continue;
-               sendFirstHalfDHPacket(0, ctx.getOurExponential(), pn, 
pn.getHandshakeIPs()[i]);
+        int sentCount = 0;
+        for(int i=0;i<handshakeIPs.length;i++){
+          if( handshakeIPs[i].getAddress() == null ) continue;
+               sendFirstHalfDHPacket(0, ctx.getOurExponential(), pn, 
handshakeIPs[i]);
                pn.sentHandshake();
+               sentCount += 1;
         }
+        if(sentCount==0) {
+            pn.couldNotSendHandshake();
+        }
     }

     public boolean isDisconnected(PeerContext context) {

Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java    2006-05-11 01:07:59 UTC (rev 
8651)
+++ trunk/freenet/src/freenet/node/Node.java    2006-05-11 04:24:24 UTC (rev 
8652)
@@ -497,6 +497,9 @@
        // use dyndns hostnames
        java.security.Security.setProperty("networkaddress.cache.ttl" , "300");

+       // set Java's negative DNS cache to 1 minute rather than the default 10 
seconds
+       java.security.Security.setProperty("networkaddress.cache.negative.ttl" 
, "60");
+       
        FilePersistentConfig cfg = new FilePersistentConfig(configFilename);

        // First, set up logging. It is global, and may be shared between 
several nodes.
@@ -1593,7 +1596,7 @@
                                Peer p = peerList[i].getRemoteDetectedPeer();
                                if(p == null || p.isNull()) continue;
                                InetAddress ip = p.getAddress();
-                               if(!IPUtil.checkAddress(p.getAddress())) 
continue;
+                               if(!IPUtil.checkAddress(ip)) continue;
                                if(countsByPeer.containsKey(ip)) {
                                        Integer count = (Integer) 
countsByPeer.get(ip);
                                        Integer newCount = new 
Integer(count.intValue()+1);

Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java        2006-05-11 01:07:59 UTC 
(rev 8651)
+++ trunk/freenet/src/freenet/node/PeerNode.java        2006-05-11 04:24:24 UTC 
(rev 8652)
@@ -358,8 +358,12 @@
        Peer[] p=null;

        if(detectedPeer == null && nominalPeer.size() == 0) return new Peer[0];
+
+       InetAddress peerIP = detectedPeer.getHandshakeAddress();
+
+       if(peerIP == null && nominalPeer.size() == 0) return new Peer[0];

-       if( ! nominalPeer.contains(detectedPeer)){
+       if( peerIP != null && ! nominalPeer.contains(detectedPeer)){
                p= new Peer[1+nominalPeer.size()];
                p[0]=detectedPeer;
                for(int i=1;i<nominalPeer.size()+1;i++)
@@ -371,7 +375,6 @@
        InetAddress localhost = node.localhostAddress;
        InetAddress nodeIP = node.getPrimaryIPAddress();
        if(nodeIP != null && nodeIP.equals(localhost)) return p;
-       InetAddress peerIP = detectedPeer.getAddress();
        if(peerIP != null && peerIP.equals(localhost)) return p;
        if(nodeIP != null && nodeIP.equals(peerIP)) {
                Peer[] newPeers = new Peer[p.length+1];
@@ -530,6 +533,7 @@
      * sent.
      */
     public synchronized void sentHandshake() {
+        Logger.debug(this, "sentHandshake(): "+this);
         long now = System.currentTimeMillis();
         if(invalidVersion() && !firstHandshake) {
             sendHandshakeTime = now + Node.MIN_TIME_BETWEEN_VERSION_PROBES
@@ -540,6 +544,24 @@
         }
         firstHandshake = false;
     }
+    
+    /**
+     * Call this method when a handshake request could not be sent (i.e. no IP 
address available)
+     * sent.
+     */
+    public synchronized void couldNotSendHandshake() {
+        Logger.minor(this, "couldNotSendHandshake(): "+this);
+        long now = System.currentTimeMillis();
+        if(invalidVersion() && !firstHandshake) {
+            sendHandshakeTime = now + Node.MIN_TIME_BETWEEN_VERSION_PROBES
+              + 
node.random.nextInt(Node.RANDOMIZED_TIME_BETWEEN_VERSION_PROBES)
+              + 
node.random.nextInt(Node.RANDOMIZED_TIME_BETWEEN_VERSION_PROBES);
+        } else {
+            sendHandshakeTime = now + Node.MIN_TIME_BETWEEN_HANDSHAKE_SENDS
+              + 
node.random.nextInt(Node.RANDOMIZED_TIME_BETWEEN_HANDSHAKE_SENDS)
+              + 
node.random.nextInt(Node.RANDOMIZED_TIME_BETWEEN_HANDSHAKE_SENDS);
+        }
+    }

     /**
      * @return The maximum time between received packets.


Reply via email to