Author: nextgens
Date: 2008-10-28 18:09:24 +0000 (Tue, 28 Oct 2008)
New Revision: 23154

Modified:
   trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties
   trunk/freenet/src/freenet/node/FNPPacketMangler.java
   trunk/freenet/src/freenet/node/NodeCryptoConfig.java
Log:
Add a new config option to disable data-packet padding

Modified: trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties
===================================================================
--- trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties   2008-10-28 
17:41:52 UTC (rev 23153)
+++ trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties   2008-10-28 
18:09:24 UTC (rev 23154)
@@ -700,6 +700,8 @@
 Node.opennetEnabledLong=Enable insecure mode (aka opennet)? If this is 
enabled, the node will automatically exchange node references with other 
untrusted nodes (Strangers as opposed to Friends). 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 trusted 
(Friends) connections to them, and turn this off.
 Node.outBWLimit=Output bandwidth limit (bytes per second)
 Node.outBWLimitLong=Hard output bandwidth limit (bytes/sec); the node should 
almost never exceed this
+Node.paddDataPackets=Padd data packets sent by the node with random-length 
content?
+Node.paddDataPacketsLong=Padd data packets sent by the node with random-length 
content? It obviously increase the per-packet overhead so some people might 
want to turn it off.
 Node.passOpennetPeersThroughDarknet=Relay opennet noderefs through darknet 
peers?
 Node.passOpennetPeersThroughDarknetLong=If true, opennet noderefs (NEVER our 
own darknet noderef) will be relayed through our darknet peers. So a node (this 
node, or its peers) can get opennet peers from its darknet peers. This is 
useful because it allows us to bootstrap new opennet peers after having lost 
our peers due to downtime, for example. However, it may make traffic analysis 
slightly easier, so turn it off if you are paranoid.
 Node.port=FNP port number (UDP)

Modified: trunk/freenet/src/freenet/node/FNPPacketMangler.java
===================================================================
--- trunk/freenet/src/freenet/node/FNPPacketMangler.java        2008-10-28 
17:41:52 UTC (rev 23153)
+++ trunk/freenet/src/freenet/node/FNPPacketMangler.java        2008-10-28 
18:09:24 UTC (rev 23154)
@@ -2352,41 +2352,51 @@
                1 + // no forgotten packets
                length; // the payload !

-               if(logMINOR) Logger.minor(this, "Pre-padding length: 
"+packetLength);
-               
-               // Padding
-               // This will do an adequate job of disguising the contents, and 
a poor (but not totally
-               // worthless) job of disguising the traffic. FIXME!!!!!
-               // Ideally we'd mimic the size profile - and the session bytes! 
- of a common protocol.
+               boolean paddThisPacket = crypto.config.paddDataPackets();
+               int paddedLen;
+               if(paddThisPacket) {
+                       if(logMINOR)
+                               Logger.minor(this, "Pre-padding length: " + 
packetLength);

-               int paddedLen;
-               
-               if(packetLength < 64) {
-                       // Up to 37 bytes of payload (after base overhead above 
of 27 bytes), padded size 96-128 bytes.
-                       // Most small messages, and most ack only packets.
-                       paddedLen = 64 + node.fastWeakRandom.nextInt(32);
+                       // Padding
+                       // This will do an adequate job of disguising the 
contents, and a poor (but not totally
+                       // worthless) job of disguising the traffic. FIXME!!!!!
+                       // Ideally we'd mimic the size profile - and the 
session bytes! - of a common protocol.
+
+                       if(packetLength < 64)
+                               // Up to 37 bytes of payload (after base 
overhead above of 27 bytes), padded size 96-128 bytes.
+                               // Most small messages, and most ack only 
packets.
+                               paddedLen = 64 + 
node.fastWeakRandom.nextInt(32);
+                       else {
+                               // Up to 69 bytes of payload, final size 
128-192 bytes (CHK request, CHK insert, opennet announcement, CHK offer, swap 
reply) 
+                               // Up to 133 bytes of payload, final size 
192-256 bytes (SSK request, get offered CHK, offer SSK[, SSKInsertRequestNew], 
get offered SSK)
+                               // Up to 197 bytes of payload, final size 
256-320 bytes (swap commit/complete[, SSKDataFoundNew, SSKInsertRequestAltNew])
+                               // Up to 1093 bytes of payload, final size 
1152-1216 bytes (bulk transmit, block transmit, time deltas, SSK pubkey[, 
SSKData, SSKDataInsert])
+                               packetLength += 32;
+                               paddedLen = ((packetLength + 63) / 64) * 64;
+                               paddedLen += node.fastWeakRandom.nextInt(64);
+                               // FIXME get rid of this, we shouldn't be 
sending packets anywhere near this size unless
+                               // we've done PMTU...
+                               if(packetLength <= 1280 && paddedLen > 1280)
+                                       paddedLen = 1280;
+                               int maxPacketSize = sock.getMaxPacketSize();
+                               if(packetLength <= maxPacketSize && paddedLen > 
maxPacketSize)
+                                       paddedLen = maxPacketSize;
+                               packetLength -= 32;
+                               paddedLen -= 32;
+                       }
                } else {
-                       // Up to 69 bytes of payload, final size 128-192 bytes 
(CHK request, CHK insert, opennet announcement, CHK offer, swap reply) 
-                       // Up to 133 bytes of payload, final size 192-256 bytes 
(SSK request, get offered CHK, offer SSK[, SSKInsertRequestNew], get offered 
SSK)
-                       // Up to 197 bytes of payload, final size 256-320 bytes 
(swap commit/complete[, SSKDataFoundNew, SSKInsertRequestAltNew])
-                       // Up to 1093 bytes of payload, final size 1152-1216 
bytes (bulk transmit, block transmit, time deltas, SSK pubkey[, SSKData, 
SSKDataInsert])
-                       packetLength += 32;
-                       paddedLen = ((packetLength + 63) / 64) * 64;
-                       paddedLen += node.fastWeakRandom.nextInt(64);
-                       // FIXME get rid of this, we shouldn't be sending 
packets anywhere near this size unless
-                       // we've done PMTU...
-                       if(packetLength <= 1280 && paddedLen > 1280) paddedLen 
= 1280;
-                       int maxPacketSize = sock.getMaxPacketSize();
-                       if(packetLength <= maxPacketSize && paddedLen > 
maxPacketSize) paddedLen = maxPacketSize;
-                       packetLength -= 32;
-                       paddedLen -= 32;
+                       if(logMINOR)
+                               Logger.minor(this, "Don't padd the packet: we 
have been asked not to.");
+                       paddedLen = packetLength;
                }

                byte[] padding = new byte[paddedLen - packetLength];
-               node.fastWeakRandom.nextBytes(padding);
-
-               packetLength = paddedLen;
-
+               if(paddThisPacket) {
+                       node.fastWeakRandom.nextBytes(padding);
+                       packetLength = paddedLen;
+               }
+               
                if(logMINOR) Logger.minor(this, "Packet length: 
"+packetLength+" ("+length+")");

                byte[] plaintext = new byte[packetLength];
@@ -2496,8 +2506,10 @@
                System.arraycopy(buf, offset, plaintext, ptr, length);
                ptr += length;

-               System.arraycopy(padding, 0, plaintext, ptr, padding.length);
-               ptr += padding.length;
+               if(paddThisPacket) {
+                       System.arraycopy(padding, 0, plaintext, ptr, 
padding.length);
+                       ptr += padding.length;
+               }

                if(ptr != plaintext.length) {
                        Logger.error(this, "Inconsistent length: 
"+plaintext.length+" buffer but "+(ptr)+" actual");

Modified: trunk/freenet/src/freenet/node/NodeCryptoConfig.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeCryptoConfig.java        2008-10-28 
17:41:52 UTC (rev 23153)
+++ trunk/freenet/src/freenet/node/NodeCryptoConfig.java        2008-10-28 
18:09:24 UTC (rev 23154)
@@ -3,6 +3,7 @@
  * http://www.gnu.org/ for further details of the GPL. */
 package freenet.node;

+import freenet.config.NodeNeedRestartException;
 import java.net.UnknownHostException;

 import freenet.config.InvalidConfigValueException;
@@ -54,6 +55,9 @@
        /** If true, include local addresses on noderefs */
        public boolean includeLocalAddressesInNoderefs;

+       /** If false we won't make any effort do disguise the length of packets 
*/
+       private boolean paddDataPackets;
+       
        NodeCryptoConfig(SubConfig config, int sortOrder, boolean isOpennet, 
SecurityLevels securityLevels) throws NodeInitException {
                this.isOpennet = isOpennet;

@@ -231,6 +235,34 @@

                includeLocalAddressesInNoderefs = 
config.getBoolean("includeLocalAddressesInNoderefs");

+               // enable/disable Padding of outgoing packets (won't affect 
auth-packets)
+               
+               config.register("paddDataPackets", true, sortOrder++, true, 
false, "Node.paddDataPackets", "Node.paddDataPacketsLong", new 
BooleanCallback() {
+
+                       @Override
+                       public Boolean get() {
+                               return paddDataPackets;
+                       }
+
+                       @Override
+                       public void set(Boolean val) throws 
InvalidConfigValueException, NodeNeedRestartException {
+                               if(val == get()) return;
+                               paddDataPackets = val;
+                       }
+               });
+               
+               paddDataPackets = config.getBoolean("paddDataPackets");
+               securityLevels.addNetworkThreatLevelListener(new 
SecurityLevelListener<NETWORK_THREAT_LEVEL>() {
+
+                       public void onChange(NETWORK_THREAT_LEVEL oldLevel, 
NETWORK_THREAT_LEVEL newLevel) {
+                               // Might be useful for nodes which are running 
with a tight bandwidth quota to minimize the overhead,
+                               // so turn it off for LOW. Otherwise is 
sensible.
+                               if(newLevel == NETWORK_THREAT_LEVEL.LOW)
+                                       paddDataPackets = false;
+                               if(oldLevel == NETWORK_THREAT_LEVEL.LOW)
+                                       paddDataPackets = true;
+                       }
+               });
        }

        /** The number of config options i.e. the amount to increment sortOrder 
by */
@@ -303,5 +335,8 @@
        public boolean includeLocalAddressesInNoderefs() {
                return includeLocalAddressesInNoderefs;
        }
-
+       
+       public boolean paddDataPackets() {
+               return paddDataPackets;
+       }
 }


Reply via email to