diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java index 42696da25ba8912fe78226da0bc887e33288f489..5b9bffb95704e4de06ef116b732939c47749e09b 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java +++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java @@ -193,6 +193,7 @@ public class SnarkManager implements CompleteListener { if (_umgr != null) { _uhandler = new UpdateHandler(_context, _umgr, SnarkManager.this); _umgr.register(_uhandler, UpdateType.ROUTER_SIGNED, UpdateMethod.TORRENT, 10); + _umgr.register(_uhandler, UpdateType.ROUTER_SIGNED_SU3, UpdateMethod.TORRENT, 10); _log.warn("Registering with update manager"); } else { _log.warn("No update manager to register with"); @@ -210,6 +211,7 @@ public class SnarkManager implements CompleteListener { if (_umgr != null && _uhandler != null) { //_uhandler.shutdown(); _umgr.unregister(_uhandler, UpdateType.ROUTER_SIGNED, UpdateMethod.TORRENT); + _umgr.unregister(_uhandler, UpdateType.ROUTER_SIGNED_SU3, UpdateMethod.TORRENT); } _running = false; _monitor.interrupt(); diff --git a/apps/i2psnark/java/src/org/klomp/snark/UpdateHandler.java b/apps/i2psnark/java/src/org/klomp/snark/UpdateHandler.java index 4e5b56a41990e5b6a483dacbbef9633994f58b4c..695e951a83bab638955d28adf2cf99580ce8bf60 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/UpdateHandler.java +++ b/apps/i2psnark/java/src/org/klomp/snark/UpdateHandler.java @@ -42,10 +42,10 @@ class UpdateHandler implements Updater { */ public UpdateTask update(UpdateType type, UpdateMethod method, List<URI> updateSources, String id, String newVersion, long maxTime) { - if (type != UpdateType.ROUTER_SIGNED || + if ((type != UpdateType.ROUTER_SIGNED && type != UpdateType.ROUTER_SIGNED_SU3) || method != UpdateMethod.TORRENT || updateSources.isEmpty()) return null; - UpdateRunner update = new UpdateRunner(_context, _umgr, _smgr, updateSources, newVersion); + UpdateRunner update = new UpdateRunner(_context, _umgr, _smgr, type, updateSources, newVersion); _umgr.notifyProgress(update, "<b>" + _smgr.util().getString("Updating") + "</b>"); return update; } diff --git a/apps/i2psnark/java/src/org/klomp/snark/UpdateRunner.java b/apps/i2psnark/java/src/org/klomp/snark/UpdateRunner.java index 63d9670f177c251f31557d20fc76c35e0509e16d..a75679d3310849b94e5e167c82c9d6f941050b01 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/UpdateRunner.java +++ b/apps/i2psnark/java/src/org/klomp/snark/UpdateRunner.java @@ -22,6 +22,7 @@ class UpdateRunner implements UpdateTask, CompleteListener { private final Log _log; private final UpdateManager _umgr; private final SnarkManager _smgr; + private final UpdateType _type; private final List<URI> _urls; private volatile boolean _isRunning; private volatile boolean _hasMetaInfo; @@ -36,11 +37,12 @@ class UpdateRunner implements UpdateTask, CompleteListener { private static final long CHECK_INTERVAL = 3*60*1000; public UpdateRunner(I2PAppContext ctx, UpdateManager umgr, SnarkManager smgr, - List<URI> uris, String newVersion) { + UpdateType type, List<URI> uris, String newVersion) { _context = ctx; _log = ctx.logManager().getLog(getClass()); _umgr = umgr; _smgr = smgr; + _type = type; _urls = uris; _newVersion = newVersion; } @@ -56,7 +58,7 @@ class UpdateRunner implements UpdateTask, CompleteListener { } } - public UpdateType getType() { return UpdateType.ROUTER_SIGNED; } + public UpdateType getType() { return _type; } public UpdateMethod getMethod() { return UpdateMethod.TORRENT; } diff --git a/apps/routerconsole/java/src/net/i2p/router/update/ConsoleUpdateManager.java b/apps/routerconsole/java/src/net/i2p/router/update/ConsoleUpdateManager.java index 1d97872e0eace24e4003c967083e49fff15f5d50..17fdb0319176269b57c41a4fc77bdcfcb04be0a7 100644 --- a/apps/routerconsole/java/src/net/i2p/router/update/ConsoleUpdateManager.java +++ b/apps/routerconsole/java/src/net/i2p/router/update/ConsoleUpdateManager.java @@ -69,6 +69,7 @@ public class ConsoleUpdateManager implements UpdateManager { private final Map<UpdateItem, Version> _downloaded; /** downloaded AND installed */ private final Map<UpdateItem, Version> _installed; + private final boolean _allowTorrent; private static final DecimalFormat _pct = new DecimalFormat("0.0%"); private volatile String _status; @@ -90,6 +91,13 @@ public class ConsoleUpdateManager implements UpdateManager { _downloaded = new ConcurrentHashMap(); _installed = new ConcurrentHashMap(); _status = ""; + // DEBUG slow start for snark updates + // For 0.9.4 update, only for dev builds + // For 0.9.5 update, only for dev builds and 1% more + // For 0.9.6 update, only for dev builds and 3% more + // For 0.9.8 update, only for dev builds and 30% more + // Remove this for 100% + _allowTorrent = RouterVersion.BUILD != 0 || _context.random().nextInt(100) < 30; } public static ConsoleUpdateManager getInstance() { @@ -99,6 +107,7 @@ public class ConsoleUpdateManager implements UpdateManager { public void start() { notifyInstalled(NEWS, "", Long.toString(NewsHelper.lastUpdated(_context))); notifyInstalled(ROUTER_SIGNED, "", RouterVersion.VERSION); + notifyInstalled(ROUTER_SIGNED_SU3, "", RouterVersion.VERSION); // hack to init from the current news file... do this before we register Updaters // This will not kick off any Updaters as none are yet registered (new NewsFetcher(_context, this, Collections.EMPTY_LIST)).checkForUpdates(); @@ -122,6 +131,10 @@ public class ConsoleUpdateManager implements UpdateManager { register(c, ROUTER_SIGNED, HTTP, 0); // news is an update checker for the router Updater u = new UpdateHandler(_context, this); register(u, ROUTER_SIGNED, HTTP, 0); + if (ConfigUpdateHandler.USE_SU3_UPDATE) { + register(c, ROUTER_SIGNED_SU3, HTTP, 0); + register(u, ROUTER_SIGNED_SU3, HTTP, 0); + } // TODO see NewsFetcher //register(u, ROUTER_SIGNED, HTTPS_CLEARNET, -5); //register(u, ROUTER_SIGNED, HTTP_CLEARNET, -10); @@ -558,18 +571,18 @@ public class ConsoleUpdateManager implements UpdateManager { * Call once for each type/method pair. */ public void register(Updater updater, UpdateType type, UpdateMethod method, int priority) { - if ((type == ROUTER_SIGNED || type == ROUTER_UNSIGNED) && NewsHelper.dontInstall(_context)) { + if ((type == ROUTER_SIGNED || type == ROUTER_UNSIGNED || type == ROUTER_SIGNED_SU3) && + NewsHelper.dontInstall(_context)) { if (_log.shouldLog(Log.WARN)) _log.warn("Ignoring registration for " + type + ", router updates disabled"); return; } - // DEBUG slow start for snark updates - // For 0.9.4 update, only for dev builds - // For 0.9.5 update, only for dev builds and 1% more - // For 0.9.6 update, only for dev builds and 3% more - // For 0.9.8 update, only for dev builds and 30% more - // Remove this for 100% - if (method == TORRENT && RouterVersion.BUILD == 0 && _context.random().nextInt(100) > 29) { + if (type == ROUTER_SIGNED_SU3 && !ConfigUpdateHandler.USE_SU3_UPDATE) { + if (_log.shouldLog(Log.WARN)) + _log.warn("Ignoring registration for " + type + ", SU3 updates disabled"); + return; + } + if (method == TORRENT && !_allowTorrent) { if (_log.shouldLog(Log.WARN)) _log.warn("Ignoring torrent registration"); return; @@ -723,8 +736,10 @@ public class ConsoleUpdateManager implements UpdateManager { // fall through case ROUTER_SIGNED: + case ROUTER_SIGNED_SU3: if (shouldInstall() && !(isUpdateInProgress(ROUTER_SIGNED) || + isUpdateInProgress(ROUTER_SIGNED_SU3) || isUpdateInProgress(ROUTER_UNSIGNED))) { if (_log.shouldLog(Log.INFO)) _log.info("Updating " + ui + " after notify"); @@ -761,6 +776,7 @@ public class ConsoleUpdateManager implements UpdateManager { switch (task.getType()) { case NEWS: case ROUTER_SIGNED: + case ROUTER_SIGNED_SU3: case ROUTER_UNSIGNED: // ConfigUpdateHandler, SummaryHelper, SummaryBarRenderer handle status display break; @@ -877,6 +893,12 @@ public class ConsoleUpdateManager implements UpdateManager { notifyDownloaded(task.getType(), task.getID(), actualVersion); break; + case ROUTER_SIGNED_SU3: + rv = handleSu3File(task.getURI(), actualVersion, file); + if (rv) + notifyDownloaded(task.getType(), task.getID(), actualVersion); + break; + case ROUTER_UNSIGNED: rv = handleUnsignedFile(task.getURI(), actualVersion, file); if (rv) { @@ -932,10 +954,30 @@ public class ConsoleUpdateManager implements UpdateManager { _log.info(ui + " " + ver + " downloaded"); _downloaded.put(ui, ver); // one trumps the other - if (type == ROUTER_SIGNED) + if (type == ROUTER_SIGNED) { _downloaded.remove(new UpdateItem(ROUTER_UNSIGNED, "")); - else if (type == ROUTER_UNSIGNED) + _downloaded.remove(new UpdateItem(ROUTER_SIGNED_SU3, "")); + // remove available from other type + UpdateItem altui = new UpdateItem(ROUTER_SIGNED_SU3, id); + Version old = _available.get(altui); + if (old != null && old.compareTo(ver) <= 0) + _available.remove(altui); + // ... and declare the alt downloaded as well + _downloaded.put(altui, ver); + } else if (type == ROUTER_SIGNED_SU3) { _downloaded.remove(new UpdateItem(ROUTER_SIGNED, "")); + _downloaded.remove(new UpdateItem(ROUTER_UNSIGNED, "")); + // remove available from other type + UpdateItem altui = new UpdateItem(ROUTER_SIGNED, id); + Version old = _available.get(altui); + if (old != null && old.compareTo(ver) <= 0) + _available.remove(altui); + // ... and declare the alt downloaded as well + _downloaded.put(altui, ver); + } else if (type == ROUTER_UNSIGNED) { + _downloaded.remove(new UpdateItem(ROUTER_SIGNED, "")); + _downloaded.remove(new UpdateItem(ROUTER_SIGNED_SU3, "")); + } Version old = _available.get(ui); if (old != null && old.compareTo(ver) <= 0) _available.remove(ui); @@ -969,6 +1011,7 @@ public class ConsoleUpdateManager implements UpdateManager { break; case ROUTER_SIGNED: + { // avoid dup variables in next case String URLs = _context.getProperty(ConfigUpdateHandler.PROP_UPDATE_URL, ConfigUpdateHandler.DEFAULT_UPDATE_URL); StringTokenizer tok = new StringTokenizer(URLs, " ,\r\n"); List<URI> rv = new ArrayList(); @@ -979,6 +1022,21 @@ public class ConsoleUpdateManager implements UpdateManager { } Collections.shuffle(rv, _context.random()); return rv; + } + + case ROUTER_SIGNED_SU3: + { + String URLs = ConfigUpdateHandler.SU3_UPDATE_URLS; + StringTokenizer tok = new StringTokenizer(URLs, " ,\r\n"); + List<URI> rv = new ArrayList(); + while (tok.hasMoreTokens()) { + try { + rv.add(new URI(tok.nextToken().trim())); + } catch (URISyntaxException use) {} + } + Collections.shuffle(rv, _context.random()); + return rv; + } case ROUTER_UNSIGNED: String url = _context.getProperty(ConfigUpdateHandler.PROP_ZIP_URL); @@ -1011,12 +1069,35 @@ public class ConsoleUpdateManager implements UpdateManager { * @return success */ private boolean handleSudFile(URI uri, String actualVersion, File f) { + return handleRouterFile(uri, actualVersion, f, false); + } + + /** + * @return success + * @since 0.9.9 + */ + private boolean handleSu3File(URI uri, String actualVersion, File f) { + return handleRouterFile(uri, actualVersion, f, true); + } + + /** + * Process sud, su2, or su3 + * @return success + * @since 0.9.9 + */ + private boolean handleRouterFile(URI uri, String actualVersion, File f, boolean isSU3) { String url = uri.toString(); - // Process the .sud/.su2 file updateStatus("<b>" + _("Update downloaded") + "</b>"); - TrustedUpdate up = new TrustedUpdate(_context); File to = new File(_context.getRouterDir(), Router.UPDATE_FILE); - String err = up.migrateVerified(RouterVersion.VERSION, f, to); + String err; + // Process the file + if (isSU3) { + err = "todo"; + } else { + TrustedUpdate up = new TrustedUpdate(_context); + err = up.migrateVerified(RouterVersion.VERSION, f, to); + } + /////////// // caller must delete now.. why? //f.delete(); @@ -1277,6 +1358,8 @@ public class ConsoleUpdateManager implements UpdateManager { @Override public String toString() { + if ("".equals(id)) + return "UpdateItem " + type; return "UpdateItem " + type + ' ' + id; } } diff --git a/apps/routerconsole/java/src/net/i2p/router/update/DummyHandler.java b/apps/routerconsole/java/src/net/i2p/router/update/DummyHandler.java index 8470d0efef6295e3d0294d4e14642fe4ce2f0a21..d93872a6ffa1b06fbb5849af061e1e67d6f10acb 100644 --- a/apps/routerconsole/java/src/net/i2p/router/update/DummyHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/update/DummyHandler.java @@ -48,13 +48,10 @@ class DummyHandler implements Checker, Updater { private final long _delay; public DummyRunner(RouterContext ctx, ConsoleUpdateManager mgr, long maxTime) { - super(ctx, mgr, Collections.EMPTY_LIST); + super(ctx, mgr, UpdateType.TYPE_DUMMY, Collections.EMPTY_LIST); _delay = maxTime; } - @Override - public UpdateType getType() { return UpdateType.TYPE_DUMMY; } - @Override public UpdateMethod getMethod() { return UpdateMethod.METHOD_DUMMY; } diff --git a/apps/routerconsole/java/src/net/i2p/router/update/NewsFetcher.java b/apps/routerconsole/java/src/net/i2p/router/update/NewsFetcher.java index 61ae0354c914593be336d29ff35fa104b4bbcadd..e208d024d84a390214d2b3368fc43952cdd11c63 100644 --- a/apps/routerconsole/java/src/net/i2p/router/update/NewsFetcher.java +++ b/apps/routerconsole/java/src/net/i2p/router/update/NewsFetcher.java @@ -49,7 +49,7 @@ class NewsFetcher extends UpdateRunner { private static final String TEMP_NEWS_FILE = "news.xml.temp"; public NewsFetcher(RouterContext ctx, ConsoleUpdateManager mgr, List<URI> uris) { - super(ctx, mgr, uris); + super(ctx, mgr, NEWS, uris); _newsFile = new File(ctx.getRouterDir(), NewsHelper.NEWS_FILE); _tempFile = new File(ctx.getTempDir(), "tmp-" + ctx.random().nextLong() + TEMP_NEWS_FILE); long lastMod = NewsHelper.lastChecked(ctx); @@ -57,9 +57,6 @@ class NewsFetcher extends UpdateRunner { _lastModified = RFC822Date.to822Date(lastMod); } - @Override - public UpdateType getType() { return NEWS; } - private boolean dontInstall() { return NewsHelper.dontInstall(_context); } @@ -114,6 +111,7 @@ class NewsFetcher extends UpdateRunner { private static final String MIN_VERSION_KEY = "minversion"; private static final String SUD_KEY = "sudtorrent"; private static final String SU2_KEY = "su2torrent"; + private static final String SU3_KEY = "su3torrent"; private static final String CLEARNET_SUD_KEY = "sudclearnet"; private static final String CLEARNET_SU2_KEY = "su2clearnet"; private static final String I2P_SUD_KEY = "sudi2p"; @@ -149,6 +147,23 @@ class NewsFetcher extends UpdateRunner { // and look for a second entry with clearnet URLs // TODO clearnet URLs, notify with HTTP_CLEARNET and/or HTTPS_CLEARNET Map<UpdateMethod, List<URI>> sourceMap = new HashMap(4); + // Must do su3 first + if (ConfigUpdateHandler.USE_SU3_UPDATE) { + sourceMap.put(HTTP, _mgr.getUpdateURLs(ROUTER_SIGNED_SU3, "", HTTP)); + String murl = args.get(SU3_KEY); + if (murl != null) { + List<URI> uris = tokenize(murl); + if (!uris.isEmpty()) { + Collections.shuffle(uris, _context.random()); + sourceMap.put(TORRENT, uris); + } + } + // notify about all sources at once + _mgr.notifyVersionAvailable(this, _currentURI, ROUTER_SIGNED_SU3, + "", sourceMap, ver, ""); + sourceMap.clear(); + } + // now do sud/su2 sourceMap.put(HTTP, _mgr.getUpdateURLs(ROUTER_SIGNED, "", HTTP)); String key = FileUtil.isPack200Supported() ? SU2_KEY : SUD_KEY; String murl = args.get(key); @@ -160,9 +175,8 @@ class NewsFetcher extends UpdateRunner { } } // notify about all sources at once - _mgr.notifyVersionAvailable(this, _currentURI, - ROUTER_SIGNED, "", sourceMap, - ver, ""); + _mgr.notifyVersionAvailable(this, _currentURI, ROUTER_SIGNED, + "", sourceMap, ver, ""); } else { if (_log.shouldLog(Log.DEBUG)) _log.debug("Our version is current"); diff --git a/apps/routerconsole/java/src/net/i2p/router/update/PluginUpdateChecker.java b/apps/routerconsole/java/src/net/i2p/router/update/PluginUpdateChecker.java index 4c2da620fa49e152e91026d8b821861a80e057de..5e4ceb2813509c8023a7aa642244bfd2def184b5 100644 --- a/apps/routerconsole/java/src/net/i2p/router/update/PluginUpdateChecker.java +++ b/apps/routerconsole/java/src/net/i2p/router/update/PluginUpdateChecker.java @@ -35,16 +35,13 @@ class PluginUpdateChecker extends UpdateRunner { public PluginUpdateChecker(RouterContext ctx, ConsoleUpdateManager mgr, List<URI> uris, String appName, String oldVersion ) { - super(ctx, mgr, uris, oldVersion); + super(ctx, mgr, UpdateType.PLUGIN, uris, oldVersion); if (!uris.isEmpty()) _currentURI = uris.get(0); _appName = appName; _oldVersion = oldVersion; } - @Override - public UpdateType getType() { return UpdateType.PLUGIN; } - @Override public String getID() { return _appName; } diff --git a/apps/routerconsole/java/src/net/i2p/router/update/PluginUpdateRunner.java b/apps/routerconsole/java/src/net/i2p/router/update/PluginUpdateRunner.java index 6439903da90dfbad6e9833ed3131d796fbf8d469..a7646afc799be03e4359c367f47386b53d778257 100644 --- a/apps/routerconsole/java/src/net/i2p/router/update/PluginUpdateRunner.java +++ b/apps/routerconsole/java/src/net/i2p/router/update/PluginUpdateRunner.java @@ -60,7 +60,7 @@ class PluginUpdateRunner extends UpdateRunner { public PluginUpdateRunner(RouterContext ctx, ConsoleUpdateManager mgr, List<URI> uris, String appName, String oldVersion ) { - super(ctx, mgr, uris); + super(ctx, mgr, UpdateType.PLUGIN, uris); if (uris.isEmpty()) throw new IllegalArgumentException("uri cannot be empty"); else @@ -70,12 +70,6 @@ class PluginUpdateRunner extends UpdateRunner { _oldVersion = oldVersion; } - - @Override - public UpdateType getType() { - return UpdateType.PLUGIN; - } - @Override public URI getURI() { return _uri; } diff --git a/apps/routerconsole/java/src/net/i2p/router/update/UnsignedUpdateChecker.java b/apps/routerconsole/java/src/net/i2p/router/update/UnsignedUpdateChecker.java index 8b3bd7946ded460784a0c9331dfe0a3a6335df9d..fddc6486e0d3d4b0dd4468530d2f795cce026927 100644 --- a/apps/routerconsole/java/src/net/i2p/router/update/UnsignedUpdateChecker.java +++ b/apps/routerconsole/java/src/net/i2p/router/update/UnsignedUpdateChecker.java @@ -28,17 +28,10 @@ class UnsignedUpdateChecker extends UpdateRunner { public UnsignedUpdateChecker(RouterContext ctx, ConsoleUpdateManager mgr, List<URI> uris, long lastUpdateTime) { - super(ctx, mgr, uris); + super(ctx, mgr, UpdateType.ROUTER_UNSIGNED, uris); _ms = lastUpdateTime; } - //////// begin UpdateTask methods - - @Override - public UpdateType getType() { return UpdateType.ROUTER_UNSIGNED; } - - //////// end UpdateTask methods - @Override public void run() { _isRunning = true; diff --git a/apps/routerconsole/java/src/net/i2p/router/update/UnsignedUpdateRunner.java b/apps/routerconsole/java/src/net/i2p/router/update/UnsignedUpdateRunner.java index e010714c12ff6d80394f5635a4a9d51f3e770811..1216868542cdb58a919c7b76599da1762a156e7b 100644 --- a/apps/routerconsole/java/src/net/i2p/router/update/UnsignedUpdateRunner.java +++ b/apps/routerconsole/java/src/net/i2p/router/update/UnsignedUpdateRunner.java @@ -25,16 +25,12 @@ import net.i2p.util.Log; class UnsignedUpdateRunner extends UpdateRunner { public UnsignedUpdateRunner(RouterContext ctx, ConsoleUpdateManager mgr, List<URI> uris) { - super(ctx, mgr, uris); + super(ctx, mgr, ROUTER_UNSIGNED, uris); if (!uris.isEmpty()) _currentURI = uris.get(0); } - @Override - public UpdateType getType() { return ROUTER_UNSIGNED; } - - /** Get the file */ @Override protected void update() { diff --git a/apps/routerconsole/java/src/net/i2p/router/update/UpdateHandler.java b/apps/routerconsole/java/src/net/i2p/router/update/UpdateHandler.java index 1ba0ceb546377889c0af46c29d2b4fc6a3ec08ab..af3f0e39ccd29b3936ce49e53116f9ea06984e4d 100644 --- a/apps/routerconsole/java/src/net/i2p/router/update/UpdateHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/update/UpdateHandler.java @@ -38,10 +38,10 @@ class UpdateHandler implements Updater { */ public UpdateTask update(UpdateType type, UpdateMethod method, List<URI> updateSources, String id, String newVersion, long maxTime) { - if (type != UpdateType.ROUTER_SIGNED || + if ((type != UpdateType.ROUTER_SIGNED && type != UpdateType.ROUTER_SIGNED_SU3) || method != UpdateMethod.HTTP || updateSources.isEmpty()) return null; - UpdateRunner update = new UpdateRunner(_context, _mgr, updateSources); + UpdateRunner update = new UpdateRunner(_context, _mgr, type, updateSources); // set status before thread to ensure UI feedback _mgr.notifyProgress(update, "<b>" + _mgr._("Updating") + "</b>"); return update; diff --git a/apps/routerconsole/java/src/net/i2p/router/update/UpdateRunner.java b/apps/routerconsole/java/src/net/i2p/router/update/UpdateRunner.java index a9fc6d3c6b13efea7bc1e47036e2c11a02606247..f048752d03fb7459a2ef5a924211fdc666806536 100644 --- a/apps/routerconsole/java/src/net/i2p/router/update/UpdateRunner.java +++ b/apps/routerconsole/java/src/net/i2p/router/update/UpdateRunner.java @@ -30,6 +30,7 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList protected final RouterContext _context; protected final Log _log; protected final ConsoleUpdateManager _mgr; + protected final UpdateType _type; protected final List<URI> _urls; protected final String _updateFile; protected volatile boolean _isRunning; @@ -53,20 +54,22 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList /** * Uses router version for partial checks */ - public UpdateRunner(RouterContext ctx, ConsoleUpdateManager mgr, List<URI> uris) { - this(ctx, mgr, uris, RouterVersion.VERSION); + public UpdateRunner(RouterContext ctx, ConsoleUpdateManager mgr, UpdateType type, List<URI> uris) { + this(ctx, mgr, type, uris, RouterVersion.VERSION); } /** * @param currentVersion used for partial checks * @since 0.9.7 */ - public UpdateRunner(RouterContext ctx, ConsoleUpdateManager mgr, List<URI> uris, String currentVersion) { + public UpdateRunner(RouterContext ctx, ConsoleUpdateManager mgr, UpdateType type, + List<URI> uris, String currentVersion) { super("Update Runner"); setDaemon(true); _context = ctx; _log = ctx.logManager().getLog(getClass()); _mgr = mgr; + _type = type; _urls = uris; _baos = new ByteArrayOutputStream(TrustedUpdate.HEADER_BYTES); _updateFile = (new File(ctx.getTempDir(), "update" + ctx.random().nextInt() + ".tmp")).getAbsolutePath(); @@ -82,7 +85,7 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList interrupt(); } - public UpdateType getType() { return UpdateType.ROUTER_SIGNED; } + public UpdateType getType() { return _type; } public UpdateMethod getMethod() { return UpdateMethod.HTTP; } diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHandler.java index e427c3b3c058c4bd7c74efcbf318826c4cbf12d3..72486b68bc9b9c9bf9cd4b5c7298b900c582403b 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHandler.java @@ -1,5 +1,6 @@ package net.i2p.router.web; +import java.io.File; import java.util.HashMap; import java.util.Map; @@ -50,6 +51,7 @@ public class ConfigUpdateHandler extends FormHandler { public static final String PROP_ZIP_URL = "router.updateUnsignedURL"; public static final String PROP_UPDATE_URL = "router.updateURL"; + /** * Changed as of release 0.8 to support both .sud and .su2 * Some JVMs (IcedTea) don't have pack200 @@ -75,6 +77,10 @@ public class ConfigUpdateHandler extends FormHandler { "http://update.killyourtv.i2p/i2pupdate.sud\r\n" + "http://update.postman.i2p/i2pupdate.sud" ; + /** + * These are only for .sud and .su2. + * Do NOT use this for .su3 + */ public static final String DEFAULT_UPDATE_URL; static { if (FileUtil.isPack200Supported()) @@ -83,6 +89,34 @@ public class ConfigUpdateHandler extends FormHandler { DEFAULT_UPDATE_URL = NO_PACK200_URLS; } + private static final String SU3_CERT_DIR = "certificates/update"; + + /** + * Only enabled if we have pack200 and trusted public key certificates installed + * @since 0.9.9 + */ + public static final boolean USE_SU3_UPDATE; + static { + String[] files = (new File(I2PAppContext.getGlobalContext().getBaseDir(), SU3_CERT_DIR)).list(); + USE_SU3_UPDATE = FileUtil.isPack200Supported() && files != null && files.length > 0; + } + + private static final String DEFAULT_SU3_UPDATE_URLS = + "http://echelon.i2p/i2p/i2pupdate.su3\r\n" + + "http://inr.i2p/i2p/i2pupdate.su3\r\n" + + "http://meeh.i2p/i2pupdate/i2pupdate.su3\r\n" + + "http://stats.i2p/i2p/i2pupdate.su3\r\n" + + "http://www.i2p2.i2p/_static/i2pupdate.su3\r\n" + + "http://update.dg.i2p/files/i2pupdate.su3\r\n" + + "http://update.killyourtv.i2p/i2pupdate.su3\r\n" + + "http://update.postman.i2p/i2pupdate.su3" ; + + /** + * Empty string if disabled. Cannot be overridden by config. + * @since 0.9.9 + */ + public static final String SU3_UPDATE_URLS = USE_SU3_UPDATE ? DEFAULT_SU3_UPDATE_URLS : ""; + public static final String PROP_TRUSTED_KEYS = "router.trustedUpdateKeys"; /** diff --git a/apps/routerconsole/java/src/net/i2p/router/web/NewsHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/NewsHelper.java index c1fbf2b05cb604729aaff4e7fb95392ca9f695d2..9576b2ac0be9ee467c0f82f4f045d0009b41bba9 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/NewsHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/NewsHelper.java @@ -49,6 +49,7 @@ public class NewsHelper extends ContentHelper { ConsoleUpdateManager mgr = ConsoleUpdateManager.getInstance(); if (mgr == null) return false; return mgr.isUpdateInProgress(ROUTER_SIGNED) || + mgr.isUpdateInProgress(ROUTER_SIGNED_SU3) || mgr.isUpdateInProgress(ROUTER_UNSIGNED) || mgr.isUpdateInProgress(TYPE_DUMMY); } @@ -60,7 +61,8 @@ public class NewsHelper extends ContentHelper { public static boolean isUpdateAvailable() { ConsoleUpdateManager mgr = ConsoleUpdateManager.getInstance(); if (mgr == null) return false; - return mgr.getUpdateAvailable(ROUTER_SIGNED) != null; + return mgr.getUpdateAvailable(ROUTER_SIGNED) != null || + mgr.getUpdateAvailable(ROUTER_SIGNED_SU3) != null; } /** @@ -71,6 +73,9 @@ public class NewsHelper extends ContentHelper { public static String updateVersion() { ConsoleUpdateManager mgr = ConsoleUpdateManager.getInstance(); if (mgr == null) return null; + String rv = mgr.getUpdateAvailable(ROUTER_SIGNED_SU3); + if (rv != null) + return rv; return mgr.getUpdateAvailable(ROUTER_SIGNED); } @@ -82,6 +87,9 @@ public class NewsHelper extends ContentHelper { public static String updateVersionDownloaded() { ConsoleUpdateManager mgr = ConsoleUpdateManager.getInstance(); if (mgr == null) return null; + String rv = mgr.getUpdateDownloaded(ROUTER_SIGNED_SU3); + if (rv != null) + return rv; return mgr.getUpdateDownloaded(ROUTER_SIGNED); } diff --git a/apps/routerconsole/java/src/net/i2p/router/web/UpdateHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/UpdateHandler.java index 412a9072835574dbf55fe2d24325275435a6c888..4148a63afa4fcf53e43040d8023db50f20aa5b48 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/UpdateHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/UpdateHandler.java @@ -66,6 +66,8 @@ public class UpdateHandler { _nonce.equals(System.getProperty("net.i2p.router.web.UpdateHandler.noncePrev"))) { if (_action.contains("Unsigned")) { update(ROUTER_UNSIGNED); + } else if (ConfigUpdateHandler.USE_SU3_UPDATE) { + update(ROUTER_SIGNED_SU3); } else { update(ROUTER_SIGNED); } @@ -76,7 +78,8 @@ public class UpdateHandler { ConsoleUpdateManager mgr = (ConsoleUpdateManager) _context.updateManager(); if (mgr == null) return; - if (mgr.isUpdateInProgress(ROUTER_SIGNED) || mgr.isUpdateInProgress(ROUTER_UNSIGNED)) { + if (mgr.isUpdateInProgress(ROUTER_SIGNED) || mgr.isUpdateInProgress(ROUTER_UNSIGNED) || + mgr.isUpdateInProgress(ROUTER_SIGNED_SU3)) { _log.error("Update already running"); return; } diff --git a/core/java/src/net/i2p/crypto/SU3File.java b/core/java/src/net/i2p/crypto/SU3File.java index bf4c6b165d3aa6b3439669f79441e99ac9b5e89b..508c59d6d3b52c9f60a383ed5e910dad9c9a9e1a 100644 --- a/core/java/src/net/i2p/crypto/SU3File.java +++ b/core/java/src/net/i2p/crypto/SU3File.java @@ -64,11 +64,16 @@ public class SU3File { private static final int TYPE_ZIP = 0; + public static final int CONTENT_UNKNOWN = 0; + public static final int CONTENT_ROUTER = 1; + public static final int CONTENT_PLUGIN = 2; + public static final int CONTENT_RESEED = 3; + private enum ContentType { - UNKNOWN(0, "unknown"), - ROUTER(1, "router"), - PLUGIN(2, "plugin"), - RESEED(3, "reseed") + UNKNOWN(CONTENT_UNKNOWN, "unknown"), + ROUTER(CONTENT_ROUTER, "router"), + PLUGIN(CONTENT_PLUGIN, "plugin"), + RESEED(CONTENT_RESEED, "reseed") ; private final int code; diff --git a/core/java/src/net/i2p/update/UpdateType.java b/core/java/src/net/i2p/update/UpdateType.java index eea76eb15b10c8a637c4b247d8429fe3dcaa78be..73786ef6ca20abc036524109b45367d80132d67a 100644 --- a/core/java/src/net/i2p/update/UpdateType.java +++ b/core/java/src/net/i2p/update/UpdateType.java @@ -6,14 +6,22 @@ package net.i2p.update; * @since 0.9.4 */ public enum UpdateType { - TYPE_DUMMY, // Internal use only + /** Dummy: internal use only */ + TYPE_DUMMY, NEWS, ROUTER_SIGNED, ROUTER_UNSIGNED, PLUGIN, + /** unused */ GEOIP, + /** unused */ BLOCKLIST, + /** unused */ RESEED, + /** unused */ HOMEPAGE, - ADDRESSBOOK + /** unused */ + ADDRESSBOOK, + /** @since 0.9.9 */ + ROUTER_SIGNED_SU3 }