Author: toad
Date: 2008-12-02 18:51:25 +0000 (Tue, 02 Dec 2008)
New Revision: 24014

Modified:
   trunk/freenet/src/freenet/node/FNPPacketMangler.java
   trunk/freenet/src/freenet/node/PacketTracker.java
   trunk/freenet/src/freenet/node/PeerNode.java
Log:
New negotiation type 3. If we connect with neg type 3, we don't change the 
PacketTracker on rekeying.
Should help a lot with bug #2692.


Modified: trunk/freenet/src/freenet/node/FNPPacketMangler.java
===================================================================
--- trunk/freenet/src/freenet/node/FNPPacketMangler.java        2008-12-02 
13:55:19 UTC (rev 24013)
+++ trunk/freenet/src/freenet/node/FNPPacketMangler.java        2008-12-02 
18:51:25 UTC (rev 24014)
@@ -533,7 +533,7 @@
                        Logger.error(this, "Decrypted auth packet but invalid 
version: "+version);
                        return;
                }
-               if(negType != 2) {
+               if(!(negType == 2 || negType == 3)) {
                        Logger.error(this, "Unknown neg type: "+negType);
                        return;
                }
@@ -549,10 +549,10 @@
                
                if(packetType == 0) {
                        // Phase 1
-                       processJFKMessage1(payload,4,null,replyTo, true, 
setupType);
+                       processJFKMessage1(payload,4,null,replyTo, true, 
setupType, negType);
                } else if(packetType == 2) {
                        // Phase 3
-                       processJFKMessage3(payload, 4, null, replyTo, false, 
true, setupType);
+                       processJFKMessage3(payload, 4, null, replyTo, false, 
true, setupType, negType);
                } else {
                        Logger.error(this, "Invalid phase "+packetType+" for 
anonymous-initiator (we are the responder)");
                }
@@ -577,7 +577,7 @@
                        Logger.error(this, "Decrypted auth packet but invalid 
version: "+version);
                        return;
                }
-               if(negType != 2) {
+               if(!(negType == 2 || negType == 3)) {
                        Logger.error(this, "Unknown neg type: "+negType);
                        return;
                }
@@ -593,10 +593,10 @@
                
                if(packetType == 1) {
                        // Phase 2
-                       processJFKMessage2(payload, 4, pn, replyTo, true, 
setupType);
+                       processJFKMessage2(payload, 4, pn, replyTo, true, 
setupType, negType);
                } else if(packetType == 3) {
                        // Phase 4
-                       processJFKMessage4(payload, 4, pn, replyTo, false, 
true, setupType);
+                       processJFKMessage4(payload, 4, pn, replyTo, false, 
true, setupType, negType);
                } else {
                        Logger.error(this, "Invalid phase "+packetType+" for 
anonymous-initiator (we are the responder)");
                }
@@ -642,7 +642,7 @@
                } else if (negType == 1) {
                        Logger.error(this, "Old StationToStation (negType 1) 
not supported.");
                        return;
-               } else if (negType==2){
+               } else if (negType==2 || negType == 3){ // negType == 3 => no 
new PacketTracker when rekeying
                        /*
                         * We implement Just Fast Keying key management 
protocol with active identity protection
                         * for the initiator and no identity protection for the 
responder
@@ -673,7 +673,7 @@
                                 * session key will be different,can be used to 
differentiate between
                                 * parallel sessions
                                 */
-                               
processJFKMessage1(payload,3,pn,replyTo,false,-1);
+                               
processJFKMessage1(payload,3,pn,replyTo,false,-1,negType);
 
                        }
                        else if(packetType==1){
@@ -682,7 +682,7 @@
                                 * nonce and an authenticator calculated from a 
transient hash key private
                                 * to the responder.
                                 */
-                               
processJFKMessage2(payload,3,pn,replyTo,false,-1);
+                               
processJFKMessage2(payload,3,pn,replyTo,false,-1,negType);
                        }
                        else if(packetType==2){
                                /*
@@ -690,7 +690,7 @@
                                 * cached by the Responder.Receiving a 
duplicate message simply causes
                                 * the responder to Re-transmit the 
corresponding message4
                                 */
-                               processJFKMessage3(payload, 3, pn, replyTo, 
oldOpennetPeer, false, -1);
+                               processJFKMessage3(payload, 3, pn, replyTo, 
oldOpennetPeer, false, -1, negType);
                        }
                        else if(packetType==3){
                                /*
@@ -698,7 +698,7 @@
                                 * using the same keys as in the previous 
message.
                                 * The signature is non-message recovering
                                 */
-                               processJFKMessage4(payload, 3, pn, replyTo, 
oldOpennetPeer, false, -1);
+                               processJFKMessage4(payload, 3, pn, replyTo, 
oldOpennetPeer, false, -1, negType);
                        }
                } else {
                        Logger.error(this, "Decrypted auth packet but unknown 
negotiation type "+negType+" from "+replyTo+" possibly from "+pn);
@@ -729,7 +729,7 @@
         * ACM Transactions on Information and System Security, Vol 7 No 2, May 
2004, Pages 1-30.
         * 
         */     
-       private void processJFKMessage1(byte[] payload,int offset,PeerNode 
pn,Peer replyTo, boolean unknownInitiator, int setupType)
+       private void processJFKMessage1(byte[] payload,int offset,PeerNode 
pn,Peer replyTo, boolean unknownInitiator, int setupType, int negType)
        {
                long t1=System.currentTimeMillis();
                if(logMINOR) Logger.minor(this, "Got a JFK(1) message, 
processing it - "+pn);
@@ -760,7 +760,7 @@
                
                NativeBigInteger _hisExponential = new 
NativeBigInteger(1,hisExponential);
                if(DiffieHellman.checkDHExponentialValidity(this.getClass(), 
_hisExponential)) {
-                       sendJFKMessage2(nonceInitiator, hisExponential, pn, 
replyTo, unknownInitiator, setupType);
+                       sendJFKMessage2(nonceInitiator, hisExponential, pn, 
replyTo, unknownInitiator, setupType, negType);
                }else
                        Logger.error(this, "We can't accept the exponential 
"+pn+" sent us!! REDFLAG: IT CAN'T HAPPEN UNLESS AGAINST AN ACTIVE ATTACKER!!");
 
@@ -777,7 +777,7 @@
         * know the responder in all cases.
         * @param replyTo The peer to send the actual packet to.
         */
-       private void sendJFKMessage1(PeerNode pn, Peer replyTo, boolean 
unknownInitiator, int setupType) {
+       private void sendJFKMessage1(PeerNode pn, Peer replyTo, boolean 
unknownInitiator, int setupType, int negType) {
                if(logMINOR) Logger.minor(this, "Sending a JFK(1) message to 
"+replyTo+" for "+pn.getPeer());
                final long now = System.currentTimeMillis();
                DiffieHellmanLightContext ctx = (DiffieHellmanLightContext) 
pn.getKeyAgreementSchemeContext();
@@ -804,9 +804,9 @@
                if(unknownInitiator) {
                        offset += modulusLength;
                        System.arraycopy(pn.identityHash, 0, message1, offset, 
pn.identityHash.length);
-                       
sendAnonAuthPacket(1,2,0,setupType,message1,pn,replyTo,pn.anonymousInitiatorSetupCipher);
+                       
sendAnonAuthPacket(1,negType,0,setupType,message1,pn,replyTo,pn.anonymousInitiatorSetupCipher);
                } else {
-                       sendAuthPacket(1,2,0,message1,pn,replyTo);
+                       sendAuthPacket(1,negType,0,message1,pn,replyTo);
                }
                long t2=System.currentTimeMillis();
                if((t2-now)>500)
@@ -824,7 +824,7 @@
         * @param pn The node to encrypt the message for. CAN BE NULL if 
anonymous-initiator.
         * @param replyTo The peer to send the packet to.
         */
-       private void sendJFKMessage2(byte[] nonceInitator, byte[] 
hisExponential, PeerNode pn, Peer replyTo, boolean unknownInitiator, int 
setupType) {
+       private void sendJFKMessage2(byte[] nonceInitator, byte[] 
hisExponential, PeerNode pn, Peer replyTo, boolean unknownInitiator, int 
setupType, int negType) {
                if(logMINOR) Logger.minor(this, "Sending a JFK(2) message to 
"+pn);
                DiffieHellmanLightContext ctx = getLightDiffieHellmanContext();
                // g^r
@@ -857,9 +857,9 @@
                System.arraycopy(authenticator, 0, message2, offset, 
HASH_LENGTH);
 
                if(unknownInitiator)
-                       
sendAnonAuthPacket(1,2,1,setupType,message2,pn,replyTo,crypto.anonSetupCipher);
+                       
sendAnonAuthPacket(1,negType,1,setupType,message2,pn,replyTo,crypto.anonSetupCipher);
                else
-                       sendAuthPacket(1,2,1,message2,pn,replyTo);
+                       sendAuthPacket(1,negType,1,message2,pn,replyTo);
        }
 
        /*
@@ -896,7 +896,7 @@
         * @param pn The peerNode we are talking to. Cannot be null as we are 
the initiator.
         */
 
-       private void processJFKMessage2(byte[] payload,int inputOffset,PeerNode 
pn,Peer replyTo, boolean unknownInitiator, int setupType)
+       private void processJFKMessage2(byte[] payload,int inputOffset,PeerNode 
pn,Peer replyTo, boolean unknownInitiator, int setupType, int negType)
        {
                long t1=System.currentTimeMillis();
                if(logMINOR) Logger.minor(this, "Got a JFK(2) message, 
processing it - "+pn.getPeer());
@@ -939,7 +939,7 @@
                }
                if(message3 != null) {
                        Logger.normal(this, "We replayed a message from the 
cache (shouldn't happen often) - "+pn.getPeer());
-                       sendAuthPacket(1, 2, 3, (byte[]) message3, pn, replyTo);
+                       sendAuthPacket(1, negType, 3, (byte[]) message3, pn, 
replyTo);
                        return;
                }
                
@@ -977,7 +977,7 @@
                // At this point we know it's from the peer, so we can report a 
packet received.
                pn.receivedPacket(true, false);
                
-               sendJFKMessage3(1, 2, 3, nonceInitiator, nonceResponder, 
hisExponential, authenticator, pn, replyTo, unknownInitiator, setupType);
+               sendJFKMessage3(1, negType, 3, nonceInitiator, nonceResponder, 
hisExponential, authenticator, pn, replyTo, unknownInitiator, setupType);
 
                long t2=System.currentTimeMillis();
                if((t2-t1)>500)
@@ -1008,7 +1008,7 @@
         * responder.
         * @return byte Message3
         */
-       private void processJFKMessage3(byte[] payload, int inputOffset, 
PeerNode pn,Peer replyTo, boolean oldOpennetPeer, boolean unknownInitiator, int 
setupType)
+       private void processJFKMessage3(byte[] payload, int inputOffset, 
PeerNode pn,Peer replyTo, boolean oldOpennetPeer, boolean unknownInitiator, int 
setupType, int negType)
        {
                final long t1 = System.currentTimeMillis();
                if(logMINOR) Logger.minor(this, "Got a JFK(3) message, 
processing it - "+pn);
@@ -1071,9 +1071,9 @@
                        // We are replaying a JFK(4).
                        // Therefore if it is anon-initiator it is encrypted 
with our setup key.
                        if(unknownInitiator)
-                               sendAnonAuthPacket(1,2,3,setupType, (byte[]) 
message4, null, replyTo, crypto.anonSetupCipher);
+                               sendAnonAuthPacket(1,negType,3,setupType, 
(byte[]) message4, null, replyTo, crypto.anonSetupCipher);
                        else
-                               sendAuthPacket(1, 2, 3, (byte[]) message4, pn, 
replyTo);
+                               sendAuthPacket(1, negType, 3, (byte[]) 
message4, pn, replyTo);
                        return;
                } else {
                        if(logDEBUG) Logger.debug(this, "No message4 found for 
"+HexUtil.bytesToHex(authenticator)+" responderExponential 
"+Fields.hashCode(responderExponential)+" initiatorExponential 
"+Fields.hashCode(initiatorExponential)+" nonceResponder 
"+Fields.hashCode(nonceResponder)+" nonceInitiator 
"+Fields.hashCode(nonceInitiator)+" address 
"+HexUtil.bytesToHex(replyTo.getAddress().getAddress()));
@@ -1155,7 +1155,7 @@
                pn.receivedPacket(true, false);
                
                // Send reply
-               sendJFKMessage4(1, 2, 3, nonceInitiator, 
nonceResponder,initiatorExponential, responderExponential, 
+               sendJFKMessage4(1, negType, 3, nonceInitiator, 
nonceResponder,initiatorExponential, responderExponential, 
                                c, Ke, Ka, authenticator, hisRef, pn, replyTo, 
unknownInitiator, setupType);
                
                c.initialize(Ks);
@@ -1175,7 +1175,7 @@
                        // wantPeer will call node.peers.addPeer(), we don't 
have to.
                }
                
-               if(pn.completedHandshake(bootID, hisRef, 0, hisRef.length, c, 
Ks, replyTo, true)) {
+               if(pn.completedHandshake(bootID, hisRef, 0, hisRef.length, c, 
Ks, replyTo, true, negType)) {
                        if(dontWant)
                                node.peers.disconnect(pn, true, false);
                        else
@@ -1240,7 +1240,7 @@
         * @param pn The PeerNode we are talking to. Cannot be null as we are 
the initiator.
         * @param replyTo The Peer we are replying to.
         */
-       private boolean processJFKMessage4(byte[] payload, int inputOffset, 
PeerNode pn, Peer replyTo, boolean oldOpennetPeer, boolean unknownInitiator, 
int setupType)
+       private boolean processJFKMessage4(byte[] payload, int inputOffset, 
PeerNode pn, Peer replyTo, boolean oldOpennetPeer, boolean unknownInitiator, 
int setupType, int negType)
        {
                final long t1 = System.currentTimeMillis();
                if(logMINOR) Logger.minor(this, "Got a JFK(4) message, 
processing it - "+pn.getPeer());
@@ -1370,7 +1370,7 @@
                
                // We change the key
                c.initialize(pn.jfkKs);
-               if(pn.completedHandshake(bootID, data, 8, data.length - 8, c, 
pn.jfkKs, replyTo, false)) {
+               if(pn.completedHandshake(bootID, data, 8, data.length - 8, c, 
pn.jfkKs, replyTo, false, negType)) {
                        if(dontWant)
                                node.peers.disconnect(pn, true, false);
                        else
@@ -1411,7 +1411,7 @@
         * @param replyTo The Peer to send the packet to.
         */
 
-       private void sendJFKMessage3(int version,int negType,int phase,byte[] 
nonceInitiator,byte[] nonceResponder,byte[] hisExponential, byte[] 
authenticator, final PeerNode pn, final Peer replyTo, final boolean 
unknownInitiator, final int setupType)
+       private void sendJFKMessage3(int version,final int negType,int 
phase,byte[] nonceInitiator,byte[] nonceResponder,byte[] hisExponential, byte[] 
authenticator, final PeerNode pn, final Peer replyTo, final boolean 
unknownInitiator, final int setupType)
        {
                if(logMINOR) Logger.minor(this, "Sending a JFK(3) message to 
"+pn.getPeer());
                long t1=System.currentTimeMillis();
@@ -1503,18 +1503,18 @@
                                authenticatorCache.put(new 
ByteArrayWrapper(authenticator),message3);
                }
                if(unknownInitiator)
-                       sendAnonAuthPacket(1, 2, 2, setupType, message3, pn, 
replyTo, pn.anonymousInitiatorSetupCipher);
+                       sendAnonAuthPacket(1, negType, 2, setupType, message3, 
pn, replyTo, pn.anonymousInitiatorSetupCipher);
                else
-                       sendAuthPacket(1, 2, 2, message3, pn, replyTo);
+                       sendAuthPacket(1, negType, 2, message3, pn, replyTo);
                
                /* Re-send the packet after 5sec if we don't get any reply */
                node.getTicker().queueTimedJob(new Runnable() {
                        public void run() {
                                if(pn.timeLastConnected() >= 
pn.lastReceivedPacketTime()) {
                                        if(unknownInitiator)
-                                               sendAnonAuthPacket(1, 2, 2, 
setupType, message3, pn, replyTo, pn.anonymousInitiatorSetupCipher);
+                                               sendAnonAuthPacket(1, negType, 
2, setupType, message3, pn, replyTo, pn.anonymousInitiatorSetupCipher);
                                        else
-                                               sendAuthPacket(1, 2, 2, 
message3, pn, replyTo);
+                                               sendAuthPacket(1, negType, 2, 
message3, pn, replyTo);
                                }
                        }
                }, 5*1000);
@@ -1599,9 +1599,9 @@
                }
                
                if(unknownInitiator)
-                       sendAnonAuthPacket(1, 2, 3, setupType, message4, pn, 
replyTo, crypto.anonSetupCipher);
+                       sendAnonAuthPacket(1, negType, 3, setupType, message4, 
pn, replyTo, crypto.anonSetupCipher);
                else
-                       sendAuthPacket(1, 2, 3, message4, pn, replyTo);
+                       sendAuthPacket(1, negType, 3, message4, pn, replyTo);
                long t2=System.currentTimeMillis();
                if((t2-t1)>500)
                        Logger.error(this,"Message4 timeout error:Sending 
packet for"+pn.getPeer());
@@ -2774,7 +2774,7 @@
                        pn.couldNotSendHandshake();
                        return;
                }
-               sendJFKMessage1(pn, peer, pn.handshakeUnknownInitiator(), 
pn.handshakeSetupType());
+               sendJFKMessage1(pn, peer, pn.handshakeUnknownInitiator(), 
pn.handshakeSetupType(), negType);
                if(logMINOR)
                        Logger.minor(this, "Sending handshake to "+peer+" for 
"+pn);
                pn.sentHandshake();
@@ -2794,7 +2794,7 @@
        }
 
        public int[] supportedNegTypes() {
-               return new int[] { 2 };
+               return new int[] { 2, 3 };
        }
 
        public int fullHeadersLengthOneMessage() {

Modified: trunk/freenet/src/freenet/node/PacketTracker.java
===================================================================
--- trunk/freenet/src/freenet/node/PacketTracker.java   2008-12-02 13:55:19 UTC 
(rev 24013)
+++ trunk/freenet/src/freenet/node/PacketTracker.java   2008-12-02 18:51:25 UTC 
(rev 24014)
@@ -107,6 +107,7 @@
         */
        public void deprecated() {
                logMINOR = Logger.shouldLog(Logger.MINOR, this);
+               if(logMINOR) Logger.minor(this, "Deprecated: "+this);
                isDeprecated = true;
                sentPacketsContents.interrupt();
        }
@@ -1009,6 +1010,10 @@
         * *** Must only be called if the KeyTracker is not to be kept. 
Otherwise, we may receive some packets twice. ***
         */
        public void completelyDeprecated(KeyTracker newTracker) {
+               if(newTracker.packets == this) {
+                       Logger.error(this, "Completely deprecated in favour of 
self!");
+                       return;
+               }
                if(logMINOR)
                        Logger.minor(this, "Completely deprecated: " + this + " 
in favour of " + newTracker);
                LimitedRangeIntByteArrayMapElement[] elements = clear();

Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java        2008-12-02 13:55:19 UTC 
(rev 24013)
+++ trunk/freenet/src/freenet/node/PeerNode.java        2008-12-02 18:51:25 UTC 
(rev 24014)
@@ -1805,7 +1805,7 @@
        * @param replyTo The IP the handshake came in on.
        * @return True unless we rejected the handshake, or it failed to parse.
        */
-       public boolean completedHandshake(long thisBootID, byte[] data, int 
offset, int length, BlockCipher encCipher, byte[] encKey, Peer replyTo, boolean 
unverified) {
+       public boolean completedHandshake(long thisBootID, byte[] data, int 
offset, int length, BlockCipher encCipher, byte[] encKey, Peer replyTo, boolean 
unverified, int negType) {
                logMINOR = Logger.shouldLog(Logger.MINOR, PeerNode.class);
                long now = System.currentTimeMillis();
 
@@ -1852,15 +1852,13 @@
                        routable = false;
                } else
                        older = false;
-               PacketTracker packets = new PacketTracker(this);
-               KeyTracker newTracker = new KeyTracker(this, packets, 
encCipher, encKey);
-               if(logMINOR) Logger.minor(this, "New key tracker in 
completedHandshake: "+newTracker+" for "+shortToString());
                changedIP(replyTo);
                boolean bootIDChanged = false;
                boolean wasARekey = false;
                KeyTracker oldPrev = null;
                KeyTracker oldCur = null;
                KeyTracker prev = null;
+               KeyTracker newTracker;
                MessageItem[] messagesTellDisconnected = null;
                synchronized(this) {
                        handshakeCount = 0;
@@ -1887,7 +1885,11 @@
                        } else if(bootIDChanged && logMINOR)
                                Logger.minor(this, "Changed boot ID from " + 
bootID + " to " + thisBootID + " for " + getPeer());
                        this.bootID = thisBootID;
+                       PacketTracker packets;
+                       boolean newPacketTracker = false;
                        if(bootIDChanged) {
+                               packets = new PacketTracker(this);
+                               newPacketTracker = true;
                                oldPrev = previousTracker;
                                oldCur = currentTracker;
                                previousTracker = null;
@@ -1897,7 +1899,22 @@
                                // connection initial messages by 
maybeOnConnect().
                                messagesTellDisconnected = 
grabQueuedMessageItems();
                                this.offeredMainJarVersion = 0;
-                       } // else it's a rekey
+                       } else {
+                               // else it's a rekey
+                               if(currentTracker != null && 
currentTracker.packets.isDeprecated()) {
+                                       packets = new PacketTracker(this);
+                                       newPacketTracker = true;
+                               } else if(currentTracker != null && negType >= 
3)
+                                       packets = currentTracker.packets;
+                               else if(previousTracker != null && negType >= 3)
+                                       packets = previousTracker.packets;
+                               else {
+                                       packets = new PacketTracker(this);
+                                       newPacketTracker = true;
+                               }
+                       }
+                       newTracker = new KeyTracker(this, packets, encCipher, 
encKey);
+                       if(logMINOR) Logger.minor(this, "New key tracker in 
completedHandshake: "+newTracker+" for "+shortToString()+" neg type "+negType+" 
new packet tracker: "+newPacketTracker);
                        if(unverified) {
                                if(unverifiedTracker != null) {
                                        // Keep the old unverified tracker if 
possible.
@@ -1941,11 +1958,11 @@
                        node.lm.lostOrRestartedNode(this);
                        node.usm.onRestart(this);
                }
-               if(oldPrev != null)
+               if(oldPrev != null && oldPrev.packets != newTracker.packets)
                        oldPrev.packets.completelyDeprecated(newTracker);
-               if(oldCur != null)
+               if(oldCur != null && oldCur.packets != newTracker.packets)
                        oldCur.packets.completelyDeprecated(newTracker);
-               if(prev != null)
+               if(prev != null && prev.packets != newTracker.packets)
                        prev.packets.deprecated();
        PacketThrottle throttle;
        synchronized(this) {
@@ -1979,6 +1996,7 @@
         */
        private synchronized void maybeSwapTrackers() {
                if(currentTracker == null || previousTracker == null) return;
+               if(currentTracker.packets == previousTracker.packets) return;
                long delta = Math.abs(currentTracker.packets.createdTime - 
previousTracker.packets.createdTime);
                if(previousTracker != null && 
(!previousTracker.packets.isDeprecated()) &&
                                delta < CHECK_FOR_SWAPPED_TRACKERS_INTERVAL) {
@@ -2006,9 +2024,9 @@
                                KeyTracker temp = previousTracker;
                                previousTracker = currentTracker;
                                currentTracker = temp;
-                               if(logMINOR) Logger.minor(this, "Swapped 
KeyTracker's on "+this+" cur "+currentTracker+" prev "+previousTracker);
+                               if(logMINOR) Logger.minor(this, "Swapped 
KeyTracker's on "+this+" cur "+currentTracker+" prev "+previousTracker+" delta 
"+delta+" cur.deprecated="+currentTracker.packets.isDeprecated()+" 
prev.deprecated="+previousTracker.packets.isDeprecated());
                        } else {
-                               if(logMINOR) Logger.minor(this, "Not swapping 
KeyTracker's on "+this+" cur "+currentTracker+" prev "+previousTracker);
+                               if(logMINOR) Logger.minor(this, "Not swapping 
KeyTracker's on "+this+" cur "+currentTracker+" prev "+previousTracker+" delta 
"+delta+" cur.deprecated="+currentTracker.packets.isDeprecated()+" 
prev.deprecated="+previousTracker.packets.isDeprecated());
                        }
                } else {
                        if (logMINOR)
@@ -2160,7 +2178,7 @@
                                peerAddedTime = 0;  // don't store anymore
                                ctx = null;
                                maybeSwapTrackers();
-                               if(previousTracker != null)
+                               if(previousTracker != null && 
previousTracker.packets != currentTracker.packets)
                                        previousTracker.packets.deprecated();
                        } else
                                return;

_______________________________________________
cvs mailing list
[email protected]
http://emu.freenetproject.org/cgi-bin/mailman/listinfo/cvs

Reply via email to