diff --git a/apps/systray/java/src/net/i2p/apps/systray/UrlLauncher.java b/apps/systray/java/src/net/i2p/apps/systray/UrlLauncher.java index f93f0876a..aeb159aa3 100644 --- a/apps/systray/java/src/net/i2p/apps/systray/UrlLauncher.java +++ b/apps/systray/java/src/net/i2p/apps/systray/UrlLauncher.java @@ -43,6 +43,32 @@ public class UrlLauncher { private static final int MAX_WAIT_TIME = 5*60*1000; private static final int MAX_TRIES = 99; + /** + * Browsers to try IN-ORDER + */ + private static final String[] BROWSERS = { + // This debian script tries everything in $BROWSER, then gnome-www-browser and x-www-browser + // if X is running and www-browser otherwise. Those point to the user's preferred + // browser using the update-alternatives system. + "sensible-browser", + // another one that opens a preferred browser + "xdg-open", + // Try x-www-browser directly + "x-www-browser", + // general graphical browsers + "defaultbrowser", // puppy linux + "opera -newpage", + "firefox", + "mozilla", + "netscape", + "konqueror", + "galeon", + // Text Mode Browsers only below here + "www-browser", + "links", + "lynx" + }; + /** * Prevent bad user experience by waiting for the server to be there * before launching the browser. @@ -156,7 +182,7 @@ public class UrlLauncher { if (bufferedReader != null) try { bufferedReader.close(); } catch (IOException ioe) {} } - if (_shellCommand.executeSilentAndWaitTimed(browserString + " " + url, 5)) + if (_shellCommand.executeSilentAndWaitTimed(browserString + ' ' + url, 5)) return true; } else { @@ -164,48 +190,10 @@ public class UrlLauncher { // fall through } - // This debian script tries everything in $BROWSER, then gnome-www-browser and x-www-browser - // if X is running and www-browser otherwise. Those point to the user's preferred - // browser using the update-alternatives system. - if (_shellCommand.executeSilentAndWaitTimed("sensible-browser " + url, 5)) - return true; - - // Try x-www-browser directly - if (_shellCommand.executeSilentAndWaitTimed("x-www-browser " + url, 5)) - return true; - - // puppy linux - if (_shellCommand.executeSilentAndWaitTimed("defaultbrowser " + url, 5)) - return true; - - if (_shellCommand.executeSilentAndWaitTimed("opera -newpage " + url, 5)) - return true; - - if (_shellCommand.executeSilentAndWaitTimed("firefox " + url, 5)) - return true; - - if (_shellCommand.executeSilentAndWaitTimed("mozilla " + url, 5)) - return true; - - if (_shellCommand.executeSilentAndWaitTimed("netscape " + url, 5)) - return true; - - if (_shellCommand.executeSilentAndWaitTimed("konqueror " + url, 5)) - return true; - - if (_shellCommand.executeSilentAndWaitTimed("galeon " + url, 5)) - return true; - - // Text Mode Browsers only below here - if (_shellCommand.executeSilentAndWaitTimed("www-browser " + url, 5)) - return true; - - if (_shellCommand.executeSilentAndWaitTimed("links " + url, 5)) - return true; - - if (_shellCommand.executeSilentAndWaitTimed("lynx " + url, 5)) - return true; - + for (int i = 0; i < BROWSERS.length; i++) { + if (_shellCommand.executeSilentAndWaitTimed(BROWSERS[i] + ' ' + url, 5)) + return true; + } } return false; } diff --git a/core/java/src/net/i2p/I2PAppContext.java b/core/java/src/net/i2p/I2PAppContext.java index be42467f4..e7527c3d1 100644 --- a/core/java/src/net/i2p/I2PAppContext.java +++ b/core/java/src/net/i2p/I2PAppContext.java @@ -113,13 +113,13 @@ public class I2PAppContext { private volatile boolean _simpleTimerInitialized; private volatile boolean _simpleTimer2Initialized; protected final Set _shutdownTasks; - private File _baseDir; - private File _configDir; - private File _routerDir; - private File _pidDir; - private File _logDir; - private File _appDir; - private File _tmpDir; + private final File _baseDir; + private final File _configDir; + private final File _routerDir; + private final File _pidDir; + private final File _logDir; + private final File _appDir; + private volatile File _tmpDir; // split up big lock on this to avoid deadlocks private final Object _lock1 = new Object(), _lock2 = new Object(), _lock3 = new Object(), _lock4 = new Object(), _lock5 = new Object(), _lock6 = new Object(), _lock7 = new Object(), _lock8 = new Object(), @@ -210,11 +210,9 @@ public class I2PAppContext { if (envProps != null) _overrideProps.putAll(envProps); _shutdownTasks = new ConcurrentHashSet(32); - initializeDirs(); _portMapper = new PortMapper(this); - } - /** + /* * Directories. These are all set at instantiation and will not be changed by * subsequent property changes. * All properties, if set, should be absolute paths. @@ -259,7 +257,7 @@ public class I2PAppContext { * All dirs except the base are created if they don't exist, but the creation will fail silently. * @since 0.7.6 */ - private void initializeDirs() { + String s = getProperty("i2p.dir.base", System.getProperty("user.dir")); _baseDir = new File(s); diff --git a/core/java/src/net/i2p/util/SimpleByteCache.java b/core/java/src/net/i2p/util/SimpleByteCache.java index b41f9ad9b..dae27d80e 100644 --- a/core/java/src/net/i2p/util/SimpleByteCache.java +++ b/core/java/src/net/i2p/util/SimpleByteCache.java @@ -16,7 +16,7 @@ import java.util.concurrent.LinkedBlockingQueue; */ public final class SimpleByteCache { - private static final Map _caches = new ConcurrentHashMap(8); + private static final ConcurrentHashMap _caches = new ConcurrentHashMap(8); private static final int DEFAULT_SIZE = 64; @@ -45,7 +45,9 @@ public final class SimpleByteCache { SimpleByteCache cache = _caches.get(sz); if (cache == null) { cache = new SimpleByteCache(cacheSize, size); - _caches.put(sz, cache); + SimpleByteCache old = _caches.putIfAbsent(sz, cache); + if (old != null) + cache = old; } cache.resize(cacheSize); return cache; diff --git a/history.txt b/history.txt index d802e2979..add456e93 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,12 @@ +2012-09-25 zzz + * Context: Make files final + * EventLog: Fix IAE on portable + * Jetty: Add non-NIO selector option (ticket #715) + * OutboundEstablishState: Cleanup (ticket #671) + * SimpleByteCache: Concurrent fix + * UPnP: Cleanup & final + * URLLauncher: Add xdg-open (ticket #617) + 2012-09-21 zzz * BuildHandler: Use CoDel for inbound queue * ByteCache: @@ -45,8 +54,8 @@ - Raise netdb store and reply priority * Router: - Boost priority of shutdown thread - - Replace ident log with new, general-purpose event log. - - Use for stops, starts, and updates, and others. + - Replace ident log with new, general-purpose event log; + use for stops, starts, and updates, and others. - New AQM CoDel queue utilities - Startup/shutdown synchronization fixes * RouterAddress: Remove unused expiration field to save space diff --git a/installer/resources/eepsite/jetty.xml b/installer/resources/eepsite/jetty.xml index 51af55379..ba30a55eb 100644 --- a/installer/resources/eepsite/jetty.xml +++ b/installer/resources/eepsite/jetty.xml @@ -12,7 +12,7 @@ - + @@ -65,7 +65,8 @@ --> @@ -106,6 +109,24 @@ + + + diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 87e5bffca..282c18b42 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 1; + public final static long BUILD = 2; /** for example "-test" */ public final static String EXTRA = ""; diff --git a/router/java/src/net/i2p/router/transport/UPnP.java b/router/java/src/net/i2p/router/transport/UPnP.java index 1401b3baa..abcd8214e 100644 --- a/router/java/src/net/i2p/router/transport/UPnP.java +++ b/router/java/src/net/i2p/router/transport/UPnP.java @@ -78,7 +78,7 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener { private volatile boolean thinksWeAreDoubleNatted = false; /** List of ports we want to forward */ - private Set portsToForward; + private final Set portsToForward; /** List of ports we have actually forwarded */ private final Set portsForwarded; /** Callback to call when a forward fails or succeeds */ @@ -88,13 +88,14 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener { super(); _context = context; _log = _context.logManager().getLog(UPnP.class); + portsToForward = new HashSet(); portsForwarded = new HashSet(); addDeviceChangeListener(this); } - public boolean runPlugin() { + public synchronized boolean runPlugin() { synchronized(lock) { - portsToForward = null; + portsToForward.clear(); } return super.start(); } @@ -102,9 +103,9 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener { /** * WARNING - Blocking up to 2 seconds */ - public void terminate() { + public synchronized void terminate() { synchronized(lock) { - portsToForward = null; + portsToForward.clear(); } // this gets spun off in a thread... unregisterPortMappings(); @@ -221,9 +222,10 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener { private void registerPortMappings() { Set ports; synchronized(lock) { - ports = portsToForward; + ports = new HashSet(portsForwarded); } - if(ports == null) return; + if (ports.isEmpty()) + return; registerPorts(ports); } @@ -281,6 +283,8 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener { synchronized(lock) { ports = new HashSet(portsForwarded); } + if (ports.isEmpty()) + return; this.unregisterPorts(ports); } @@ -528,17 +532,15 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener { if(upstreamMaxBitRate > 0) sb.append("
").append(_("UPnP reports the maximum upstream bit rate is {0}bits/sec", DataHelper.formatSize2(upstreamMaxBitRate))); synchronized(lock) { - if(portsToForward != null) { - for(ForwardPort port : portsToForward) { - sb.append("
"); - if(portsForwarded.contains(port)) - // {0} is TCP or UDP - // {1,number,#####} prevents 12345 from being output as 12,345 in the English locale. - // If you want the digit separator in your locale, translate as {1}. - sb.append(_("{0} port {1,number,#####} was successfully forwarded by UPnP.", protoToString(port.protocol), port.portNumber)); - else - sb.append(_("{0} port {1,number,#####} was not forwarded by UPnP.", protoToString(port.protocol), port.portNumber)); - } + for(ForwardPort port : portsToForward) { + sb.append("
"); + if(portsForwarded.contains(port)) + // {0} is TCP or UDP + // {1,number,#####} prevents 12345 from being output as 12,345 in the English locale. + // If you want the digit separator in your locale, translate as {1}. + sb.append(_("{0} port {1,number,#####} was successfully forwarded by UPnP.", protoToString(port.protocol), port.portNumber)); + else + sb.append(_("{0} port {1,number,#####} was not forwarded by UPnP.", protoToString(port.protocol), port.portNumber)); } } @@ -726,13 +728,13 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener { _log.error("ForwardPortCallback changed from "+forwardCallback+" to "+cb+" - using new value, but this is very strange!"); } forwardCallback = cb; - if(portsToForward == null || portsToForward.isEmpty()) { - portsToForward = ports; + if (portsToForward.isEmpty()) { + portsToForward.addAll(ports); portsToForwardNow = ports; portsToDumpNow = null; } else if(ports.isEmpty()) { portsToDumpNow = portsToForward; - portsToForward = ports; + portsToForward.clear(); portsToForwardNow = null; } else { // Some ports to keep, some ports to dump @@ -760,7 +762,8 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener { portsToDumpNow.add(port); } } - portsToForward = ports; + portsToForward.clear(); + portsToForward.addAll(ports); } if(_router == null) { if (_log.shouldLog(Log.WARN)) @@ -768,9 +771,9 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener { return; // When one is found, we will do the forwards } } - if(portsToDumpNow != null) + if(portsToDumpNow != null && !portsToDumpNow.isEmpty()) unregisterPorts(portsToDumpNow); - if(portsToForwardNow != null) + if(portsToForwardNow != null && !portsToForwardNow.isEmpty()) registerPorts(portsToForwardNow); } diff --git a/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java b/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java index 47922180d..797060c58 100644 --- a/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java +++ b/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java @@ -369,7 +369,7 @@ class OutboundEstablishState { off += 4; DataHelper.toLong(signed, off, 4, _receivedSignedOnTime); boolean valid = _context.dsa().verifySignature(_receivedSignature, signed, _remotePeer.getSigningPublicKey()); - if (!valid || _log.shouldLog(Log.DEBUG)) { + if (_log.shouldLog(Log.DEBUG) || (_log.shouldLog(Log.WARN) && !valid)) { StringBuilder buf = new StringBuilder(128); buf.append("Signed sessionCreated:"); buf.append(" Alice: ").append(Addresses.toString(_aliceIP, _alicePort)); diff --git a/router/java/src/net/i2p/router/util/EventLog.java b/router/java/src/net/i2p/router/util/EventLog.java index 9a2d9d20e..d3486206b 100644 --- a/router/java/src/net/i2p/router/util/EventLog.java +++ b/router/java/src/net/i2p/router/util/EventLog.java @@ -48,12 +48,11 @@ public class EventLog { public static final String WATCHDOG = "watchdog"; /** - * @param file must be absolute - * @throws IllegalArgumentException if not absolute + * @param file should be absolute */ public EventLog(I2PAppContext ctx, File file) { - if (!file.isAbsolute()) - throw new IllegalArgumentException(); + //if (!file.isAbsolute()) + // throw new IllegalArgumentException(); _context = ctx; _file = file; _cache = new HashMap(4); @@ -128,7 +127,7 @@ public class EventLog { continue; Long ltime = Long.valueOf(time); String info = s.length > 2 ? s[2] : ""; - rv.put(time, info); + rv.put(ltime, info); } catch (IndexOutOfBoundsException ioobe) { } catch (NumberFormatException nfe) { }