Oops, that had an NPE in it, see
http://lostlogicx.com/transfer/freenet-blacklist.patch for a complete
corrected patch or
http://lostlogicx.com/transfer/freenet-blacklist-fix-npe.patch for an
incrimental fix from the patch attached to my original message.

--Brandon

On Sun, 09/21/03 at 21:10:58 -0500, Brandon Low wrote:
> Not sure how this is as far as correct ways to fix things, but the
> attached patch is one potential way to fix the problems which we've been
> having with excessive connections being opened all the time on recent
> builds.
> 
> Applies to 6205 code.
> 
> Impliments a BlackListQueue by modifying LRUQueue to include times and a
> clean function.  The BlackListQueue is currently set to blackList a node
> for 60 seconds if it's connection has suddenly and unexpectedly died.
> On my node this seems to massively reduce the number of cyclic
> connections being opened.  In order to make this work, I also had to fix
> tcpAddress.hashCode() and by proxy therefor Peer.hashCode() they could
> have different values for the same peer depending on how the
> constructors were called.  I'm not sure why upstream nodes are so often
> repeatedly allowing an incoming connection to complete and then dumping
> it, but with this patch, that behaviour no longer punishes the network
> so much.
> 
> --Brandon

> Index: src/freenet/ConnectionHandler.java
> ===================================================================
> RCS file: /cvsroot/freenet/freenet/src/freenet/ConnectionHandler.java,v
> retrieving revision 1.159
> diff -u -r1.159 ConnectionHandler.java
> --- src/freenet/ConnectionHandler.java        20 Sep 2003 19:58:59 -0000      1.159
> +++ src/freenet/ConnectionHandler.java        22 Sep 2003 02:05:04 -0000
> @@ -1246,6 +1246,7 @@
>       public void queuedClose() {
>               logDEBUG = Core.logger.shouldLog(Logger.DEBUG,this);
>               if(logDEBUG) logDEBUG("Queued close", true);
> +        ocm.blackList(peer);
>               terminate();
>               if(logDEBUG) logDEBUG("Terminated in queuedClose()");
>       }
> Index: src/freenet/OpenConnectionManager.java
> ===================================================================
> RCS file: /cvsroot/freenet/freenet/src/freenet/OpenConnectionManager.java,v
> retrieving revision 1.106
> diff -u -r1.106 OpenConnectionManager.java
> --- src/freenet/OpenConnectionManager.java    19 Sep 2003 17:18:04 -0000      1.106
> +++ src/freenet/OpenConnectionManager.java    22 Sep 2003 02:05:04 -0000
> @@ -53,6 +53,8 @@
>       private Object openConnsSync = new Object();
>      
>      private final LRUQueue lru = new LRUQueue();
> +    // Queue of blacklisted peers
> +    private final LRUQueue blq = new LRUQueue(60000,100);
>      private int maxConnections = -1;
>      
>       private boolean logDEBUG = true;
> @@ -318,6 +320,11 @@
>               }
>      }
>      
> +    public void blackList(Peer p){
> +        Core.logger.log(this, "blackListing " + p, Logger.DEBUG);
> +        blq.push(p);
> +    }    
> +    
>      /**
>       * Creates a new Connection which is started and added.
>       * @param c     The Core to connect from
> @@ -340,24 +347,36 @@
>               boolean updatedRefcount = false;
>               
>               boolean weStarted = false;
> +        blq.clean();
> +        Core.logger.log(this, "Current blackListQueue size: " + blq.size() +
> +                        ", Checking " + p, 
> +                        Logger.DEBUG);
> +        if ( blq.containsKey(p) ) {
> +            Core.logger.log(this, "Attempted to open connection for blackListed " +
> +                            p,Logger.DEBUG);
> +            ConnectFailedException e = 
> +                new ConnectFailedException(p.getAddress(), 
> +                                           p.getIdentity(),
> +                                           "BlackListed",
> +                                           true);
> +            Core.logger.log(this, "Failed to connect: " + e, Logger.DEBUG);
> +            throw e;
> +        }
>               try {
>                       synchronized(connectionJobs) {
> -                             while(ct == null || ct.done) {
> -                                     ct = (ConnectionJob)(connectionJobs.get(p));
> -                                     if(ct != null && ct.done) {
> -                                             if(connectionJobs.get(p) == ct) {
> -                                                     connectionJobs.remove(p);
> -                                                     continue;
> -                                             }
> -                                     }
> -                                     break;
> -                             }
> -                             if(ct != null) {
> -                                     Core.logger.log(this, "Got "+ct+", waiting on 
> it",
> -                                                                     Logger.DEBUG);
> -                                     updatedRefcount = true;
> -                                     ct.incRefcount();
> -                             } else {
> +                if ( ( ct = (ConnectionJob)connectionJobs.get(p) ) != null ) {
> +                    if ( ct.done ) {
> +                        connectionJobs.remove(p);
> +                        ct = null;
> +                    } else {
> +                        Core.logger.log(this, "Got "+ct+", waiting on it",
> +                        Logger.DEBUG);
> +                        updatedRefcount = true;
> +                        ct.incRefcount();
> +                    }
> +                }
> +                    
> +                             if(ct == null) {
>                                       weStarted = true;
>                                       ct = new ConnectionJob(c, p);
>                                       connectionJobs.put(p, ct);
> Index: src/freenet/Peer.java
> ===================================================================
> RCS file: /cvsroot/freenet/freenet/src/freenet/Peer.java,v
> retrieving revision 1.3
> diff -u -r1.3 Peer.java
> --- src/freenet/Peer.java     12 Sep 2003 01:52:25 -0000      1.3
> +++ src/freenet/Peer.java     22 Sep 2003 02:05:04 -0000
> @@ -58,7 +58,7 @@
>      }
>      
>      public int hashCode() {
> -     return id.hashCode() ^ addr.hashCode();
> +        return id.hashCode() ^ addr.hashCode();
>      }
>      
>      public String toString() {
> Index: src/freenet/support/LRUQueue.java
> ===================================================================
> RCS file: /cvsroot/freenet/freenet/src/freenet/support/LRUQueue.java,v
> retrieving revision 1.4
> diff -u -r1.4 LRUQueue.java
> --- src/freenet/support/LRUQueue.java 10 Sep 2003 19:45:28 -0000      1.4
> +++ src/freenet/support/LRUQueue.java 22 Sep 2003 02:05:05 -0000
> @@ -5,6 +5,11 @@
>  
>  public class LRUQueue {
>  
> +    private long maxQueueTimeMillis=60000;
> +    private int maxQueueElements=100;
> +    private final DoublyLinkedListImpl list = new DoublyLinkedListImpl();
> +    private final Hashtable hash = new Hashtable();
> +    
>      /*
>       * I've just converted this to using the DLList and Hashtable
>       * this makes it Hashtable time instead of O(N) for push and
> @@ -12,9 +17,14 @@
>       * push is by far the most done operation, this should be an
>       * overall improvement.
>       */
> -    private final DoublyLinkedListImpl list = new DoublyLinkedListImpl();
> -    private final Hashtable hash = new Hashtable();
> +    public LRUQueue() {
> +    }
>      
> +    public LRUQueue(long maxQueueTimeMillis,int maxQueueElements) {
> +        this.maxQueueTimeMillis = maxQueueTimeMillis;
> +        this.maxQueueElements = maxQueueElements;
> +    }
> +
>      /**
>       *       push()ing an object that is already in
>       *       the queue moves that object to the most
> @@ -28,10 +38,29 @@
>              hash.put(obj,insert);
>          } else {
>              list.remove(insert);
> +            insert.lastTouchedTimeMillis = System.currentTimeMillis();
>          }
>  
>          list.unshift(insert);
> -    } 
> +    }
> +    
> +    /* This method should only be used by those interested in limiting an object's
> +     * time in the LRUQueue, it will clean out any objects who have been in the
> +     * queue for longer than maxQueueTimeMillis
> +     */
> +    public final synchronized void clean() {
> +        while ( list.size() > maxQueueElements ) {
> +            hash.remove(((QItem)list.pop()).obj);
> +        }
> +        while ( list.size() > 0 && 
> +                System.currentTimeMillis() > 
> ((QItem)list.tail()).lastTouchedTimeMillis + maxQueueTimeMillis ) {
> +                hash.remove(((QItem)list.pop()).obj);
> +        }
> +    }
> +    
> +    public final synchronized boolean containsKey(Object obj) {
> +        return hash.containsKey(obj);
> +    }
>  
>      // Least recently pushed Object.
>      public final synchronized Object pop() {
> @@ -68,9 +97,11 @@
>  
>      private static class QItem extends DoublyLinkedListImpl.Item {
>          public Object obj;
> +        public long lastTouchedTimeMillis;
>  
>          public QItem(Object obj) {
>              this.obj = obj;
> +            lastTouchedTimeMillis = System.currentTimeMillis();
>          }
>      }
>  }
> Index: src/freenet/transport/tcpAddress.java
> ===================================================================
> RCS file: /cvsroot/freenet/freenet/src/freenet/transport/tcpAddress.java,v
> retrieving revision 1.15
> diff -u -r1.15 tcpAddress.java
> --- src/freenet/transport/tcpAddress.java     12 Sep 2003 01:52:26 -0000      1.15
> +++ src/freenet/transport/tcpAddress.java     22 Sep 2003 02:05:05 -0000
> @@ -65,7 +65,8 @@
>          this.host = host;
>       if(host!=null) {
>           valname = host.getHostAddress();
> -         hashCode = port ^ host.hashCode() ^ valname.hashCode();
> +        
> +         hashCode = port ^ valname.hashCode();//host.hashCode() ^ 
> valname.hashCode();
>       } else {
>           hashCode = port;
>           valname = "";
> @@ -82,8 +83,8 @@
>       hostName = hostname;
>       host = null;
>       //doDeferredLookup();
> -     hashCode = port ^ hostname.hashCode();
>          valname = hostname;
> +     hashCode = port ^ valname.hashCode();
>      }
>  
>      /** 
> @@ -105,7 +106,7 @@
>              throw new BadAddressException(""+e);
>          }
>          setPort(Integer.parseInt(str.substring(colon + 1)));
> -     hashCode = port ^ host.hashCode();
> +     hashCode = port ^ valname.hashCode();
>      }
>      
>      public final void doDeferredLookup() throws UnknownHostException {

> _______________________________________________
> Devl mailing list
> [EMAIL PROTECTED]
> http://dodo.freenetproject.org/cgi-bin/mailman/listinfo/devl
_______________________________________________
Devl mailing list
[EMAIL PROTECTED]
http://dodo.freenetproject.org/cgi-bin/mailman/listinfo/devl

Reply via email to