Author: toad
Date: 2006-03-30 16:42:58 +0000 (Thu, 30 Mar 2006)
New Revision: 8371

Added:
   trunk/freenet/src/freenet/node/PeerManagerUserAlert.java
Modified:
   trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java
   trunk/freenet/src/freenet/node/Node.java
   trunk/freenet/src/freenet/node/PeerManager.java
   trunk/freenet/src/freenet/node/PeerNode.java
   trunk/freenet/src/freenet/node/UserAlert.java
   trunk/freenet/src/freenet/node/UserAlertManager.java
   trunk/freenet/src/freenet/node/Version.java
Log:
597:
UserAlertManager done. Warn the user when he has less than 3 connections.

Modified: trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java  2006-03-30 
15:00:41 UTC (rev 8370)
+++ trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java  2006-03-30 
16:42:58 UTC (rev 8371)
@@ -1,23 +1,20 @@
 package freenet.clients.http;

 import java.io.IOException;
+import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URISyntaxException;
-import java.net.MalformedURLException;
 import java.util.Enumeration;

 import freenet.client.HighLevelSimpleClient;
+import freenet.config.SubConfig;
 import freenet.node.Node;
 import freenet.node.Version;
-import freenet.config.Option;
-import freenet.config.SubConfig;
-import freenet.config.StringArrOption;
 import freenet.pluginmanager.HTTPRequest;
 import freenet.support.Bucket;
 import freenet.support.BucketTools;
+import freenet.support.HTMLEncoder;
 import freenet.support.Logger;
-import freenet.support.HTMLEncoder;
-import freenet.keys.FreenetURI;

 public class WelcomeToadlet extends Toadlet {
        private static final String[] DEFAULT_BOOKMARKS = {
@@ -195,7 +192,10 @@
                ctx.getPageMaker().makeHead(buf, "Freenet FProxy Homepage");
                if(node.isTestnetEnabled())
                        buf.append("<div style=\"color: red; font-size: 200%; 
\">WARNING: TESTNET MODE ENABLED</div>");
+
+               // Alerts

+               node.alerts.toHtml(buf);

                // Fetch-a-key box
                buf.append("<br style=\"clear: all; \" />\n");

Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java    2006-03-30 15:00:41 UTC (rev 
8370)
+++ trunk/freenet/src/freenet/node/Node.java    2006-03-30 16:42:58 UTC (rev 
8371)
@@ -258,6 +258,7 @@
     final RequestStarter sskRequestStarter;
     final RequestThrottle sskInsertThrottle;
     final RequestStarter sskInsertStarter;
+       public final UserAlertManager alerts;

     File downloadDir;
     public final ClientRequestScheduler chkFetchScheduler;
@@ -493,6 +494,7 @@

        // Easy stuff
         startupTime = System.currentTimeMillis();
+        alerts = new UserAlertManager();
         recentlyCompletedIDs = new LRUQueue();
        this.config = config;
        this.random = random;
@@ -731,6 +733,7 @@
         // Then read the peers
         peers = new PeerManager(this, new File(nodeDir, 
"peers-"+portNumber).getPath());
         peers.writePeers();
+        peers.checkEmpty();
         nodePinger = new NodePinger(this);

         usm.setDispatcher(dispatcher=new NodeDispatcher(this));
@@ -2016,7 +2019,7 @@
        }

        InetAddress lastIP;
-       
+
        public void redetectAddress() {
                InetAddress newIP = detectPrimaryIPAddress();
                if(newIP.equals(lastIP)) return;

Modified: trunk/freenet/src/freenet/node/PeerManager.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerManager.java     2006-03-30 15:00:41 UTC 
(rev 8370)
+++ trunk/freenet/src/freenet/node/PeerManager.java     2006-03-30 16:42:58 UTC 
(rev 8371)
@@ -41,6 +41,8 @@
     PeerNode[] connectedPeers;

     final String filename;
+
+    private final PeerManagerUserAlert ua;

     /**
      * Create a PeerManager by reading a list of peers from
@@ -50,6 +52,8 @@
      */
     public PeerManager(Node node, String filename) {
         this.filename = filename;
+               ua = new PeerManagerUserAlert(node);
+               node.alerts.register(ua);
         myPeers = new PeerNode[0];
         connectedPeers = new PeerNode[0];
         this.node = node;
@@ -92,29 +96,35 @@
         }
     }

-    public synchronized boolean addPeer(PeerNode pn) {
+    public boolean addPeer(PeerNode pn) {
+       synchronized(this) {
         for(int i=0;i<myPeers.length;i++) {
-            if(myPeers[i].equals(pn)) return false;
+            if(myPeers[i].equals(pn)) {
+               return false;
+            }
         }
         PeerNode[] newMyPeers = new PeerNode[myPeers.length+1];
         System.arraycopy(myPeers, 0, newMyPeers, 0, myPeers.length);
         newMyPeers[myPeers.length] = pn;
         myPeers = newMyPeers;
         Logger.normal(this, "Added "+pn);
+       }
+        checkEmpty();
         return true;
     }

-    private synchronized boolean removePeer(PeerNode pn) {
+    private boolean removePeer(PeerNode pn) {
+       synchronized(this) {
        boolean isInPeers = false;
         for(int i=0;i<myPeers.length;i++) {
-            if(myPeers[i].equals(pn)) isInPeers=true;
+            if(myPeers[i] == pn) isInPeers=true;
         }
         if(!isInPeers) return false;

         // removing from connectedPeers
         ArrayList a = new ArrayList();
         for(int i=0;i<myPeers.length;i++) {
-               if(myPeers[i]!=pn)
+               if(myPeers[i]!=pn && myPeers[i].isConnected())
                        a.add(myPeers[i]);
         }

@@ -133,14 +143,39 @@
         }
         myPeers = newMyPeers;
         Logger.normal(this, "Removed "+pn);
+       }
+        checkEmpty();
         return true;
     }

-    public synchronized void addConnectedPeer(PeerNode pn) {
+       public boolean disconnected(PeerNode pn) {
+               synchronized(this) {
+               boolean isInPeers = false;
+               for(int i=0;i<connectedPeers.length;i++) {
+                       if(connectedPeers[i] == pn) isInPeers=true;
+               }
+               if(!isInPeers) return false;
+               // removing from connectedPeers
+               ArrayList a = new ArrayList();
+               for(int i=0;i<myPeers.length;i++) {
+                       if(myPeers[i]!=pn && myPeers[i].isConnected())
+                               a.add(myPeers[i]);
+               }
+        
+        PeerNode[] newConnectedPeers = new PeerNode[a.size()];
+        newConnectedPeers = (PeerNode[]) a.toArray(newConnectedPeers);
+           connectedPeers = newConnectedPeers;
+               }
+           checkEmpty();
+           return true;
+       }
+       
+    public void addConnectedPeer(PeerNode pn) {
        if(!pn.isConnected()) {
                Logger.minor(this, "Not connected: "+pn);
                return;
        }
+       synchronized(this) {
         for(int i=0;i<connectedPeers.length;i++) {
             if(connectedPeers[i] == pn) {
                 Logger.minor(this, "Already connected: "+pn);
@@ -164,6 +199,8 @@
         newConnectedPeers[connectedPeers.length] = pn;
         connectedPeers = newConnectedPeers;
         Logger.minor(this, "Connected peers: "+connectedPeers.length);
+       }
+        checkEmpty();
     }

 //    NodePeer route(double targetLocation, RoutingContext ctx) {
@@ -463,4 +500,20 @@
         }
         return true;
        }
+
+       /**
+        * Check whether the PM is empty. If so, file a PeerManagerUserAlert on 
the UAM.
+        */
+       public void checkEmpty() {
+               int conns, peers;
+               synchronized(this) {
+                       conns = this.connectedPeers.length;
+                       peers = this.myPeers.length;
+               }
+               synchronized(ua) {
+                       ua.conns = conns;
+                       ua.peers = peers;
+               }
+       }
+
 }

Added: trunk/freenet/src/freenet/node/PeerManagerUserAlert.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerManagerUserAlert.java    2006-03-30 
15:00:41 UTC (rev 8370)
+++ trunk/freenet/src/freenet/node/PeerManagerUserAlert.java    2006-03-30 
16:42:58 UTC (rev 8371)
@@ -0,0 +1,66 @@
+package freenet.node;
+
+public class PeerManagerUserAlert implements UserAlert {
+
+       final Node n;
+       int conns;
+       int peers;
+       
+       PeerManagerUserAlert(Node n) {
+               this.n = n;
+       }
+       
+       public boolean userCanDismiss() {
+               return false;
+       }
+
+       public String getTitle() {
+               if(peers == 0)
+                       return "No peers found";
+               if(conns == 0)
+                       return "No open connections";
+               if(conns == 1)
+                       return "Only 1 open connection";
+               if(conns == 2)
+                       return "Only 2 open connections";
+               else throw new IllegalArgumentException("Not valid");
+       }
+
+       public String getText() {
+               String s;
+               if(peers == 0) {
+               s = "This node has no peers to connect to, therefore it will 
not " +
+                               "be able to function normally. Ideally you 
should connect to peers run by people you know " +
+                                       "(if you are paranoid, then people you 
trust; if not, then " +
+                                       "at least people you've talked to)";
+               String end = " log on to irc.freenode.net channel " +
+                       "#freenet and ask around for somebody to connect to";
+               if(n.testnetEnabled)
+                       s += ", but since this is a testnet node, we suggest 
that you "+end+".";
+               else
+                       s += ". You could " + end + ", but remember that you 
are vulnerable to " +
+                                       "those you are directly connected to. 
(This is especially true in this early alpha of Freenet 0.7...)";
+               } else if(conns == 0) {
+                       s = "This node has not been able to connect to any 
other nodes so far; it will not be able to function normally. "+
+                       "Hopefully some of your peers will connect soon; if 
not, try to get some more peers.";
+               } else if(conns == 1) {
+                       s = "This node only has one connection. Performance 
will be impaired, and you have no anonymity nor even plausible deniability if 
that one person is malicious. "+
+                       "Try to get at least 3 connected peers at any given 
time.";
+               } else if(conns == 2) {
+                       s = "This node has only two connections. Performance 
and security will not be very good, and your node is not doing any routing for 
other nodes."+
+                       "Try to get at least 3 connected peers at any given 
time.";
+               } else throw new IllegalArgumentException("Not valid");
+               return s;
+       }
+
+       public short getPriorityClass() {
+               if(peers == 0 || conns == 0)
+                       return UserAlert.CRITICAL_ERROR;
+               return UserAlert.ERROR;
+       }
+
+       public boolean isValid() {
+               return peers == 0 || conns <= 2;
+       }
+       
+}

Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java        2006-03-30 15:00:41 UTC 
(rev 8370)
+++ trunk/freenet/src/freenet/node/PeerNode.java        2006-03-30 16:42:58 UTC 
(rev 8371)
@@ -401,6 +401,7 @@
     public void disconnected() {
         Logger.normal(this, "Disconnected "+this);
         node.usm.onDisconnect(this);
+        node.peers.disconnected(this);
         synchronized(this) {
             isConnected = false;
             if(currentTracker != null)
@@ -700,6 +701,7 @@
             // Update the next time to check
             sentHandshake();
             isConnected = false;
+            node.peers.disconnected(this);
             return false;
         }
         KeyTracker newTracker = new KeyTracker(this, encCipher, encKey);
@@ -736,6 +738,8 @@
             isConnected = true;
             ctx = null;
         }
+        if(!isConnected)
+               node.peers.disconnected(this);
         Logger.normal(this, "Completed handshake with "+this+" on "+replyTo+" 
- current: "+currentTracker+" old: "+previousTracker+" unverified: 
"+unverifiedTracker+" bootID: "+thisBootID);
         try {
                        receivedPacket();

Modified: trunk/freenet/src/freenet/node/UserAlert.java
===================================================================
--- trunk/freenet/src/freenet/node/UserAlert.java       2006-03-30 15:00:41 UTC 
(rev 8370)
+++ trunk/freenet/src/freenet/node/UserAlert.java       2006-03-30 16:42:58 UTC 
(rev 8371)
@@ -23,12 +23,18 @@
         */
        public short getPriorityClass();

+       /**
+        * Is the alert valid right now? Suggested use is to synchronize on the
+        * alert, then check this, then get the data.
+        */
+       public boolean isValid();
+       
        /** An error which prevents normal operation */
        public final static short CRITICAL_ERROR = 0;
-       /** A less serious error */
+       /** An error which prevents normal operation but might be temporary */
        public final static short ERROR = 1;
-       /** A non-immediate problem */
-       public final static short NORMAL = 2;
+       /** An error; limited anonymity due to not enough connections, for 
example */
+       public final static short WARNING = 2;
        /** Something minor */
        public final static short MINOR = 3;
 }

Modified: trunk/freenet/src/freenet/node/UserAlertManager.java
===================================================================
--- trunk/freenet/src/freenet/node/UserAlertManager.java        2006-03-30 
15:00:41 UTC (rev 8370)
+++ trunk/freenet/src/freenet/node/UserAlertManager.java        2006-03-30 
16:42:58 UTC (rev 8371)
@@ -1,8 +1,73 @@
 package freenet.node;

+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashSet;
+
 /**
  * Collection of UserAlert's.
  */
-public class UserAlertManager {
+public class UserAlertManager implements Comparator {

+       final HashSet alerts;
+       
+       UserAlertManager() {
+               alerts = new HashSet();
+       }
+       
+       public synchronized void register(UserAlert alert) {
+               alerts.add(alert);
+       }
+       
+       public synchronized void unregister(UserAlert alert) {
+               alerts.remove(alert);
+       }
+
+       public UserAlert[] getAlerts() {
+               UserAlert[] a = (UserAlert[]) alerts.toArray(new 
UserAlert[alerts.size()]);
+               Arrays.sort(a, this);
+               return a;
+       }
+
+       public int compare(Object arg0, Object arg1) {
+               UserAlert a0 = (UserAlert)arg0;
+               UserAlert a1 = (UserAlert)arg1;
+               if(a0 == a1) return 0;
+               short p0 = a0.getPriorityClass();
+               short p1 = a1.getPriorityClass();
+               if(p0 < p1) return -1;
+               if(p0 > p1) return 1;
+               return 0;
+       }
+
+       /**
+        * Write the alerts as HTML to a StringBuffer
+        */
+       public void toHtml(StringBuffer buf) {
+               UserAlert[] a = getAlerts();
+               for(int i=0;i<a.length;i++) {
+                       UserAlert alert = a[i];
+                       synchronized(alert) {
+                               if(!alert.isValid()) return;
+                               // FIXME should have separate CSS styles for 
each type of alert
+                               buf.append("<p><b>");
+                               short level = a[i].getPriorityClass();
+                               if(level <= UserAlert.CRITICAL_ERROR)
+                                       buf.append("<font color=\"darkred\">");
+                               else if(level <= UserAlert.ERROR)
+                                       buf.append("<font color=\"red\">");
+                               else if(level <= UserAlert.WARNING)
+                                       buf.append("<font color=\"blue\">");
+                               else if(level <= UserAlert.MINOR)
+                                       buf.append("<font color=\"green\">");
+                               buf.append(a[i].getTitle());
+                               if(level <= UserAlert.MINOR)
+                                       buf.append("</font>");
+                               buf.append("</b><br>\n");
+                               buf.append(a[i].getText());
+                               buf.append("<p>\n");
+                       }
+               }
+       }
+       
 }

Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2006-03-30 15:00:41 UTC (rev 
8370)
+++ trunk/freenet/src/freenet/node/Version.java 2006-03-30 16:42:58 UTC (rev 
8371)
@@ -20,7 +20,7 @@
        public static final String protocolVersion = "1.0";

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

        /** Oldest build of Fred we will talk to */
        private static final int lastGoodBuild = 591;


Reply via email to