Author: toad
Date: 2007-06-09 21:33:19 +0000 (Sat, 09 Jun 2007)
New Revision: 13507
Modified:
trunk/freenet/src/freenet/client/FetchException.java
trunk/freenet/src/freenet/client/async/ClientGetter.java
trunk/freenet/src/freenet/node/LocationManager.java
trunk/freenet/src/freenet/node/Node.java
trunk/freenet/src/freenet/node/PeerManager.java
trunk/freenet/src/freenet/node/updater/NodeUpdateManager.java
trunk/freenet/src/freenet/node/updater/NodeUpdater.java
trunk/freenet/src/freenet/node/updater/RevocationChecker.java
Log:
Another step towards Update Over Mandatory: Download binary blobs of main jar,
ext jar, revocation key.
Send the UOMAnnounce message... sometimes.
Modified: trunk/freenet/src/freenet/client/FetchException.java
===================================================================
--- trunk/freenet/src/freenet/client/FetchException.java 2007-06-09
19:56:59 UTC (rev 13506)
+++ trunk/freenet/src/freenet/client/FetchException.java 2007-06-09
21:33:19 UTC (rev 13507)
@@ -127,6 +127,18 @@
Logger.minor(this,
"FetchException("+getMessage(mode)+"): "+t.getMessage(),t);
}
+ public FetchException(int mode, String reason, Throwable t) {
+ super(reason+" : "+getMessage(mode)+": "+t.getMessage());
+ extraMessage = t.getMessage();
+ this.mode = mode;
+ errorCodes = null;
+ initCause(t);
+ newURI = null;
+ expectedSize = -1;
+ if(Logger.shouldLog(Logger.MINOR, this))
+ Logger.minor(this,
"FetchException("+getMessage(mode)+"): "+t.getMessage(),t);
+ }
+
public FetchException(int mode, FailureCodeTracker errorCodes) {
super(getMessage(mode));
extraMessage = null;
Modified: trunk/freenet/src/freenet/client/async/ClientGetter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/ClientGetter.java 2007-06-09
19:56:59 UTC (rev 13506)
+++ trunk/freenet/src/freenet/client/async/ClientGetter.java 2007-06-09
21:33:19 UTC (rev 13507)
@@ -41,7 +41,7 @@
/** If not null, HashSet to track keys already added for a binary blob
*/
final HashSet binaryBlobKeysAddedAlready;
private DataOutputStream binaryBlobStream;
-
+
/**
* Fetch a key.
* @param client
@@ -101,7 +101,7 @@
binaryBlobStream = new
DataOutputStream(binaryBlobBucket.getOutputStream());
BinaryBlob.writeBinaryBlobHeader(binaryBlobStream);
} catch (IOException e) {
- onFailure(new
FetchException(FetchException.BUCKET_ERROR, "Failed to open binary blob
bucket"), null);
+ onFailure(new
FetchException(FetchException.BUCKET_ERROR, "Failed to open binary blob
bucket", e), null);
return false;
}
}
@@ -267,8 +267,9 @@
* called onFailure() with an appropriate error.
*/
private boolean closeBinaryBlobStream() {
- if(binaryBlobBucket == null) return true;
+ if(binaryBlobKeysAddedAlready == null) return true;
synchronized(binaryBlobKeysAddedAlready) {
+ if(binaryBlobStream == null) return true;
try {
BinaryBlob.writeEndBlob(binaryBlobStream);
binaryBlobStream.close();
Modified: trunk/freenet/src/freenet/node/LocationManager.java
===================================================================
--- trunk/freenet/src/freenet/node/LocationManager.java 2007-06-09 19:56:59 UTC
(rev 13506)
+++ trunk/freenet/src/freenet/node/LocationManager.java 2007-06-09 21:33:19 UTC
(rev 13507)
@@ -543,7 +543,7 @@
*/
private void announceLocChange() {
Message msg = DMT.createFNPLocChangeNotification(loc.getValue());
- node.peers.localBroadcast(msg);
+ node.peers.localBroadcast(msg, false);
}
private boolean locked;
Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java 2007-06-09 19:56:59 UTC (rev
13506)
+++ trunk/freenet/src/freenet/node/Node.java 2007-06-09 21:33:19 UTC (rev
13507)
@@ -2890,4 +2890,8 @@
clientCore.alerts.register(timeSkewDetectedUserAlert);
}
}
+
+ public File getNodeDir() {
+ return nodeDir;
+ }
}
Modified: trunk/freenet/src/freenet/node/PeerManager.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerManager.java 2007-06-09 19:56:59 UTC
(rev 13506)
+++ trunk/freenet/src/freenet/node/PeerManager.java 2007-06-09 21:33:19 UTC
(rev 13507)
@@ -441,13 +441,18 @@
/**
* Asynchronously send this message to every connected peer.
*/
- public void localBroadcast(Message msg) {
+ public void localBroadcast(Message msg, boolean ignoreRoutability) {
PeerNode[] peers;
synchronized (this) {
peers = connectedPeers;
}
for(int i=0;i<peers.length;i++) {
- if(peers[i].isRoutable()) try {
+ if(ignoreRoutability) {
+ if(!peers[i].isConnected()) continue;
+ } else {
+ if(!peers[i].isRoutable()) continue;
+ }
+ try {
peers[i].sendAsync(msg, null, 0, null);
} catch (NotConnectedException e) {
// Ignore
Modified: trunk/freenet/src/freenet/node/updater/NodeUpdateManager.java
===================================================================
--- trunk/freenet/src/freenet/node/updater/NodeUpdateManager.java
2007-06-09 19:56:59 UTC (rev 13506)
+++ trunk/freenet/src/freenet/node/updater/NodeUpdateManager.java
2007-06-09 21:33:19 UTC (rev 13507)
@@ -9,6 +9,8 @@
import freenet.config.Config;
import freenet.config.InvalidConfigValueException;
import freenet.config.SubConfig;
+import freenet.io.comm.DMT;
+import freenet.io.comm.Message;
import freenet.keys.FreenetURI;
import freenet.l10n.L10n;
import freenet.node.Node;
@@ -51,6 +53,7 @@
final boolean shouldUpdateExt;
/** Currently deploying an update? */
boolean isDeployingUpdate;
+ boolean started;
Node node;
@@ -71,7 +74,7 @@
private RevocationKeyFoundUserAlert revocationAlert;
// Update alert
private final UpdatedVersionAvailableUserAlert alert;
-
+
private boolean logMINOR;
public NodeUpdateManager(Node node, Config config) throws
InvalidConfigValueException {
@@ -127,18 +130,34 @@
updaterConfig.finishedInitialization();
- this.revocationChecker = new RevocationChecker(this);
+ this.revocationChecker = new RevocationChecker(this, new
File(node.getNodeDir(), "revocation-key.fblob"));
}
public void start() throws InvalidConfigValueException {
+ Message msg = getUOMAnnouncement();
+ node.peers.localBroadcast(msg, true);
+
+ synchronized(this) {
+ started = true;
+ }
+
node.clientCore.alerts.register(alert);
enable(wasEnabledOnStartup);
-
}
+ private Message getUOMAnnouncement() {
+ return DMT.createUOMAnnounce(updateURI.toString(),
extURI.toString(), revocationURI.toString(), hasBeenBlown,
+ mainUpdater == null ? -1 :
mainUpdater.getFetchedVersion(),
+ extUpdater == null ? -1 :
extUpdater.getFetchedVersion(),
+ revocationChecker.lastSucceeded(),
revocationChecker.getRevocationDNFCounter(),
+ revocationChecker.getBlobSize(),
+ mainUpdater == null ? -1 :
mainUpdater.getBlobSize(),
+ extUpdater == null ? -1 :
extUpdater.getBlobSize());
+ }
+
/**
* Is auto-update enabled?
*/
@@ -178,9 +197,9 @@
throw new
InvalidConfigValueException(l10n("noUpdateWithoutWrapper"));
}
// Start it
- mainUpdater = new NodeUpdater(this, updateURI,
false, Version.buildNumber());
+ mainUpdater = new NodeUpdater(this, updateURI,
false, Version.buildNumber(), "main-jar-");
if(shouldUpdateExt)
- extUpdater = new NodeUpdater(this,
extURI, true, NodeStarter.extBuildNumber);
+ extUpdater = new NodeUpdater(this,
extURI, true, NodeStarter.extBuildNumber, "ext-jar-");
}
}
if(!enable) {
Modified: trunk/freenet/src/freenet/node/updater/NodeUpdater.java
===================================================================
--- trunk/freenet/src/freenet/node/updater/NodeUpdater.java 2007-06-09
19:56:59 UTC (rev 13506)
+++ trunk/freenet/src/freenet/node/updater/NodeUpdater.java 2007-06-09
21:33:19 UTC (rev 13507)
@@ -22,6 +22,7 @@
import freenet.node.Version;
import freenet.support.Logger;
import freenet.support.io.ArrayBucket;
+import freenet.support.io.FileBucket;
public class NodeUpdater implements ClientCallback, USKCallback {
static private boolean logMINOR;
@@ -45,8 +46,10 @@
private boolean isFetching;
public final boolean extUpdate;
+ private final String blobFilenamePrefix;
+ private File tempBlobFile;
- NodeUpdater(NodeUpdateManager manager, FreenetURI URI, boolean
extUpdate, int current) {
+ NodeUpdater(NodeUpdateManager manager, FreenetURI URI, boolean
extUpdate, int current, String blobFilenamePrefix) {
logMINOR = Logger.shouldLog(Logger.MINOR, this);
this.manager = manager;
this.node = manager.node;
@@ -54,11 +57,12 @@
this.ticker = node.ps;
this.core = node.clientCore;
this.currentVersion = current;
- this.availableVersion = current;
+ this.availableVersion = -1;
this.isRunning = true;
this.cg = null;
this.isFetching = false;
this.extUpdate = extUpdate;
+ this.blobFilenamePrefix = blobFilenamePrefix;
FetchContext tempContext = core.makeClient((short)0,
true).getFetchContext();
tempContext.allowSplitfiles = true;
@@ -108,16 +112,23 @@
if(availableVersion == fetchedVersion) return;
fetchingVersion = availableVersion;
- Logger.normal(this,"Starting the update process
("+availableVersion+ ')');
- System.err.println("Starting the update process: found
the update ("+availableVersion+"), now fetching it.");
+ if(availableVersion > currentVersion) {
+ Logger.normal(this,"Starting the update process
("+availableVersion+ ')');
+ System.err.println("Starting the update
process: found the update ("+availableVersion+"), now fetching it.");
+ }
+ if(logMINOR)
+ Logger.minor(this,"Starting the update process
("+availableVersion+ ')');
// We fetch it
try{
if((cg==null)||cg.isCancelled()){
if(logMINOR) Logger.minor(this,
"Scheduling request for "+URI.setSuggestedEdition(availableVersion));
- System.err.println("Starting
"+(extUpdate?"freenet-ext.jar ":"")+"fetch for "+availableVersion);
+ if(availableVersion > currentVersion)
+ System.err.println("Starting
"+(extUpdate?"freenet-ext.jar ":"")+"fetch for "+availableVersion);
+ tempBlobFile =
+
File.createTempFile(blobFilenamePrefix+"-"+availableVersion, ".fblob.tmp",
manager.node.getNodeDir());
cg = new ClientGetter(this,
core.requestStarters.chkFetchScheduler, core.requestStarters.sskFetchScheduler,
URI.setSuggestedEdition(availableVersion), ctx,
RequestStarter.UPDATE_PRIORITY_CLASS,
- this, new
ArrayBucket(), null);
+ this, new
ArrayBucket(), new FileBucket(tempBlobFile, false, false, false, false, false));
toStart = cg;
}
isFetching = true;
@@ -137,6 +148,10 @@
}
}
+ private File getBlobFile(int availableVersion) {
+ return new File(node.getNodeDir(),
blobFilenamePrefix+availableVersion+".fblob");
+ }
+
private final Object writeJarSync = new Object();
public void writeJarTo(File fNew) throws IOException {
@@ -165,6 +180,7 @@
logMINOR = Logger.shouldLog(Logger.MINOR, this);
synchronized(this) {
if(result == null || result.asBucket() == null ||
result.asBucket().size() == 0) {
+ tempBlobFile.delete();
Logger.error(this, "Cannot update: result
either null or empty for "+availableVersion);
System.err.println("Cannot update: result
either null or empty for "+availableVersion);
// Try again
@@ -175,6 +191,13 @@
}
return;
}
+ File blobFile = getBlobFile(fetchingVersion);
+ if(!tempBlobFile.renameTo(blobFile)) {
+ blobFile.delete();
+ if(!tempBlobFile.renameTo(blobFile)) {
+ Logger.error(this, "Not able to rename
binary blob for node updater: "+tempBlobFile+" -> "+blobFile+" - may not be
able to tell other peers about this build");
+ }
+ }
this.fetchedVersion = fetchingVersion;
if(fetchedVersion > currentVersion) {
System.out.println("Found "+fetchingVersion);
@@ -192,6 +215,7 @@
logMINOR = Logger.shouldLog(Logger.MINOR, this);
if(!isRunning) return;
int errorCode = e.getMode();
+ tempBlobFile.delete();
if(logMINOR) Logger.minor(this, "onFailure("+e+ ',' +state+
')');
synchronized(this) {
@@ -306,4 +330,8 @@
if(fetchingVersion == 0) return availableVersion;
else return fetchingVersion;
}
+
+ public long getBlobSize() {
+ return getBlobFile(getFetchedVersion()).length();
+ }
}
Modified: trunk/freenet/src/freenet/node/updater/RevocationChecker.java
===================================================================
--- trunk/freenet/src/freenet/node/updater/RevocationChecker.java
2007-06-09 19:56:59 UTC (rev 13506)
+++ trunk/freenet/src/freenet/node/updater/RevocationChecker.java
2007-06-09 21:33:19 UTC (rev 13507)
@@ -1,5 +1,8 @@
package freenet.node.updater;
+import java.io.File;
+import java.io.IOException;
+
import freenet.client.FetchException;
import freenet.client.FetchResult;
import freenet.client.FetchContext;
@@ -11,6 +14,7 @@
import freenet.node.NodeClientCore;
import freenet.node.RequestStarter;
import freenet.support.Logger;
+import freenet.support.io.FileBucket;
/**
* Fetches the revocation key. Each time it starts, it will try to fetch it
until it has 3 DNFs. If it ever finds it, it will
@@ -30,11 +34,15 @@
private boolean wasAggressive;
/** Last time at which we got 3 DNFs on the revocation key */
private long lastSucceeded;
+
+ private File blobFile;
+ private File tmpBlobFile;
- public RevocationChecker(NodeUpdateManager manager) {
+ public RevocationChecker(NodeUpdateManager manager, File blobFile) {
this.manager = manager;
core = manager.node.clientCore;
this.revocationDNFCounter = 0;
+ this.blobFile = blobFile;
this.logMINOR = Logger.shouldLog(Logger.MINOR, this);
ctxRevocation = core.makeClient((short)0,
true).getFetchContext();
ctxRevocation.allowSplitfiles = false;
@@ -61,6 +69,10 @@
* */
public void start(boolean aggressive, boolean reset) {
+ if(manager.isBlown()) {
+ Logger.error(this, "Not starting revocation checker:
key already blown!");
+ return;
+ }
logMINOR = Logger.shouldLog(Logger.MINOR, this);
try {
ClientGetter cg = null;
@@ -82,10 +94,15 @@
if(logMINOR) Logger.minor(this,
"fetcher="+revocationGetter);
if(revocationGetter != null)
Logger.minor(this, "revocation
fetcher: cancelled="+revocationGetter.isCancelled()+",
finished="+revocationGetter.isFinished());
+ try {
+ tmpBlobFile =
File.createTempFile("revocation-", ".fblob.tmp", manager.node.getNodeDir());
+ } catch (IOException e) {
+ Logger.error(this, "Cannot
record revocation fetch (therefore cannot pass it on to peers)!: "+e, e);
+ }
cg = revocationGetter = new
ClientGetter(this, core.requestStarters.chkFetchScheduler,
core.requestStarters.sskFetchScheduler, manager.revocationURI, ctxRevocation,
aggressive ?
RequestStarter.MAXIMUM_PRIORITY_CLASS :
RequestStarter.IMMEDIATE_SPLITFILE_PRIORITY_CLASS,
- this, null, null);
+ this, null, tmpBlobFile
== null ? null : new FileBucket(tmpBlobFile, false, false, false, false,
false));
if(logMINOR) Logger.minor(this, "Queued
another revocation fetcher");
}
}
@@ -114,6 +131,15 @@
public void onSuccess(FetchResult result, ClientGetter state) {
// The key has been blown !
// FIXME: maybe we need a bigger warning message.
+ if(!tmpBlobFile.renameTo(blobFile)) {
+ blobFile.delete();
+ if(!tmpBlobFile.renameTo(blobFile)) {
+ Logger.error(this, "Not able to rename binary
blob for revocation fetcher: "+tmpBlobFile+" -> "+blobFile+" - may not be able
to tell other peers about this revocation");
+ System.err.println("Not able to rename binary
blob for revocation fetcher: "+tmpBlobFile+" -> "+blobFile+" - may not be able
to tell other peers about this revocation");
+ }
+ }
+ if(tmpBlobFile != null)
+ tmpBlobFile.renameTo(blobFile);
String msg = null;
try {
byte[] buf = result.asByteArray();
@@ -133,6 +159,7 @@
public void onFailure(FetchException e, ClientGetter state) {
Logger.minor(this, "Revocation fetch failed: "+e);
+ if(tmpBlobFile != null) tmpBlobFile.delete();
logMINOR = Logger.shouldLog(Logger.MINOR, this);
int errorCode = e.getMode();
boolean completed = false;
@@ -193,4 +220,8 @@
revocationGetter.cancel();
}
+ public long getBlobSize() {
+ return blobFile.length();
+ }
+
}