Author: toad
Date: 2005-11-12 22:10:01 +0000 (Sat, 12 Nov 2005)
New Revision: 7539

Modified:
   trunk/freenet/src/freenet/client/BlockInserter.java
   trunk/freenet/src/freenet/client/FileInserter.java
   trunk/freenet/src/freenet/client/InserterException.java
   trunk/freenet/src/freenet/client/SplitInserter.java
   trunk/freenet/src/freenet/client/StandardOnionFECCodec.java
   trunk/freenet/src/freenet/io/comm/LowLevelFilter.java
   trunk/freenet/src/freenet/io/comm/UdpSocketManager.java
   trunk/freenet/src/freenet/node/FNPPacketMangler.java
   trunk/freenet/src/freenet/node/InsertSender.java
   trunk/freenet/src/freenet/node/KeyTracker.java
   trunk/freenet/src/freenet/node/PeerNode.java
   trunk/freenet/src/freenet/node/Version.java
   trunk/freenet/src/freenet/support/DoublyLinkedListImpl.java
   trunk/freenet/src/freenet/support/UpdatableSortedLinkedList.java
   
trunk/freenet/src/freenet/support/UpdatableSortedLinkedListWithForeignIndex.java
Log:
177:
Crazy debugging.
Found the reason why list.size() was negative. We were removing from it after 
clear(). It couldn't detect this. It can now.

Modified: trunk/freenet/src/freenet/client/BlockInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/BlockInserter.java 2005-11-12 21:25:51 UTC 
(rev 7538)
+++ trunk/freenet/src/freenet/client/BlockInserter.java 2005-11-12 22:10:01 UTC 
(rev 7539)
@@ -108,7 +108,7 @@
        }

        private void fatalError(Throwable t, int code) {
-               fatalError(new InserterException(code, t.toString()), code);
+               fatalError(new InserterException(code, t), code);
        }

        private void nonfatalError(InserterException e, int code) {

Modified: trunk/freenet/src/freenet/client/FileInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/FileInserter.java  2005-11-12 21:25:51 UTC 
(rev 7538)
+++ trunk/freenet/src/freenet/client/FileInserter.java  2005-11-12 22:10:01 UTC 
(rev 7539)
@@ -146,14 +146,14 @@
        private void translateException(LowLevelPutException e) throws 
InserterException {
                switch(e.code) {
                case LowLevelPutException.INTERNAL_ERROR:
-                       throw new 
InserterException(InserterException.INTERNAL_ERROR);
+                       throw new 
InserterException(InserterException.INTERNAL_ERROR, e);
                case LowLevelPutException.REJECTED_OVERLOAD:
                        throw new 
InserterException(InserterException.REJECTED_OVERLOAD);
                case LowLevelPutException.ROUTE_NOT_FOUND:
                        throw new 
InserterException(InserterException.ROUTE_NOT_FOUND);
                default:
                        Logger.error(this, "Unknown LowLevelPutException code: 
"+e.code+" on "+this);
-                       throw new 
InserterException(InserterException.INTERNAL_ERROR);
+                       throw new 
InserterException(InserterException.INTERNAL_ERROR, e);
                }
        }


Modified: trunk/freenet/src/freenet/client/InserterException.java
===================================================================
--- trunk/freenet/src/freenet/client/InserterException.java     2005-11-12 
21:25:51 UTC (rev 7538)
+++ trunk/freenet/src/freenet/client/InserterException.java     2005-11-12 
22:10:01 UTC (rev 7539)
@@ -2,6 +2,7 @@

 import java.io.IOException;

+import freenet.node.LowLevelPutException;
 import freenet.support.Logger;

 public class InserterException extends Exception {
@@ -30,7 +31,7 @@
                errorCodes = null;
        }

-       public InserterException(int mode, IOException e) {
+       public InserterException(int mode, Throwable e) {
                super(getMessage(mode)+": "+e.getMessage());
                Logger.minor(this, "Creating InserterException: 
"+getMessage(mode)+": "+e, e);
                this.mode = mode;

Modified: trunk/freenet/src/freenet/client/SplitInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/SplitInserter.java 2005-11-12 21:25:51 UTC 
(rev 7538)
+++ trunk/freenet/src/freenet/client/SplitInserter.java 2005-11-12 22:10:01 UTC 
(rev 7539)
@@ -84,7 +84,7 @@
                        Logger.error(this, "Caught "+t, t);
                        tracker.kill();
                        if(t instanceof InserterException) throw 
(InserterException)t;
-                       throw new 
InserterException(InserterException.INTERNAL_ERROR, t.toString());
+                       throw new 
InserterException(InserterException.INTERNAL_ERROR, t);
                }
        }


Modified: trunk/freenet/src/freenet/client/StandardOnionFECCodec.java
===================================================================
--- trunk/freenet/src/freenet/client/StandardOnionFECCodec.java 2005-11-12 
21:25:51 UTC (rev 7538)
+++ trunk/freenet/src/freenet/client/StandardOnionFECCodec.java 2005-11-12 
22:10:01 UTC (rev 7539)
@@ -266,6 +266,12 @@
        private void realEncode(SplitfileBlock[] dataBlockStatus,
                        SplitfileBlock[] checkBlockStatus, int blockLength, 
BucketFactory bf)
                        throws IOException {
+               Runtime.getRuntime().gc();
+               Runtime.getRuntime().runFinalization();
+               Runtime.getRuntime().gc();
+               Runtime.getRuntime().runFinalization();
+               long memUsedAtStart = Runtime.getRuntime().totalMemory() - 
Runtime.getRuntime().freeMemory();
+               Logger.minor(this, "Memory in use at start: "+memUsedAtStart);
                System.err.println("************* Encoding " + 
dataBlockStatus.length
                                + " -> " + checkBlockStatus.length + " 
*************");
                Logger.minor(this, "Doing encode: " + dataBlockStatus.length
@@ -334,7 +340,19 @@
                                        // Do the encode
                                        // Not shuffled
                                        long startTime = 
System.currentTimeMillis();
+                                       Runtime.getRuntime().gc();
+                                       Runtime.getRuntime().runFinalization();
+                                       Runtime.getRuntime().gc();
+                                       Runtime.getRuntime().runFinalization();
+                                       long memUsedBeforeStripe = 
Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
+                                       Logger.minor(this, "Memory in use 
before stripe: "+memUsedBeforeStripe);
                                        code.encode(dataPackets, checkPackets, 
toEncode);
+                                       Runtime.getRuntime().gc();
+                                       Runtime.getRuntime().runFinalization();
+                                       Runtime.getRuntime().gc();
+                                       Runtime.getRuntime().runFinalization();
+                                       long memUsedAfterStripe = 
Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
+                                       Logger.minor(this, "Memory in use after 
stripe: "+memUsedAfterStripe);
                                        long endTime = 
System.currentTimeMillis();
                                        Logger.minor(this, "Stripe encode took "
                                                        + (endTime - startTime) 
+ " ms for k=" + k + ", n="

Modified: trunk/freenet/src/freenet/io/comm/LowLevelFilter.java
===================================================================
--- trunk/freenet/src/freenet/io/comm/LowLevelFilter.java       2005-11-12 
21:25:51 UTC (rev 7538)
+++ trunk/freenet/src/freenet/io/comm/LowLevelFilter.java       2005-11-12 
22:10:01 UTC (rev 7539)
@@ -1,6 +1,8 @@
 package freenet.io.comm;

+import freenet.node.PacketSequenceException;

+
 /**
  * Filter interface used by Freenet to decrypt incoming packets.
  */
@@ -28,8 +30,9 @@
      * @param offset The offset to start reading from.
      * @param length The length in bytes to read.
      * @param peer The PeerContext the messages will be sent to.
+     * @throws PacketSequenceException 
      */
-    void processOutgoing(byte[] buf, int offset, int length, PeerContext peer) 
throws NotConnectedException;
+    void processOutgoing(byte[] buf, int offset, int length, PeerContext peer) 
throws NotConnectedException, LowLevelFilterException;

     /**
      * Is the given connection closed?

Modified: trunk/freenet/src/freenet/io/comm/UdpSocketManager.java
===================================================================
--- trunk/freenet/src/freenet/io/comm/UdpSocketManager.java     2005-11-12 
21:25:51 UTC (rev 7538)
+++ trunk/freenet/src/freenet/io/comm/UdpSocketManager.java     2005-11-12 
22:10:01 UTC (rev 7539)
@@ -46,6 +46,29 @@
        protected UdpSocketManager() {
        }

+       public void start() {
+               super.start();
+               Thread checker = new Thread(new USMChecker());
+               checker.setDaemon(true);
+               checker.start();
+       }
+       
+       public class USMChecker implements Runnable {
+               public void run() {
+                       while(true) {
+                               try {
+                                       Thread.sleep(10*1000);
+                               } catch (InterruptedException e) {
+                                       // Ignore
+                               }
+                               if(UdpSocketManager.this.isAlive())
+                                       Logger.minor(this, "PING on 
"+UdpSocketManager.this);
+                               else
+                                       Logger.error(this, "MAIN LOOP 
TERMINATED");
+                       }
+               }
+       }
+
        public UdpSocketManager(int listenPort) throws SocketException {
                super("UdpSocketManager sender thread on port " + listenPort);
                try {
@@ -64,6 +87,7 @@
        }

        public void run() { // Listen for packets
+               try {
                while (_active) {
                    try {
                        DatagramPacket packet = getPacket();
@@ -78,6 +102,7 @@
                            if(lowLevelFilter != null) {
                                try {
                                    lowLevelFilter.process(data, offset, 
length, peer);
+                                   Logger.minor(this, "Successfully handled 
packet length "+length);
                                } catch (Throwable t) {
                                    Logger.error(this, "Caught "+t+" from 
"+lowLevelFilter, t);
                                }
@@ -88,15 +113,19 @@
                                if(m != null)
                                    checkFilters(m);
                            }
-                       }
+                       } else
+                               Logger.minor(this, "Null packet");
                    } catch (Throwable t) {
                        Logger.error(this, "Caught "+t, t);
                    }
                }
+               } finally {
+               Logger.error(this, "run() exiting");
                synchronized (this) {
                        _isDone = true;
                        notifyAll();
                }
+               }
        }

        /**
@@ -361,7 +390,7 @@
                        try {
                                lowLevelFilter.processOutgoing(blockToSend, 0, 
blockToSend.length, destination);
                                return;
-                       } catch (Throwable t) {
+                       } catch (LowLevelFilterException t) {
                                Logger.error(this, "Caught "+t+" sending "+m+" 
to "+destination, t);
                                destination.forceDisconnect();
                                throw new NotConnectedException("Error 
"+t.toString()+" forced disconnect");
@@ -395,6 +424,7 @@
     }

     public void close(boolean exit) {
+       Logger.error(this, "Closing.", new Exception("error"));
                _active = false;
                synchronized (this) {
                        while (!_isDone) {

Modified: trunk/freenet/src/freenet/node/FNPPacketMangler.java
===================================================================
--- trunk/freenet/src/freenet/node/FNPPacketMangler.java        2005-11-12 
21:25:51 UTC (rev 7538)
+++ trunk/freenet/src/freenet/node/FNPPacketMangler.java        2005-11-12 
22:10:01 UTC (rev 7539)
@@ -12,11 +12,6 @@
 import freenet.crypt.EntropySource;
 import freenet.crypt.PCFBMode;
 import freenet.io.comm.*;
-import freenet.io.comm.LowLevelFilter;
-import freenet.io.comm.Message;
-import freenet.io.comm.Peer;
-import freenet.io.comm.PeerContext;
-import freenet.io.comm.UdpSocketManager;
 import freenet.support.Fields;
 import freenet.support.HexUtil;
 import freenet.support.Logger;
@@ -723,6 +718,7 @@
         }

         int ackRequestsCount = decrypted[ptr++] & 0xff;
+        Logger.minor(this, "Ack requests: "+ackRequestsCount);

         // These two are relative to our outgoing packet number
         // Because they relate to packets we have sent.
@@ -737,7 +733,7 @@
         }

         int forgottenCount = decrypted[ptr++] & 0xff;
-        //Logger.minor(this, "Forgotten packets: "+forgottenCount);
+        Logger.minor(this, "Forgotten packets: "+forgottenCount);

         for(int i=0;i<forgottenCount;i++) {
             int offset = decrypted[ptr++] & 0xff;
@@ -748,7 +744,10 @@
             tracker.destForgotPacket(realSeqNo);
         }

-        if(seqNumber == -1) return;
+        if(seqNumber == -1) {
+               Logger.minor(this, "Returning because seqno = "+seqNumber);
+               return;
+        }
         // No sequence number == no messages

         int messages = decrypted[ptr++] & 0xff;
@@ -771,6 +770,7 @@
                 usm.checkFilters(m);
             }
         }
+        Logger.minor(this, "Done");
     }

     /**
@@ -915,8 +915,9 @@
      * @param length Number of messages to read.
      * @param bufferLength Size of the buffer to write into.
      * @param pn Node to send the messages to.
+     * @throws PacketSequenceException 
      */
-    private void innerProcessOutgoing(byte[][] messageData, int start, int 
length, int bufferLength, PeerNode pn, boolean neverWaitForPacketNumber, 
AsyncMessageCallback[] callbacks) throws NotConnectedException, 
WouldBlockException {
+    private void innerProcessOutgoing(byte[][] messageData, int start, int 
length, int bufferLength, PeerNode pn, boolean neverWaitForPacketNumber, 
AsyncMessageCallback[] callbacks) throws NotConnectedException, 
WouldBlockException, PacketSequenceException {
         Logger.minor(this, 
"innerProcessOutgoing(...,"+start+","+length+","+bufferLength+")");
         byte[] buf = new byte[bufferLength];
         buf[0] = (byte)length;
@@ -935,8 +936,10 @@
     /**
      * Build a packet and send it. From a Message recently converted into 
byte[],
      * but with no outer formatting.
+     * @throws PacketSequenceException 
      */
-    public void processOutgoing(byte[] buf, int offset, int length, 
PeerContext peer) throws NotConnectedException {
+    public void processOutgoing(byte[] buf, int offset, int length, 
PeerContext peer) throws NotConnectedException, PacketSequenceException {
+       Logger.minor(this, "processOutgoing(buf, "+offset+", "+length+", 
"+peer.getPeer());
         if(!(peer instanceof PeerNode))
             throw new IllegalArgumentException();
         PeerNode pn = (PeerNode)peer;
@@ -948,8 +951,9 @@
     /**
      * Build a packet and send it. From a Message recently converted into 
byte[],
      * but with no outer formatting.
+     * @throws PacketSequenceException 
      */
-    public void processOutgoing(byte[] buf, int offset, int length, KeyTracker 
tracker) throws KeyChangedException, NotConnectedException {
+    public void processOutgoing(byte[] buf, int offset, int length, KeyTracker 
tracker) throws KeyChangedException, NotConnectedException, 
PacketSequenceException {
         byte[] newBuf = preformat(buf, offset, length);
         processOutgoingPreformatted(newBuf, 0, newBuf.length, tracker, -1, 
null);
     }
@@ -957,8 +961,9 @@

     /**
      * Send a packet, with a packet number.
+     * @throws PacketSequenceException 
      */
-    public void processOutgoing(byte[] buf, int offset, int length, KeyTracker 
tracker, int packetNo, AsyncMessageCallback[] callbacks) throws 
KeyChangedException, NotConnectedException {
+    public void processOutgoing(byte[] buf, int offset, int length, KeyTracker 
tracker, int packetNo, AsyncMessageCallback[] callbacks) throws 
KeyChangedException, NotConnectedException, PacketSequenceException {
         byte[] newBuf = preformat(buf, offset, length);
         processOutgoingPreformatted(newBuf, 0, newBuf.length, tracker, 
packetNo, callbacks);
     }
@@ -966,10 +971,12 @@
     /**
      * Send a packet using the current key. Retry if it fails solely because
      * the key changes.
+     * @throws PacketSequenceException 
      */
-    void processOutgoingPreformatted(byte[] buf, int offset, int length, 
PeerNode peer, int k, AsyncMessageCallback[] callbacks) throws 
NotConnectedException {
+    void processOutgoingPreformatted(byte[] buf, int offset, int length, 
PeerNode peer, int k, AsyncMessageCallback[] callbacks) throws 
NotConnectedException, PacketSequenceException {
         while(true) {
             try {
+               Logger.minor(this, "At beginning of processOutgoingPreformatted 
loop for "+peer.getPeer());
                 KeyTracker tracker = peer.getCurrentKeyTracker();
                 if(tracker == null) {
                     Logger.normal(this, "Dropping packet: Not connected yet");
@@ -978,6 +985,7 @@
                 processOutgoingPreformatted(buf, offset, length, tracker, k, 
callbacks);
                 return;
             } catch (KeyChangedException e) {
+               Logger.normal(this, "Key changed");
                 // Go around again
             }
         }
@@ -986,8 +994,9 @@
     /**
      * Send a packet using the current key. Retry if it fails solely because
      * the key changes.
+     * @throws PacketSequenceException 
      */
-    void processOutgoingPreformatted(byte[] buf, int offset, int length, 
PeerNode peer, boolean neverWaitForPacketNumber, AsyncMessageCallback[] 
callbacks) throws NotConnectedException, WouldBlockException {
+    void processOutgoingPreformatted(byte[] buf, int offset, int length, 
PeerNode peer, boolean neverWaitForPacketNumber, AsyncMessageCallback[] 
callbacks) throws NotConnectedException, WouldBlockException, 
PacketSequenceException {
         while(true) {
             try {
                 KeyTracker tracker = peer.getCurrentKeyTracker();
@@ -1038,8 +1047,9 @@
      * Means this is a resend of a dropped packet.
      * @throws NotConnectedException If the node is not connected.
      * @throws KeyChangedException If the primary key changes while we are 
trying to send this packet.
+     * @throws PacketSequenceException 
      */
-    public void processOutgoingPreformatted(byte[] buf, int offset, int 
length, KeyTracker tracker, int packetNumber, AsyncMessageCallback[] callbacks) 
throws KeyChangedException, NotConnectedException {
+    public void processOutgoingPreformatted(byte[] buf, int offset, int 
length, KeyTracker tracker, int packetNumber, AsyncMessageCallback[] callbacks) 
throws KeyChangedException, NotConnectedException, PacketSequenceException {
         if(Logger.shouldLog(Logger.MINOR, this)) {
             String log = 
"processOutgoingPreformatted("+Fields.hashCode(buf)+", 
"+offset+","+length+","+tracker+","+packetNumber+",";
             if(callbacks == null) log += "null";
@@ -1120,8 +1130,8 @@
             Logger.minor(this, "Acking "+ackSeq);
             int offsetSeq = otherSideSeqNumber - ackSeq;
             if(offsetSeq > 255 || offsetSeq < 0)
-                throw new IllegalStateException("bad ack offset "+offsetSeq+
-                        " - seqNumber="+otherSideSeqNumber+", 
ackNumber="+ackSeq);
+                throw new PacketSequenceException("bad ack offset "+offsetSeq+
+                        " - seqNumber="+otherSideSeqNumber+", 
ackNumber="+ackSeq+" talking to "+tracker.pn.getPeer());
             plaintext[ptr++] = (byte)offsetSeq;
         }

@@ -1131,8 +1141,8 @@
             Logger.minor(this, "Resend req: "+reqSeq);
             int offsetSeq = otherSideSeqNumber - reqSeq;
             if(offsetSeq > 255 || offsetSeq < 0)
-                throw new IllegalStateException("bad resend request offset 
"+offsetSeq+
-                        " - reqSeq="+reqSeq+", 
otherSideSeqNumber="+otherSideSeqNumber);
+                throw new PacketSequenceException("bad resend request offset 
"+offsetSeq+
+                        " - reqSeq="+reqSeq+", 
otherSideSeqNumber="+otherSideSeqNumber+" talking to "+tracker.pn.getPeer());
             plaintext[ptr++] = (byte)offsetSeq;
         }

@@ -1145,8 +1155,8 @@
             // a packet we sent to them.
             int offsetSeq = realSeqNumber - ackReqSeq;
             if(offsetSeq > 255 || offsetSeq < 0)
-                throw new IllegalStateException("bad ack requests offset: 
"+offsetSeq+
-                        " - ackReqSeq="+ackReqSeq+", 
packetNumber="+realSeqNumber);
+                throw new PacketSequenceException("bad ack requests offset: 
"+offsetSeq+
+                        " - ackReqSeq="+ackReqSeq+", 
packetNumber="+realSeqNumber+" talking to "+tracker.pn.getPeer());
             plaintext[ptr++] = (byte)offsetSeq;
         }


Modified: trunk/freenet/src/freenet/node/InsertSender.java
===================================================================
--- trunk/freenet/src/freenet/node/InsertSender.java    2005-11-12 21:25:51 UTC 
(rev 7538)
+++ trunk/freenet/src/freenet/node/InsertSender.java    2005-11-12 22:10:01 UTC 
(rev 7539)
@@ -27,7 +27,7 @@
         this.prb = prb;
         this.fromStore = fromStore;
         this.closestLocation = closestLocation;
-        Thread t = new Thread(this, "InsertSender for UID "+uid+" on 
"+node.portNumber);
+        Thread t = new Thread(this, "InsertSender for UID "+uid+" on 
"+node.portNumber+" at "+System.currentTimeMillis());
         t.setDaemon(true);
         t.start();
     }

Modified: trunk/freenet/src/freenet/node/KeyTracker.java
===================================================================
--- trunk/freenet/src/freenet/node/KeyTracker.java      2005-11-12 21:25:51 UTC 
(rev 7538)
+++ trunk/freenet/src/freenet/node/KeyTracker.java      2005-11-12 22:10:01 UTC 
(rev 7539)
@@ -320,7 +320,12 @@
      * @param seqNumber The packet's serial number.
      */
     public synchronized void receivedPacket(int seqNumber) {
-        pn.receivedPacket();
+        try {
+                       pn.receivedPacket();
+               } catch (NotConnectedException e) {
+                       Logger.minor(this, "Ignoring, because disconnected");
+                       return;
+               }
         if(seqNumber == -1) return;
         receivedPacketNumber(seqNumber);
         if(packetNumbersReceived.contains(seqNumber)) {
@@ -449,9 +454,9 @@
             pn.node.ps.queuedResendPacket();
         } else {
             String msg = "Asking me to resend packet "+seqNumber+
-                       " which we haven't sent yet or which they have already 
acked";
+                       " which we haven't sent yet or which they have already 
acked (next="+nextPacketNumber+")";
             // Can have a race condition
-            if(seqNumber < nextPacketNumber && seqNumber > nextPacketNumber-16)
+            if(seqNumber < nextPacketNumber && seqNumber > nextPacketNumber-64)
                 Logger.minor(this, msg);
             else
                 Logger.error(this, msg);
@@ -622,7 +627,7 @@
                     int packetNumber = qrr.packetNumber;
                     if(qrr.activeTime <= now) {
                         if(sentPacketsContents.get(packetNumber) == null) {
-                            Logger.error(this, "Asking to ack packet which has 
already been acked: "+packetNumber+" on "+this+".grabAckRequests");
+                            Logger.minor(this, "Asking to ack packet which has 
already been acked: "+packetNumber+" on "+this+".grabAckRequests");
                             ackRequestQueue.remove(qrr);
                             continue;
                         }

Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java        2005-11-12 21:25:51 UTC 
(rev 7538)
+++ trunk/freenet/src/freenet/node/PeerNode.java        2005-11-12 22:10:01 UTC 
(rev 7539)
@@ -325,9 +325,11 @@
             currentTracker = previousTracker = unverifiedTracker = null;
         }
         node.lm.lostOrRestartedNode(this);
+        sendHandshakeTime = System.currentTimeMillis();
     }

     public void forceDisconnect() {
+       Logger.error(this, "Forcing disconnect on "+this, new 
Exception("debug"));
        disconnected();
     }

@@ -554,10 +556,12 @@

     /**
      * Update timeLastReceivedPacket
+     * @throws NotConnectedException 
      */
-    synchronized void receivedPacket() {
+    synchronized void receivedPacket() throws NotConnectedException {
         if(isConnected == false && unverifiedTracker == null) {
             Logger.error(this, "Received packet while disconnected!: "+this, 
new Exception("error"));
+            throw new NotConnectedException();
         }
         timeLastReceivedPacket = System.currentTimeMillis();
         randomizeMaxTimeBetweenPacketReceives();
@@ -644,7 +648,12 @@
             ctx = null;
         }
         Logger.normal(this, "Completed handshake with "+this+" on "+replyTo+" 
- current: "+currentTracker+" old: "+previousTracker+" unverified: 
"+unverifiedTracker+" bootID: "+thisBootID);
-        receivedPacket();
+        try {
+                       receivedPacket();
+               } catch (NotConnectedException e) {
+                       Logger.error(this, "Disconnected in completedHandshake 
with "+this);
+                       return true; // i suppose
+               }
         node.peers.addConnectedPeer(this);
         sentInitialMessages = false;
         return true;
@@ -795,8 +804,9 @@

     /**
      * Send a payload-less packet on either key if necessary.
+     * @throws PacketSequenceException 
      */
-    public void sendAnyUrgentNotifications() {
+    public void sendAnyUrgentNotifications() throws PacketSequenceException {
         Logger.minor(this, "sendAnyUrgentNotifications");
         long now = System.currentTimeMillis();
         KeyTracker cur, prev;

Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2005-11-12 21:25:51 UTC (rev 
7538)
+++ trunk/freenet/src/freenet/node/Version.java 2005-11-12 22:10:01 UTC (rev 
7539)
@@ -20,10 +20,10 @@
        public static final String protocolVersion = "1.0";

        /** The build number of the current revision */
-       public static final int buildNumber = 176;
+       public static final int buildNumber = 177;

        /** Oldest build of Fred we will talk to */
-       public static final int lastGoodBuild = 176;
+       public static final int lastGoodBuild = 177;

        /** The highest reported build of fred */
        public static int highestSeenBuild = buildNumber;

Modified: trunk/freenet/src/freenet/support/DoublyLinkedListImpl.java
===================================================================
--- trunk/freenet/src/freenet/support/DoublyLinkedListImpl.java 2005-11-12 
21:25:51 UTC (rev 7538)
+++ trunk/freenet/src/freenet/support/DoublyLinkedListImpl.java 2005-11-12 
22:10:01 UTC (rev 7539)
@@ -66,6 +66,20 @@
      * Reset the size of the list to zero.
      */
     public void clear() {
+       // Help to detect removal after clear().
+       // The check in remove() is enough, strictly,
+       // as long as people don't add elements afterwards.
+       Enumeration e = forwardElements();
+       DoublyLinkedList.Item pos = _headptr.next;
+       DoublyLinkedList.Item opos = _headptr;
+       while(true) {
+               pos.setParent(null);
+               pos.setPrev(null);
+               opos = pos;
+               pos = pos.getNext();
+               opos.setNext(null);
+               if(pos == _tailptr) break;
+       }
         _headptr.next = _tailptr;
         _tailptr.prev = _headptr;
         size = 0;
@@ -222,10 +236,19 @@
      * @return  this item, or null if the item was not in the list
      */
     public DoublyLinkedList.Item remove(DoublyLinkedList.Item i) {
+       if(isEmpty()) {
+               Logger.error(this, "Illegal ERROR: Removing from an empty 
list!!");
+               throw new IllegalStateException("Illegal ERROR: Removing from 
an empty list!!");
+       }
        if (i.getParent() != this)
                throw new PromiscuousItemException(i, i.getParent());
         DoublyLinkedList.Item next = i.getNext(), prev = i.getPrev();
         if (next == null || prev == null) return null;  // not in the list
+        if(next.getPrev() != i || prev.getNext() != i) {
+               String msg = "Illegal ERROR: i="+i+", next="+next+", 
next.prev="+next.getPrev()+", prev="+prev+", prev.next="+prev.getNext();
+               Logger.error(this, msg);
+               throw new IllegalStateException(msg);
+        }
         prev.setNext(next);
         next.setPrev(prev);
         i.setNext(null);

Modified: trunk/freenet/src/freenet/support/UpdatableSortedLinkedList.java
===================================================================
--- trunk/freenet/src/freenet/support/UpdatableSortedLinkedList.java    
2005-11-12 21:25:51 UTC (rev 7538)
+++ trunk/freenet/src/freenet/support/UpdatableSortedLinkedList.java    
2005-11-12 22:10:01 UTC (rev 7539)
@@ -21,14 +21,17 @@
         Logger.minor(this, "Add("+i+") on "+this);
         if(list.isEmpty()) {
             list.push(i);
+            checkList();
             return;
         }
         if(i.compareTo(list.tail()) >= 0) {
             list.push(i);
+            checkList();
             return;
         }
         if(i.compareTo(list.head()) <= 0) {
             list.unshift(i);
+            checkList();
             return;
         }
         // Search the list for a good place to put it
@@ -39,6 +42,7 @@
                 (UpdatableSortedLinkedListItem) e.nextElement();
             if(prev != null && cur.compareTo(i) >= 0 && prev.compareTo(i) <= 
0) {
                 list.insertNext(prev, i);
+                checkList();
                 return;
             }
             Logger.minor(this, "Not matching "+cur+" "+prev);
@@ -47,26 +51,59 @@
         throw new IllegalStateException("impossible");
     }

-    public synchronized void remove(UpdatableSortedLinkedListItem i) {
+    private StringBuffer sb = new StringBuffer(1000);
+    
+    protected synchronized void checkList() {
+       // FIXME once satisfied that this works, make it only happen 
occasionally
+       int statedLength = list.size();
+       int realLength = 0;
+       sb.setLength(0);
+       int x = 0;
+       for(Enumeration e = list.elements();e.hasMoreElements();) {
+               UpdatableSortedLinkedListItem i = 
(UpdatableSortedLinkedListItem) e.nextElement();
+               sb.append(x);
+               sb.append("=");
+               sb.append(i);
+               sb.append('\n');
+               realLength++;
+       }
+       if(statedLength != realLength) {
+               String err = "statedLength = "+statedLength+" but realLength = 
"+realLength+" on "+this;
+               Logger.error(this, "Illegal ERROR: "+err, new 
Exception("error"));
+               Logger.error(this, "Details:\n"+sb.toString());
+               throw new IllegalStateException(err);
+       } else {
+               Logger.minor(this, "checkList() successful: realLength = 
statedLength = "+realLength+" on "+this);
+               Logger.minor(this, "Details:\n"+sb.toString());
+       }
+       }
+
+       public synchronized void remove(UpdatableSortedLinkedListItem i) {
         Logger.minor(this, "Remove("+i+") on "+this);
+        checkList();
         list.remove(i);
+        checkList();
     }

     public synchronized void update(UpdatableSortedLinkedListItem i) {
         Logger.minor(this, "Update("+i+") on "+this);
+        checkList();
         if(i.compareTo(list.tail()) > 0) {
             list.remove(i);
             list.push(i);
+            checkList();
             return;
         }
         if(i.compareTo(list.head()) < 0) {
             list.remove(i);
             list.unshift(i);
+            checkList();
             return;
         }
         if(list.head() == list.tail() && i != list.head()) {
             Logger.error(this, "Only 1 element: "+list.head()+" and updating 
"+i+" on "+this, new Exception("error"));
             add(i);
+            checkList();
             return;
         }
         // Forwards or backwards?
@@ -94,6 +131,7 @@
                 if(i.compareTo(next) < 0 && i.compareTo(prev) > 0) {
                     list.remove(i);
                     list.insertNext(prev, i);
+                    checkList();
                     return;
                 }
             }
@@ -108,6 +146,7 @@
                 if(i.compareTo(next) < 0 && i.compareTo(prev) > 0) {
                     list.remove(i);
                     list.insertNext(prev, i);
+                    checkList();
                     return;
                 }
             }
@@ -116,6 +155,7 @@
         dump();
         remove(i);
         add(i);
+        checkList();
     }

     /**

Modified: 
trunk/freenet/src/freenet/support/UpdatableSortedLinkedListWithForeignIndex.java
===================================================================
--- 
trunk/freenet/src/freenet/support/UpdatableSortedLinkedListWithForeignIndex.java
    2005-11-12 21:25:51 UTC (rev 7538)
+++ 
trunk/freenet/src/freenet/support/UpdatableSortedLinkedListWithForeignIndex.java
    2005-11-12 22:10:01 UTC (rev 7539)
@@ -30,11 +30,13 @@
         }
         super.add(i);
         map.put(i.indexValue(), item);
+        checkList();
     }

     public synchronized void remove(UpdatableSortedLinkedListItem item) {
         super.remove(item);
         
map.remove(((IndexableUpdatableSortedLinkedListItem)item).indexValue());
+        checkList();
     }

     public synchronized boolean containsKey(Object o) {
@@ -48,5 +50,6 @@
         IndexableUpdatableSortedLinkedListItem item = 
             (IndexableUpdatableSortedLinkedListItem) map.get(key);
         if(item != null) remove(item);
+        checkList();
     }
 }


Reply via email to