Author: toad
Date: 2008-11-28 19:43:32 +0000 (Fri, 28 Nov 2008)
New Revision: 23958

Modified:
   trunk/freenet/src/freenet/node/NodeDispatcher.java
   trunk/freenet/src/freenet/node/PeerNode.java
   trunk/freenet/src/freenet/node/updater/NodeUpdateManager.java
   trunk/freenet/src/freenet/node/updater/UpdateOverMandatoryManager.java
Log:
Update Over Mandatory for freenet-ext.jar


Modified: trunk/freenet/src/freenet/node/NodeDispatcher.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeDispatcher.java  2008-11-28 18:53:59 UTC 
(rev 23957)
+++ trunk/freenet/src/freenet/node/NodeDispatcher.java  2008-11-28 19:43:32 UTC 
(rev 23958)
@@ -134,6 +134,8 @@
                        return node.nodeUpdater.uom.handleRequestJar(m, source, 
true);
                } else if(spec == DMT.UOMSendingMain && 
source.isRealConnection()) {
                        return node.nodeUpdater.uom.handleSendingMain(m, 
source);
+               } else if(spec == DMT.UOMSendingExtra && 
source.isRealConnection()) {
+                       return node.nodeUpdater.uom.handleSendingExt(m, source);
                } else if(spec == DMT.FNPOpennetAnnounceRequest) {
                        return handleAnnounceRequest(m, source);
                } else if(spec == DMT.FNPRoutingStatus) {

Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java        2008-11-28 18:53:59 UTC 
(rev 23957)
+++ trunk/freenet/src/freenet/node/PeerNode.java        2008-11-28 19:43:32 UTC 
(rev 23958)
@@ -4031,6 +4031,16 @@
                return offeredMainJarVersion;
        }
 
+       private volatile long offeredExtJarVersion;
+       
+       public void setExtJarOfferedVersion(long extJarVersion) {
+               offeredExtJarVersion = extJarVersion;
+       }
+       
+       public long getExtJarOfferedVersion() {
+               return offeredExtJarVersion;
+       }
+
        /**
         * Maybe send something. A SINGLE PACKET.
         * Don't send everything at once, for two reasons:

Modified: trunk/freenet/src/freenet/node/updater/NodeUpdateManager.java
===================================================================
--- trunk/freenet/src/freenet/node/updater/NodeUpdateManager.java       
2008-11-28 18:53:59 UTC (rev 23957)
+++ trunk/freenet/src/freenet/node/updater/NodeUpdateManager.java       
2008-11-28 19:43:32 UTC (rev 23958)
@@ -935,4 +935,8 @@
        protected long getStartedFetchingNextMainJarTimestamp() {
                return startedFetchingNextMainJar;
        }
+       
+       protected long getStartedFetchingNextExtJarTimestamp() {
+               return startedFetchingNextExtJar;
+       }
 }

Modified: trunk/freenet/src/freenet/node/updater/UpdateOverMandatoryManager.java
===================================================================
--- trunk/freenet/src/freenet/node/updater/UpdateOverMandatoryManager.java      
2008-11-28 18:53:59 UTC (rev 23957)
+++ trunk/freenet/src/freenet/node/updater/UpdateOverMandatoryManager.java      
2008-11-28 19:43:32 UTC (rev 23958)
@@ -69,12 +69,18 @@
        private final HashSet<PeerNode> nodesSayKeyRevokedFailedTransfer;
        /** PeerNode's which have offered the main jar which we are not 
fetching it from right now */
        private final HashSet<PeerNode> nodesOfferedMainJar;
+       /** PeerNode's which have offered the main jar which we are not 
fetching it from right now */
+       private final HashSet<PeerNode> nodesOfferedExtJar;
        /** PeerNode's we've asked to send the main jar */
        private final HashSet<PeerNode> nodesAskedSendMainJar;
+       /** PeerNode's we've asked to send the ext jar */
+       private final HashSet<PeerNode> nodesAskedSendExtJar;
        /** PeerNode's sending us the main jar */
        private final HashSet<PeerNode> nodesSendingMainJar;
+       /** PeerNode's sending us the ext jar */
+       private final HashSet<PeerNode> nodesSendingExtJar;
        // 2 for reliability, no more as gets very slow/wasteful
-       static final int MAX_NODES_SENDING_MAIN_JAR = 2;
+       static final int MAX_NODES_SENDING_JAR = 2;
        /** Maximum time between asking for the main jar and it starting to 
transfer */
        static final int REQUEST_MAIN_JAR_TIMEOUT = 60 * 1000;
        //** Grace time before we use UoM to update */
@@ -89,8 +95,11 @@
                nodesSayKeyRevoked = new HashSet<PeerNode>();
                nodesSayKeyRevokedFailedTransfer = new HashSet<PeerNode>();
                nodesOfferedMainJar = new HashSet<PeerNode>();
+               nodesOfferedExtJar = new HashSet<PeerNode>();
                nodesAskedSendMainJar = new HashSet<PeerNode>();
+               nodesAskedSendExtJar = new HashSet<PeerNode>();
                nodesSendingMainJar = new HashSet<PeerNode>();
+               nodesSendingExtJar = new HashSet<PeerNode>();
                logMINOR = Logger.shouldLog(Logger.MINOR, this);
        }
 
@@ -216,8 +225,10 @@
 
                long now = System.currentTimeMillis();
                
-               handleMainJarOffer(now, mainJarFileLength, mainJarVersion, 
source, mainJarKey);
+               //handleMainJarOffer(now, mainJarFileLength, mainJarVersion, 
source, mainJarKey);
                
+               handleExtJarOffer(now, extraJarFileLength, extraJarVersion, 
source, extraJarKey);
+               
                return true;
        }
 
@@ -252,7 +263,7 @@
                                try {
                                        FreenetURI mainJarURI = new 
FreenetURI(jarKey).setSuggestedEdition(mainJarVersion);
                                        
if(mainJarURI.equals(updateManager.updateURI.setSuggestedEdition(mainJarVersion)))
-                                               sendUOMRequestMain(source, 
true);
+                                               sendUOMRequest(source, true, 
false);
                                        else
                                                System.err.println("Node " + 
source.userToString() + " offered us a new main jar (version " + mainJarVersion 
+ ") but his key was different to ours:\n" +
                                                        "our key: " + 
updateManager.updateURI + "\nhis key:" + mainJarURI);
@@ -287,49 +298,123 @@
                
        }
 
-       private void sendUOMRequestMain(final PeerNode source, boolean 
addOnFail) {
+       private void handleExtJarOffer(long now, long extJarFileLength, long 
extJarVersion, PeerNode source, String jarKey) {
+               
+               long started = 
updateManager.getStartedFetchingNextExtJarTimestamp();
+               long whenToTakeOverTheNormalUpdater;
+               if(started > 0)
+                       whenToTakeOverTheNormalUpdater = started + GRACE_TIME;
+               else
+                       whenToTakeOverTheNormalUpdater = 
System.currentTimeMillis() + GRACE_TIME;
+               boolean isOutdated = updateManager.node.isOudated();
+               // if the new build is self-mandatory or if the "normal" 
updater has been trying to update for more than one hour
+               Logger.normal(this, "We received a valid UOMAnnounce : 
(isOutdated=" + isOutdated + " version=" + extJarVersion + " 
whenToTakeOverTheNormalUpdater=" + 
TimeUtil.formatTime(whenToTakeOverTheNormalUpdater - now) + ") file length " + 
extJarFileLength + " updateManager version " + 
updateManager.newExtJarVersion());
+               if(extJarVersion > NodeStarter.extBuildNumber && 
extJarFileLength > 0 &&
+                       extJarVersion > updateManager.newExtJarVersion()) {
+                       source.setExtJarOfferedVersion(extJarVersion);
+                       // Offer is valid.
+                       if(logMINOR)
+                               Logger.minor(this, "Offer is valid");
+                       if((isOutdated) || whenToTakeOverTheNormalUpdater < 
now) {
+                               // Take up the offer, subject to limits on 
number of simultaneous downloads.
+                               // If we have fetches running already, then 
sendUOMRequestMain() will add the offer to nodesOfferedMainJar,
+                               // so that if all our fetches fail, we can 
fetch from this node.
+                               if(!isOutdated) {
+                                       String howLong = 
TimeUtil.formatTime(now - started);
+                                       Logger.error(this, "The update process 
seems to have been stuck for " + howLong + "; let's switch to UoM! SHOULD NOT 
HAPPEN! (1) (ext)");
+                                       System.out.println("The update process 
seems to have been stuck for " + howLong + "; let's switch to UoM! SHOULD NOT 
HAPPEN! (1) (ext)");
+                               } else if(logMINOR)
+                                       Logger.minor(this, "Fetching via UOM as 
our build is deprecated");
+                               // Fetch it
+                               try {
+                                       FreenetURI extJarURI = new 
FreenetURI(jarKey).setSuggestedEdition(extJarVersion);
+                                       
if(extJarURI.equals(updateManager.extURI.setSuggestedEdition(extJarVersion)))
+                                               sendUOMRequest(source, true, 
true);
+                                       else
+                                               System.err.println("Node " + 
source.userToString() + " offered us a new ext jar (version " + extJarVersion + 
") but his key was different to ours:\n" +
+                                                       "our key: " + 
updateManager.extURI + "\nhis key:" + extJarURI);
+                               } catch(MalformedURLException e) {
+                                       // Should maybe be a useralert?
+                                       Logger.error(this, "Node " + source + " 
sent us a UOMAnnounce claiming to have a new ext jar, but it had an invalid 
URI: " + jarKey + " : " + e, e);
+                                       System.err.println("Node " + 
source.userToString() + " sent us a UOMAnnounce claiming to have a new jar, but 
it had an invalid URI: " + jarKey + " : " + e);
+                               }
+                       } else {
+                               // Don't take up the offer. Add to 
nodesOfferedMainJar, so that we know where to fetch it from when we need it.
+                               synchronized(this) {
+                                       nodesOfferedExtJar.add(source);
+                               }
+                               
updateManager.node.getTicker().queueTimedJob(new Runnable() {
+
+                                       public void run() {
+                                               if(updateManager.isBlown())
+                                                       return;
+                                               if(!updateManager.isEnabled())
+                                                       return;
+                                               if(updateManager.hasNewExtJar())
+                                                       return;
+                                               
if(!updateManager.node.isOudated()) {
+                                                       Logger.error(this, "The 
update process seems to have been stuck for too long; let's switch to UoM! 
SHOULD NOT HAPPEN! (2)");
+                                                       System.out.println("The 
update process seems to have been stuck for too long; let's switch to UoM! 
SHOULD NOT HAPPEN! (2)");
+                                               }
+                                               maybeRequestExtJar();
+                                       }
+                               }, whenToTakeOverTheNormalUpdater - now);
+                       }
+               }
+               
+       }
+
+       private void sendUOMRequest(final PeerNode source, boolean addOnFail, 
final boolean isExt) {
+               final String name = isExt ? "Main" : "Extra";
+               String lname = isExt ? "main" : "ext";
                if(logMINOR)
-                       Logger.minor(this, "sendUOMRequestMain(" + source + "," 
+ addOnFail + ")");
+                       Logger.minor(this, "sendUOMRequest"+name+"(" + source + 
"," + addOnFail + ")");
                if(!source.isConnected())
                        return;
+               final HashSet<PeerNode> sendingJar = isExt ? nodesSendingExtJar 
: nodesSendingMainJar;
+               final HashSet<PeerNode> askedSendJar = isExt ? 
nodesAskedSendExtJar : nodesAskedSendMainJar;
                synchronized(this) {
-                       long offeredVersion = source.getMainJarOfferedVersion();
-                       if(offeredVersion < updateManager.newMainJarVersion()) {
+                       long offeredVersion = isExt ? 
source.getExtJarOfferedVersion() : source.getMainJarOfferedVersion();
+                       long updateVersion = isExt ? 
updateManager.newExtJarVersion() : updateManager.newMainJarVersion();
+                       if(offeredVersion < updateVersion) {
                                if(offeredVersion <= 0)
-                                       Logger.error(this, "Not sending UOM 
request to " + source + " because it hasn't offered anything!");
+                                       Logger.error(this, "Not sending UOM 
"+lname+" request to " + source + " because it hasn't offered anything!");
                                else
                                        if(logMINOR)
-                                               Logger.minor(this, "Not sending 
UOM request to " + source + " because we already have its offered version " + 
offeredVersion);
+                                               Logger.minor(this, "Not sending 
UOM "+lname+" request to " + source + " because we already have its offered 
version " + offeredVersion);
                                return;
                        }
-                       if(updateManager.getMainVersion() >= offeredVersion) {
+                       int curVersion = isExt ? updateManager.getExtVersion() 
: updateManager.getMainVersion();
+                       if(curVersion >= offeredVersion) {
                                if(logMINOR)
-                                       Logger.minor(this, "Not fetching from " 
+ source + " because current jar version " + updateManager.getMainVersion() + " 
is more recent than " + source.getMainJarOfferedVersion());
+                                       Logger.minor(this, "Not fetching from " 
+ source + " because current "+lname+" jar version " + 
updateManager.getMainVersion() + " is more recent than " + offeredVersion);
                                return;
                        }
-                       if(nodesAskedSendMainJar.contains(source)) {
+                       if(askedSendJar.contains(source)) {
                                if(logMINOR)
-                                       Logger.minor(this, "Recently asked node 
" + source + " so not re-asking yet.");
+                                       Logger.minor(this, "Recently asked node 
" + source + " ("+lname+") so not re-asking yet.");
                                return;
                        }
-                       if(addOnFail && nodesAskedSendMainJar.size() + 
nodesSendingMainJar.size() >= MAX_NODES_SENDING_MAIN_JAR) {
-                               if(nodesOfferedMainJar.add(source))
-                                       System.err.println("Offered main jar by 
" + source.userToString() + " (already fetching from " + 
nodesSendingMainJar.size() + "), but will use this offer if our current fetches 
fail).");
+                       if(addOnFail && askedSendJar.size() + sendingJar.size() 
>= MAX_NODES_SENDING_JAR) {
+                               HashSet<PeerNode> offeredJar = isExt ? 
nodesOfferedExtJar : nodesOfferedMainJar;
+                               if(offeredJar.add(source))
+                                       System.err.println("Offered "+lname+" 
jar by " + source.userToString() + " (already fetching from " + 
sendingJar.size() + "), but will use this offer if our current fetches fail).");
                                return;
                        } else {
-                               if(nodesSendingMainJar.contains(source)) {
+                               if(sendingJar.contains(source)) {
                                        if(logMINOR)
-                                               Logger.minor(this, "Not 
fetching main jar from " + source.userToString() + " because already fetching 
from that node");
+                                               Logger.minor(this, "Not 
fetching "+lname+" jar from " + source.userToString() + " because already 
fetching from that node");
                                        return;
                                }
-                               nodesAskedSendMainJar.add(source);
+                               sendingJar.add(source);
                        }
                }
 
-               Message msg = 
DMT.createUOMRequestMain(updateManager.node.random.nextLong());
+               Message msg = isExt ? 
DMT.createUOMRequestExtra(updateManager.node.random.nextLong()) :
+                       
DMT.createUOMRequestMain(updateManager.node.random.nextLong());
 
                try {
-                       System.err.println("Fetching main jar from " + 
source.userToString());
+                       System.err.println("Fetching "+lname+" jar from " + 
source.userToString());
                        source.sendAsync(msg, new AsyncMessageCallback() {
 
                                public void acknowledged() {
@@ -337,19 +422,25 @@
                                }
 
                                public void disconnected() {
-                                       Logger.normal(this, "Disconnected from 
" + source.userToString() + " after sending UOMRequestMain");
+                                       Logger.normal(this, "Disconnected from 
" + source.userToString() + " after sending UOMRequest"+name);
                                        
synchronized(UpdateOverMandatoryManager.this) {
-                                               
nodesAskedSendMainJar.remove(source);
+                                               sendingJar.remove(source);
                                        }
-                                       maybeRequestMainJar();
+                                       if(isExt)
+                                               maybeRequestExtJar();
+                                       else
+                                               maybeRequestMainJar();
                                }
 
                                public void fatalError() {
-                                       Logger.normal(this, "Fatal error from " 
+ source.userToString() + " after sending UOMRequestMain");
+                                       Logger.normal(this, "Fatal error from " 
+ source.userToString() + " after sending UOMRequest"+name);
                                        
synchronized(UpdateOverMandatoryManager.this) {
-                                               
nodesAskedSendMainJar.remove(source);
+                                               askedSendJar.remove(source);
                                        }
-                                       maybeRequestMainJar();
+                                       if(isExt)
+                                               maybeRequestExtJar();
+                                       else
+                                               maybeRequestMainJar();
                                }
 
                                public void sent() {
@@ -358,27 +449,33 @@
 
                                                public void run() {
                                                        
synchronized(UpdateOverMandatoryManager.this) {
-                                                               
if(!nodesAskedSendMainJar.contains(source))
+                                                               
if(!askedSendJar.contains(source))
                                                                        return;
-                                                               
nodesAskedSendMainJar.remove(source); // free up a slot
+                                                               
askedSendJar.remove(source); // free up a slot
                                                        }
-                                                       maybeRequestMainJar();
+                                                       if(isExt)
+                                                               
maybeRequestExtJar();
+                                                       else
+                                                               
maybeRequestMainJar();
                                                }
                                        }, REQUEST_MAIN_JAR_TIMEOUT);
                                }
                        }, updateManager.ctr);
                } catch(NotConnectedException e) {
                        synchronized(this) {
-                               nodesAskedSendMainJar.remove(source);
+                               askedSendJar.remove(source);
                        }
-                       maybeRequestMainJar();
+                       if(isExt)
+                               maybeRequestExtJar();
+                       else
+                               maybeRequestMainJar();
                }
        }
 
        protected void maybeRequestMainJar() {
                PeerNode[] offers;
                synchronized(this) {
-                       if(nodesAskedSendMainJar.size() + 
nodesSendingMainJar.size() >= MAX_NODES_SENDING_MAIN_JAR)
+                       if(nodesAskedSendMainJar.size() + 
nodesSendingMainJar.size() >= MAX_NODES_SENDING_JAR)
                                return;
                        if(nodesOfferedMainJar.isEmpty())
                                return;
@@ -388,17 +485,41 @@
                        if(!offers[i].isConnected())
                                continue;
                        synchronized(this) {
-                               if(nodesAskedSendMainJar.size() + 
nodesSendingMainJar.size() >= MAX_NODES_SENDING_MAIN_JAR)
+                               if(nodesAskedSendMainJar.size() + 
nodesSendingMainJar.size() >= MAX_NODES_SENDING_JAR)
                                        return;
                                if(nodesSendingMainJar.contains(offers[i]))
                                        continue;
                                if(nodesAskedSendMainJar.contains(offers[i]))
                                        continue;
                        }
-                       sendUOMRequestMain(offers[i], false);
+                       sendUOMRequest(offers[i], false, false);
                }
        }
 
+       protected void maybeRequestExtJar() {
+               PeerNode[] offers;
+               synchronized(this) {
+                       if(nodesAskedSendExtJar.size() + 
nodesSendingExtJar.size() >= MAX_NODES_SENDING_JAR)
+                               return;
+                       if(nodesOfferedExtJar.isEmpty())
+                               return;
+                       offers = nodesOfferedExtJar.toArray(new 
PeerNode[nodesOfferedExtJar.size()]);
+               }
+               for(int i = 0; i < offers.length; i++) {
+                       if(!offers[i].isConnected())
+                               continue;
+                       synchronized(this) {
+                               if(nodesAskedSendExtJar.size() + 
nodesSendingExtJar.size() >= MAX_NODES_SENDING_JAR)
+                                       return;
+                               if(nodesSendingExtJar.contains(offers[i]))
+                                       continue;
+                               if(nodesAskedSendExtJar.contains(offers[i]))
+                                       continue;
+                       }
+                       sendUOMRequest(offers[i], false, true);
+               }
+       }
+
        private void alertUser() {
                synchronized(this) {
                        if(alert != null)
@@ -1147,6 +1268,117 @@
                return true;
        }
 
+       public boolean handleSendingExt(Message m, final PeerNode source) {
+               final long uid = m.getLong(DMT.UID);
+               final long length = m.getLong(DMT.FILE_LENGTH);
+               String key = m.getString(DMT.EXTRA_JAR_KEY);
+               final int version = m.getInt(DMT.EXTRA_JAR_VERSION);
+               final FreenetURI jarURI;
+               try {
+                       jarURI = new 
FreenetURI(key).setSuggestedEdition(version);
+               } catch(MalformedURLException e) {
+                       Logger.error(this, "Failed receiving ext jar " + 
version + " because URI not parsable: " + e + " for " + key, e);
+                       System.err.println("Failed receiving ext jar " + 
version + " because URI not parsable: " + e + " for " + key);
+                       e.printStackTrace();
+                       cancelSend(source, uid);
+                       synchronized(this) {
+                               this.nodesAskedSendExtJar.remove(source);
+                       }
+                       return true;
+               }
+
+               
if(!jarURI.equals(updateManager.extURI.setSuggestedEdition(version))) {
+                       System.err.println("Node sending us a ext jar update (" 
+ version + ") from the wrong URI:\n" +
+                               "Node: " + source.userToString() + "\n" +
+                               "Our   URI: " + updateManager.extURI + "\n" +
+                               "Their URI: " + jarURI);
+                       cancelSend(source, uid);
+                       synchronized(this) {
+                               this.nodesAskedSendExtJar.remove(source);
+                       }
+                       return true;
+               }
+
+               if(updateManager.isBlown()) {
+                       if(logMINOR)
+                               Logger.minor(this, "Key blown, so not receiving 
main jar from " + source + "(" + uid + ")");
+                       cancelSend(source, uid);
+                       synchronized(this) {
+                               this.nodesAskedSendExtJar.remove(source);
+                       }
+                       return true;
+               }
+
+               if(length > NodeUpdateManager.MAX_MAIN_JAR_LENGTH) {
+                       System.err.println("Node " + source.userToString() + " 
offered us a ext jar (" + version + ") " + SizeUtil.formatSize(length) + " 
long. This is unacceptably long so we have refused the transfer.");
+                       Logger.error(this, "Node " + source.userToString() + " 
offered us a ext jar (" + version + ") " + SizeUtil.formatSize(length) + " 
long. This is unacceptably long so we have refused the transfer.");
+                       // If the transfer fails, we don't try again.
+                       cancelSend(source, uid);
+                       synchronized(this) {
+                               this.nodesAskedSendExtJar.remove(source);
+                       }
+                       return true;
+               }
+
+               // Okay, we can receive it
+
+               final File temp;
+
+               try {
+                       temp = File.createTempFile("ext-", ".fblob.tmp", 
updateManager.node.clientCore.getPersistentTempDir());
+                       temp.deleteOnExit();
+               } catch(IOException e) {
+                       System.err.println("Cannot save new ext jar to disk and 
therefore cannot fetch it from our peer!: " + e);
+                       e.printStackTrace();
+                       cancelSend(source, uid);
+                       synchronized(this) {
+                               this.nodesAskedSendExtJar.remove(source);
+                       }
+                       return true;
+               }
+
+               RandomAccessFileWrapper raf;
+               try {
+                       raf = new RandomAccessFileWrapper(temp, "rw");
+               } catch(FileNotFoundException e) {
+                       Logger.error(this, "Peer " + source + " sending us a 
ext jar binary blob, but we lost the temp file " + temp + " : " + e, e);
+                       synchronized(this) {
+                               this.nodesAskedSendExtJar.remove(source);
+                       }
+                       return true;
+               }
+
+               PartiallyReceivedBulk prb = new 
PartiallyReceivedBulk(updateManager.node.getUSM(), length,
+                       Node.PACKET_SIZE, raf, false);
+
+               final BulkReceiver br = new BulkReceiver(prb, source, uid, 
updateManager.ctr);
+
+               updateManager.node.executor.execute(new Runnable() {
+
+                       public void run() {
+                               try {
+                                       
synchronized(UpdateOverMandatoryManager.class) {
+                                               
nodesAskedSendExtJar.remove(source);
+                                               nodesSendingExtJar.add(source);
+                                       }
+                                       if(br.receive())
+                                               // Success!
+                                               processExtJarBlob(temp, source, 
version, jarURI);
+                                       else {
+                                               Logger.error(this, "Failed to 
transfer ext jar " + version + " from " + source);
+                                               System.err.println("Failed to 
transfer ext jar " + version + " from " + source);
+                                       }
+                               } finally {
+                                       
synchronized(UpdateOverMandatoryManager.class) {
+                                               
nodesSendingExtJar.remove(source);
+                                       }
+                               }
+                       }
+               }, "Ext jar (" + version + ") receive for " + uid + " from " + 
source.userToString());
+
+               return true;
+       }
+
        protected void processMainJarBlob(final File temp, final PeerNode 
source, final int version, FreenetURI uri) {
                SimpleBlockSet blocks = new SimpleBlockSet();
 
@@ -1269,6 +1501,128 @@
 
        }
 
+       protected void processExtJarBlob(final File temp, final PeerNode 
source, final int version, FreenetURI uri) {
+               SimpleBlockSet blocks = new SimpleBlockSet();
+
+               DataInputStream dis = null;
+               try {
+                       dis = new DataInputStream(new BufferedInputStream(new 
FileInputStream(temp)));
+                       BinaryBlob.readBinaryBlob(dis, blocks, true);
+               } catch(FileNotFoundException e) {
+                       Logger.error(this, "Somebody deleted " + temp + " ? We 
lost the ext jar (" + version + ") from " + source.userToString() + "!");
+                       System.err.println("Somebody deleted " + temp + " ? We 
lost the ext jar (" + version + ") from " + source.userToString() + "!");
+                       return;
+               } catch(IOException e) {
+                       Logger.error(this, "Could not read ext jar (" + version 
+ ") from temp file " + temp + " from node " + source.userToString() + " !");
+                       System.err.println("Could not read ext jar (" + version 
+ ") from temp file " + temp + " from node " + source.userToString() + " !");
+                       // FIXME will be kept until exit for debugging purposes
+                       return;
+               } catch(BinaryBlobFormatException e) {
+                       Logger.error(this, "Peer " + source.userToString() + " 
sent us an invalid ext jar (" + version + ")!: " + e, e);
+                       System.err.println("Peer " + source.userToString() + " 
sent us an invalid ext jar (" + version + ")!: " + e);
+                       e.printStackTrace();
+                       // FIXME will be kept until exit for debugging purposes
+                       return;
+               } finally {
+                       if(dis != null)
+                               try {
+                                       dis.close();
+                               } catch(IOException e) {
+                                       // Ignore
+                               }
+               }
+
+               // Fetch the jar from the datastore plus the binary blob
+
+               FetchContext tempContext = 
updateManager.node.clientCore.makeClient((short) 0, true).getFetchContext();
+               tempContext.localRequestOnly = true;
+               tempContext.blocks = blocks;
+
+               File f;
+               FileBucket b = null;
+               try {
+                       f = File.createTempFile("ext-", ".fblob.tmp", 
updateManager.node.clientCore.getPersistentTempDir());
+                       b = new FileBucket(f, false, false, true, true, true);
+               } catch(IOException e) {
+                       Logger.error(this, "Cannot share ext jar from " + 
source.userToString() + " with our peers because cannot write the cleaned 
version to disk: " + e, e);
+                       System.err.println("Cannot share ext jar from " + 
source.userToString() + " with our peers because cannot write the cleaned 
version to disk: " + e);
+                       e.printStackTrace();
+                       b = null;
+                       f = null;
+               }
+               final FileBucket cleanedBlob = b;
+               final File cleanedBlobFile = f;
+
+               ClientCallback myCallback = new ClientCallback() {
+
+                       public void onFailure(FetchException e, ClientGetter 
state) {
+                               if(e.mode == FetchException.CANCELLED) {
+                                       // Eh?
+                                       Logger.error(this, "Cancelled fetch 
from store/blob of ext jar (" + version + ") from " + source.userToString());
+                                       System.err.println("Cancelled fetch 
from store/blob of ext jar (" + version + ") from " + source.userToString() + " 
to " + temp + " - please report to developers");
+                               // Probably best to keep files around for now.
+                               } else if(e.isFatal()) {
+                                       // Bogus as inserted. Ignore.
+                                       temp.delete();
+                                       Logger.error(this, "Failed to fetch ext 
jar " + version + " from " + source.userToString() + " : fatal error (update 
was probably inserted badly): " + e, e);
+                                       System.err.println("Failed to fetch ext 
jar " + version + " from " + source.userToString() + " : fatal error (update 
was probably inserted badly): " + e);
+                               } else {
+                                       Logger.error(this, "Failed to fetch ext 
jar " + version + " from blob from " + source.userToString());
+                                       System.err.println("Failed to fetch ext 
jar " + version + " from blob from " + source.userToString());
+                               }
+                       }
+
+                       public void onFailure(InsertException e, 
BaseClientPutter state) {
+                               // Ignore, not possible
+                       }
+
+                       public void onFetchable(BaseClientPutter state) {
+                               // Irrelevant
+                       }
+
+                       public void onGeneratedURI(FreenetURI uri, 
BaseClientPutter state) {
+                               // Ignore, not possible
+                       }
+
+                       public void onMajorProgress() {
+                               // Ignore
+                       }
+
+                       public void onSuccess(FetchResult result, ClientGetter 
state) {
+                               System.err.println("Got ext jar version " + 
version + " from " + source.userToString());
+                               if(result.size() == 0) {
+                                       System.err.println("Ignoring because 0 
bytes long");
+                                       return;
+                               }
+
+                               NodeUpdater extUpdater = 
updateManager.extUpdater;
+                               if(extUpdater == null) {
+                                       System.err.println("Not updating 
because ext updater is disabled!");
+                                       return;
+                               }
+                               extUpdater.onSuccess(result, state, 
cleanedBlobFile, version);
+                               temp.delete();
+                               insertBlob(extUpdater.getBlobFile(version), 
"ext jar");
+                       }
+
+                       public void onSuccess(BaseClientPutter state) {
+                               // Ignore, not possible
+                       }
+               };
+
+               ClientGetter cg = new ClientGetter(myCallback,
+                       
updateManager.node.clientCore.requestStarters.chkFetchScheduler,
+                       
updateManager.node.clientCore.requestStarters.sskFetchScheduler,
+                       uri, tempContext, (short) 0, this, null, cleanedBlob);
+
+               try {
+                       cg.start();
+               } catch(FetchException e1) {
+                       myCallback.onFailure(e1, cg);
+               }
+
+       }
+
        protected boolean removeOldTempFiles() {
                File oldTempFilesPeerDir = 
updateManager.node.clientCore.getPersistentTempDir();
                if(!oldTempFilesPeerDir.exists())

_______________________________________________
cvs mailing list
[email protected]
http://emu.freenetproject.org/cgi-bin/mailman/listinfo/cvs

Reply via email to