Author: nextgens
Date: 2007-09-29 18:42:16 +0000 (Sat, 29 Sep 2007)
New Revision: 15391

Added:
   branches/freenet-jfk/src/freenet/node/fcp/PeerMessage.java
Removed:
   branches/freenet-jfk/src/freenet/node/fcp/Peer.java
Modified:
   branches/freenet-jfk/src/freenet/clients/http/ConnectionsToadlet.java
   branches/freenet-jfk/src/freenet/clients/http/DarknetConnectionsToadlet.java
   branches/freenet-jfk/src/freenet/clients/http/OpennetConnectionsToadlet.java
   branches/freenet-jfk/src/freenet/crypt/SHA256.java
   branches/freenet-jfk/src/freenet/io/comm/FreenetInetAddress.java
   branches/freenet-jfk/src/freenet/io/comm/Peer.java
   branches/freenet-jfk/src/freenet/l10n/freenet.l10n.en.properties
   branches/freenet-jfk/src/freenet/node/FNPPacketMangler.java
   branches/freenet-jfk/src/freenet/node/IPDetectorPluginManager.java
   branches/freenet-jfk/src/freenet/node/NodeDispatcher.java
   branches/freenet-jfk/src/freenet/node/NodeIPDetector.java
   branches/freenet-jfk/src/freenet/node/OpennetManager.java
   branches/freenet-jfk/src/freenet/node/OpennetPeerNode.java
   branches/freenet-jfk/src/freenet/node/OpennetPeerNodeStatus.java
   branches/freenet-jfk/src/freenet/node/PacketSender.java
   branches/freenet-jfk/src/freenet/node/PeerManager.java
   branches/freenet-jfk/src/freenet/node/PeerNode.java
   branches/freenet-jfk/src/freenet/node/Version.java
   branches/freenet-jfk/src/freenet/node/fcp/AddPeer.java
   branches/freenet-jfk/src/freenet/node/fcp/ListPeerMessage.java
   branches/freenet-jfk/src/freenet/node/fcp/ListPeersMessage.java
   branches/freenet-jfk/src/freenet/node/fcp/ModifyPeer.java
   branches/freenet-jfk/src/freenet/node/updater/NodeUpdateManager.java
   branches/freenet-jfk/src/freenet/pluginmanager/PluginInfoWrapper.java
   branches/freenet-jfk/src/freenet/pluginmanager/PluginManager.java
   branches/freenet-jfk/src/freenet/support/Serializer.java
   branches/freenet-jfk/src/freenet/support/TimeUtil.java
   branches/freenet-jfk/test/freenet/support/TimeUtilTest.java
Log:
freenet-jfk: merge changes from trunk back to the branch up to r15281

Modified: branches/freenet-jfk/src/freenet/clients/http/ConnectionsToadlet.java
===================================================================
--- branches/freenet-jfk/src/freenet/clients/http/ConnectionsToadlet.java       
2007-09-29 18:13:44 UTC (rev 15390)
+++ branches/freenet-jfk/src/freenet/clients/http/ConnectionsToadlet.java       
2007-09-29 18:42:16 UTC (rev 15391)
@@ -128,6 +128,15 @@
                this.peers = n.peers;
        }

+       abstract SimpleColumn[] endColumnHeaders(boolean advancedModeEnabled);
+       
+       abstract class SimpleColumn {
+               abstract protected void drawColumn(HTMLNode peerRow, 
PeerNodeStatus peerNodeStatus);
+               abstract public String getSortString();
+               abstract public String getTitleKey();
+               abstract public String getExplanationKey();
+       }
+       
        public void handleGet(URI uri, final HTTPRequest request, 
ToadletContext ctx) throws ToadletContextClosedException, IOException, 
RedirectException {
                String path = uri.getPath();
                if(path.endsWith("myref.fref")) {
@@ -425,10 +434,22 @@
                                        peerTableHeaderRow.addChild("th", 
"Time\u00a0Delta");
                                }

+                               SimpleColumn[] endCols = 
endColumnHeaders(advancedModeEnabled);
+                               if(endCols != null) {
+                                       for(int i=0;i<endCols.length;i++) {
+                                               SimpleColumn col = endCols[i];
+                                               HTMLNode header = 
peerTableHeaderRow.addChild("th");
+                                               String sortString = 
col.getSortString();
+                                               if(sortString != null)
+                                                       header = 
header.addChild("a", "href", sortString(isReversed, sortString));
+                                               header.addChild("span", new 
String[] { "title", "style" }, new String[] { 
L10n.getString(col.getExplanationKey()), "border-bottom: 1px dotted; cursor: 
help;" }, L10n.getString(col.getTitleKey()));
+                                       }
+                               }
+                               
                                for (int peerIndex = 0, peerCount = 
peerNodeStatuses.length; peerIndex < peerCount; peerIndex++) {

                                        PeerNodeStatus peerNodeStatus = 
peerNodeStatuses[peerIndex];
-                                       drawRow(peerTable, peerNodeStatus, 
advancedModeEnabled, fProxyJavascriptEnabled, now, path, enablePeerActions);
+                                       drawRow(peerTable, peerNodeStatus, 
advancedModeEnabled, fProxyJavascriptEnabled, now, path, enablePeerActions, 
endCols);

                                }

@@ -698,7 +719,7 @@

        abstract protected SimpleFieldSet getNoderef();

-       private void drawRow(HTMLNode peerTable, PeerNodeStatus peerNodeStatus, 
boolean advancedModeEnabled, boolean fProxyJavascriptEnabled, long now, String 
path, boolean enablePeerActions) {
+       private void drawRow(HTMLNode peerTable, PeerNodeStatus peerNodeStatus, 
boolean advancedModeEnabled, boolean fProxyJavascriptEnabled, long now, String 
path, boolean enablePeerActions, SimpleColumn[] endCols) {
                HTMLNode peerRow = peerTable.addChild("tr");

                if(enablePeerActions) {
@@ -787,6 +808,12 @@
                        peerRow.addChild("td", "class", "peer-idle" /* FIXME 
*/).addChild("#", TimeUtil.formatTime(peerNodeStatus.getClockDelta()));
                }

+               if(endCols != null) {
+                       for(int i=0;i<endCols.length;i++) {
+                               endCols[i].drawColumn(peerRow, peerNodeStatus);
+                       }
+               }
+               
                if (path.endsWith("displaymessagetypes.html")) {
                        drawMessageTypes(peerTable, peerNodeStatus);
                }

Modified: 
branches/freenet-jfk/src/freenet/clients/http/DarknetConnectionsToadlet.java
===================================================================
--- 
branches/freenet-jfk/src/freenet/clients/http/DarknetConnectionsToadlet.java    
    2007-09-29 18:13:44 UTC (rev 15390)
+++ 
branches/freenet-jfk/src/freenet/clients/http/DarknetConnectionsToadlet.java    
    2007-09-29 18:42:16 UTC (rev 15391)
@@ -377,4 +377,8 @@
                return false;
        }

+       SimpleColumn[] endColumnHeaders(boolean advancedMode) {
+               return null;
+       }
+
 }

Modified: 
branches/freenet-jfk/src/freenet/clients/http/OpennetConnectionsToadlet.java
===================================================================
--- 
branches/freenet-jfk/src/freenet/clients/http/OpennetConnectionsToadlet.java    
    2007-09-29 18:13:44 UTC (rev 15390)
+++ 
branches/freenet-jfk/src/freenet/clients/http/OpennetConnectionsToadlet.java    
    2007-09-29 18:42:16 UTC (rev 15391)
@@ -1,12 +1,16 @@
 package freenet.clients.http;

+import java.util.Comparator;
+
 import freenet.client.HighLevelSimpleClient;
 import freenet.l10n.L10n;
 import freenet.node.Node;
 import freenet.node.NodeClientCore;
+import freenet.node.OpennetPeerNodeStatus;
 import freenet.node.PeerNodeStatus;
 import freenet.support.HTMLNode;
 import freenet.support.SimpleFieldSet;
+import freenet.support.TimeUtil;

 public class OpennetConnectionsToadlet extends ConnectionsToadlet implements 
LinkEnabledCallback {

@@ -80,4 +84,47 @@
                return true;
        }

+       protected class OpennetComparator extends ComparatorByStatus {
+
+               OpennetComparator(String sortBy, boolean reversed) {
+                       super(sortBy, reversed);
+               }
+       
+               protected int customCompare(PeerNodeStatus firstNode, 
PeerNodeStatus secondNode, String sortBy) {
+                       if(sortBy.equals("successTime")) {
+                               long t1 = 
((OpennetPeerNodeStatus)firstNode).timeLastSuccess;
+                               long t2 = 
((OpennetPeerNodeStatus)secondNode).timeLastSuccess;
+                               if(t1 > t2) return reversed ? 1 : -1;
+                               else if(t2 > t1) return reversed ? -1 : 1;
+                       }
+                       return super.customCompare(firstNode, secondNode, 
sortBy);
+               }
+       }
+       
+       protected Comparator comparator(String sortBy, boolean reversed) {
+               return new OpennetComparator(sortBy, reversed);
+       }
+
+       SimpleColumn[] endColumnHeaders(boolean advancedMode) {
+               if(!advancedMode) return null;
+               return new SimpleColumn[] { 
+                               new SimpleColumn() {
+
+                                       protected void drawColumn(HTMLNode 
peerRow, PeerNodeStatus peerNodeStatus) {
+                                               OpennetPeerNodeStatus status = 
(OpennetPeerNodeStatus) peerNodeStatus;
+                                               long tLastSuccess = 
status.timeLastSuccess;
+                                               peerRow.addChild("td", "class", 
"peer-last-success", tLastSuccess > 0 ? 
TimeUtil.formatTime(System.currentTimeMillis() - tLastSuccess) : "NEVER");
+                                       }
+                                       public String getExplanationKey() {
+                                               return 
"OpennetConnectionsToadlet.successTime";
+                                       }
+                                       public String getSortString() {
+                                               return "successTime";
+                                       }
+                                       public String getTitleKey() {
+                                               return 
"OpennetConnectionsToadlet.successTimeTitle";
+                                       }
+                               }};
+       }
+               
 }

Modified: branches/freenet-jfk/src/freenet/crypt/SHA256.java
===================================================================
--- branches/freenet-jfk/src/freenet/crypt/SHA256.java  2007-09-29 18:13:44 UTC 
(rev 15390)
+++ branches/freenet-jfk/src/freenet/crypt/SHA256.java  2007-09-29 18:42:16 UTC 
(rev 15391)
@@ -415,7 +415,7 @@
        public static int getDigestLength() {
                return HASH_SIZE;
        }
-       
+
        public static Digest getInstance() {
                return new SHA256();
        }

Modified: branches/freenet-jfk/src/freenet/io/comm/FreenetInetAddress.java
===================================================================
--- branches/freenet-jfk/src/freenet/io/comm/FreenetInetAddress.java    
2007-09-29 18:13:44 UTC (rev 15390)
+++ branches/freenet-jfk/src/freenet/io/comm/FreenetInetAddress.java    
2007-09-29 18:42:16 UTC (rev 15391)
@@ -11,6 +11,8 @@

 import freenet.io.AddressIdentifier;
 import freenet.support.Logger;
+import freenet.support.transport.ip.HostnameSyntaxException;
+import freenet.support.transport.ip.HostnameUtil;
 import freenet.support.transport.ip.IPUtil;

 /**
@@ -44,6 +46,33 @@
                        ba = new byte[4];
                        dis.readFully(ba);
                } else {
+                       throw new IOException("Unknown type byte (old form? 
corrupt stream? too short/long prev field?): "+(int)firstByte);
+               }
+               _address = InetAddress.getByAddress(ba);
+               String name = null;
+               String s = dis.readUTF();
+               if(s.length() > 0)
+                       name = s;
+               hostname = name;
+       }
+
+       /**
+        * Create from serialized form on a DataInputStream.
+        */
+       public FreenetInetAddress(DataInputStream dis, boolean 
checkHostnameOrIPSyntax) throws HostnameSyntaxException, IOException {
+               int firstByte = dis.readUnsignedByte();
+               byte[] ba;
+               if(firstByte == 255) {
+                       if(Logger.shouldLog(Logger.MINOR, this)) 
Logger.minor(this, "New format IPv6 address");
+                       // New format IPv6 address
+                       ba = new byte[16];
+                       dis.readFully(ba);
+               } else if(firstByte == 0) {
+                       if(Logger.shouldLog(Logger.MINOR, this)) 
Logger.minor(this, "New format IPv4 address");
+                       // New format IPv4 address
+                       ba = new byte[4];
+                       dis.readFully(ba);
+               } else {
                        // Old format IPv4 address
                        ba = new byte[4];
                        ba[0] = (byte)firstByte;
@@ -55,6 +84,9 @@
                if(s.length() > 0)
                        name = s;
                hostname = name;
+        if(checkHostnameOrIPSyntax && null != hostname) {
+               if(!HostnameUtil.isValidHostname(hostname, true)) throw new 
HostnameSyntaxException();
+               }
        }

        /**
@@ -77,6 +109,37 @@
         AddressIdentifier.AddressType addressType = 
AddressIdentifier.getAddressType(host);
         boolean logDEBUG = Logger.shouldLog(Logger.DEBUG, this);
         if(logDEBUG) Logger.debug(this, "Address type of '"+host+"' appears to 
be '"+addressType+ '\'');
+        if(addressType != AddressIdentifier.AddressType.OTHER) {
+               // Is an IP address
+            addr = InetAddress.getByName(host);
+            // Don't catch UnknownHostException here, if it happens there's a 
bug in AddressIdentifier.
+            if(logDEBUG) Logger.debug(this, "host is '"+host+"' and 
addr.getHostAddress() is '"+addr.getHostAddress()+ '\'');
+            if(addr != null) {
+                host = null;
+            } else {
+                addr = null;
+            }
+        }
+        if( addr == null ) {
+               if(logDEBUG) Logger.debug(this, '\'' +host+"' does not look 
like an IP address");
+        }
+        this._address = addr;
+        this.hostname = host;
+        // we're created with a hostname so delay the lookup of the address
+        // until it's needed to work better with dynamic DNS hostnames
+       }
+
+       public FreenetInetAddress(String host, boolean allowUnknown, boolean 
checkHostnameOrIPSyntax) throws HostnameSyntaxException, UnknownHostException {
+        InetAddress addr = null;
+        if(host != null){
+               if(host.startsWith("/")) host = host.substring(1);
+               host = host.trim();
+        }
+        // if we were created with an explicit IP address, use it as such
+        // debugging log messages because AddressIdentifier doesn't appear to 
handle all IPv6 literals correctly, such as "fe80::204:1234:dead:beef"
+        AddressIdentifier.AddressType addressType = 
AddressIdentifier.getAddressType(host);
+        boolean logDEBUG = Logger.shouldLog(Logger.DEBUG, this);
+        if(logDEBUG) Logger.debug(this, "Address type of '"+host+"' appears to 
be '"+addressType+ '\'');
         if(!addressType.toString().equals("Other")) {
             try {
                 addr = InetAddress.getByName(host);
@@ -97,6 +160,9 @@
         }
         this._address = addr;
         this.hostname = host;
+        if(checkHostnameOrIPSyntax && null != this.hostname) {
+               if(!HostnameUtil.isValidHostname(this.hostname, true)) throw 
new HostnameSyntaxException();
+               }
         // we're created with a hostname so delay the lookup of the address
         // until it's needed to work better with dynamic DNS hostnames
        }
@@ -256,19 +322,14 @@
                        return hostname;
        }

-       public void writeToDataOutputStream(DataOutputStream dos, boolean 
oldForm) throws IOException {
+       public void writeToDataOutputStream(DataOutputStream dos) throws 
IOException {
                InetAddress addr = this.getAddress();
                if (addr == null) throw new UnknownHostException();
                byte[] data = addr.getAddress();
-               if(oldForm) {
-                       if(data.length != 4)
-                               throw new IllegalArgumentException("IPv6 not 
supported at present");
-               } else {
-                       if(data.length == 4)
-                               dos.write(0);
-                       else
-                               dos.write(255);
-               }
+               if(data.length == 4)
+                       dos.write(0);
+               else
+                       dos.write(255);
                dos.write(data);
                if(hostname != null)
                        dos.writeUTF(hostname);

Modified: branches/freenet-jfk/src/freenet/io/comm/Peer.java
===================================================================
--- branches/freenet-jfk/src/freenet/io/comm/Peer.java  2007-09-29 18:13:44 UTC 
(rev 15390)
+++ branches/freenet-jfk/src/freenet/io/comm/Peer.java  2007-09-29 18:42:16 UTC 
(rev 15391)
@@ -26,7 +26,6 @@
 import java.net.UnknownHostException;

 import freenet.support.transport.ip.HostnameSyntaxException;
-import freenet.support.transport.ip.HostnameUtil;
 import freenet.support.transport.ip.IPUtil;

 /**
@@ -56,6 +55,11 @@
                _port = dis.readInt();
        }

+       public Peer(DataInputStream dis, boolean checkHostnameOrIPSyntax) 
throws HostnameSyntaxException, IOException {
+               addr = new FreenetInetAddress(dis, checkHostnameOrIPSyntax);
+               _port = dis.readInt();
+       }
+
        /**
         * Create a Peer from an InetAddress and a port. The IP address is 
primary; that is
         * to say, it will remain the same regardless of DNS changes. Don't do 
this if you
@@ -74,22 +78,15 @@
         * @param physical The string to be parsed, in the format [ ip or 
domain name ]:[ port number].
         * @param allowUnknown If true, allow construction of the Peer even if 
the domain name
         * lookup fails.
-        * @param checkHostname If true, validate the syntax of the given DNS 
hostname or IPv4
-        * IP address
-        * @throws HostSyntaxException If the string is not formatted as a 
proper DNS hostname
-        * or IPv4 IP address
         * @throws PeerParseException If the string is not valid e.g. if it 
doesn't contain a 
         * port.
         * @throws UnknownHostException If allowUnknown is not set, and a 
domain name which does
         * not exist was passed in.
         */
-    public Peer(String physical, boolean allowUnknown, boolean checkHostname) 
throws HostnameSyntaxException, PeerParseException, UnknownHostException {
+    public Peer(String physical, boolean allowUnknown) throws 
PeerParseException, UnknownHostException {
         int offset = physical.lastIndexOf(':'); // ipv6
         if(offset < 0) throw new PeerParseException();
         String host = physical.substring(0, offset);
-        if(checkHostname) {
-               if(!HostnameUtil.isValidHostname(host, true)) throw new 
HostnameSyntaxException();
-               }
         addr = new FreenetInetAddress(host, allowUnknown);
         String strport = physical.substring(offset+1);
         try {
@@ -97,9 +94,8 @@
         } catch (NumberFormatException e) {
             throw new PeerParseException(e);
         }
-    }
+       }

-
        /**
         * Create a Peer from a string. This may be an IP address or a domain 
name. If it
         * is the latter, the name is primary rather than the IP address; 
@@ -108,23 +104,27 @@
         * @param physical The string to be parsed, in the format [ ip or 
domain name ]:[ port number].
         * @param allowUnknown If true, allow construction of the Peer even if 
the domain name
         * lookup fails.
+        * @param checkHostnameOrIPSyntax If true, validate the syntax of the 
given DNS hostname or IPv4
+        * IP address
+        * @throws HostSyntaxException If the string is not formatted as a 
proper DNS hostname
+        * or IPv4 IP address
         * @throws PeerParseException If the string is not valid e.g. if it 
doesn't contain a 
         * port.
         * @throws UnknownHostException If allowUnknown is not set, and a 
domain name which does
         * not exist was passed in.
         */
-    public Peer(String physical, boolean allowUnknown) throws 
PeerParseException, UnknownHostException {
+    public Peer(String physical, boolean allowUnknown, boolean 
checkHostnameOrIPSyntax) throws HostnameSyntaxException, PeerParseException, 
UnknownHostException {
         int offset = physical.lastIndexOf(':'); // ipv6
         if(offset < 0) throw new PeerParseException();
         String host = physical.substring(0, offset);
-        addr = new FreenetInetAddress(host, allowUnknown);
+        addr = new FreenetInetAddress(host, allowUnknown, 
checkHostnameOrIPSyntax);
         String strport = physical.substring(offset+1);
         try {
             _port = Integer.parseInt(strport);
         } catch (NumberFormatException e) {
             throw new PeerParseException(e);
         }
-       }
+    }

     public Peer(FreenetInetAddress addr, int port) {
        this.addr = addr;
@@ -219,8 +219,8 @@
                return addr.toString() + ':' + _port;
        }

-       public void writeToDataOutputStream(DataOutputStream dos, boolean 
oldForm) throws IOException {
-               addr.writeToDataOutputStream(dos, oldForm);
+       public void writeToDataOutputStream(DataOutputStream dos) throws 
IOException {
+               addr.writeToDataOutputStream(dos);
                dos.writeInt(_port);
        }


Modified: branches/freenet-jfk/src/freenet/l10n/freenet.l10n.en.properties
===================================================================
--- branches/freenet-jfk/src/freenet/l10n/freenet.l10n.en.properties    
2007-09-29 18:13:44 UTC (rev 15390)
+++ branches/freenet-jfk/src/freenet/l10n/freenet.l10n.en.properties    
2007-09-29 18:42:16 UTC (rev 15391)
@@ -605,6 +605,8 @@
 NodeUpdateManager.updateFailedTitle=Update Failed!
 NodeUpdateManager.updateURI=Where should the node look for updates?
 NodeUpdateManager.updateURILong=Where should the node look for updates?
+OpennetConnectionsToadlet.successTimeTitle=Last success
+OpennetConnectionsToadlet.successTime=Last time there was a successful CHK 
fetch from the node
 OpennetConnectionsToadlet.fullTitle=${counts} Strangers (Untrusted Peers) of 
${name}
 OpennetConnectionsToadlet.peersListTitle=My Opennet Peers (untrusted peers 
added by the node in promiscuous mode)
 OpennetUserAlert.warningTitle=Warning: Promiscuous Mode Enabled: Your node 
will connect to Strangers

Modified: branches/freenet-jfk/src/freenet/node/FNPPacketMangler.java
===================================================================
--- branches/freenet-jfk/src/freenet/node/FNPPacketMangler.java 2007-09-29 
18:13:44 UTC (rev 15390)
+++ branches/freenet-jfk/src/freenet/node/FNPPacketMangler.java 2007-09-29 
18:42:16 UTC (rev 15391)
@@ -1252,7 +1252,6 @@
                } catch (LocalAddressException e) {
                        Logger.error(this, "Tried to send auth packet to local 
address: "+replyTo+" for "+pn+" - maybe you should set allowLocalAddresses for 
this peer??");
                }
-               if(logMINOR) Logger.minor(this, "Sending auth packet (long) to 
"+replyTo+" - size "+data.length+" data length: "+output.length);
        }

        private void sendPacket(byte[] data, Peer replyTo, PeerNode pn, int 
alreadyReportedBytes) throws LocalAddressException {
@@ -2335,6 +2334,8 @@
                                sendFirstHalfDHPacket(0, negType, 
ctx.getOurExponential(), pn, peer);
                        else
                                sendMessage1(pn, peer);
+                       if(logMINOR)
+                               Logger.minor(this, "Sending handshake to 
"+peer+" for "+pn+" ("+i+" of "+handshakeIPs.length);
                        pn.sentHandshake();
                        sentCount += 1;
                }

Modified: branches/freenet-jfk/src/freenet/node/IPDetectorPluginManager.java
===================================================================
--- branches/freenet-jfk/src/freenet/node/IPDetectorPluginManager.java  
2007-09-29 18:13:44 UTC (rev 15390)
+++ branches/freenet-jfk/src/freenet/node/IPDetectorPluginManager.java  
2007-09-29 18:42:16 UTC (rev 15391)
@@ -1,6 +1,7 @@
 package freenet.node;

 import java.net.InetAddress;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
@@ -16,6 +17,7 @@
 import freenet.pluginmanager.ForwardPort;
 import freenet.pluginmanager.ForwardPortCallback;
 import freenet.pluginmanager.ForwardPortStatus;
+import freenet.pluginmanager.FredPlugin;
 import freenet.pluginmanager.FredPluginIPDetector;
 import freenet.pluginmanager.FredPluginPortForward;
 import freenet.support.HTMLNode;
@@ -196,6 +198,7 @@
         * Remove a plugin.
         */
        public void unregisterDetectorPlugin(FredPluginIPDetector d) {
+               DetectorRunner runningDetector;
                synchronized(this) {
                        int count = 0;
                        for(int i=0;i<plugins.length;i++) {
@@ -208,7 +211,9 @@
                                if(plugins[i] != d) newPlugins[x++] = 
plugins[i];
                        }
                        plugins = newPlugins;
+                       runningDetector = (DetectorRunner) runners.get(d);
                }
+               runningDetector.kill();
        }


@@ -244,7 +249,7 @@
         * (To detect new IP address)
         */ 

-       private DetectorRunner runner;
+       private HashMap /*<FredIPDetectorPlugin,DetectorRunner>*/ runners;
        private boolean lastDetectAttemptFailed;
        private long lastDetectAttemptEndedTime;
        private long firstTimeMaybeFakePeers;
@@ -266,10 +271,11 @@
                                detector.hasDetectedPM();
                                return;
                        }
-                       if(runner != null) {
+                       if(runners.size() < plugins.length) {
                                if(logMINOR) Logger.minor(this, "Already 
running IP detection plugins");
                                return;
-                       }
+                       } // FIXME what about detectors that take ages vs 
detectors that are fast?
+                       
                        // If detect attempt failed to produce an IP in the 
last 5 minutes, don't
                        // try again yet.
                        if(lastDetectAttemptFailed) {
@@ -487,13 +493,28 @@
        private void startDetect() {
                if(logMINOR) Logger.minor(this, "Detecting...");
                synchronized(this) {
-                       runner = new DetectorRunner();
-                       node.executor.execute(runner, "Plugin detector runner");
+                       for(int i=0;i<plugins.length;i++) {
+                               FredPluginIPDetector plugin = plugins[i];
+                               if(runners.containsKey(plugin)) continue;
+                               DetectorRunner d = new 
DetectorRunner(plugins[i]);
+                               runners.put(plugin, d);
+                               node.executor.execute(d, "Plugin detector 
runner for "+plugins[i].getClass());
+                       }
                }
        }

        public class DetectorRunner implements Runnable {
+               
+               final FredPluginIPDetector plugin;

+               public DetectorRunner(FredPluginIPDetector detector) {
+                       plugin = detector;
+               }
+
+               public void kill() {
+                       node.pluginManager.killPlugin((FredPlugin)plugin, 0);
+               }
+
                public void run() {
                        freenet.support.Logger.OSThread.logPID(this);
                        try {
@@ -508,12 +529,10 @@
                public void realRun() {
                        if(logMINOR) Logger.minor(this, "Running plugin 
detection");
                        try {
-                               FredPluginIPDetector[] run = plugins;
                                Vector v = new Vector();
-                               for(int i=0;i<run.length;i++) {
                                        DetectedIP[] detected = null;
                                        try {
-                                               detected = run[i].getAddress();
+                                               detected = plugin.getAddress();
                                        } catch (Throwable t) {
                                                Logger.error(this, "Caught "+t, 
t);
                                        }
@@ -521,7 +540,6 @@
                                                for(int 
j=0;j<detected.length;j++)
                                                        v.add(detected[j]);
                                        }
-                               }
                                synchronized(IPDetectorPluginManager.this) {
                                        lastDetectAttemptEndedTime = 
System.currentTimeMillis();
                                        boolean failed = false;
@@ -621,7 +639,9 @@
                                }
                                detector.processDetectedIPs(list);
                        } finally {
-                               runner = null;
+                               synchronized(IPDetectorPluginManager.this) {
+                                       runners.remove(plugin);
+                               }
                                detector.hasDetectedPM();
                        }
                }

Modified: branches/freenet-jfk/src/freenet/node/NodeDispatcher.java
===================================================================
--- branches/freenet-jfk/src/freenet/node/NodeDispatcher.java   2007-09-29 
18:13:44 UTC (rev 15390)
+++ branches/freenet-jfk/src/freenet/node/NodeDispatcher.java   2007-09-29 
18:42:16 UTC (rev 15391)
@@ -157,8 +157,12 @@
                // If true, purge all references to this node. Otherwise, we 
can keep the node
                // around in secondary tables etc in order to more easily 
reconnect later. 
                // (Mostly used on opennet)
-               // Not used at the moment - FIXME
                boolean purge = m.getBoolean(DMT.PURGE);
+               if(purge) {
+                       OpennetManager om = node.getOpennet();
+                       if(om != null)
+                               om.purgeOldOpennetPeer(source);
+               }
                // Process parting message
                int type = m.getInt(DMT.NODE_TO_NODE_MESSAGE_TYPE);
                ShortBuffer messageData = (ShortBuffer) 
m.getObject(DMT.NODE_TO_NODE_MESSAGE_DATA);

Modified: branches/freenet-jfk/src/freenet/node/NodeIPDetector.java
===================================================================
--- branches/freenet-jfk/src/freenet/node/NodeIPDetector.java   2007-09-29 
18:13:44 UTC (rev 15390)
+++ branches/freenet-jfk/src/freenet/node/NodeIPDetector.java   2007-09-29 
18:42:16 UTC (rev 15391)
@@ -11,7 +11,6 @@
 import freenet.config.SubConfig;
 import freenet.io.comm.FreenetInetAddress;
 import freenet.io.comm.Peer;
-import freenet.io.comm.PeerParseException;
 import freenet.l10n.L10n;
 import freenet.node.useralerts.IPUndetectedUserAlert;
 import freenet.node.useralerts.SimpleUserAlert;
@@ -149,8 +148,11 @@
                        }
                }

-               if(addresses.isEmpty() && (oldIPAddress != null) && 
!oldIPAddress.equals(overrideIPAddress))
+               if(addresses.isEmpty() && (oldIPAddress != null) && 
!oldIPAddress.equals(overrideIPAddress)) {
                        addresses.add(oldIPAddress);
+                       if(oldIPAddress.isRealInternetAddress(false, true))
+                               addedValidIP = true;
+               }

                // Try to pick it up from our connections
                if(node.peers != null) {
@@ -306,23 +308,14 @@
                                        redetectAddress();
                                        return;
                                }
-                               // Try making a dummy Peer, which will allow us 
to do a syntax check on the given hostname/IP address
+                               FreenetInetAddress addr;
                                try {
-                                       String hostAndDummyPort = val + 
":8888";  // add a dummy port so our string can be parsed by Peer's constructor
-                                       new Peer(hostAndDummyPort, false, true);
+                                       addr = new FreenetInetAddress(val, 
false, true);
                                } catch (HostnameSyntaxException e) {
                                        throw new 
InvalidConfigValueException(l10n("unknownHostErrorInIPOverride", "error", 
"hostname or IP address syntax error"));
-                               } catch (PeerParseException e) {
-                                       throw new 
InvalidConfigValueException(l10n("unknownHostErrorInIPOverride", "error", 
"parse error"));
                                } catch (UnknownHostException e) {
                                        throw new 
InvalidConfigValueException(l10n("unknownHostErrorInIPOverride", "error", 
e.getMessage()));
                                }
-                               FreenetInetAddress addr;
-                               try {
-                                       addr = new FreenetInetAddress(val, 
false);
-                               } catch (UnknownHostException e) {
-                                       throw new 
InvalidConfigValueException(l10n("unknownHostErrorInIPOverride", "error", 
e.getMessage()));
-                               }
                                overrideIPAddress = addr;
                                lastIPAddress = null;
                                redetectAddress();

Modified: branches/freenet-jfk/src/freenet/node/OpennetManager.java
===================================================================
--- branches/freenet-jfk/src/freenet/node/OpennetManager.java   2007-09-29 
18:13:44 UTC (rev 15390)
+++ branches/freenet-jfk/src/freenet/node/OpennetManager.java   2007-09-29 
18:42:16 UTC (rev 15391)
@@ -52,7 +52,7 @@
        // FIXME should be a function of # opennet peers? max # opennet peers? 
...
        static final int MIN_SUCCESS_BETWEEN_DROP_CONNS = 10;
        // FIXME make this configurable
-       static final int MAX_PEERS = 15;
+       static final int MAX_PEERS = 20;
        /** Chance of resetting path folding (for plausible deniability) is 1 
in this number. */
        static final int RESET_PATH_FOLDING_PROB = 20;
        /** Don't re-add a node until it's been up and disconnected for at 
least this long */
@@ -60,7 +60,7 @@
        /** Don't drop a node until it's at least this old */
        static final int DROP_MIN_AGE = 300*1000;
        /** Don't drop a node until this long after startup */
-       static final int DROP_STARTUP_DELAY = 300*1000;
+       static final int DROP_STARTUP_DELAY = 120*1000;
        /** Don't drop a node until this long after losing connection to it */
        static final int DROP_DISCONNECT_DELAY = 300*1000;
        /** But if it has disconnected more than once in this period, allow it 
to be dropped anyway */
@@ -206,10 +206,7 @@
                        if(logMINOR) Logger.minor(this, "Not adding self as 
opennet peer");
                        return false; // Equal to myself
                }
-               PeerNode match;
-               if(((match = node.peers.containsPeer(pn)) != null) && 
-                               (match.isConnected() || 
(!match.neverConnected()) || 
-                                               
match.timeSinceAddedOrRestarted() < DONT_READD_TIME)) {
+               if(peersLRU.contains(pn)) {
                        if(logMINOR) Logger.minor(this, "Not adding 
"+pn.userToString()+" to opennet list as already there");
                        return false;
                }
@@ -242,9 +239,15 @@
         * @return True if the node was added / should be added.
         */
        public boolean wantPeer(PeerNode nodeToAddNow, boolean addAtLRU) {
-               boolean ret = true;
+               boolean notMany = false;
                boolean noDisconnect;
                synchronized(this) {
+                       if(nodeToAddNow != null &&
+                                       peersLRU.contains(nodeToAddNow)) {
+                               if(logMINOR)
+                                       Logger.minor(this, "Opennet peer 
already present in LRU: "+nodeToAddNow);
+                               return true;
+                       }
                        if(peersLRU.size() < MAX_PEERS) {
                                if(nodeToAddNow != null) {
                                        if(logMINOR) Logger.minor(this, "Added 
opennet peer "+nodeToAddNow+" as opennet peers list not full");
@@ -257,15 +260,16 @@
                                        if(logMINOR) Logger.minor(this, "Want 
peer because not enough opennet nodes");
                                }
                                timeLastOffered = System.currentTimeMillis();
-                               ret = true;
+                               notMany = true;
                        }
                        noDisconnect = successCount < 
MIN_SUCCESS_BETWEEN_DROP_CONNS;
                }
-               if(ret) {
+               if(notMany) {
                        if(nodeToAddNow != null)
-                               node.peers.addPeer(nodeToAddNow, true); // Add 
to peers outside the OM lock
+                               node.peers.addPeer(nodeToAddNow, true, true); 
// Add to peers outside the OM lock
                        return true;
                }
+               boolean canAdd = true;
                Vector dropList = new Vector();
                synchronized(this) {
                        boolean hasDisconnected = false;
@@ -276,41 +280,30 @@
                        } else while(peersLRU.size() > MAX_PEERS - 
(nodeToAddNow == null ? 0 : 1)) {
                                PeerNode toDrop;
                                // can drop peers which are over the limit
-                               toDrop = peerToDrop(noDisconnect && 
nodeToAddNow != null && peersLRU.size() >= MAX_PEERS);
+                               toDrop = peerToDrop(noDisconnect || 
nodeToAddNow == null);
                                if(toDrop == null) {
                                        if(logMINOR)
-                                               Logger.minor(this, "No more 
peers to drop, cannot accept peer"+(nodeToAddNow == null ? "" : 
nodeToAddNow.toString()));
-                                       ret = false;
+                                               Logger.minor(this, "No more 
peers to drop, still "+peersLRU.size()+" peers, cannot accept 
peer"+(nodeToAddNow == null ? "" : nodeToAddNow.toString()));
+                                       canAdd = false;
                                        break;
                                }
                                if(logMINOR)
-                                       Logger.minor(this, "Drop opennet peer: 
"+toDrop+" (connected="+toDrop.isConnected()+")");
+                                       Logger.minor(this, "Drop opennet peer: 
"+toDrop+" (connected="+toDrop.isConnected()+") of "+peersLRU.size());
                                if(!toDrop.isConnected())
                                        hasDisconnected = true;
                                peersLRU.remove(toDrop);
                                dropList.add(toDrop);
                        }
-                       if(ret) {
+                       if(canAdd) {
                                long now = System.currentTimeMillis();
                                if(nodeToAddNow != null) {
-                                       // Here we can't avoid nested locks. So 
always take the OpennetManager lock first.
-                                       if(!node.peers.addPeer(nodeToAddNow)) {
-                                               // Can't add it, already 
present (some sort of race condition)
-                                               PeerNode readd = (PeerNode) 
dropList.remove(dropList.size()-1);
-                                               peersLRU.pushLeast(readd);
-                                               ret = false;
-                                               if(logMINOR) Logger.minor(this, 
"Could not add opennet peer "+nodeToAddNow+" because already in list");
-                                       } else {
-                                               successCount = 0;
-                                               if(addAtLRU)
-                                                       
peersLRU.pushLeast(nodeToAddNow);
-                                               else
-                                                       
peersLRU.push(nodeToAddNow);
-                                               if(logMINOR) Logger.minor(this, 
"Added opennet peer "+nodeToAddNow+" after clearing "+dropList.size()+" items");
-                                               oldPeers.remove(nodeToAddNow);
-                                               // Always take OpennetManager 
lock before PeerManager
-                                               
node.peers.addPeer(nodeToAddNow, true);
-                                       }
+                                       successCount = 0;
+                                       if(addAtLRU)
+                                               
peersLRU.pushLeast(nodeToAddNow);
+                                       else
+                                               peersLRU.push(nodeToAddNow);
+                                       if(logMINOR) Logger.minor(this, "Added 
opennet peer "+nodeToAddNow+" after clearing "+dropList.size()+" items - now 
have "+peersLRU.size()+" opennet peers");
+                                       oldPeers.remove(nodeToAddNow);
                                        if(!dropList.isEmpty())
                                                timeLastDropped = now;
                                } else {
@@ -318,7 +311,7 @@
                                                if(logMINOR)
                                                        Logger.minor(this, 
"Cannot accept peer because of minimum time between offers (last offered 
"+(now-timeLastOffered)+" ms ago)");
                                                // Cancel
-                                               ret = false;
+                                               canAdd = false;
                                        } else {
                                                if(!dropList.isEmpty())
                                                        timeLastDropped = now;
@@ -327,20 +320,30 @@
                                }
                        }
                }
+               if(nodeToAddNow != null && canAdd && 
!node.peers.addPeer(nodeToAddNow, true, true)) {
+                       if(logMINOR)
+                               Logger.minor(this, "Already in global peers 
list: "+nodeToAddNow+" when adding opennet node");
+                       // Just because it's in the global peers list doesn't 
mean its in the LRU, it may be an old-opennet-peers reconnection.
+                       // In which case we add it to the global peers list 
*before* adding it here.
+               }
                for(int i=0;i<dropList.size();i++) {
                        OpennetPeerNode pn = (OpennetPeerNode) dropList.get(i);
                        if(logMINOR) Logger.minor(this, "Dropping LRU opennet 
peer: "+pn);
                        node.peers.disconnect(pn, true, true);
                }
-               return ret;
+               return canAdd;
        }

        private void dropExcessPeers() {
                while(peersLRU.size() > MAX_PEERS) {
+                       if(logMINOR)
+                               Logger.minor(this, "Dropping opennet peers: 
currently "+peersLRU.size());
                        PeerNode toDrop;
                        toDrop = peerToDrop(false);
                        if(toDrop == null) return;
                        peersLRU.remove(toDrop);
+                       if(logMINOR)
+                               Logger.minor(this, "Dropping "+toDrop);
                        node.peers.disconnect(toDrop, true, true);
                }
        }
@@ -402,7 +405,6 @@
                        while (oldPeers.size() > MAX_OLD_PEERS)
                                oldPeers.pop();
                }
-               pn.disconnected();
        }

        synchronized PeerNode[] getOldPeers() {
@@ -436,4 +438,8 @@
                return nodes[node.random.nextInt(nodes.length)];
        }

+       public void purgeOldOpennetPeer(PeerNode source) {
+               oldPeers.remove(source);
+       }
+
 }

Modified: branches/freenet-jfk/src/freenet/node/OpennetPeerNode.java
===================================================================
--- branches/freenet-jfk/src/freenet/node/OpennetPeerNode.java  2007-09-29 
18:13:44 UTC (rev 15390)
+++ branches/freenet-jfk/src/freenet/node/OpennetPeerNode.java  2007-09-29 
18:42:16 UTC (rev 15391)
@@ -57,6 +57,7 @@

        public void onRemove() {
                opennet.onRemove(this);
+               super.onRemove();
        }

     public synchronized SimpleFieldSet exportMetadataFieldSet() {
@@ -69,12 +70,14 @@
        return timeLastSuccess;
     }

-    public void disconnected() {
-       synchronized(this) {
-               timePrevDisconnect = timeLastDisconnect;
-                       timeLastDisconnect = System.currentTimeMillis();
-       }
-       super.disconnected();
+    public boolean disconnected() {
+       if(super.disconnected()) {
+               synchronized(this) {
+                       timePrevDisconnect = timeLastDisconnect;
+                       timeLastDisconnect = System.currentTimeMillis();
+               }
+               return true;
+       } else return false;
     }

     public synchronized long timeLastDisconnect() {

Modified: branches/freenet-jfk/src/freenet/node/OpennetPeerNodeStatus.java
===================================================================
--- branches/freenet-jfk/src/freenet/node/OpennetPeerNodeStatus.java    
2007-09-29 18:13:44 UTC (rev 15390)
+++ branches/freenet-jfk/src/freenet/node/OpennetPeerNodeStatus.java    
2007-09-29 18:42:16 UTC (rev 15391)
@@ -4,6 +4,9 @@

        OpennetPeerNodeStatus(PeerNode peerNode) {
                super(peerNode);
+               timeLastSuccess = ((OpennetPeerNode)peerNode).timeLastSuccess();
        }

+       public final long timeLastSuccess;
+       
 }

Modified: branches/freenet-jfk/src/freenet/node/PacketSender.java
===================================================================
--- branches/freenet-jfk/src/freenet/node/PacketSender.java     2007-09-29 
18:13:44 UTC (rev 15390)
+++ branches/freenet-jfk/src/freenet/node/PacketSender.java     2007-09-29 
18:42:16 UTC (rev 15391)
@@ -27,6 +27,7 @@
 public class PacketSender implements Runnable, Ticker {

        private static boolean logMINOR;
+       private static boolean logDEBUG;

        /** Maximum time we will queue a message for in millseconds */
        static final int MAX_COALESCING_DELAY = 200;
@@ -68,6 +69,7 @@
         myThread.setDaemon(true);
         myThread.setPriority(Thread.MAX_PRIORITY);
         logMINOR = Logger.shouldLog(Logger.MINOR, this);
+        logDEBUG = Logger.shouldLog(Logger.DEBUG, this);
         rpiTemp = new Vector();
         rpiIntTemp = new int[64];
     }
@@ -328,12 +330,16 @@
         if(om != null) {
                int connCount = node.peers.quickCountConnectedPeers();
                int minDelay = connCount == 0 ? 
MIN_OLD_OPENNET_CONNECT_DELAY_NO_CONNS : MIN_OLD_OPENNET_CONNECT_DELAY;
+               if(logDEBUG)
+                       Logger.debug(this, "Conns "+connCount+" minDelay 
"+minDelay+" old opennet peers "+om.countOldOpennetPeers()+" last sent "+(now - 
timeLastSentOldOpennetConnectAttempt)+" startup "+(now - node.startupTime));
                if(now - timeLastSentOldOpennetConnectAttempt > minDelay &&
                                connCount <= 
MIN_CONNECTIONS_TRY_OLD_OPENNET_PEERS &&
                                om.countOldOpennetPeers() > 0 &&
                                now - node.startupTime > 
OpennetManager.DROP_STARTUP_DELAY) {
                PeerNode pn = om.randomOldOpennetNode();
                if(pn != null) {
+                       if(logMINOR)
+                               Logger.minor(this, "Sending old-opennet connect 
attempt to "+pn);
                        pn.getOutgoingMangler().sendHandshake(pn);
                        timeLastSentOldOpennetConnectAttempt = now;
                        if(pn.noContactDetails() && node.getPeerNodes().length 
> 0 && connCount > 0 && node.random.nextBoolean())
@@ -419,6 +425,9 @@
         }

         if(sleepTime > 0) {
+               // Update logging only when have time to do so
+            logMINOR = Logger.shouldLog(Logger.MINOR, this);
+            logDEBUG = Logger.shouldLog(Logger.DEBUG, this);
             try {
                 synchronized(this) {
                        if(logMINOR) Logger.minor(this, "Sleeping for 
"+sleepTime);

Modified: branches/freenet-jfk/src/freenet/node/PeerManager.java
===================================================================
--- branches/freenet-jfk/src/freenet/node/PeerManager.java      2007-09-29 
18:13:44 UTC (rev 15390)
+++ branches/freenet-jfk/src/freenet/node/PeerManager.java      2007-09-29 
18:42:16 UTC (rev 15391)
@@ -126,10 +126,12 @@
      */
     void tryReadPeers(String filename, NodeCrypto crypto, OpennetManager 
opennet, boolean isOpennet, boolean oldOpennetPeers) {
        synchronized(writePeersSync) {
-               if(isOpennet) {
-                       openFilename = filename;
-               } else {
-                       darkFilename = filename;
+               if(!oldOpennetPeers) {
+                       if(isOpennet) {
+                               openFilename = filename;
+                       } else {
+                               darkFilename = filename;
+                       }
                }
        }
        OutgoingPacketMangler mangler = crypto.packetMangler;
@@ -137,12 +139,14 @@
         File backupFile = new File(filename+".bak");
         // Try to read the node list from disk
        if(peersFile.exists()) {
-               if(readPeers(peersFile, mangler, crypto, opennet, isOpennet, 
oldOpennetPeers)) {
+               if(readPeers(peersFile, mangler, crypto, opennet, 
oldOpennetPeers)) {
                    String msg;
-                   if(isOpennet) {
-                           msg = "Read "+getOpennetPeers().length+" peers from 
"+peersFile;
+                   if(oldOpennetPeers) {
+                       msg = "Read "+opennet.countOldOpennetPeers()+" 
old-opennet-peers from "+peersFile;
+                   } else if(isOpennet) {
+                           msg = "Read "+getOpennetPeers().length+" opennet 
peers from "+peersFile;
                                } else {
-                           msg = "Read "+getDarknetPeers().length+" peers from 
"+peersFile;
+                           msg = "Read "+getDarknetPeers().length+" darknet 
peers from "+peersFile;
                                }
                        Logger.normal(this, msg);
                        System.out.println(msg);
@@ -151,12 +155,14 @@
                }
        // Try the backup
        if(backupFile.exists()) {
-               if(readPeers(backupFile, mangler, crypto, opennet, isOpennet, 
oldOpennetPeers)) {
+               if(readPeers(backupFile, mangler, crypto, opennet, 
oldOpennetPeers)) {
                    String msg;
-                   if(isOpennet) {
-                           msg = "Read "+getOpennetPeers().length+" peers from 
"+backupFile;
+                   if(oldOpennetPeers) {
+                       msg = "Read "+opennet.countOldOpennetPeers()+" 
old-opennet-peers from "+peersFile;
+                   } else if(isOpennet) {
+                           msg = "Read "+getOpennetPeers().length+" opennet 
peers from "+peersFile;
                                } else {
-                           msg = "Read "+getDarknetPeers().length+" peers from 
"+backupFile;
+                           msg = "Read "+getDarknetPeers().length+" darknet 
peers from "+peersFile;
                                }
                        Logger.normal(this, msg);
                        System.out.println(msg);
@@ -167,7 +173,7 @@
        }               
        }

-       private boolean readPeers(File peersFile, OutgoingPacketMangler 
mangler, NodeCrypto crypto, OpennetManager opennet, boolean isOpennet, boolean 
oldOpennetPeers) {
+       private boolean readPeers(File peersFile, OutgoingPacketMangler 
mangler, NodeCrypto crypto, OpennetManager opennet, boolean oldOpennetPeers) {
        boolean gotSome = false;
        FileInputStream fis;
                try {
@@ -204,7 +210,7 @@
                 if(oldOpennetPeers)
                        opennet.addOldOpennetNode(pn);
                 else
-                       addPeer(pn, true);
+                       addPeer(pn, true, false);
                 gotSome = true;
             }
         } catch (EOFException e) {
@@ -221,7 +227,7 @@
        }

        public boolean addPeer(PeerNode pn) {
-               return addPeer(pn, false);
+               return addPeer(pn, false, false);
        }

        /**
@@ -229,10 +235,14 @@
         * @param pn The node to add to the routing table.
         * @param ignoreOpennet If true, don't check for opennet peers. If 
false, check for opennet peers and if so,
         * if opennet is enabled auto-add them to the opennet LRU, otherwise 
fail.
+        * @param reactivate If true, re-enable the peer if it is in state 
DISCONNECTING before re-adding it.
         * @return True if the node was successfully added. False if it was 
already present, or if we tried to add
         * an opennet peer when opennet was disabled.
         */
-       boolean addPeer(PeerNode pn, boolean ignoreOpennet) {
+       boolean addPeer(PeerNode pn, boolean ignoreOpennet, boolean reactivate) 
{
+               assert(pn != null);
+               if(reactivate)
+                       pn.forceCancelDisconnecting();
                synchronized (this) {
                        for (int i = 0; i < myPeers.length; i++) {
                                if (myPeers[i].equals(pn)) {
@@ -270,47 +280,50 @@
        }

     private boolean removePeer(PeerNode pn) {
+               boolean isInPeers = false;
        synchronized(this) {
-       boolean isInPeers = false;
-        for(int i=0;i<myPeers.length;i++) {
-            if(myPeers[i] == pn) isInPeers=true;
-        }
-        int peerNodeStatus = pn.getPeerNodeStatus();
-        removePeerNodeStatus( peerNodeStatus, pn );
-        String peerNodePreviousRoutingBackoffReason = 
pn.getPreviousBackoffReason();
-        if(peerNodePreviousRoutingBackoffReason != null) {
-               
removePeerNodeRoutingBackoffReason(peerNodePreviousRoutingBackoffReason, pn);
-        }
-        if(pn instanceof DarknetPeerNode)
-               ((DarknetPeerNode)pn).removeExtraPeerDataDir();
-        if(!isInPeers) return false;
+               for(int i=0;i<myPeers.length;i++) {
+                       if(myPeers[i] == pn) isInPeers=true;
+               }
+               int peerNodeStatus = pn.getPeerNodeStatus();
+               removePeerNodeStatus( peerNodeStatus, pn );
+               String peerNodePreviousRoutingBackoffReason = 
pn.getPreviousBackoffReason();
+               if(peerNodePreviousRoutingBackoffReason != null) {
+                       
removePeerNodeRoutingBackoffReason(peerNodePreviousRoutingBackoffReason, pn);
+               }
+               if(pn instanceof DarknetPeerNode)
+                       ((DarknetPeerNode)pn).removeExtraPeerDataDir();
+               
+               if(isInPeers) {

-        // removing from connectedPeers
-        ArrayList a = new ArrayList();
-        for(int i=0;i<myPeers.length;i++) {
-               if((myPeers[i]!=pn) && myPeers[i].isRoutable())
-                       a.add(myPeers[i]);
-        }
-        
-        PeerNode[] newConnectedPeers = new PeerNode[a.size()];
-        newConnectedPeers = (PeerNode[]) a.toArray(newConnectedPeers);
-           connectedPeers = newConnectedPeers;
-        
-        // removing from myPeers
-        PeerNode[] newMyPeers = new PeerNode[myPeers.length-1];
-        int positionInNewArray = 0;
-        for(int i=0;i<myPeers.length;i++) {
-               if(myPeers[i]!=pn){
-                       newMyPeers[positionInNewArray] = myPeers[i];
-                       positionInNewArray++;
-               }
-        }
-        myPeers = newMyPeers;
-        
-        Logger.normal(this, "Removed "+pn);
+                       // removing from connectedPeers
+                       ArrayList a = new ArrayList();
+                       for(int i=0;i<myPeers.length;i++) {
+                               if((myPeers[i]!=pn) && myPeers[i].isRoutable())
+                                       a.add(myPeers[i]);
+                       }
+                       
+                       PeerNode[] newConnectedPeers = new PeerNode[a.size()];
+                       newConnectedPeers = (PeerNode[]) 
a.toArray(newConnectedPeers);
+                       connectedPeers = newConnectedPeers;
+                       
+                       // removing from myPeers
+                       PeerNode[] newMyPeers = new PeerNode[myPeers.length-1];
+                       int positionInNewArray = 0;
+                       for(int i=0;i<myPeers.length;i++) {
+                               if(myPeers[i]!=pn){
+                                       newMyPeers[positionInNewArray] = 
myPeers[i];
+                                       positionInNewArray++;
+                               }
+                       }
+                       myPeers = newMyPeers;
+                       
+                       Logger.normal(this, "Removed "+pn);
+               }
        }
        pn.onRemove();
-        updatePMUserAlert();
+       if(isInPeers)
+               updatePMUserAlert();
         return true;
     }

@@ -446,13 +459,13 @@
                                        }
                                }, 0, null);
                        } catch (NotConnectedException e) {
-                       if(removePeer(pn))
+                       if(pn.isDisconnecting() && removePeer(pn))
                                writePeers();
                        return;
                        }
                        node.getTicker().queueTimedJob(new Runnable() {
                                public void run() {
-                               if(removePeer(pn))
+                               if(pn.isDisconnecting() && removePeer(pn))
                                        writePeers();
                                }
                        }, 60*1000);

Modified: branches/freenet-jfk/src/freenet/node/PeerNode.java
===================================================================
--- branches/freenet-jfk/src/freenet/node/PeerNode.java 2007-09-29 18:13:44 UTC 
(rev 15390)
+++ branches/freenet-jfk/src/freenet/node/PeerNode.java 2007-09-29 18:42:16 UTC 
(rev 15391)
@@ -944,13 +944,16 @@

     /**
      * Disconnected e.g. due to not receiving a packet for ages.
+     * @return True if the node was connected, false if it was not.
      */
-    public void disconnected() {
+    public boolean disconnected() {
         long now = System.currentTimeMillis();
         Logger.normal(this, "Disconnected "+this);
         node.usm.onDisconnect(this);
         node.peers.disconnected(this);
+        boolean ret;
         synchronized(this) {
+               ret = isConnected;
                // Force renegotiation.
             isConnected = false;
             isRoutable = false;
@@ -966,6 +969,7 @@
         }
         node.lm.lostOrRestartedNode(this);
         setPeerNodeStatus(now);
+        return ret;
     }

     public void forceDisconnect() {
@@ -2735,9 +2739,6 @@
        /** Called when a request or insert succeeds. Used by opennet. */
        public abstract void onSuccess(boolean insert, boolean ssk);

-       /** Called when the peer is removed from the PeerManager */
-       public abstract void onRemove();
-
        /** Called when a delayed disconnect is occurring. Tell the node that 
it is being disconnected, but
         * that the process may take a while. */
        public void notifyDisconnecting() {
@@ -2747,6 +2748,24 @@
                setPeerNodeStatus(System.currentTimeMillis());
        }

+       /** Called to cancel a delayed disconnect. Always succeeds even if the 
node was not being 
+        * disconnected. */
+       public void forceCancelDisconnecting() {
+               synchronized(this) {
+                       disconnecting = false;
+               }
+               setPeerNodeStatus(System.currentTimeMillis());
+       }
+       
+       /** Called when the peer is removed from the PeerManager */
+       public void onRemove() {
+               disconnected();
+       }
+
+       public synchronized boolean isDisconnecting() {
+               return disconnecting;
+       }
+       
        protected byte[] getJFKBuffer() {
                return jfkBuffer;
        }

Modified: branches/freenet-jfk/src/freenet/node/Version.java
===================================================================
--- branches/freenet-jfk/src/freenet/node/Version.java  2007-09-29 18:13:44 UTC 
(rev 15390)
+++ branches/freenet-jfk/src/freenet/node/Version.java  2007-09-29 18:42:16 UTC 
(rev 15391)
@@ -24,17 +24,17 @@
        public static final String protocolVersion = "1.0";

        /** The build number of the current revision */
-       private static final int buildNumber = 1064;
+       private static final int buildNumber = 1065;

        /** Oldest build of Fred we will talk to */
-       private static final int oldLastGoodBuild = 1058;
-       private static final int newLastGoodBuild = 1064;
+       private static final int oldLastGoodBuild = 1064;
+       private static final int newLastGoodBuild = 1065;
        static final long transitionTime;

        static {
                final Calendar _cal = 
Calendar.getInstance(TimeZone.getTimeZone("GMT"));
                // year, month - 1 (or constant), day, hour, minute, second
-               _cal.set( 2007, Calendar.SEPTEMBER, 28, 0, 0, 0 );
+               _cal.set( 2007, Calendar.SEPTEMBER, 30, 0, 0, 0 );
                transitionTime = _cal.getTimeInMillis();
        }


Modified: branches/freenet-jfk/src/freenet/node/fcp/AddPeer.java
===================================================================
--- branches/freenet-jfk/src/freenet/node/fcp/AddPeer.java      2007-09-29 
18:13:44 UTC (rev 15390)
+++ branches/freenet-jfk/src/freenet/node/fcp/AddPeer.java      2007-09-29 
18:42:16 UTC (rev 15391)
@@ -149,7 +149,7 @@
                        }
                        System.out.println("Added darknet peer: "+pn);
                }
-               handler.outputHandler.queue(new Peer(pn, true, true));
+               handler.outputHandler.queue(new PeerMessage(pn, true, true));
        }

 }

Modified: branches/freenet-jfk/src/freenet/node/fcp/ListPeerMessage.java
===================================================================
--- branches/freenet-jfk/src/freenet/node/fcp/ListPeerMessage.java      
2007-09-29 18:13:44 UTC (rev 15390)
+++ branches/freenet-jfk/src/freenet/node/fcp/ListPeerMessage.java      
2007-09-29 18:42:16 UTC (rev 15391)
@@ -36,7 +36,7 @@
                        handler.outputHandler.queue(msg);
                        return;
                }
-               handler.outputHandler.queue(new Peer(pn, true, true));
+               handler.outputHandler.queue(new PeerMessage(pn, true, true));
        }

 }

Modified: branches/freenet-jfk/src/freenet/node/fcp/ListPeersMessage.java
===================================================================
--- branches/freenet-jfk/src/freenet/node/fcp/ListPeersMessage.java     
2007-09-29 18:13:44 UTC (rev 15390)
+++ branches/freenet-jfk/src/freenet/node/fcp/ListPeersMessage.java     
2007-09-29 18:42:16 UTC (rev 15391)
@@ -35,7 +35,7 @@
                PeerNode[] nodes = node.getPeerNodes();
                for(int i = 0; i < nodes.length; i++) {
                        PeerNode pn = nodes[i];
-                       handler.outputHandler.queue(new Peer(pn, withMetadata, 
withVolatile));
+                       handler.outputHandler.queue(new PeerMessage(pn, 
withMetadata, withVolatile));
                }

                handler.outputHandler.queue(new EndListPeersMessage());

Modified: branches/freenet-jfk/src/freenet/node/fcp/ModifyPeer.java
===================================================================
--- branches/freenet-jfk/src/freenet/node/fcp/ModifyPeer.java   2007-09-29 
18:13:44 UTC (rev 15390)
+++ branches/freenet-jfk/src/freenet/node/fcp/ModifyPeer.java   2007-09-29 
18:42:16 UTC (rev 15391)
@@ -76,7 +76,7 @@
                                
dpn.setAllowLocalAddresses(Fields.stringToBool(allowLocalAddressesString, 
false));
                        }
                }
-               handler.outputHandler.queue(new Peer(pn, true, true));
+               handler.outputHandler.queue(new PeerMessage(pn, true, true));
        }

 }

Deleted: branches/freenet-jfk/src/freenet/node/fcp/Peer.java
===================================================================
--- branches/freenet-jfk/src/freenet/node/fcp/Peer.java 2007-09-29 18:13:44 UTC 
(rev 15390)
+++ branches/freenet-jfk/src/freenet/node/fcp/Peer.java 2007-09-29 18:42:16 UTC 
(rev 15391)
@@ -1,49 +0,0 @@
-/* This code is part of Freenet. It is distributed under the GNU General
- * Public License, version 2 (or at your option any later version). See
- * http://www.gnu.org/ for further details of the GPL. */
-package freenet.node.fcp;
-
-import freenet.node.Node;
-import freenet.node.PeerNode;
-import freenet.support.SimpleFieldSet;
-
-public class Peer extends FCPMessage {
-       static final String name = "Peer";
-       
-       final PeerNode pn;
-       final boolean withMetadata;
-       final boolean withVolatile;
-       
-       public Peer(PeerNode pn, boolean withMetadata, boolean withVolatile) {
-               this.pn = pn;
-               this.withMetadata = withMetadata;
-               this.withVolatile = withVolatile;
-       }
-       
-       public SimpleFieldSet getFieldSet() {
-               SimpleFieldSet fs = pn.exportFieldSet();
-               if(withMetadata) {
-                       SimpleFieldSet meta = pn.exportMetadataFieldSet();
-                       if(!meta.isEmpty()) {
-                               fs.put("metadata", meta);
-                       }
-               }
-               if(withVolatile) {
-                       SimpleFieldSet vol = pn.exportVolatileFieldSet();
-                       if(!vol.isEmpty()) {
-                               fs.put("volatile", vol);
-                       }
-               }
-               return fs;
-       }
-
-       public String getName() {
-               return name;
-       }
-
-       public void run(FCPConnectionHandler handler, Node node)
-                       throws MessageInvalidException {
-               throw new 
MessageInvalidException(ProtocolErrorMessage.INVALID_MESSAGE, "Peer goes from 
server to client not the other way around", null, false);
-       }
-
-}

Copied: branches/freenet-jfk/src/freenet/node/fcp/PeerMessage.java (from rev 
15390, trunk/freenet/src/freenet/node/fcp/PeerMessage.java)
===================================================================
--- branches/freenet-jfk/src/freenet/node/fcp/PeerMessage.java                  
        (rev 0)
+++ branches/freenet-jfk/src/freenet/node/fcp/PeerMessage.java  2007-09-29 
18:42:16 UTC (rev 15391)
@@ -0,0 +1,49 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+package freenet.node.fcp;
+
+import freenet.node.Node;
+import freenet.node.PeerNode;
+import freenet.support.SimpleFieldSet;
+
+public class PeerMessage extends FCPMessage {
+       static final String name = "Peer";
+       
+       final PeerNode pn;
+       final boolean withMetadata;
+       final boolean withVolatile;
+       
+       public PeerMessage(PeerNode pn, boolean withMetadata, boolean 
withVolatile) {
+               this.pn = pn;
+               this.withMetadata = withMetadata;
+               this.withVolatile = withVolatile;
+       }
+       
+       public SimpleFieldSet getFieldSet() {
+               SimpleFieldSet fs = pn.exportFieldSet();
+               if(withMetadata) {
+                       SimpleFieldSet meta = pn.exportMetadataFieldSet();
+                       if(!meta.isEmpty()) {
+                               fs.put("metadata", meta);
+                       }
+               }
+               if(withVolatile) {
+                       SimpleFieldSet vol = pn.exportVolatileFieldSet();
+                       if(!vol.isEmpty()) {
+                               fs.put("volatile", vol);
+                       }
+               }
+               return fs;
+       }
+
+       public String getName() {
+               return name;
+       }
+
+       public void run(FCPConnectionHandler handler, Node node)
+                       throws MessageInvalidException {
+               throw new 
MessageInvalidException(ProtocolErrorMessage.INVALID_MESSAGE, "Peer goes from 
server to client not the other way around", null, false);
+       }
+
+}

Modified: branches/freenet-jfk/src/freenet/node/updater/NodeUpdateManager.java
===================================================================
--- branches/freenet-jfk/src/freenet/node/updater/NodeUpdateManager.java        
2007-09-29 18:13:44 UTC (rev 15390)
+++ branches/freenet-jfk/src/freenet/node/updater/NodeUpdateManager.java        
2007-09-29 18:42:16 UTC (rev 15391)
@@ -116,6 +116,10 @@

         try {
                        updateURI = new 
FreenetURI(updaterConfig.getString("URI"));
+                       long ver = updateURI.getSuggestedEdition();
+                       if(ver < Version.buildNumber())
+                               ver = Version.buildNumber();
+                       updateURI = updateURI.setSuggestedEdition(ver);
                } catch (MalformedURLException e) {
                        throw new 
InvalidConfigValueException(l10n("invalidUpdateURI", "error", 
e.getLocalizedMessage()));
                }
@@ -135,6 +139,10 @@

         try {
                        extURI = new 
FreenetURI(updaterConfig.getString("extURI"));
+                       long ver = extURI.getSuggestedEdition();
+                       if(ver < NodeStarter.extBuildNumber)
+                               ver = NodeStarter.extBuildNumber;
+                       extURI = extURI.setSuggestedEdition(ver);
                } catch (MalformedURLException e) {
                        throw new 
InvalidConfigValueException(l10n("invalidExtURI", "error", 
e.getLocalizedMessage()));
                }

Modified: branches/freenet-jfk/src/freenet/pluginmanager/PluginInfoWrapper.java
===================================================================
--- branches/freenet-jfk/src/freenet/pluginmanager/PluginInfoWrapper.java       
2007-09-29 18:13:44 UTC (rev 15390)
+++ branches/freenet-jfk/src/freenet/pluginmanager/PluginInfoWrapper.java       
2007-09-29 18:42:16 UTC (rev 15391)
@@ -14,7 +14,7 @@
        private Thread thread;
        private long start;
        private String threadName;
-       private FredPlugin plug;
+       final FredPlugin plug;
        private boolean isPproxyPlugin;
        private boolean isThreadlessPlugin;
        private boolean isIPDetectorPlugin;
@@ -26,9 +26,9 @@
        //public String 

        public PluginInfoWrapper(FredPlugin plug, String filename) {
+               this.plug = plug;
                if (fedPluginThread) return;
                className = plug.getClass().toString();
-               this.plug = plug;
                this.filename = filename;
                threadName = 'p' + className.replaceAll("^class ", "") + '_' + 
hashCode();
                start = System.currentTimeMillis();

Modified: branches/freenet-jfk/src/freenet/pluginmanager/PluginManager.java
===================================================================
--- branches/freenet-jfk/src/freenet/pluginmanager/PluginManager.java   
2007-09-29 18:13:44 UTC (rev 15390)
+++ branches/freenet-jfk/src/freenet/pluginmanager/PluginManager.java   
2007-09-29 18:42:16 UTC (rev 15391)
@@ -285,8 +285,10 @@
                synchronized (pluginWrappers) {
                        for(int i=0;i<pluginWrappers.size() && !found;i++) {
                                pi = (PluginInfoWrapper) pluginWrappers.get(i);
-                               if (pi.getThreadName().equals(name))
+                               if (pi.getThreadName().equals(name)) {
                                        found = true;
+                                       break;
+                               }
                        }
                }
                if (found) {
@@ -294,6 +296,21 @@
                }
        }

+       public void killPlugin(FredPlugin plugin, int maxWaitTime) {
+               PluginInfoWrapper pi = null;
+               boolean found = false;
+               synchronized (pluginWrappers) {
+                       for(int i=0;i<pluginWrappers.size() && !found;i++) {
+                               pi = (PluginInfoWrapper) pluginWrappers.get(i);
+                               if (pi.plug == plugin) {
+                                       found = true;
+                               }
+                       }
+               }
+               if (found) {
+                       pi.stopPlugin(this, maxWaitTime);
+               }
+       }

        /**
         * Method to load a plugin from the given path and return is as an 
object.

Modified: branches/freenet-jfk/src/freenet/support/Serializer.java
===================================================================
--- branches/freenet-jfk/src/freenet/support/Serializer.java    2007-09-29 
18:13:44 UTC (rev 15390)
+++ branches/freenet-jfk/src/freenet/support/Serializer.java    2007-09-29 
18:42:16 UTC (rev 15391)
@@ -95,17 +95,6 @@
                }
        }

-       private static boolean needOldPeerFormat(PeerContext ctx) {
-               int ver = ctx.getVersionNumber();
-               if(ver >= 1008) {
-                       if(Logger.shouldLog(Logger.MINOR, Serializer.class)) 
Logger.minor(Serializer.class, "New format peer: "+ver+" : "+ctx);
-               } else {
-                       if(Logger.shouldLog(Logger.MINOR, Serializer.class)) 
Logger.minor(Serializer.class, "Old format peer: "+ver+" : "+ctx);
-               }
-               
-               return ver < 1008;
-       }
-
        public static void writeToDataOutputStream(Object object, 
DataOutputStream dos, PeerContext ctx) throws IOException {
                Class type = object.getClass();
                if (type.equals(Boolean.class)) {
@@ -135,7 +124,7 @@
                                }
                        }
                } else if (type.equals(Peer.class)) {
-                       ((Peer)object).writeToDataOutputStream(dos, 
needOldPeerFormat(ctx));
+                       ((Peer)object).writeToDataOutputStream(dos);
                } else if 
(WritableToDataOutputStream.class.isAssignableFrom(type)) {
                        WritableToDataOutputStream b = 
(WritableToDataOutputStream) object;
                        b.writeToDataOutputStream(dos);

Modified: branches/freenet-jfk/src/freenet/support/TimeUtil.java
===================================================================
--- branches/freenet-jfk/src/freenet/support/TimeUtil.java      2007-09-29 
18:13:44 UTC (rev 15390)
+++ branches/freenet-jfk/src/freenet/support/TimeUtil.java      2007-09-29 
18:42:16 UTC (rev 15391)
@@ -51,7 +51,7 @@
             l = l * -1;
         }
         if( !withSecondFractions && l < 1000 ) {
-            return "";
+            return "0";
         }
         if(termCount >= maxTerms) {
             return sb.toString();

Modified: branches/freenet-jfk/test/freenet/support/TimeUtilTest.java
===================================================================
--- branches/freenet-jfk/test/freenet/support/TimeUtilTest.java 2007-09-29 
18:13:44 UTC (rev 15390)
+++ branches/freenet-jfk/test/freenet/support/TimeUtilTest.java 2007-09-29 
18:42:16 UTC (rev 15391)
@@ -126,7 +126,7 @@
         */
        public void testFormatTime_LongIntBoolean_milliseconds() {
                long methodValue = 1;   //1ms
-               assertEquals(TimeUtil.formatTime(methodValue,6,false),"");
+               assertEquals(TimeUtil.formatTime(methodValue,6,false),"0");
                assertEquals(TimeUtil.formatTime(methodValue,6,true),"0.001s");
        }



Reply via email to