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;