diff --git a/apps/i2psnark/java/build.xml b/apps/i2psnark/java/build.xml index 8b8c340606..e500dcc614 100644 --- a/apps/i2psnark/java/build.xml +++ b/apps/i2psnark/java/build.xml @@ -79,7 +79,7 @@ - + diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java b/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java index 3aec9394c1..11f0fff86f 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java +++ b/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java @@ -426,6 +426,10 @@ public class PeerCoordinator implements PeerListener _log.info("New connection to peer: " + peer + " for " + name); } + // We may have gotten the metainfo after the peer was created. + if (metainfo != null) + peer.setMetaInfo(metainfo); + // Add it to the beginning of the list. // And try to optimistically make it a uploader. // Can't add to beginning since we converted from a List to a Queue diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerState.java b/apps/i2psnark/java/src/org/klomp/snark/PeerState.java index aadc5cba25..111ddbbe61 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/PeerState.java +++ b/apps/i2psnark/java/src/org/klomp/snark/PeerState.java @@ -496,10 +496,14 @@ class PeerState implements DataLoader } /** - * Switch from magnet mode to normal mode + * Switch from magnet mode to normal mode. + * If we already have the metainfo, this does nothing. + * @param meta non-null * @since 0.8.4 */ public void setMetaInfo(MetaInfo meta) { + if (metainfo != null) + return; BitField oldBF = bitfield; if (oldBF != null) { if (oldBF.size() != meta.getPieces()) @@ -511,7 +515,7 @@ class PeerState implements DataLoader //bitfield = new BitField(meta.getPieces()); } metainfo = meta; - if (bitfield.count() > 0) + if (bitfield != null && bitfield.count() > 0) setInteresting(true); } diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java index f3ef456dce..369fd3d2ba 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java +++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java @@ -351,7 +351,8 @@ public class I2PSnarkServlet extends Default { // Using a unique name fixes Opera, except for the buttons with js confirms, see below String ua = req.getHeader("User-Agent"); boolean isDegraded = ua != null && (ua.startsWith("Lynx") || ua.startsWith("w3m") || - ua.startsWith("ELinks") || ua.startsWith("Dillo")); + ua.startsWith("ELinks") || ua.startsWith("Links") || + ua.startsWith("Dillo")); boolean noThinsp = isDegraded || (ua != null && ua.startsWith("Opera")); if (_manager.util().connected()) { diff --git a/apps/i2ptunnel/jsp/edit.jsp b/apps/i2ptunnel/jsp/edit.jsp index 2da356e9cd..e35f23c0fb 100644 --- a/apps/i2ptunnel/jsp/edit.jsp +++ b/apps/i2ptunnel/jsp/edit.jsp @@ -1,13 +1,17 @@ -<%@page pageEncoding="UTF-8"%> -<%@page contentType="text/html" import="net.i2p.i2ptunnel.web.EditBean" %><% +<% + // NOTE: Do the header carefully so there is no whitespace before the <%@page pageEncoding="UTF-8" +%><%@page contentType="text/html" import="net.i2p.i2ptunnel.web.EditBean" +%><% String tun = request.getParameter("tunnel"); if (tun != null) { try { int curTunnel = Integer.parseInt(tun); if (EditBean.staticIsClient(curTunnel)) { - %><% + %><% } else { - %><% + %><% } } catch (NumberFormatException nfe) { %>Invalid tunnel parameter<% @@ -16,9 +20,9 @@ String tun = request.getParameter("tunnel"); String type = request.getParameter("type"); int curTunnel = -1; if (EditBean.isClient(type)) { - %><% + %><% } else { - %><% + %><% } } %> diff --git a/apps/i2ptunnel/jsp/editServer.jsp b/apps/i2ptunnel/jsp/editServer.jsp index e7a28bcd3f..45e96f73d0 100644 --- a/apps/i2ptunnel/jsp/editServer.jsp +++ b/apps/i2ptunnel/jsp/editServer.jsp @@ -188,7 +188,7 @@ <% if (!"".equals(editBean.getDestinationBase64(curTunnel))) { %> - <%=intl._("Add to local addressbook")%> + <%=intl._("Add to local addressbook")%> <% } %> @@ -340,7 +340,7 @@ - + <%=intl._("(Tunnel must be stopped first)")%> @@ -374,7 +374,7 @@
- +
@@ -453,7 +453,6 @@
class="tickbox" /> -
@@ -465,13 +464,12 @@ - +
class="tickbox" /> -
class="tickbox" /> -
- + <%=intl._("(Tunnel must be stopped first)")%>
diff --git a/apps/i2ptunnel/jsp/index.jsp b/apps/i2ptunnel/jsp/index.jsp index a5e07c5329..9b41491950 100644 --- a/apps/i2ptunnel/jsp/index.jsp +++ b/apps/i2ptunnel/jsp/index.jsp @@ -1,10 +1,13 @@ <% + // NOTE: Do the header carefully so there is no whitespace before the -<%@page pageEncoding="UTF-8"%> -<%@page contentType="text/html" import="net.i2p.i2ptunnel.web.IndexBean"%> + +%><%@page pageEncoding="UTF-8" +%><%@page contentType="text/html" import="net.i2p.i2ptunnel.web.IndexBean" +%> diff --git a/apps/routerconsole/java/src/net/i2p/router/web/CSSHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/CSSHelper.java index 8a1b920461..33aa93df28 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/CSSHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/CSSHelper.java @@ -70,6 +70,7 @@ public class CSSHelper extends HelperBase { */ public boolean allowIFrame(String ua) { return ua == null || !(ua.startsWith("Lynx") || ua.startsWith("w3m") || - ua.startsWith("ELinks") || ua.startsWith("Dillo")); + ua.startsWith("ELinks") || ua.startsWith("Links") || + ua.startsWith("Dillo")); } } diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ProfileOrganizerRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/ProfileOrganizerRenderer.java index f1b4779ddb..d83720d079 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ProfileOrganizerRenderer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ProfileOrganizerRenderer.java @@ -171,8 +171,10 @@ class ProfileOrganizerRenderer { buf.append(' ').append(fails).append('/').append(total).append(' ').append(_("Test Fails")); } buf.append(" "); - buf.append("").append(_("profile")).append(""); + //buf.append("").append(_("profile")).append(""); + buf.append("").append(_("profile")).append(""); buf.append(" +-\n"); buf.append(""); // let's not build the whole page in memory (~500 bytes per peer) diff --git a/apps/routerconsole/java/src/net/i2p/router/web/StatHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/StatHelper.java index 2b7e81fb41..6cfc7bdcfc 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/StatHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/StatHelper.java @@ -1,37 +1,73 @@ package net.i2p.router.web; -import java.util.Iterator; +import java.io.IOException; import java.util.Set; +import net.i2p.data.DataFormatException; import net.i2p.data.Hash; -import net.i2p.router.RouterContext; /** - * uuuugly. dump the peer profile data if given a peer. + * Dump the peer profile data if given a full B64 peer string or prefix. * */ public class StatHelper extends HelperBase { private String _peer; + /** + * Caller should strip HTML (XSS) + */ public void setPeer(String peer) { _peer = peer; } + /** + * Look up based on a b64 prefix or full b64. + * Prefix is inefficient. + */ public String getProfile() { - RouterContext ctx = (RouterContext)net.i2p.router.RouterContext.listContexts().get(0); - Set peers = ctx.profileOrganizer().selectAllPeers(); - for (Iterator iter = peers.iterator(); iter.hasNext(); ) { - Hash peer = (Hash)iter.next(); + if (_peer == null || _peer.length() <= 0) + return "No peer specified"; + if (_peer.length() >= 44) + return outputProfile(); + Set peers = _context.profileOrganizer().selectAllPeers(); + for (Hash peer : peers) { if (peer.toBase64().startsWith(_peer)) { - try { - WriterOutputStream wos = new WriterOutputStream(_out); - ctx.profileOrganizer().exportProfile(peer, wos); - wos.flush(); - _out.flush(); - return ""; - } catch (Exception e) { - e.printStackTrace(); - } + return dumpProfile(peer); } } - return "Unknown"; + return "Unknown peer " + _peer; + } + + /** + * Look up based on the full b64 - efficient + * @since 0.8.5 + */ + private String outputProfile() { + Hash peer = new Hash(); + try { + peer.fromBase64(_peer); + return dumpProfile(peer); + } catch (DataFormatException dfe) { + return "Bad peer hash " + _peer; + } + } + + /** + * dump the profile + * @since 0.8.5 + */ + private String dumpProfile(Hash peer) { + try { + WriterOutputStream wos = new WriterOutputStream(_out); + boolean success = _context.profileOrganizer().exportProfile(peer, wos); + if (success) { + wos.flush(); + _out.flush(); + return ""; + } else { + return "Unknown peer " + _peer; + } + } catch (IOException e) { + e.printStackTrace(); + return "IO Error " + e; + } } } diff --git a/apps/routerconsole/jsp/css.jsi b/apps/routerconsole/jsp/css.jsi index e259d0707b..8e133a1279 100644 --- a/apps/routerconsole/jsp/css.jsi +++ b/apps/routerconsole/jsp/css.jsi @@ -10,9 +10,12 @@ if (request.getCharacterEncoding() == null) request.setCharacterEncoding("UTF-8"); - response.setHeader("Pragma", "no-cache"); - response.setHeader("Cache-Control","no-cache"); - response.setDateHeader("Expires", 0); + // Now that we use POST for most forms, these prevent the back button from working after a form submit + // Just let the browser do its thing + //response.setHeader("Pragma", "no-cache"); + //response.setHeader("Cache-Control","no-cache"); + //response.setDateHeader("Expires", 0); + // the above will b0rk if the servlet engine has already flushed // the response prior to including this file, so it should be // near the top diff --git a/apps/routerconsole/jsp/dumpprofile.jsp b/apps/routerconsole/jsp/dumpprofile.jsp index dfdcc0b6e5..af6c8de744 100644 --- a/apps/routerconsole/jsp/dumpprofile.jsp +++ b/apps/routerconsole/jsp/dumpprofile.jsp @@ -1,5 +1,6 @@ <%@page contentType="text/plain" %>" +/>" +/>" /><% helper.storeWriter(out); %> diff --git a/apps/routerconsole/jsp/viewprofile.jsp b/apps/routerconsole/jsp/viewprofile.jsp new file mode 100644 index 0000000000..36897d4a9a --- /dev/null +++ b/apps/routerconsole/jsp/viewprofile.jsp @@ -0,0 +1,30 @@ +<%@page contentType="text/html"%> +<%@page pageEncoding="UTF-8"%> + + + +<%@include file="css.jsi" %> +<%=intl.title("Peer Profile")%> + +<%@include file="summary.jsi" %> +

<%=intl._("Peer Profile")%>

+
+<% + String peerB64 = request.getParameter("peer"); + if (peerB64 == null || peerB64.length() <= 0) { + out.print("No peer specified"); + } else { + peerB64 = net.i2p.data.DataHelper.stripHTML(peerB64); // XSS +%> + +" /> + +<% stathelper.storeWriter(out); %> +

<%=intl._("Profile for peer {0}", peerB64)%>

+
+
+
+<% + } +%> +
diff --git a/core/java/src/net/i2p/crypto/DHSessionKeyBuilder.java b/core/java/src/net/i2p/crypto/DHSessionKeyBuilder.java index 192bde0629..160cc1354b 100644 --- a/core/java/src/net/i2p/crypto/DHSessionKeyBuilder.java +++ b/core/java/src/net/i2p/crypto/DHSessionKeyBuilder.java @@ -82,7 +82,9 @@ public class DHSessionKeyBuilder { // add to the defaults for every 128MB of RAM, up to 512MB long maxMemory = Runtime.getRuntime().maxMemory(); - int factor = Math.min(4, (int) (1 + (maxMemory / (128*1024*1024l)))); + if (maxMemory == Long.MAX_VALUE) + maxMemory = 127*1024*1024l; + int factor = (int) Math.max(1l, Math.min(4l, 1 + (maxMemory / (128*1024*1024l)))); int defaultMin = DEFAULT_DH_PRECALC_MIN * factor; int defaultMax = DEFAULT_DH_PRECALC_MAX * factor; MIN_NUM_BUILDERS = ctx.getProperty(PROP_DH_PRECALC_MIN, defaultMin); diff --git a/core/java/src/net/i2p/crypto/YKGenerator.java b/core/java/src/net/i2p/crypto/YKGenerator.java index 165749a7cf..ef8546e2f0 100644 --- a/core/java/src/net/i2p/crypto/YKGenerator.java +++ b/core/java/src/net/i2p/crypto/YKGenerator.java @@ -60,7 +60,9 @@ class YKGenerator { // add to the defaults for every 128MB of RAM, up to 1GB long maxMemory = Runtime.getRuntime().maxMemory(); - int factor = Math.min(8, (int) (1 + (maxMemory / (128*1024*1024l)))); + if (maxMemory == Long.MAX_VALUE) + maxMemory = 127*1024*1024l; + int factor = (int) Math.max(1l, Math.min(8l, 1 + (maxMemory / (128*1024*1024l)))); int defaultMin = DEFAULT_YK_PRECALC_MIN * factor; int defaultMax = DEFAULT_YK_PRECALC_MAX * factor; MIN_NUM_BUILDERS = ctx.getProperty(PROP_YK_PRECALC_MIN, defaultMin); diff --git a/core/java/src/net/i2p/data/DataHelper.java b/core/java/src/net/i2p/data/DataHelper.java index 4e3db770b0..1aa5e90405 100644 --- a/core/java/src/net/i2p/data/DataHelper.java +++ b/core/java/src/net/i2p/data/DataHelper.java @@ -1195,6 +1195,10 @@ public class DataHelper { case 2: return str + "M"; case 3: return str + "G"; case 4: return str + "T"; + case 5: return str + "P"; + case 6: return str + "E"; + case 7: return str + "Z"; + case 8: return str + "Y"; default: return bytes + ""; } } @@ -1221,12 +1225,17 @@ public class DataHelper { case 2: return str + " M"; case 3: return str + " G"; case 4: return str + " T"; + case 5: return str + " P"; + case 6: return str + " E"; + case 7: return str + " Z"; + case 8: return str + " Y"; default: return bytes + " "; } } /** * Strip out any HTML (simply removing any less than / greater than symbols) + * @param orig may be null, returns empty string if null */ public static String stripHTML(String orig) { if (orig == null) return ""; diff --git a/core/java/src/net/i2p/data/RouterInfo.java b/core/java/src/net/i2p/data/RouterInfo.java index b4aae94b18..7d6ff8a8e5 100644 --- a/core/java/src/net/i2p/data/RouterInfo.java +++ b/core/java/src/net/i2p/data/RouterInfo.java @@ -52,7 +52,8 @@ public class RouterInfo extends DatabaseEntry { /** should we cache the byte and string versions _byteified ? **/ private boolean _shouldCache; /** maybe we should check if we are floodfill? */ - private static final boolean CACHE_ALL = Runtime.getRuntime().maxMemory() > 128*1024*1024l; + private static final boolean CACHE_ALL = Runtime.getRuntime().maxMemory() > 128*1024*1024l && + Runtime.getRuntime().maxMemory() < Long.MAX_VALUE; public static final String PROP_NETWORK_ID = "netId"; public static final String PROP_CAPABILITIES = "caps"; diff --git a/core/java/src/net/i2p/data/SDSCache.java b/core/java/src/net/i2p/data/SDSCache.java index 562c49c79a..8698f6a78b 100644 --- a/core/java/src/net/i2p/data/SDSCache.java +++ b/core/java/src/net/i2p/data/SDSCache.java @@ -50,6 +50,8 @@ public class SDSCache { private static final double FACTOR; static { long maxMemory = Runtime.getRuntime().maxMemory(); + if (maxMemory == Long.MAX_VALUE) + maxMemory = 96*1024*1024l; FACTOR = Math.max(MIN_FACTOR, Math.min(MAX_FACTOR, maxMemory / (128*1024*1024d))); } diff --git a/core/java/src/net/i2p/stat/PersistenceHelper.java b/core/java/src/net/i2p/stat/PersistenceHelper.java index d8c1312d42..1d5c6a4663 100644 --- a/core/java/src/net/i2p/stat/PersistenceHelper.java +++ b/core/java/src/net/i2p/stat/PersistenceHelper.java @@ -1,10 +1,16 @@ package net.i2p.stat; +import java.util.Date; import java.util.Properties; +import net.i2p.data.DataHelper; import net.i2p.util.Log; -/** object orientation gives you hairy palms. */ +/** + * Output rate data. + * This is used via ProfilePersistenceHelper and the output + * must be compatible. + */ class PersistenceHelper { private final static Log _log = new Log(PersistenceHelper.class); private final static String NL = System.getProperty("line.separator"); @@ -15,6 +21,18 @@ class PersistenceHelper { buf.append(prefix).append(name).append('=').append(value).append(NL).append(NL); } + /** @since 0.8.5 */ + public final static void addDate(StringBuilder buf, String prefix, String name, String description, long value) { + String when = value > 0 ? (new Date(value)).toString() : "Never"; + add(buf, prefix, name, description + ' ' + when, value); + } + + /** @since 0.8.5 */ + public final static void addTime(StringBuilder buf, String prefix, String name, String description, long value) { + String when = DataHelper.formatDuration(value); + add(buf, prefix, name, description + ' ' + when, value); + } + public final static void add(StringBuilder buf, String prefix, String name, String description, long value) { buf.append("# ").append(prefix).append(name).append(NL); buf.append("# ").append(description).append(NL); @@ -48,4 +66,4 @@ class PersistenceHelper { } return 0; } -} \ No newline at end of file +} diff --git a/core/java/src/net/i2p/stat/Rate.java b/core/java/src/net/i2p/stat/Rate.java index 21e496739a..8bf5bcf472 100644 --- a/core/java/src/net/i2p/stat/Rate.java +++ b/core/java/src/net/i2p/stat/Rate.java @@ -400,42 +400,41 @@ public class Rate { } public void store(String prefix, StringBuilder buf) throws IOException { - PersistenceHelper.add(buf, prefix, ".period", "Number of milliseconds in the period", _period); - PersistenceHelper.add(buf, prefix, ".creationDate", - "When was this rate created? (milliseconds since the epoch, GMT)", _creationDate); - PersistenceHelper.add(buf, prefix, ".lastCoalesceDate", - "When did we last coalesce this rate? (milliseconds since the epoch, GMT)", + PersistenceHelper.addTime(buf, prefix, ".period", "Length of the period:", _period); + PersistenceHelper.addDate(buf, prefix, ".creationDate", + "When was this rate created?", _creationDate); + PersistenceHelper.addDate(buf, prefix, ".lastCoalesceDate", + "When did we last coalesce this rate?", _lastCoalesceDate); - PersistenceHelper.add(buf, prefix, ".currentDate", - "When did this data get written? (milliseconds since the epoch, GMT)", now()); + PersistenceHelper.addDate(buf, prefix, ".currentDate", + "When was this data written?", now()); PersistenceHelper.add(buf, prefix, ".currentTotalValue", "Total value of data points in the current (uncoalesced) period", _currentTotalValue); - PersistenceHelper - .add(buf, prefix, ".currentEventCount", + PersistenceHelper.add(buf, prefix, ".currentEventCount", "How many events have occurred in the current (uncoalesced) period?", _currentEventCount); - PersistenceHelper.add(buf, prefix, ".currentTotalEventTime", - "How many milliseconds have the events in the current (uncoalesced) period consumed?", + PersistenceHelper.addTime(buf, prefix, ".currentTotalEventTime", + "How much time have the events in the current (uncoalesced) period consumed?", _currentTotalEventTime); PersistenceHelper.add(buf, prefix, ".lastTotalValue", "Total value of data points in the most recent (coalesced) period", _lastTotalValue); PersistenceHelper.add(buf, prefix, ".lastEventCount", "How many events have occurred in the most recent (coalesced) period?", _lastEventCount); - PersistenceHelper.add(buf, prefix, ".lastTotalEventTime", - "How many milliseconds have the events in the most recent (coalesced) period consumed?", + PersistenceHelper.addTime(buf, prefix, ".lastTotalEventTime", + "How much time have the events in the most recent (coalesced) period consumed?", _lastTotalEventTime); PersistenceHelper.add(buf, prefix, ".extremeTotalValue", "Total value of data points in the most extreme period", _extremeTotalValue); PersistenceHelper.add(buf, prefix, ".extremeEventCount", "How many events have occurred in the most extreme period?", _extremeEventCount); - PersistenceHelper.add(buf, prefix, ".extremeTotalEventTime", - "How many milliseconds have the events in the most extreme period consumed?", + PersistenceHelper.addTime(buf, prefix, ".extremeTotalEventTime", + "How much time have the events in the most extreme period consumed?", _extremeTotalEventTime); PersistenceHelper.add(buf, prefix, ".lifetimeTotalValue", "Total value of data points since this stat was created", _lifetimeTotalValue); PersistenceHelper.add(buf, prefix, ".lifetimeEventCount", "How many events have occurred since this stat was created?", _lifetimeEventCount); - PersistenceHelper.add(buf, prefix, ".lifetimeTotalEventTime", - "How many milliseconds have the events since this stat was created consumed?", + PersistenceHelper.addTime(buf, prefix, ".lifetimeTotalEventTime", + "How much total time was consumed by the events since this stat was created?", _lifetimeTotalEventTime); } diff --git a/core/java/src/net/i2p/util/ByteCache.java b/core/java/src/net/i2p/util/ByteCache.java index 3ef72ca10c..2d3eb482db 100644 --- a/core/java/src/net/i2p/util/ByteCache.java +++ b/core/java/src/net/i2p/util/ByteCache.java @@ -69,6 +69,8 @@ public final class ByteCache { private static final int MAX_CACHE; static { long maxMemory = Runtime.getRuntime().maxMemory(); + if (maxMemory == Long.MAX_VALUE) + maxMemory = 96*1024*1024l; MAX_CACHE = (int) Math.min(4*1024*1024l, Math.max(128*1024l, maxMemory / 128)); } diff --git a/core/java/src/net/i2p/util/SimpleScheduler.java b/core/java/src/net/i2p/util/SimpleScheduler.java index 951f5929eb..61e2e66b34 100644 --- a/core/java/src/net/i2p/util/SimpleScheduler.java +++ b/core/java/src/net/i2p/util/SimpleScheduler.java @@ -43,6 +43,8 @@ public class SimpleScheduler { _log = _context.logManager().getLog(SimpleScheduler.class); _name = name; long maxMemory = Runtime.getRuntime().maxMemory(); + if (maxMemory == Long.MAX_VALUE) + maxMemory = 96*1024*1024l; _threads = (int) Math.max(MIN_THREADS, Math.min(MAX_THREADS, 1 + (maxMemory / (32*1024*1024)))); _executor = new ScheduledThreadPoolExecutor(_threads, new CustomThreadFactory()); _executor.prestartAllCoreThreads(); diff --git a/core/java/src/net/i2p/util/SimpleTimer.java b/core/java/src/net/i2p/util/SimpleTimer.java index ee3f35120f..b19b5d691a 100644 --- a/core/java/src/net/i2p/util/SimpleTimer.java +++ b/core/java/src/net/i2p/util/SimpleTimer.java @@ -44,6 +44,8 @@ public class SimpleTimer { runner.setDaemon(true); runner.start(); long maxMemory = Runtime.getRuntime().maxMemory(); + if (maxMemory == Long.MAX_VALUE) + maxMemory = 128*1024*1024l; int threads = (int) Math.max(MIN_THREADS, Math.min(MAX_THREADS, 1 + (maxMemory / (32*1024*1024)))); for (int i = 1; i <= threads ; i++) { I2PThread executor = new I2PThread(new Executor(_context, _log, _readyEvents, runn)); diff --git a/core/java/src/net/i2p/util/SimpleTimer2.java b/core/java/src/net/i2p/util/SimpleTimer2.java index a497915e23..955f8faa3a 100644 --- a/core/java/src/net/i2p/util/SimpleTimer2.java +++ b/core/java/src/net/i2p/util/SimpleTimer2.java @@ -43,6 +43,8 @@ public class SimpleTimer2 { _name = name; _count = 0; long maxMemory = Runtime.getRuntime().maxMemory(); + if (maxMemory == Long.MAX_VALUE) + maxMemory = 96*1024*1024l; _threads = (int) Math.max(MIN_THREADS, Math.min(MAX_THREADS, 1 + (maxMemory / (32*1024*1024)))); _executor = new CustomScheduledThreadPoolExecutor(_threads, new CustomThreadFactory()); _executor.prestartAllCoreThreads(); diff --git a/history.txt b/history.txt index 8bf5c2aef8..04e9e58e76 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,16 @@ +2011-03-20 zzz + * Console: Remove cache directives + * i2psnark: Fix peers stuck at uninteresting after metainfo fetch + * i2ptunnel: Change all clients to 3 hops by default (new installs only) + * Profiles: + - Nicer profile dump + - More efficient profile lookup for display + - Fix dumpprofile NPE + - Change file suffix from .dat to .txt.gz + - Set firstHeardAbout on creation + * Rate: Fix equals() + * Recognize links and links2 as text browsers + 2011-03-12 zzz * Blocklist: Add bogons since they won't change any more * BuildHandler: Loop double-check diff --git a/installer/resources/i2ptunnel.config b/installer/resources/i2ptunnel.config index 7b0e37b182..0a7f3fe401 100644 --- a/installer/resources/i2ptunnel.config +++ b/installer/resources/i2ptunnel.config @@ -21,6 +21,10 @@ tunnel.0.option.i2cp.reduceIdleTime=900000 tunnel.0.option.i2cp.reduceOnIdle=true tunnel.0.option.i2cp.reduceQuantity=1 tunnel.0.option.i2p.streaming.connectDelay=1000 +tunnel.0.option.inbound.length=3 +tunnel.0.option.inbound.lengthVariance=0 +tunnel.0.option.outbound.length=3 +tunnel.0.option.outbound.lengthVariance=0 tunnel.0.startOnLoad=true # irc @@ -44,6 +48,10 @@ tunnel.1.option.i2cp.reduceOnIdle=true tunnel.1.option.i2cp.reduceQuantity=1 tunnel.1.option.i2p.streaming.connectDelay=1000 tunnel.1.option.i2p.streaming.maxWindowSize=16 +tunnel.1.option.inbound.length=3 +tunnel.1.option.inbound.lengthVariance=0 +tunnel.1.option.outbound.length=3 +tunnel.1.option.outbound.lengthVariance=0 tunnel.1.startOnLoad=true # I2P's mtn server @@ -61,6 +69,10 @@ tunnel.2.option.outbound.nickname=shared clients tunnel.2.option.i2cp.reduceIdleTime=900000 tunnel.2.option.i2cp.reduceOnIdle=true tunnel.2.option.i2cp.reduceQuantity=1 +tunnel.2.option.inbound.length=3 +tunnel.2.option.inbound.lengthVariance=0 +tunnel.2.option.outbound.length=3 +tunnel.2.option.outbound.lengthVariance=0 tunnel.2.startOnLoad=false # local eepserver @@ -94,6 +106,10 @@ tunnel.4.option.i2cp.reduceIdleTime=900000 tunnel.4.option.i2cp.reduceOnIdle=true tunnel.4.option.i2cp.reduceQuantity=1 tunnel.4.option.i2p.streaming.connectDelay=1000 +tunnel.4.option.inbound.length=3 +tunnel.4.option.inbound.lengthVariance=0 +tunnel.4.option.outbound.length=3 +tunnel.4.option.outbound.lengthVariance=0 tunnel.4.startOnLoad=true tunnel.4.targetDestination=smtp.postman.i2p tunnel.4.type=client @@ -112,6 +128,10 @@ tunnel.5.option.i2cp.reduceIdleTime=900000 tunnel.5.option.i2cp.reduceOnIdle=true tunnel.5.option.i2cp.reduceQuantity=1 tunnel.5.option.i2p.streaming.connectDelay=1000 +tunnel.5.option.inbound.length=3 +tunnel.5.option.inbound.lengthVariance=0 +tunnel.5.option.outbound.length=3 +tunnel.5.option.outbound.lengthVariance=0 tunnel.5.startOnLoad=true tunnel.5.targetDestination=pop.postman.i2p tunnel.5.type=client @@ -133,5 +153,9 @@ tunnel.6.option.i2cp.reduceIdleTime=900000 tunnel.6.option.i2cp.reduceOnIdle=true tunnel.6.option.i2cp.reduceQuantity=1 tunnel.6.option.i2p.streaming.connectDelay=1000 +tunnel.6.option.inbound.length=3 +tunnel.6.option.inbound.lengthVariance=0 +tunnel.6.option.outbound.length=3 +tunnel.6.option.outbound.lengthVariance=0 tunnel.6.startOnLoad=true diff --git a/router/java/src/net/i2p/router/JobQueue.java b/router/java/src/net/i2p/router/JobQueue.java index 70a1b3bfef..7f5cb008fe 100644 --- a/router/java/src/net/i2p/router/JobQueue.java +++ b/router/java/src/net/i2p/router/JobQueue.java @@ -61,6 +61,8 @@ public class JobQueue { private static final int RUNNERS; static { long maxMemory = Runtime.getRuntime().maxMemory(); + if (maxMemory == Long.MAX_VALUE) + maxMemory = 128*1024*1024l; if (maxMemory < 64*1024*1024) RUNNERS = 3; else if (maxMemory < 256*1024*1024) diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java index 5904d04ea0..79f05bbd46 100644 --- a/router/java/src/net/i2p/router/Router.java +++ b/router/java/src/net/i2p/router/Router.java @@ -1432,7 +1432,10 @@ private static class CoalesceStatsEvent implements SimpleTimer.TimedEvent { ctx.statManager().createRateStat("router.highCapacityPeers", "How many high capacity peers we know", "Throttle", new long[] { 5*60*1000, 60*60*1000 }); ctx.statManager().createRateStat("router.fastPeers", "How many fast peers we know", "Throttle", new long[] { 5*60*1000, 60*60*1000 }); _maxMemory = Runtime.getRuntime().maxMemory(); - ctx.statManager().createRateStat("router.memoryUsed", "(Bytes) Max is " + (_maxMemory / (1024*1024)) + "MB", "Router", new long[] { 60*1000 }); + String legend = "(Bytes)"; + if (_maxMemory < Long.MAX_VALUE) + legend += " Max is " + DataHelper.formatSize(_maxMemory) + 'B'; + ctx.statManager().createRateStat("router.memoryUsed", legend, "Router", new long[] { 60*1000 }); } private RouterContext getContext() { return _ctx; } public void timeReached() { diff --git a/router/java/src/net/i2p/router/RouterContext.java b/router/java/src/net/i2p/router/RouterContext.java index ee891b230b..4ac21fce55 100644 --- a/router/java/src/net/i2p/router/RouterContext.java +++ b/router/java/src/net/i2p/router/RouterContext.java @@ -93,6 +93,8 @@ public class RouterContext extends I2PAppContext { // or about 2 seconds per buffer - so about 200x faster // to fill than to drain - so we don't need too many long maxMemory = Runtime.getRuntime().maxMemory(); + if (maxMemory == Long.MAX_VALUE) + maxMemory = 96*1024*1024l; long buffs = Math.min(16, Math.max(2, maxMemory / (14 * 1024 * 1024))); envProps.setProperty("prng.buffers", "" + buffs); } diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index c10128fe62..fecba78d69 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 = 6; + public final static long BUILD = 7; /** for example "-test" */ public final static String EXTRA = ""; diff --git a/router/java/src/net/i2p/router/peermanager/PeerProfile.java b/router/java/src/net/i2p/router/peermanager/PeerProfile.java index 6818abb961..034f559ae4 100644 --- a/router/java/src/net/i2p/router/peermanager/PeerProfile.java +++ b/router/java/src/net/i2p/router/peermanager/PeerProfile.java @@ -62,6 +62,10 @@ public class PeerProfile { public PeerProfile(RouterContext context, Hash peer) { this(context, peer, true); } + + /** + * @param expand must be true (see below) + */ public PeerProfile(RouterContext context, Hash peer, boolean expand) { _context = context; _log = context.logManager().getLog(PeerProfile.class); @@ -125,7 +129,10 @@ public class PeerProfile { } - /** when did we first hear about this peer? */ + /** + * When did we first hear about this peer? + * Currently unused, candidate for removal. + */ public long getFirstHeardAbout() { return _firstHeardAbout; } public void setFirstHeardAbout(long when) { _firstHeardAbout = when; } diff --git a/router/java/src/net/i2p/router/peermanager/ProfileManagerImpl.java b/router/java/src/net/i2p/router/peermanager/ProfileManagerImpl.java index 712a3cba65..5a0a69f0be 100644 --- a/router/java/src/net/i2p/router/peermanager/ProfileManagerImpl.java +++ b/router/java/src/net/i2p/router/peermanager/ProfileManagerImpl.java @@ -341,6 +341,7 @@ public class ProfileManagerImpl implements ProfileManager { PeerProfile prof = _context.profileOrganizer().getProfile(peer); if (prof == null) { prof = new PeerProfile(_context, peer); + prof.setFirstHeardAbout(_context.clock().now()); _context.profileOrganizer().addProfile(prof); } return prof; diff --git a/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java b/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java index fe33c3447f..31fd6c3742 100644 --- a/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java +++ b/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java @@ -256,10 +256,15 @@ public class ProfileOrganizer { return false; } - public void exportProfile(Hash profile, OutputStream out) throws IOException { + /** + * @return true if successful, false if not found + */ + public boolean exportProfile(Hash profile, OutputStream out) throws IOException { PeerProfile prof = getProfile(profile); - if (prof != null) + boolean rv = prof != null; + if (rv) _persistenceHelper.writeProfile(prof, out); + return rv; } /** diff --git a/router/java/src/net/i2p/router/peermanager/ProfilePersistenceHelper.java b/router/java/src/net/i2p/router/peermanager/ProfilePersistenceHelper.java index 592c1f2677..e278063aa5 100644 --- a/router/java/src/net/i2p/router/peermanager/ProfilePersistenceHelper.java +++ b/router/java/src/net/i2p/router/peermanager/ProfilePersistenceHelper.java @@ -8,6 +8,7 @@ import java.io.FilenameFilter; import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; +import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.Properties; @@ -24,13 +25,24 @@ import net.i2p.util.Log; import net.i2p.util.SecureDirectory; import net.i2p.util.SecureFileOutputStream; +/** + * Write profiles to disk at shutdown, + * read at startup. + * The files are gzip compressed, however we unfortunately store them + * with a ".dat" extension instead of ".txt.gz", so it isn't apparent. + * TODO: Migrate to new extension. + */ class ProfilePersistenceHelper { - private Log _log; - private RouterContext _context; + private final Log _log; + private final RouterContext _context; public final static String PROP_PEER_PROFILE_DIR = "router.profileDir"; public final static String DEFAULT_PEER_PROFILE_DIR = "peerProfiles"; private final static String NL = System.getProperty("line.separator"); + private static final String PREFIX = "profile-"; + private static final String SUFFIX = ".txt.gz"; + private static final String UNCOMPRESSED_SUFFIX = ".txt"; + private static final String OLD_SUFFIX = ".dat"; /** * If we haven't been able to get a message through to the peer in 3 days, @@ -76,58 +88,49 @@ class ProfilePersistenceHelper { if (_log.shouldLog(Log.DEBUG)) _log.debug("Writing the profile to " + f.getName() + " took " + delay + "ms"); } + /** write out the data from the profile to the stream */ public void writeProfile(PeerProfile profile, OutputStream out) throws IOException { String groups = null; if (_context.profileOrganizer().isFailing(profile.getPeer())) { - groups = "failing"; + groups = "Failing"; } else if (!_context.profileOrganizer().isHighCapacity(profile.getPeer())) { - groups = "not failing"; + groups = "Standard"; } else { if (_context.profileOrganizer().isFast(profile.getPeer())) - groups = "fast and high capacity"; + groups = "Fast, High Capacity"; else - groups = "high capacity"; + groups = "High Capacity"; if (_context.profileOrganizer().isWellIntegrated(profile.getPeer())) - groups = groups + ", well integrated"; + groups = groups + ", Integrated"; } StringBuilder buf = new StringBuilder(512); buf.append("########################################################################").append(NL); - buf.append("# profile for ").append(profile.getPeer().toBase64()).append(NL); + buf.append("# Profile for peer ").append(profile.getPeer().toBase64()).append(NL); if (_us != null) buf.append("# as calculated by ").append(_us.toBase64()).append(NL); buf.append("#").append(NL); - buf.append("# capacity: ").append(profile.getCapacityValue()).append(NL); - buf.append("# integration: ").append(profile.getIntegrationValue()).append(NL); - buf.append("# speedValue: ").append(profile.getSpeedValue()).append(NL); - buf.append("#").append(NL); + buf.append("# Speed: ").append(profile.getSpeedValue()).append(NL); + buf.append("# Capacity: ").append(profile.getCapacityValue()).append(NL); + buf.append("# Integration: ").append(profile.getIntegrationValue()).append(NL); buf.append("# Groups: ").append(groups).append(NL); + buf.append("#").append(NL); buf.append("########################################################################").append(NL); buf.append("##").append(NL); - buf.append("# Capacity bonus: used to affect the capacity score after all other calculations are done").append(NL); - buf.append("capacityBonus=").append(profile.getCapacityBonus()).append(NL); - buf.append("# Integration bonus: used to affect the integration score after all other calculations are done").append(NL); - buf.append("integrationBonus=").append(profile.getIntegrationBonus()).append(NL); - buf.append("# Speed bonus: used to affect the speed score after all other calculations are done").append(NL); - buf.append("speedBonus=").append(profile.getSpeedBonus()).append(NL); - buf.append(NL).append(NL); - buf.append("# Last heard about: when did we last get a reference to this peer? (milliseconds since the epoch)").append(NL); - buf.append("lastHeardAbout=").append(profile.getLastHeardAbout()).append(NL); - buf.append("# First heard about: when did we first get a reference to this peer? (milliseconds since the epoch)").append(NL); - buf.append("firstHeardAbout=").append(profile.getFirstHeardAbout()).append(NL); - buf.append("# Last sent to successfully: when did we last send the peer a message successfully? (milliseconds from the epoch)").append(NL); - buf.append("lastSentToSuccessfully=").append(profile.getLastSendSuccessful()).append(NL); - buf.append("# Last failed send: when did we last fail to send a message to the peer? (milliseconds from the epoch)").append(NL); - buf.append("lastFailedSend=").append(profile.getLastSendFailed()).append(NL); - buf.append("# Last heard from: when did we last get a message from the peer? (milliseconds from the epoch)").append(NL); - buf.append("lastHeardFrom=").append(profile.getLastHeardFrom()).append(NL); - buf.append("# moving average as to how fast the peer replies").append(NL); - buf.append("tunnelTestTimeAverage=").append(profile.getTunnelTestTimeAverage()).append(NL); - buf.append("tunnelPeakThroughput=").append(profile.getPeakThroughputKBps()).append(NL); - buf.append("tunnelPeakTunnelThroughput=").append(profile.getPeakTunnelThroughputKBps()).append(NL); - buf.append("tunnelPeakTunnel1mThroughput=").append(profile.getPeakTunnel1mThroughputKBps()).append(NL); + add(buf, "speedBonus", profile.getSpeedBonus(), "Manual adjustment to the speed score"); + add(buf, "capacityBonus", profile.getCapacityBonus(), "Manual adjustment to the capacity score"); + add(buf, "integrationBonus", profile.getIntegrationBonus(), "Manual adjustment to the integration score"); + addDate(buf, "firstHeardAbout", profile.getFirstHeardAbout(), "When did we first get a reference to this peer?"); + addDate(buf, "lastHeardAbout", profile.getLastHeardAbout(), "When did we last get a reference to this peer?"); + addDate(buf, "lastHeardFrom", profile.getLastHeardFrom(), "When did we last get a message from the peer?"); + addDate(buf, "lastSentToSuccessfully", profile.getLastSendSuccessful(), "When did we last send the peer a message successfully?"); + addDate(buf, "lastFailedSend", profile.getLastSendFailed(), "When did we last fail to send a message to the peer?"); + add(buf, "tunnelTestTimeAverage", profile.getTunnelTestTimeAverage(), "Moving average as to how fast the peer replies"); + add(buf, "tunnelPeakThroughput", profile.getPeakThroughputKBps(), "KBytes/sec"); + add(buf, "tunnelPeakTunnelThroughput", profile.getPeakTunnelThroughputKBps(), "KBytes/sec"); + add(buf, "tunnelPeakTunnel1mThroughput", profile.getPeakTunnel1mThroughputKBps(), "KBytes/sec"); buf.append(NL); out.write(buf.toString().getBytes()); @@ -148,12 +151,29 @@ class ProfilePersistenceHelper { } } - public Set readProfiles() { + /** @since 0.8.5 */ + private static void addDate(StringBuilder buf, String name, long val, String description) { + String when = val > 0 ? (new Date(val)).toString() : "Never"; + add(buf, name, val, description + ' ' + when); + } + + /** @since 0.8.5 */ + private static void add(StringBuilder buf, String name, long val, String description) { + buf.append("# ").append(name).append(NL).append("# ").append(description).append(NL); + buf.append(name).append('=').append(val).append(NL).append(NL); + } + + /** @since 0.8.5 */ + private static void add(StringBuilder buf, String name, double val, String description) { + buf.append("# ").append(name).append(NL).append("# ").append(description).append(NL); + buf.append(name).append('=').append(val).append(NL).append(NL); + } + + public Set readProfiles() { long start = _context.clock().now(); - Set files = selectFiles(); - Set profiles = new HashSet(files.size()); - for (Iterator iter = files.iterator(); iter.hasNext();) { - File f = (File)iter.next(); + Set files = selectFiles(); + Set profiles = new HashSet(files.size()); + for (File f : files) { PeerProfile profile = readProfile(f); if (profile != null) profiles.add(profile); @@ -164,10 +184,11 @@ class ProfilePersistenceHelper { return profiles; } - private Set selectFiles() { + private Set selectFiles() { File files[] = getProfileDir().listFiles(new FilenameFilter() { public boolean accept(File dir, String filename) { - return (filename.startsWith("profile-") && filename.endsWith(".dat")); + return (filename.startsWith(PREFIX) && + (filename.endsWith(SUFFIX) || filename.endsWith(OLD_SUFFIX) || filename.endsWith(UNCOMPRESSED_SUFFIX))); } }); Set rv = new HashSet(files.length); @@ -200,6 +221,14 @@ class ProfilePersistenceHelper { ", since we haven't heard from them in a long time"); file.delete(); return null; + } else if (file.getName().endsWith(OLD_SUFFIX)) { + // migrate to new file name, ignore failure + String newName = file.getAbsolutePath(); + newName = newName.substring(0, newName.length() - OLD_SUFFIX.length()) + SUFFIX; + boolean success = file.renameTo(new File(newName)); + if (!success) + // new file exists and on Windows? + file.delete(); } profile.setCapacityBonus(getLong(props, "capacityBonus")); @@ -300,8 +329,8 @@ class ProfilePersistenceHelper { } private Hash getHash(String name) { - String key = name.substring("profile-".length()); - key = key.substring(0, key.length() - ".dat".length()); + String key = name.substring(PREFIX.length()); + key = key.substring(0, 44); //Hash h = new Hash(); try { //h.fromBase64(key); @@ -317,7 +346,7 @@ class ProfilePersistenceHelper { } private File pickFile(PeerProfile profile) { - return new File(getProfileDir(), "profile-" + profile.getPeer().toBase64() + ".dat"); + return new File(getProfileDir(), PREFIX + profile.getPeer().toBase64() + SUFFIX); } private File getProfileDir() { @@ -339,7 +368,7 @@ class ProfilePersistenceHelper { rnd.nextBytes(data); Hash peer = new Hash(data); try { - File f = new File(dir, "profile-" + peer.toBase64() + ".dat"); + File f = new File(dir, PREFIX + peer.toBase64() + SUFFIX); f.createNewFile(); System.out.println("Created " + peer.toBase64()); } catch (IOException ioe) {} diff --git a/router/java/src/net/i2p/router/peermanager/TunnelHistory.java b/router/java/src/net/i2p/router/peermanager/TunnelHistory.java index 208415ca0b..bc6109bcad 100644 --- a/router/java/src/net/i2p/router/peermanager/TunnelHistory.java +++ b/router/java/src/net/i2p/router/peermanager/TunnelHistory.java @@ -2,6 +2,7 @@ package net.i2p.router.peermanager; import java.io.IOException; import java.io.OutputStream; +import java.util.Date; import java.util.Properties; import net.i2p.router.RouterContext; @@ -138,12 +139,12 @@ public class TunnelHistory { buf.append("#################").append(NL); buf.append("# Tunnel history").append(NL); buf.append("###").append(NL); - add(buf, "lastAgreedTo", _lastAgreedTo, "When did the peer last agree to participate in a tunnel? (milliseconds since the epoch)"); - add(buf, "lastFailed", _lastFailed, "When was the last time a tunnel that the peer agreed to participate failed? (milliseconds since the epoch)"); - add(buf, "lastRejectedCritical", _lastRejectedCritical, "When was the last time the peer refused to participate in a tunnel? (milliseconds since the epoch)"); - add(buf, "lastRejectedBandwidth", _lastRejectedBandwidth, "When was the last time the peer refused to participate in a tunnel? (milliseconds since the epoch)"); - add(buf, "lastRejectedTransient", _lastRejectedTransient, "When was the last time the peer refused to participate in a tunnel? (milliseconds since the epoch)"); - add(buf, "lastRejectedProbabalistic", _lastRejectedProbabalistic, "When was the last time the peer refused to participate in a tunnel? (milliseconds since the epoch)"); + addDate(buf, "lastAgreedTo", _lastAgreedTo, "When did the peer last agree to participate in a tunnel?"); + addDate(buf, "lastFailed", _lastFailed, "When was the last time a tunnel that the peer agreed to participate failed?"); + addDate(buf, "lastRejectedCritical", _lastRejectedCritical, "When was the last time the peer refused to participate in a tunnel (Critical response code)?"); + addDate(buf, "lastRejectedBandwidth", _lastRejectedBandwidth, "When was the last time the peer refused to participate in a tunnel (Bandwidth response code)?"); + addDate(buf, "lastRejectedTransient", _lastRejectedTransient, "When was the last time the peer refused to participate in a tunnel (Transient load response code)?"); + addDate(buf, "lastRejectedProbabalistic", _lastRejectedProbabalistic, "When was the last time the peer refused to participate in a tunnel (Probabalistic response code)?"); add(buf, "lifetimeAgreedTo", _lifetimeAgreedTo, "How many tunnels has the peer ever agreed to participate in?"); add(buf, "lifetimeFailed", _lifetimeFailed, "How many tunnels has the peer ever agreed to participate in that failed prematurely?"); add(buf, "lifetimeRejected", _lifetimeRejected, "How many tunnels has the peer ever refused to participate in?"); @@ -152,8 +153,13 @@ public class TunnelHistory { _failRate.store(out, "tunnelHistory.failRate"); } + private static void addDate(StringBuilder buf, String name, long val, String description) { + String when = val > 0 ? (new Date(val)).toString() : "Never"; + add(buf, name, val, description + ' ' + when); + } + private static void add(StringBuilder buf, String name, long val, String description) { - buf.append("# ").append(name.toUpperCase()).append(NL).append("# ").append(description).append(NL); + buf.append("# ").append(name).append(NL).append("# ").append(description).append(NL); buf.append("tunnels.").append(name).append('=').append(val).append(NL).append(NL); } diff --git a/router/java/src/net/i2p/router/transport/ntcp/NTCPSendFinisher.java b/router/java/src/net/i2p/router/transport/ntcp/NTCPSendFinisher.java index 24b86fd5b3..630036204d 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/NTCPSendFinisher.java +++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPSendFinisher.java @@ -34,6 +34,8 @@ class NTCPSendFinisher { private static final int THREADS; static { long maxMemory = Runtime.getRuntime().maxMemory(); + if (maxMemory == Long.MAX_VALUE) + maxMemory = 96*1024*1024l; THREADS = (int) Math.max(MIN_THREADS, Math.min(MAX_THREADS, 1 + (maxMemory / (32*1024*1024)))); } diff --git a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java index 62d57810e8..326f659eff 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java +++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java @@ -491,6 +491,8 @@ public class NTCPTransport extends TransportImpl { _pumper.startPumping(); long maxMemory = Runtime.getRuntime().maxMemory(); + if (maxMemory == Long.MAX_VALUE) + maxMemory = 128*1024*1024l; int nr, nw; if (maxMemory < 32*1024*1024) { nr = nw = 1; diff --git a/router/java/src/net/i2p/router/transport/udp/MessageReceiver.java b/router/java/src/net/i2p/router/transport/udp/MessageReceiver.java index 4988a06851..dede98ef7d 100644 --- a/router/java/src/net/i2p/router/transport/udp/MessageReceiver.java +++ b/router/java/src/net/i2p/router/transport/udp/MessageReceiver.java @@ -39,6 +39,8 @@ class MessageReceiver { _completeMessages = new LinkedBlockingQueue(); long maxMemory = Runtime.getRuntime().maxMemory(); + if (maxMemory == Long.MAX_VALUE) + maxMemory = 96*1024*1024l; if (maxMemory < 32*1024*1024) _threadCount = 1; else if (maxMemory < 64*1024*1024) diff --git a/router/java/src/net/i2p/router/transport/udp/PacketHandler.java b/router/java/src/net/i2p/router/transport/udp/PacketHandler.java index ffbcf48aca..824f4a9285 100644 --- a/router/java/src/net/i2p/router/transport/udp/PacketHandler.java +++ b/router/java/src/net/i2p/router/transport/udp/PacketHandler.java @@ -48,6 +48,8 @@ class PacketHandler { _introManager = introManager; long maxMemory = Runtime.getRuntime().maxMemory(); + if (maxMemory == Long.MAX_VALUE) + maxMemory = 96*1024*1024l; int num_handlers; if (maxMemory < 32*1024*1024) num_handlers = 1; diff --git a/router/java/src/net/i2p/router/tunnel/TunnelGatewayPumper.java b/router/java/src/net/i2p/router/tunnel/TunnelGatewayPumper.java index 7f29f5743d..38c72dfaf8 100644 --- a/router/java/src/net/i2p/router/tunnel/TunnelGatewayPumper.java +++ b/router/java/src/net/i2p/router/tunnel/TunnelGatewayPumper.java @@ -26,6 +26,8 @@ public class TunnelGatewayPumper implements Runnable { _wantsPumping = new LinkedBlockingQueue(); _stop = false; long maxMemory = Runtime.getRuntime().maxMemory(); + if (maxMemory == Long.MAX_VALUE) + maxMemory = 96*1024*1024l; _pumpers = (int) Math.max(MIN_PUMPERS, Math.min(MAX_PUMPERS, 1 + (maxMemory / (32*1024*1024)))); for (int i = 0; i < _pumpers; i++) new I2PThread(this, "Tunnel GW pumper " + (i+1) + '/' + _pumpers, true).start(); diff --git a/tests/scripts/checkpo.sh b/tests/scripts/checkpo.sh index 2e03f8be62..13f080833b 100755 --- a/tests/scripts/checkpo.sh +++ b/tests/scripts/checkpo.sh @@ -13,6 +13,7 @@ DIRS="\ apps/i2ptunnel/locale \ apps/i2psnark/locale \ apps/susidns/locale \ + apps/susimail/locale \ apps/desktopgui/locale" for i in `find $DIRS -maxdepth 1 -type f -name *.po` diff --git a/tests/scripts/checkutf8.sh b/tests/scripts/checkutf8.sh index 8efce06bf6..4753cbd300 100755 --- a/tests/scripts/checkutf8.sh +++ b/tests/scripts/checkutf8.sh @@ -16,6 +16,7 @@ DIRS="\ apps/i2ptunnel/locale \ apps/i2psnark/locale \ apps/susidns/locale \ + apps/susimail/locale \ apps/desktopgui/locale \ installer/resources/eepsite.help/help \ installer/resources/initialNews \