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;
+ }
}