Author: toad
Date: 2007-06-30 16:52:34 +0000 (Sat, 30 Jun 2007)
New Revision: 13850

Modified:
   trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties
   trunk/freenet/src/freenet/node/FNPPacketMangler.java
   trunk/freenet/src/freenet/node/Node.java
   trunk/freenet/src/freenet/node/NodeCrypto.java
   trunk/freenet/src/freenet/node/NodeCryptoConfig.java
   trunk/freenet/src/freenet/node/NodeIPPortDetector.java
   trunk/freenet/src/freenet/node/PeerManager.java
Log:
New config option for darknet and opennet (on by default on opennet): Limit to 
one connection per address?

Modified: trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties
===================================================================
--- trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties   2007-06-30 
15:39:07 UTC (rev 13849)
+++ trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties   2007-06-30 
16:52:34 UTC (rev 13850)
@@ -515,6 +515,8 @@
 Node.nodeDirLong=Name of directory to put node-related files e.g. peers list in
 Node.nodeName=Nickname for this Freenet node
 Node.nodeNameLong=Node nickname. This will be visible to your friends only.
+Node.oneConnectionPerIP=Limit to one connection per address?
+Node.oneConnectionPerIPLong=Don't allow more than one connection per address? 
This will make harvesting etc slightly harder by requiring a harvester to get 
more IP addresses (note that getting multiple IPs isn't a real deterrent, but 
it may help prevent casual harvesting). Also prevents having the same node 
connected on darknet and opennet simultaneously.
 Node.opennetEnabled=Enable Opennet support?
 Node.opennetEnabledLong=Enable Opennet? If opennet is enabled, the node will 
automatically exchange node references with other nodes. But this means that 
the fact that you are running a node is no longer private, and many attacks are 
much easier. If you know enough people running Freenet, you should stick to 
darknet connections to them.
 Node.outBWLimit=Output bandwidth limit (bytes per second)

Modified: trunk/freenet/src/freenet/node/FNPPacketMangler.java
===================================================================
--- trunk/freenet/src/freenet/node/FNPPacketMangler.java        2007-06-30 
15:39:07 UTC (rev 13849)
+++ trunk/freenet/src/freenet/node/FNPPacketMangler.java        2007-06-30 
16:52:34 UTC (rev 13850)
@@ -1506,26 +1506,22 @@
         int sentCount = 0;
         long loopTime1 = System.currentTimeMillis();
         for(int i=0;i<handshakeIPs.length;i++){
-               long innerLoopTime1 = System.currentTimeMillis();
-               if(handshakeIPs[i].getAddress(false) == null) {
+               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() && 
!handshakeIPs[i].isRealInternetAddress(false, false)) {
+               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;
                }
-               long innerLoopTime2 = System.currentTimeMillis();
-               if((innerLoopTime2 - innerLoopTime1) > 500)
-                       Logger.normal(this, "innerLoopTime2 is more than half a 
second after innerLoopTime1 ("+(innerLoopTime2 - innerLoopTime1)+") working on 
"+handshakeIPs[i]+" of "+pn.userToString());
-               sendFirstHalfDHPacket(0, negType, ctx.getOurExponential(), pn, 
handshakeIPs[i]);
-               long innerLoopTime3 = System.currentTimeMillis();
-               if((innerLoopTime3 - innerLoopTime2) > 500)
-                       Logger.normal(this, "innerLoopTime3 is more than half a 
second after innerLoopTime2 ("+(innerLoopTime3 - innerLoopTime2)+") working on 
"+handshakeIPs[i]+" of "+pn.userToString());
+               sendFirstHalfDHPacket(0, negType, ctx.getOurExponential(), pn, 
peer);
                pn.sentHandshake();
-               long innerLoopTime4 = System.currentTimeMillis();
-               if((innerLoopTime4 - innerLoopTime3) > 500)
-                       Logger.normal(this, "innerLoopTime4 is more than half a 
second after innerLoopTime3 ("+(innerLoopTime4 - innerLoopTime3)+") working on 
"+handshakeIPs[i]+" of "+pn.userToString());
                sentCount += 1;
         }
         long loopTime2 = System.currentTimeMillis();

Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java    2007-06-30 15:39:07 UTC (rev 
13849)
+++ trunk/freenet/src/freenet/node/Node.java    2007-06-30 16:52:34 UTC (rev 
13850)
@@ -604,7 +604,7 @@

                // Determine the port number

-               NodeCryptoConfig darknetConfig = new 
NodeCryptoConfig(nodeConfig, sortOrder++);
+               NodeCryptoConfig darknetConfig = new 
NodeCryptoConfig(nodeConfig, sortOrder++, false);
                sortOrder += NodeCryptoConfig.OPTION_COUNT;
                darknetCrypto = new NodeCrypto(sortOrder++, this, false, 
darknetConfig);

@@ -800,7 +800,7 @@

                boolean opennetEnabled = opennetConfig.getBoolean("enabled");

-               opennetCryptoConfig = new NodeCryptoConfig(opennetConfig, 1 /* 
0 = enabled */);
+               opennetCryptoConfig = new NodeCryptoConfig(opennetConfig, 1 /* 
0 = enabled */, true);

                if(opennetEnabled) {
                        opennet = new OpennetManager(this, opennetCryptoConfig);
@@ -2606,4 +2606,5 @@
                if(opennet == null) return -1;
                return opennet.crypto.portNumber;
        }
+
 }

Modified: trunk/freenet/src/freenet/node/NodeCrypto.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeCrypto.java      2007-06-30 15:39:07 UTC 
(rev 13849)
+++ trunk/freenet/src/freenet/node/NodeCrypto.java      2007-06-30 16:52:34 UTC 
(rev 13850)
@@ -389,5 +389,16 @@
                else
                        return node.peers.getDarknetPeers();
        }
+
+       public boolean allowConnection(PeerNode pn, FreenetInetAddress addr) {
+       if(config.oneConnectionPerAddress()) {
+               // Disallow multiple connections to the same address
+               if(node.peers.anyConnectedPeerHasAddress(addr, pn) && 
!detector.includes(addr)) {
+                       Logger.normal(this, "Not sending handshake packets to 
"+addr+" for "+pn+" : Same IP address as another node");
+                       return true;
+               }
+               }
+       return false;
+       }

 }

Modified: trunk/freenet/src/freenet/node/NodeCryptoConfig.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeCryptoConfig.java        2007-06-30 
15:39:07 UTC (rev 13849)
+++ trunk/freenet/src/freenet/node/NodeCryptoConfig.java        2007-06-30 
16:52:34 UTC (rev 13850)
@@ -9,6 +9,7 @@
 import freenet.config.SubConfig;
 import freenet.io.comm.FreenetInetAddress;
 import freenet.support.Logger;
+import freenet.support.api.BooleanCallback;
 import freenet.support.api.IntCallback;
 import freenet.support.api.StringCallback;

@@ -37,7 +38,11 @@
        /** Whether the NodeCrypto has finished starting */
        private boolean started;

-       NodeCryptoConfig(SubConfig config, int sortOrder) throws 
NodeInitException {
+       /** Whether we should prevent multiple connections to the same IP 
(taking into account other
+        * NodeCrypto's - this will usually be set for opennet but not for 
darknet). */
+       private boolean oneConnectionPerAddress;
+       
+       NodeCryptoConfig(SubConfig config, int sortOrder, boolean onePerIP) 
throws NodeInitException {

                config.register("listenPort", -1 /* means random */, 
sortOrder++, true, true, "Node.port", "Node.portLong",     new IntCallback() {
                        public int get() {
@@ -105,6 +110,24 @@

                });

+               
+               config.register("oneConnectionPerIP", onePerIP, sortOrder++, 
true, false, "Node.oneConnectionPerIP", "Node.oneConnectionPerIPLong",
+                               new BooleanCallback() {
+
+                                       public boolean get() {
+                                               
synchronized(NodeCryptoConfig.this) {
+                                                       return 
oneConnectionPerAddress;
+                                               }
+                                       }
+
+                                       public void set(boolean val) throws 
InvalidConfigValueException {
+                                               
synchronized(NodeCryptoConfig.this) {
+                                                       oneConnectionPerAddress 
= val;
+                                               }
+                                       }
+                       
+               });
+               
        }

        /** The number of config options i.e. the amount to increment sortOrder 
by */
@@ -159,4 +182,7 @@
                return dropProbability;
        }

+       public boolean oneConnectionPerAddress() {
+               return oneConnectionPerAddress;
+       }
 }

Modified: trunk/freenet/src/freenet/node/NodeIPPortDetector.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeIPPortDetector.java      2007-06-30 
15:39:07 UTC (rev 13849)
+++ trunk/freenet/src/freenet/node/NodeIPPortDetector.java      2007-06-30 
16:52:34 UTC (rev 13850)
@@ -153,4 +153,11 @@
                else
                        return lastPeers;
        }
+
+       public boolean includes(FreenetInetAddress addr) {
+               FreenetInetAddress[] a = detectPrimaryIPAddress();
+               for(int i=0;i<a.length;i++)
+                       if(a[i].equals(addr)) return true;
+               return false;
+       }
 }

Modified: trunk/freenet/src/freenet/node/PeerManager.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerManager.java     2007-06-30 15:39:07 UTC 
(rev 13849)
+++ trunk/freenet/src/freenet/node/PeerManager.java     2007-06-30 16:52:34 UTC 
(rev 13850)
@@ -22,6 +22,7 @@
 import java.util.Vector;
 import java.util.ArrayList;

+import freenet.io.comm.FreenetInetAddress;
 import freenet.io.comm.Message;
 import freenet.io.comm.NotConnectedException;
 import freenet.io.comm.Peer;
@@ -1197,4 +1198,17 @@
                }
                return (OpennetPeerNode[])v.toArray(new 
OpennetPeerNode[v.size()]);
        }
+
+       public boolean anyConnectedPeerHasAddress(FreenetInetAddress addr, 
PeerNode pn) {
+               PeerNode[] peers;
+               synchronized(this) {
+                       peers = myPeers;
+               }
+               for(int i=0;i<peers.length;i++) {
+                       if(peers[i] == pn) continue;
+                       if(!peers[i].isConnected()) continue;
+                       if(peers[i].getPeer().getFreenetAddress().equals(addr)) 
return true;
+               }
+               return false;
+       }
 }


Reply via email to