Author: nextgens
Date: 2007-11-21 17:26:21 +0000 (Wed, 21 Nov 2007)
New Revision: 15908
Modified:
trunk/freenet/src/freenet/node/FNPPacketMangler.java
trunk/freenet/src/freenet/node/PacketSender.java
trunk/freenet/src/freenet/node/PeerNode.java
Log:
Implement session-key rekeying.
We rekey once per hour or if more than 1G of data has been transfered...
whichever comes first.
Modified: trunk/freenet/src/freenet/node/FNPPacketMangler.java
===================================================================
--- trunk/freenet/src/freenet/node/FNPPacketMangler.java 2007-11-21
16:32:22 UTC (rev 15907)
+++ trunk/freenet/src/freenet/node/FNPPacketMangler.java 2007-11-21
17:26:21 UTC (rev 15908)
@@ -103,6 +103,10 @@
/** The key used to authenticate the hmac */
private final byte[] transientKey = new byte[TRANSIENT_KEY_SIZE];
public static final int TRANSIENT_KEY_REKEYING_MIN_INTERVAL =
30*60*1000;
+ /** The rekeying interval for the session key (keytrackers) */
+ public static final int SESSION_KEY_REKEYING_INTERVAL = 60*60*1000;
+ /** The amount of data sent before we ask for a rekey */
+ public static final int AMOUNT_OF_BYTES_ALLOWED_BEFORE_WE_REKEY = 1024
* 1024;
/** The Runnable in charge of rekeying on a regular basis */
private final Runnable transientKeyRekeyer = new Runnable() {
public void run() {
@@ -1817,6 +1821,8 @@
usm.checkFilters(m, sock);
}
}
+
+ tracker.pn.maybeRekey(tracker);
if(logMINOR) Logger.minor(this, "Done");
}
@@ -2075,8 +2081,8 @@
Logger.normal(this, "Key changed(2) for
"+peer.getPeer());
if(last == peer.getCurrentKeyTracker()) {
if(peer.isConnected()) {
- Logger.error(this, "Peer is
connected, yet current tracker is deprecated !!: "+e, e);
- throw new
NotConnectedException("Peer is connected, yet current tracker is deprecated !!:
"+e);
+ Logger.error(this, "Peer is
connected, yet current tracker is deprecated !! (rekey ?): "+e, e);
+ throw new
NotConnectedException("Peer is connected, yet current tracker is deprecated !!
(rekey ?): "+e);
}
}
// Go around again
Modified: trunk/freenet/src/freenet/node/PacketSender.java
===================================================================
--- trunk/freenet/src/freenet/node/PacketSender.java 2007-11-21 16:32:22 UTC
(rev 15907)
+++ trunk/freenet/src/freenet/node/PacketSender.java 2007-11-21 17:26:21 UTC
(rev 15908)
@@ -202,7 +202,7 @@
lastReceivedPacketFromAnyNode =
Math.max(pn.lastReceivedPacketTime(),
lastReceivedPacketFromAnyNode);
pn.maybeOnConnect();
- if(pn.isConnected()) {
+ if(pn.isConnected() && !pn.isRekeying()) {
// Is the node dead?
if(now - pn.lastReceivedPacketTime() >
pn.maxTimeBetweenReceivedPackets()) {
Logger.normal(this, "Disconnecting from "+pn+" -
haven't received packets recently");
Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java 2007-11-21 16:32:22 UTC
(rev 15907)
+++ trunk/freenet/src/freenet/node/PeerNode.java 2007-11-21 17:26:21 UTC
(rev 15908)
@@ -123,6 +123,15 @@
/** Previous key - has a separate packet number space */
private KeyTracker previousTracker;
+ /** When did we last rekey (promote the unverified tracker to new) ? */
+ private long timeLastRekeyed;
+
+ /** How much data did we send with the current tracker ? */
+ private long totalBytesExchangedWithCurrentTracker = 0;
+
+ /** Are we rekeying ? */
+ private boolean isRekeying = false;
+
/** Unverified tracker - will be promoted to currentTracker if
* we receive packets on it
*/
@@ -950,6 +959,26 @@
public synchronized long timeLastRoutable() {
return timeLastRoutable;
}
+
+ protected void maybeRekey(final KeyTracker tracker) {
+ long now = System.currentTimeMillis();
+ boolean hasRekeyed = false;
+ if(hasLiveHandshake(now)) return;
+ synchronized (this) {
+ if(isRekeying || !isConnected) return;
+ if((timeLastRekeyed +
FNPPacketMangler.SESSION_KEY_REKEYING_INTERVAL < now) ||
(totalBytesExchangedWithCurrentTracker >
FNPPacketMangler.AMOUNT_OF_BYTES_ALLOWED_BEFORE_WE_REKEY)) {
+ hasRekeyed = true;
+ isRekeying = true;
+ tracker.deprecated();
+ }
+ }
+ if(hasRekeyed)
+ Logger.normal(this, "We are asking for the key to be renewed
("+this.detectedPeer+')');
+ }
+
+ protected synchronized boolean isRekeying() {
+ return isRekeying;
+ }
/**
* @return The time this PeerNode was added to the node (persistent across
restarts).
@@ -980,6 +1009,7 @@
// Force renegotiation.
isConnected = false;
isRoutable = false;
+ isRekeying = false;
// Prevent sending packets to the node until that happens.
if(currentTracker != null)
currentTracker.disconnected();
@@ -1079,15 +1109,13 @@
public boolean shouldSendHandshake() {
long now = System.currentTimeMillis();
boolean tempShouldSendHandshake = false;
- synchronized(this) {
- tempShouldSendHandshake = (!isConnected()) &&
- (handshakeIPs != null) &&
- (now > sendHandshakeTime);
- }
- if(tempShouldSendHandshake && (hasLiveHandshake(now))) {
- tempShouldSendHandshake = false;
- }
- return tempShouldSendHandshake;
+ synchronized (this) {
+ tempShouldSendHandshake = ((!isConnected()) && (handshakeIPs !=
null) && (now > sendHandshakeTime)) || isRekeying;
+ }
+ if (tempShouldSendHandshake && (hasLiveHandshake(now))) {
+ tempShouldSendHandshake = false;
+ }
+ return tempShouldSendHandshake;
}
/**
@@ -1510,7 +1538,6 @@
if(bootIDChanged && logMINOR)
Logger.minor(this, "Changed boot ID from
"+bootID+" to "+thisBootID+" for "+getPeer());
this.bootID = thisBootID;
- connectedTime = now;
if(bootIDChanged) {
oldPrev = previousTracker;
oldCur = currentTracker;
@@ -1534,7 +1561,14 @@
peerAddedTime = 0; // don't store anymore
ctx = null;
}
- sentInitialMessages = false;
+
+ if(!isRekeying) {
+ connectedTime = now;
+ sentInitialMessages = false;
+ }
+ isRekeying = false;
+ timeLastRekeyed = now;
+ totalBytesExchangedWithCurrentTracker = 0;
}
if(bootIDChanged) {
@@ -2621,10 +2655,12 @@
public synchronized void reportIncomingBytes(int length) {
totalBytesIn += length;
+ totalBytesExchangedWithCurrentTracker += length;
}
public synchronized void reportOutgoingBytes(int length) {
totalBytesOut += length;
+ totalBytesExchangedWithCurrentTracker += length;
}
public synchronized long getTotalInputBytes() {