diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index da60c89b03276841c63379d793a4325d7424e6c9..dd52b10ad72d6a73dd1967f0e88cd08ca964d9f8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -52,6 +52,7 @@ test:ant: - echo junit.home=/usr/share/java >> override.properties - echo hamcrest.home=/usr/share/java >> override.properties - echo mockito.home=/usr/share/java >> override.properties + - echo build.built-by=GitHub Actions >> override.properties script: - ant test only: diff --git a/Dockerfile b/Dockerfile index f4fedaea5602ab8d383657bfbcaabeaba4ae3f2b..31da41399d12994d5eee5045d73c4270565e39b8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,6 +6,8 @@ WORKDIR /tmp/build COPY . . RUN apk add --virtual build-base gettext tar bzip2 apache-ant openjdk17 \ + && echo "build.built-by=Docker" >> override.properties \ + && ant preppkg-linux-only \ && rm -rf pkg-temp/osid pkg-temp/lib/wrapper pkg-temp/lib/wrapper.* \ && apk del build-base gettext tar bzip2 apache-ant openjdk17 @@ -13,7 +15,8 @@ RUN apk add --virtual build-base gettext tar bzip2 apache-ant openjdk17 \ FROM alpine:latest ENV APP_HOME="/i2p" -RUN apk add openjdk17-jre +RUN apk add openjdk17-jre ttf-dejavu + WORKDIR ${APP_HOME} COPY --from=builder /tmp/build/pkg-temp . diff --git a/apps/addressbook/build.xml b/apps/addressbook/build.xml index b02dc2409ea07961dcec10de6652d41f5c030593..4f165ab3805e8c09065318e5b914650c3f3cbef6 100644 --- a/apps/addressbook/build.xml +++ b/apps/addressbook/build.xml @@ -84,28 +84,36 @@ </jar> </target> + <!-- actually the jar --> <target name="warUpToDate"> - <uptodate property="war.uptodate" targetfile="${dist}/${war}"> - <srcfiles dir= "." includes="${build}/**/*.class, web.xml"/> + <uptodate property="war.uptodate" targetfile="${dist}/${jar}"> + <srcfiles dir= "." includes="${build}/**/*.class"/> </uptodate> <condition property="shouldListChanges" > <and> <not> <isset property="war.uptodate" /> </not> - <isset property="mtn.available" /> + <isset property="git.available" /> </and> </condition> </target> <target name="changes" depends="warUpToDate" if="shouldListChanges" > - <exec executable="mtn" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > - <arg value="list" /> - <arg value="changed" /> - <arg value="." /> - </exec> + <exec executable="git" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="status" /> + <arg value="-s" /> + <arg value="--porcelain" /> + <arg value="-uno" /> + <arg value="." /> + </exec> + <!-- trim flags --> + <exec executable="sed" inputstring="${workspace.changes}" outputproperty="workspace.changes.sed" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="-e" /> + <arg value="s/^[MTADRCU ]*//" /> + </exec> <!-- \n in an attribute value generates an invalid manifest --> - <exec executable="tr" inputstring="${workspace.changes}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > + <exec executable="tr" inputstring="${workspace.changes.sed}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > <arg value="-s" /> <arg value="[:space:]" /> <arg value="," /> diff --git a/apps/desktopgui/build.xml b/apps/desktopgui/build.xml index 6487bfceac9944d70b19171866d7e7394956c0e4..baf8d04c14e35d30aa9b2ecab0cb676af386d177 100644 --- a/apps/desktopgui/build.xml +++ b/apps/desktopgui/build.xml @@ -64,17 +64,24 @@ </target> <target name="listChangedFiles" depends="jarUpToDate" if="shouldListChanges" > - <exec executable="mtn" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > - <arg value="list" /> - <arg value="changed" /> - <arg value="." /> - </exec> - <!-- \n in an attribute value generates an invalid manifest --> - <exec executable="tr" inputstring="${workspace.changes}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > - <arg value="-s" /> - <arg value="[:space:]" /> - <arg value="," /> - </exec> + <exec executable="git" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="status" /> + <arg value="-s" /> + <arg value="--porcelain" /> + <arg value="-uno" /> + <arg value="." /> + </exec> + <!-- trim flags --> + <exec executable="sed" inputstring="${workspace.changes}" outputproperty="workspace.changes.sed" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="-e" /> + <arg value="s/^[MTADRCU ]*//" /> + </exec> + <!-- \n in an attribute value generates an invalid manifest --> + <exec executable="tr" inputstring="${workspace.changes.sed}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="-s" /> + <arg value="[:space:]" /> + <arg value="," /> + </exec> </target> <target name="jar" depends="compile, bundle, listChangedFiles" unless="jar.uptodate" > @@ -108,7 +115,7 @@ <not> <isset property="jar.uptodate" /> </not> - <isset property="mtn.available" /> + <isset property="git.available" /> </and> </condition> </target> diff --git a/apps/i2pcontrol/build.xml b/apps/i2pcontrol/build.xml index cc24c7e74fc23b46b3358b36fbc83841dc5fad99..d3e4883da10ca3368db57325fbcc5b792da1f7e3 100644 --- a/apps/i2pcontrol/build.xml +++ b/apps/i2pcontrol/build.xml @@ -92,7 +92,29 @@ </javac> </target> - <target name="jar" depends="compile"> + <target name="listChangedFiles" if="git.available" > + <exec executable="git" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="status" /> + <arg value="-s" /> + <arg value="--porcelain" /> + <arg value="-uno" /> + <arg value="." /> + <arg value="../resources" /> + </exec> + <!-- trim flags --> + <exec executable="sed" inputstring="${workspace.changes}" outputproperty="workspace.changes.sed" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="-e" /> + <arg value="s/^[MTADRCU ]*//" /> + </exec> + <!-- \n in an attribute value generates an invalid manifest --> + <exec executable="tr" inputstring="${workspace.changes.sed}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="-s" /> + <arg value="[:space:]" /> + <arg value="," /> + </exec> + </target> + + <target name="jar" depends="compile, listChangedFiles"> <!-- set if unset --> <property name="workspace.changes.tr" value="" /> <jar destfile="build/i2pcontrol.jar" basedir="./build/obj" includes="**/*.class" > @@ -108,7 +130,7 @@ </jar> </target> - <target name="socketJar" depends="compileSocketJar"> + <target name="socketJar" depends="compileSocketJar, listChangedFiles"> <!-- set if unset --> <property name="workspace.changes.tr" value="" /> <jar destfile="build/i2pcontrol.jar" basedir="./build/obj" includes="**/*.class" > @@ -124,7 +146,7 @@ </jar> </target> - <target name="war" depends="compile" > + <target name="war" depends="compile, listChangedFiles" > <!-- set if unset --> <property name="workspace.changes.tr" value="" /> <war destfile="build/jsonrpc.war" webxml="web.xml" > diff --git a/apps/i2psnark/java/build.xml b/apps/i2psnark/java/build.xml index b06593af08f0d96e488bd7bf7be20a4e14fc0815..edde6bf451ce1ca4337bd5bcc6cd91ac2bf78666 100644 --- a/apps/i2psnark/java/build.xml +++ b/apps/i2psnark/java/build.xml @@ -68,13 +68,20 @@ </target> <target name="listChangedFiles" depends="jarUpToDate" if="shouldListChanges" > - <exec executable="mtn" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > - <arg value="list" /> - <arg value="changed" /> + <exec executable="git" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="status" /> + <arg value="-s" /> + <arg value="--porcelain" /> + <arg value="-uno" /> <arg value=".." /> </exec> + <!-- trim flags --> + <exec executable="sed" inputstring="${workspace.changes}" outputproperty="workspace.changes.sed" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="-e" /> + <arg value="s/^[MTADRCU ]*//" /> + </exec> <!-- \n in an attribute value generates an invalid manifest --> - <exec executable="tr" inputstring="${workspace.changes}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > + <exec executable="tr" inputstring="${workspace.changes.sed}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > <arg value="-s" /> <arg value="[:space:]" /> <arg value="," /> @@ -111,7 +118,7 @@ <not> <isset property="war.uptodate" /> </not> - <isset property="mtn.available" /> + <isset property="git.available" /> </and> </condition> </target> diff --git a/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java b/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java index 412663b6607fa5a56b0d04aeca5f1bcef9adcc81..f51ecf64b4002d91a4030144f724130d35242ed1 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java +++ b/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java @@ -77,6 +77,7 @@ public class I2PSnarkUtil implements DisconnectListener { private DHT _dht; private long _startedTime; private final DisconnectListener _discon; + private int _maxFilesPerTorrent = SnarkManager.DEFAULT_MAX_FILES_PER_TORRENT; private static final int EEPGET_CONNECT_TIMEOUT = 45*1000; private static final int EEPGET_CONNECT_TIMEOUT_SHORT = 5*1000; @@ -242,6 +243,11 @@ public class I2PSnarkUtil implements DisconnectListener { /** @since 0.9.1 */ public File getTempDir() { return _tmpDir; } + /** @since 0.9.58 */ + public int getMaxFilesPerTorrent() { return _maxFilesPerTorrent; } + /** @since 0.9.58 */ + public void setMaxFilesPerTorrent(int max) { _maxFilesPerTorrent = Math.max(max, 1); } + /** * Connect to the router, if we aren't already */ diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java index e703cb9f8eb0c8fc128f679a195867a9c4eba373..d80366ca2e6a8e0307bfefbd1e239d5c47db702f 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java +++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java @@ -129,7 +129,7 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList private static final String PROP_META_ACTIVITY = "activity"; private static final String CONFIG_FILE_SUFFIX = ".config"; - private static final String CONFIG_FILE = "i2psnark" + CONFIG_FILE_SUFFIX; + public static final String CONFIG_FILE = "i2psnark" + CONFIG_FILE_SUFFIX; private static final String COMMENT_FILE_SUFFIX = ".comments.txt.gz"; public static final String PROP_FILES_PUBLIC = "i2psnark.filesPublic"; public static final String PROP_OLD_AUTO_START = "i2snark.autoStart"; // oops @@ -164,6 +164,8 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList private static final String PROP_COMMENTS = "i2psnark.comments"; /** @since 0.9.31 */ private static final String PROP_COMMENTS_NAME = "i2psnark.commentsName"; + /** @since 0.9.58 */ + public static final String PROP_MAX_FILES_PER_TORRENT = "i2psnark.maxFilesPerTorrent"; public static final int MIN_UP_BW = 10; public static final int DEFAULT_MAX_UP_BW = 25; @@ -171,6 +173,7 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList public static final int DEFAULT_REFRESH_DELAY_SECS = 15; private static final int DEFAULT_PAGE_SIZE = 50; public static final int DEFAULT_TUNNEL_QUANTITY = 3; + public static final int DEFAULT_MAX_FILES_PER_TORRENT = 2000; public static final String CONFIG_DIR_SUFFIX = ".d"; private static final String SUBDIR_PREFIX = "s"; private static final String B64 = Base64.ALPHABET_I2P; @@ -1000,6 +1003,7 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList // _util.setProxy(eepHost, eepPort); _util.setMaxUploaders(getInt(PROP_UPLOADERS_TOTAL, Snark.MAX_TOTAL_UPLOADERS)); _util.setMaxUpBW(getInt(PROP_UPBW_MAX, DEFAULT_MAX_UP_BW)); + _util.setMaxFilesPerTorrent(getInt(PROP_MAX_FILES_PER_TORRENT, DEFAULT_MAX_FILES_PER_TORRENT)); _util.setStartupDelay(getInt(PROP_STARTUP_DELAY, DEFAULT_STARTUP_DELAY)); _util.setFilesPublic(areFilesPublic()); _util.setOpenTrackers(getListConfig(PROP_OPENTRACKERS, DEFAULT_OPENTRACKERS)); @@ -1479,9 +1483,6 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList } } - /** hardcoded for sanity. perhaps this should be customizable, for people who increase their ulimit, etc. */ - public static final int MAX_FILES_PER_TORRENT = 2000; - /** * Set of canonical .torrent filenames that we are dealing with. * An unsynchronized copy. @@ -2450,8 +2451,11 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList */ private String validateTorrent(MetaInfo info) { List<List<String>> files = info.getFiles(); - if ( (files != null) && (files.size() > MAX_FILES_PER_TORRENT) ) { - return _t("Too many files in \"{0}\" ({1})!", info.getName(), files.size()); + if (files != null && files.size() > _util.getMaxFilesPerTorrent()) { + return _t("Too many files in \"{0}\" ({1})!", info.getName(), files.size()) + + " - limit is " + _util.getMaxFilesPerTorrent() + ", zip them or set " + + PROP_MAX_FILES_PER_TORRENT + '=' + files.size() + " in " + + _configFile.getAbsolutePath() + " and restart"; } else if ( (files == null) && (info.getName().endsWith(".torrent")) ) { return _t("Torrent file \"{0}\" cannot end in \".torrent\"!", info.getName()); } else if (info.getPieces() <= 0) { diff --git a/apps/i2psnark/java/src/org/klomp/snark/Storage.java b/apps/i2psnark/java/src/org/klomp/snark/Storage.java index e74cecb50e5f024d7a2cc6fbe98a66309a31b05c..5ae3e27fca2f1cad7796dcff434fc7111e96c2b7 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/Storage.java +++ b/apps/i2psnark/java/src/org/klomp/snark/Storage.java @@ -288,9 +288,13 @@ public class Storage implements Closeable * @throws IOException if too many total files */ private void addFiles(List<File> l, File f) throws IOException { + int max = _util.getMaxFilesPerTorrent(); if (!f.isDirectory()) { - if (l.size() >= SnarkManager.MAX_FILES_PER_TORRENT) - throw new IOException("Too many files, limit is " + SnarkManager.MAX_FILES_PER_TORRENT + ", zip them?"); + if (l.size() >= max) + throw new IOException(_util.getString("Too many files in \"{0}\" ({1})!", metainfo.getName(), l.size()) + + " - limit is " + max + ", zip them or set " + + SnarkManager.PROP_MAX_FILES_PER_TORRENT + '=' + l.size() + " in " + + SnarkManager.CONFIG_FILE + " and restart"); l.add(f); } else { File[] files = f.listFiles(); 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 80b268ac1085c993010401bf60372d73695b8477..98247aa7486b28aab66bce205200079f6411c222 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java +++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java @@ -326,7 +326,8 @@ public class I2PSnarkServlet extends BasicServlet { out.write("<script src=\".resources/js/configui.js?" + CoreVersion.VERSION + "\" type=\"text/javascript\"></script>\n"); } else { delay = _manager.getRefreshDelaySeconds(); - if (delay > 0) { + // init for search even if refresh disabled + //if (delay > 0) { String jsPfx = _context.isRouterContext() ? "" : ".resources"; String downMsg = _context.isRouterContext() ? _t("Router is down") : _t("I2PSnark has stopped"); // fallback to metarefresh when javascript is disabled @@ -337,7 +338,7 @@ public class I2PSnarkServlet extends BasicServlet { "var ajaxDelay = " + (delay * 1000) + ";\n" + "</script>\n" + "<script src=\".resources/js/initajax.js?" + CoreVersion.VERSION + "\" type=\"text/javascript\"></script>\n"); - } + //} out.write("<script nonce=\"" + cspNonce + "\" type=\"text/javascript\">\n" + "var deleteMessage1 = \"" + _t("Are you sure you want to delete the file \\''{0}\\'' (downloaded data will not be deleted) ?") + "\";\n" + "var deleteMessage2 = \"" + _t("Are you sure you want to delete the torrent \\''{0}\\'' and all downloaded data?") + "\";\n" + @@ -394,7 +395,7 @@ public class I2PSnarkServlet extends BasicServlet { if (search != null) out.write(" value=\"" + DataHelper.escapeHTML(search) + '"'); out.write(">" + - "<input type=\"reset\" class=\"cancel\" id=\"searchcancel\" value=\"\">" + + "<a class=\"cancel\" id=\"searchcancel\" href=\"" + _contextPath + "/\"></a>" + "</form>\n"); } } diff --git a/apps/i2psnark/launch-i2psnark b/apps/i2psnark/launch-i2psnark index 2cbd9390088007c7de524fa9829de578ad80ecb0..c72de0b27970348a6da17892b86b8e289241d105 100755 --- a/apps/i2psnark/launch-i2psnark +++ b/apps/i2psnark/launch-i2psnark @@ -35,5 +35,6 @@ raiseopenfilesulimit() { raiseopenfilesulimit -I2P="." -java $JAVA_OPTS -jar "$I2P/i2psnark.jar" +I2P="`dirname $0`" +cd "$I2P" +java $JAVA_OPTS -jar i2psnark.jar diff --git a/apps/i2psnark/resources/js/initajax.js b/apps/i2psnark/resources/js/initajax.js index 7697b0086e02dc13f51c739f42a3450e2f105033..a5db3ac527211629012879c31052432ce54340fb 100644 --- a/apps/i2psnark/resources/js/initajax.js +++ b/apps/i2psnark/resources/js/initajax.js @@ -55,7 +55,9 @@ function requestAjax2(refreshtime) { } function initAjax() { - setTimeout(requestAjax1, ajaxDelay); + if (ajaxDelay > 0) { + setTimeout(requestAjax1, ajaxDelay); + } } document.addEventListener("DOMContentLoaded", function() { diff --git a/apps/i2psnark/resources/js/search.js b/apps/i2psnark/resources/js/search.js index 67339a5e778ac33879d11f00e2f06954576cba2d..b719ddf4e2b96e6a6bd49c301c13e38164458470 100644 --- a/apps/i2psnark/resources/js/search.js +++ b/apps/i2psnark/resources/js/search.js @@ -11,17 +11,32 @@ function initSearch() var sch = document.getElementById("search"); if (sch != null) { var box = document.getElementById("searchbox"); - sch.addEventListener("reset", function(event) { + var cxl = document.getElementById("searchcancel"); + cxl.addEventListener("click", function(event) { if (box.value !== "") { box.value = ""; requestAjax2(-1); } + cxl.classList.add("disabled"); event.preventDefault(); }); box.addEventListener("input", function(event) { + if (box.value !== "") { + cxl.classList.remove("disabled"); + } else { + cxl.classList.add("disabled"); + } requestAjax2(-1); }); + + if (box.value !== "") { + cxl.classList.remove("disabled"); + } else { + cxl.classList.add("disabled"); + } + // so we don't get the link popup + cxl.removeAttribute("href"); } } diff --git a/apps/i2psnark/resources/themes/dark/snark.css b/apps/i2psnark/resources/themes/dark/snark.css index f392273d97dd32e718cca600a4ee1d821e6a6bf0..7394bbd705a7278e07176ee371a190c3bcf5e310 100644 --- a/apps/i2psnark/resources/themes/dark/snark.css +++ b/apps/i2psnark/resources/themes/dark/snark.css @@ -227,24 +227,33 @@ _:-ms-lang(x), .snarknavbar { #search { display: inline-block; position: absolute; - top: 6px; - right: 3px; + top: 16px; + right: 9px; } #searchbox { - background: #f60 url(/themes/console/images/buttons/search.png) 7px center no-repeat !important; + background: #000 url(/themes/console/images/buttons/search.png) 7px center no-repeat !important; margin: 2px 4px 2px 24px !important; padding: 4px 32px 4px 32px !important; - color: black; + color: #bb7; +} + +#searchbox:focus, #searchbox:active { + color: #ee9; } #searchcancel { - background: url(images/cancel.png); - margin: 2px 4px 2px -28px; + background: url(images/delete.png) 0px center no-repeat; + margin: 2px 4px 2px -20px; + padding: 0px 6px; color: transparent; border: none; } +#searchcancel.disabled { + display: none; +} + /* end topnav */ /* screenlog */ diff --git a/apps/i2psnark/resources/themes/light/snark.css b/apps/i2psnark/resources/themes/light/snark.css index 18134c4146da76fd04e5fc80fedb6a03c62530d3..fad322d4ad409aa816f505c003824f733a40970d 100644 --- a/apps/i2psnark/resources/themes/light/snark.css +++ b/apps/i2psnark/resources/themes/light/snark.css @@ -232,24 +232,33 @@ button::-moz-focus-inner, input::-moz-focus-inner { #search { display: inline-block; position: absolute; - top: 6px; - right: 3px; + top: 10px; + right: 6px; } #searchbox { - background: #f60 url(/themes/console/images/buttons/search.png) 7px center no-repeat !important; + background: #f8f8ff url(/themes/console/images/buttons/search.png) 7px center no-repeat !important; margin: 2px 4px 2px 24px !important; padding: 4px 32px 4px 32px !important; - color: black; + color: #47475f; +} + +#searchbox:focus, #searchbox:active { + color: #19191f; } #searchcancel { - background: url(images/cancel.png); - margin: 2px 4px 2px -28px; + background: url(images/delete.png) 0px center no-repeat; + margin: 2px 4px 2px 4px; + padding: 0px 6px; color: transparent; border: none; } +#searchcancel.disabled { + display: none; +} + /* end top nav */ /* screenlog */ diff --git a/apps/i2psnark/resources/themes/ubergine/snark.css b/apps/i2psnark/resources/themes/ubergine/snark.css index e3afeb55d5a32536b244b8c5efc3ab23519c019d..f1874006c05d554bdde287187ad7ee568bd408b8 100644 --- a/apps/i2psnark/resources/themes/ubergine/snark.css +++ b/apps/i2psnark/resources/themes/ubergine/snark.css @@ -237,19 +237,29 @@ _:-ms-lang(x), .snarkNav:last-child[href="/i2psnark/"] { } #searchbox { - background: #f60 url(/themes/console/images/buttons/search.png) 7px center no-repeat !important; + background: #212 url(/themes/console/images/buttons/search.png) 7px center no-repeat !important; margin: 2px 4px 2px 24px !important; padding: 4px 32px 4px 32px !important; - color: black; + color: #f60; +} + +#searchbox:focus, #searchbox:active { + background: #f60 url(/themes/console/images/buttons/search.png) 7px center no-repeat !important; + color: #fff; } #searchcancel { - background: url(images/cancel.png); + background: url(images/cancel.png) no-repeat; margin: 2px 4px 2px -28px; + padding: 0px 12px; color: transparent; border: none; } +#searchcancel.disabled { + display: none; +} + /* end topnav */ /* screenlogger */ diff --git a/apps/i2psnark/resources/themes/vanilla/snark.css b/apps/i2psnark/resources/themes/vanilla/snark.css index 1a70c5cac736040ec67d3fe65d40838d0884f34c..154a5ac8f740a07919157b9a6169d08b2b362908 100644 --- a/apps/i2psnark/resources/themes/vanilla/snark.css +++ b/apps/i2psnark/resources/themes/vanilla/snark.css @@ -275,24 +275,34 @@ _:-ms-lang(x), .snarkNav:link, .snarkNav:visited { #search { display: inline-block; position: absolute; - top: 6px; + top: 8px; right: 3px; } #searchbox { - background: #f60 url(/themes/console/images/buttons/search.png) 7px center no-repeat !important; + background: #efe6e0 url(/themes/console/images/buttons/search.png) 7px center no-repeat !important; margin: 2px 4px 2px 24px !important; padding: 4px 32px 4px 32px !important; - color: black; + color: #2f1500; +} + +#searchbox:focus, #searchbox:active { + background: #fffcdf url(/themes/console/images/buttons/search.png) 7px center no-repeat !important; + color: #5f1227; } #searchcancel { - background: url(images/cancel.png); - margin: 2px 4px 2px -28px; + background: url(images/delete.png) 7px center no-repeat; + margin: 2px 4px 2px -30px; + padding: 0px 14px; color: transparent; border: none; } +#searchcancel.disabled { + display: none; +} + /* end topnav */ /* screenlog */ diff --git a/apps/i2ptunnel/java/build.xml b/apps/i2ptunnel/java/build.xml index f6b6cae5cc450eefb05e710a613846fde40d4898..b8d8b24a993d14da4b98cd216f3e9b307ad5baab 100644 --- a/apps/i2ptunnel/java/build.xml +++ b/apps/i2ptunnel/java/build.xml @@ -68,13 +68,21 @@ </target> <target name="listChangedFiles" depends="jarUpToDate" if="shouldListChanges" > - <exec executable="mtn" outputproperty="workspace.changes.j" errorproperty="mtn.error2" failifexecutionfails="false" > - <arg value="list" /> - <arg value="changed" /> + <exec executable="git" outputproperty="workspace.changes.j" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="status" /> + <arg value="-s" /> + <arg value="--porcelain" /> + <arg value="-uno" /> <arg value="." /> + <arg value="../resources" /> + </exec> + <!-- trim flags --> + <exec executable="sed" inputstring="${workspace.changes.j}" outputproperty="workspace.changes.j.sed" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="-e" /> + <arg value="s/^[MTADRCU ]*//" /> </exec> <!-- \n in an attribute value generates an invalid manifest --> - <exec executable="tr" inputstring="${workspace.changes.j}" outputproperty="workspace.changes.j.tr" errorproperty="mtn.error2" failifexecutionfails="false" > + <exec executable="tr" inputstring="${workspace.changes.j.sed}" outputproperty="workspace.changes.j.tr" errorproperty="mtn.error2" failifexecutionfails="false" > <arg value="-s" /> <arg value="[:space:]" /> <arg value="," /> @@ -129,7 +137,7 @@ <not> <isset property="jar.uptodate" /> </not> - <isset property="mtn.available" /> + <isset property="git.available" /> </and> </condition> </target> @@ -162,7 +170,7 @@ <not> <isset property="uiJar.uptodate" /> </not> - <isset property="mtn.available" /> + <isset property="git.available" /> </and> </condition> </target> @@ -271,13 +279,20 @@ </target> <target name="listChangedFiles2" depends="warUpToDate" if="shouldListChanges2" > - <exec executable="mtn" outputproperty="workspace.changes.w" errorproperty="mtn.error2" failifexecutionfails="false" > - <arg value="list" /> - <arg value="changed" /> + <exec executable="git" outputproperty="workspace.changes.w" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="status" /> + <arg value="-s" /> + <arg value="--porcelain" /> + <arg value="-uno" /> <arg value="../jsp" /> </exec> + <!-- trim flags --> + <exec executable="sed" inputstring="${workspace.changes.w}" outputproperty="workspace.changes.w.sed" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="-e" /> + <arg value="s/^[MTADRCU ]*//" /> + </exec> <!-- \n in an attribute value generates an invalid manifest --> - <exec executable="tr" inputstring="${workspace.changes.w}" outputproperty="workspace.changes.w.tr" errorproperty="mtn.error2" failifexecutionfails="false" > + <exec executable="tr" inputstring="${workspace.changes.w.sed}" outputproperty="workspace.changes.w.tr" errorproperty="mtn.error2" failifexecutionfails="false" > <arg value="-s" /> <arg value="[:space:]" /> <arg value="," /> @@ -318,7 +333,7 @@ <not> <isset property="war.uptodate" /> </not> - <isset property="mtn.available" /> + <isset property="git.available" /> </and> </condition> </target> diff --git a/apps/imagegen/identicon/build.xml b/apps/imagegen/identicon/build.xml index fe735b4b548df909db546f7e85b6c8aa2de0ea04..7971176ca78a3a379ef105643046ffd97c8c0ee9 100644 --- a/apps/imagegen/identicon/build.xml +++ b/apps/imagegen/identicon/build.xml @@ -53,13 +53,20 @@ </target> <target name="listChangedFiles" depends="jarUpToDate" if="shouldListChanges" > - <exec executable="mtn" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > - <arg value="list" /> - <arg value="changed" /> + <exec executable="git" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="status" /> + <arg value="-s" /> + <arg value="--porcelain" /> + <arg value="-uno" /> <arg value="." /> </exec> + <!-- trim flags --> + <exec executable="sed" inputstring="${workspace.changes}" outputproperty="workspace.changes.sed" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="-e" /> + <arg value="s/^[MTADRCU ]*//" /> + </exec> <!-- \n in an attribute value generates an invalid manifest --> - <exec executable="tr" inputstring="${workspace.changes}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > + <exec executable="tr" inputstring="${workspace.changes.sed}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > <arg value="-s" /> <arg value="[:space:]" /> <arg value="," /> @@ -91,7 +98,7 @@ <not> <isset property="jar.uptodate" /> </not> - <isset property="mtn.available" /> + <isset property="git.available" /> </and> </condition> </target> diff --git a/apps/imagegen/imagegen/build.xml b/apps/imagegen/imagegen/build.xml index 5b4eeeaa6f3f598fcc70b233bc6b5a3e118ee544..68cb47660bbc24c6fc12432ac5370482b3a5292f 100644 --- a/apps/imagegen/imagegen/build.xml +++ b/apps/imagegen/imagegen/build.xml @@ -46,20 +46,27 @@ </target> <target name="listChangedFiles" if="shouldListChanges" > - <exec executable="mtn" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > - <arg value="list" /> - <arg value="changed" /> + <exec executable="git" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="status" /> + <arg value="-s" /> + <arg value="--porcelain" /> + <arg value="-uno" /> <arg value="." /> </exec> + <!-- trim flags --> + <exec executable="sed" inputstring="${workspace.changes}" outputproperty="workspace.changes.sed" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="-e" /> + <arg value="s/^[MTADRCU ]*//" /> + </exec> <!-- \n in an attribute value generates an invalid manifest --> - <exec executable="tr" inputstring="${workspace.changes}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > + <exec executable="tr" inputstring="${workspace.changes.sed}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > <arg value="-s" /> <arg value="[:space:]" /> <arg value="," /> </exec> </target> - <target name="war" depends="compile, warUpToDate" unless="war.uptodate" > + <target name="war" depends="compile, warUpToDate, listChangedFiles" unless="war.uptodate" > <!-- set if unset --> <property name="workspace.changes.tr" value="" /> <!-- put the identicon and zxing classes in the war --> @@ -93,7 +100,7 @@ <not> <isset property="war.uptodate" /> </not> - <isset property="mtn.available" /> + <isset property="git.available" /> </and> </condition> </target> diff --git a/apps/imagegen/zxing/build.xml b/apps/imagegen/zxing/build.xml index 23c3d6e0af17b48bd663377c1e8d6336b6b4172a..128798b5c7d9871baa1974d39a00aee26919ba57 100644 --- a/apps/imagegen/zxing/build.xml +++ b/apps/imagegen/zxing/build.xml @@ -60,13 +60,20 @@ </target> <target name="listChangedFiles" depends="jarUpToDate" if="shouldListChanges" > - <exec executable="mtn" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > - <arg value="list" /> - <arg value="changed" /> + <exec executable="git" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="status" /> + <arg value="-s" /> + <arg value="--porcelain" /> + <arg value="-uno" /> <arg value="." /> </exec> + <!-- trim flags --> + <exec executable="sed" inputstring="${workspace.changes}" outputproperty="workspace.changes.sed" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="-e" /> + <arg value="s/^[MTADRCU ]*//" /> + </exec> <!-- \n in an attribute value generates an invalid manifest --> - <exec executable="tr" inputstring="${workspace.changes}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > + <exec executable="tr" inputstring="${workspace.changes.sed}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > <arg value="-s" /> <arg value="[:space:]" /> <arg value="," /> @@ -98,7 +105,7 @@ <not> <isset property="jar.uptodate" /> </not> - <isset property="mtn.available" /> + <isset property="git.available" /> </and> </condition> </target> diff --git a/apps/jetty/build.xml b/apps/jetty/build.xml index 4bb881f20c4bf7c538458df5cf8b939398b1b7ab..f8efc9641ebdc3449eadb8c6007cbb0f3c72af31 100644 --- a/apps/jetty/build.xml +++ b/apps/jetty/build.xml @@ -424,13 +424,20 @@ </target> <target name="listChangedFiles" depends="jarUpToDate" if="shouldListChanges" > - <exec executable="mtn" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > - <arg value="list" /> - <arg value="changed" /> + <exec executable="git" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="status" /> + <arg value="-s" /> + <arg value="--porcelain" /> + <arg value="-uno" /> <arg value="." /> </exec> + <!-- trim flags --> + <exec executable="sed" inputstring="${workspace.changes}" outputproperty="workspace.changes.sed" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="-e" /> + <arg value="s/^[MTADRCU ]*//" /> + </exec> <!-- \n in an attribute value generates an invalid manifest --> - <exec executable="tr" inputstring="${workspace.changes}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > + <exec executable="tr" inputstring="${workspace.changes.sed}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > <arg value="-s" /> <arg value="[:space:]" /> <arg value="," /> @@ -469,7 +476,7 @@ <not> <isset property="jar.uptodate" /> </not> - <isset property="mtn.available" /> + <isset property="git.available" /> </and> </condition> </target> diff --git a/apps/jrobin/java/build.xml b/apps/jrobin/java/build.xml index 528fc0dfd1b7920c86b85ad9534b784fa1cabbea..b949e769dd2be48539be95fa75675b7b9fab9b6e 100644 --- a/apps/jrobin/java/build.xml +++ b/apps/jrobin/java/build.xml @@ -41,13 +41,20 @@ </target> <target name="listChangedFiles" depends="jarUpToDate" if="shouldListChanges" > - <exec executable="mtn" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > - <arg value="list" /> - <arg value="changed" /> + <exec executable="git" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="status" /> + <arg value="-s" /> + <arg value="--porcelain" /> + <arg value="-uno" /> <arg value="." /> </exec> + <!-- trim flags --> + <exec executable="sed" inputstring="${workspace.changes}" outputproperty="workspace.changes.sed" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="-e" /> + <arg value="s/^[MTADRCU ]*//" /> + </exec> <!-- \n in an attribute value generates an invalid manifest --> - <exec executable="tr" inputstring="${workspace.changes}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > + <exec executable="tr" inputstring="${workspace.changes.sed}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > <arg value="-s" /> <arg value="[:space:]" /> <arg value="," /> @@ -79,7 +86,7 @@ <not> <isset property="jar.uptodate" /> </not> - <isset property="mtn.available" /> + <isset property="git.available" /> </and> </condition> </target> diff --git a/apps/ministreaming/java/build.xml b/apps/ministreaming/java/build.xml index c7224b3ba7f513343b4fdc2a6cd2a6efbfc9dd6a..72944b25ce05180b3999090ea193894160b0eb8b 100644 --- a/apps/ministreaming/java/build.xml +++ b/apps/ministreaming/java/build.xml @@ -64,13 +64,20 @@ </target> <target name="listChangedFiles" depends="jarUpToDate" if="shouldListChanges" > - <exec executable="mtn" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > - <arg value="list" /> - <arg value="changed" /> + <exec executable="git" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="status" /> + <arg value="-s" /> + <arg value="--porcelain" /> + <arg value="-uno" /> <arg value="." /> </exec> + <!-- trim flags --> + <exec executable="sed" inputstring="${workspace.changes}" outputproperty="workspace.changes.sed" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="-e" /> + <arg value="s/^[MTADRCU ]*//" /> + </exec> <!-- \n in an attribute value generates an invalid manifest --> - <exec executable="tr" inputstring="${workspace.changes}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > + <exec executable="tr" inputstring="${workspace.changes.sed}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > <arg value="-s" /> <arg value="[:space:]" /> <arg value="," /> @@ -108,7 +115,7 @@ <not> <isset property="jar.uptodate" /> </not> - <isset property="mtn.available" /> + <isset property="git.available" /> </and> </condition> </target> diff --git a/apps/routerconsole/java/build.xml b/apps/routerconsole/java/build.xml index 65cddc0728e3c73eb2cfd9d008d44bb27a9fc6be..2c3fe7b616c03df55ea815c039612cf519033cc4 100644 --- a/apps/routerconsole/java/build.xml +++ b/apps/routerconsole/java/build.xml @@ -117,14 +117,21 @@ <!-- the jar without the latest message classes from the jsps --> <target name="listChangedFiles" depends="jarUpToDate" if="shouldListChanges" > - <exec executable="mtn" outputproperty="workspace.changes.j" errorproperty="mtn.error2" failifexecutionfails="false" > - <arg value="list" /> - <arg value="changed" /> + <exec executable="git" outputproperty="workspace.changes.j" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="status" /> + <arg value="-s" /> + <arg value="--porcelain" /> + <arg value="-uno" /> <arg value="." /> <arg value="../locale" /> </exec> + <!-- trim flags --> + <exec executable="sed" inputstring="${workspace.changes.j}" outputproperty="workspace.changes.j.sed" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="-e" /> + <arg value="s/^[MTADRCU ]*//" /> + </exec> <!-- \n in an attribute value generates an invalid manifest --> - <exec executable="tr" inputstring="${workspace.changes.j}" outputproperty="workspace.changes.j.tr" errorproperty="mtn.error2" failifexecutionfails="false" > + <exec executable="tr" inputstring="${workspace.changes.j.sed}" outputproperty="workspace.changes.j.tr" errorproperty="mtn.error2" failifexecutionfails="false" > <arg value="-s" /> <arg value="[:space:]" /> <arg value="," /> @@ -211,7 +218,7 @@ <not> <isset property="jar.uptodate" /> </not> - <isset property="mtn.available" /> + <isset property="git.available" /> </and> </condition> </target> @@ -332,13 +339,23 @@ </target> <target name="listChangedFiles2" depends="warUpToDate" if="shouldListChanges2" > - <exec executable="mtn" outputproperty="workspace.changes.w" errorproperty="mtn.error2" failifexecutionfails="false" > - <arg value="list" /> - <arg value="changed" /> + <exec executable="git" outputproperty="workspace.changes.w" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="status" /> + <arg value="-s" /> + <arg value="--porcelain" /> + <arg value="-uno" /> <arg value="../jsp" /> + <arg value="../resources" /> + <arg value="src/net/i2p/router/web/helpers" /> + <arg value="src/net/i2p/router/web/servlets" /> + </exec> + <!-- trim flags --> + <exec executable="sed" inputstring="${workspace.changes.w}" outputproperty="workspace.changes.w.sed" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="-e" /> + <arg value="s/^[MTADRCU ]*//" /> </exec> <!-- \n in an attribute value generates an invalid manifest --> - <exec executable="tr" inputstring="${workspace.changes.w}" outputproperty="workspace.changes.w.tr" errorproperty="mtn.error2" failifexecutionfails="false" > + <exec executable="tr" inputstring="${workspace.changes.w.sed}" outputproperty="workspace.changes.w.tr" errorproperty="mtn.error2" failifexecutionfails="false" > <arg value="-s" /> <arg value="[:space:]" /> <arg value="," /> @@ -376,12 +393,12 @@ <srcfiles dir= "build/obj" includes="net/i2p/router/web/helpers/*.class net/i2p/router/web/servlets/*.class" /> <srcfiles dir= "../resources" /> </uptodate> - <condition property="shouldListChanges" > + <condition property="shouldListChanges2" > <and> <not> - <isset property="jar.uptodate" /> + <isset property="war.uptodate" /> </not> - <isset property="mtn.available" /> + <isset property="git.available" /> </and> </condition> </target> 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 39b8739975d85895ff705980fd8180c620e8f4fb..b910e4f019bc866d335994c5d7f79a0fd496e61a 100644 --- a/apps/routerconsole/java/src/net/i2p/router/update/ConsoleUpdateManager.java +++ b/apps/routerconsole/java/src/net/i2p/router/update/ConsoleUpdateManager.java @@ -1755,8 +1755,27 @@ public class ConsoleUpdateManager implements UpdateManager, RouterApp { @Override public String toString() { - return "VersionAvailable \"" + version + "\" " + sourceMap + - (constraint != null ? (" \"" + constraint + '"') : ""); + StringBuilder buf = new StringBuilder(128); + buf.append("Version ").append(version).append(' '); + for (Map.Entry<UpdateMethod, List<URI>> e : sourceMap.entrySet()) { + buf.append(e.getKey()); + List<URI> u = e.getValue(); + if (u.isEmpty()) { + buf.append(' '); + } else { + buf.append('='); + if (u.size() > 1) + buf.append('['); + for (URI uri : u) { + buf.append(uri).append(' '); + } + if (u.size() > 1) + buf.append(']'); + } + } + if (constraint != null) + buf.append(" \"").append(constraint).append('"'); + return buf.toString(); } } diff --git a/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java b/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java index 533b18fabff86e29f936baa65e16a46c6908830e..31261e3deb076c5df90e017e9cb03022e496e09b 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java @@ -40,6 +40,7 @@ import net.i2p.util.Addresses; import net.i2p.util.FileSuffixFilter; import net.i2p.util.FileUtil; import net.i2p.util.I2PAppThread; +import net.i2p.util.OrderedProperties; import net.i2p.util.PortMapper; import net.i2p.util.SecureDirectory; import net.i2p.util.I2PSSLSocketFactory; @@ -1125,7 +1126,7 @@ public class RouterConsoleRunner implements RouterApp { } public static Properties webAppProperties(String dir) { - Properties rv = new Properties(); + Properties rv = new OrderedProperties(); // String webappConfigFile = _context.getProperty(PROP_WEBAPP_CONFIG_FILENAME, DEFAULT_WEBAPP_CONFIG_FILENAME); String webappConfigFile = DEFAULT_WEBAPP_CONFIG_FILENAME; File cfgFile = new File(dir, webappConfigFile); diff --git a/apps/routerconsole/java/src/net/i2p/router/web/SummaryRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/SummaryRenderer.java index b26de88978dfb521e0341702e70b87c2ae437292..7e8b1f7a5aa10636e68974c6d8e65080674608ed 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/SummaryRenderer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/SummaryRenderer.java @@ -349,9 +349,14 @@ class SummaryRenderer { // NPE here if system is missing fonts - see ticket #915 graph = new RrdGraph(def); } catch (NullPointerException npe) { - _log.error("Error rendering", npe); + _log.error("Error rendering graph", npe); StatSummarizer.setDisabled(_context); - throw new IOException("Error rendering - disabling graph generation. Missing font? See http://trac.i2p2.i2p/ticket/915"); + throw new IOException("Error rendering - disabling graph generation. Missing font?"); + } catch (Error e) { + // Docker InternalError see Gitlab #383 + _log.error("Error rendering graph", e); + StatSummarizer.setDisabled(_context); + throw new IOException("Error rendering - disabling graph generation. Missing font?"); } int totalWidth = graph.getRrdGraphInfo().getWidth(); int totalHeight = graph.getRrdGraphInfo().getHeight(); diff --git a/apps/routerconsole/java/src/net/i2p/router/web/helpers/JobQueueHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/helpers/JobQueueHelper.java index b5a67fcac1c6cf426b2f78fb79581544d1340743..185fdba80be6c8e1ae41b4066051c42c3a4b2cf2 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/helpers/JobQueueHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/helpers/JobQueueHelper.java @@ -14,7 +14,7 @@ import net.i2p.data.DataHelper; import net.i2p.router.Job; import net.i2p.router.JobStats; import net.i2p.router.web.HelperBase; -import net.i2p.util.ObjectCounter; +import net.i2p.util.ObjectCounterUnsafe; public class JobQueueHelper extends HelperBase { @@ -79,7 +79,7 @@ public class JobQueueHelper extends HelperBase { buf.append("<h3 id=\"readyjobs\">") .append(_t("Ready/waiting jobs")).append(": ").append(readyJobs.size()) .append("</h3><ol>"); - ObjectCounter<String> counter = new ObjectCounter<String>(); + ObjectCounterUnsafe<String> counter = new ObjectCounterUnsafe<String>(); for (int i = 0; i < readyJobs.size(); i++) { Job j = readyJobs.get(i); counter.increment(j.getName()); @@ -129,7 +129,7 @@ public class JobQueueHelper extends HelperBase { } /** @since 0.9.5 */ - private void getJobCounts(StringBuilder buf, ObjectCounter<String> counter) { + private void getJobCounts(StringBuilder buf, ObjectCounterUnsafe<String> counter) { List<String> names = new ArrayList<String>(counter.objects()); if (names.size() < 4) return; @@ -232,10 +232,10 @@ public class JobQueueHelper extends HelperBase { /** @since 0.9.5 */ private static class JobCountComparator implements Comparator<String>, Serializable { - private final ObjectCounter<String> _counter; + private final ObjectCounterUnsafe<String> _counter; private final Collator coll = Collator.getInstance(); - public JobCountComparator(ObjectCounter<String> counter) { + public JobCountComparator(ObjectCounterUnsafe<String> counter) { _counter = counter; } diff --git a/apps/routerconsole/java/src/net/i2p/router/web/helpers/LogsHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/helpers/LogsHelper.java index c1aa060533ef50f270f524e4d745bfea12da9300..25021f61bc0960a0c1f555628b472b853557e25a 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/helpers/LogsHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/helpers/LogsHelper.java @@ -23,6 +23,9 @@ import net.i2p.util.UIMessages; public class LogsHelper extends HelperBase { + // cache so we only load once + Attributes att; + private static final String _jstlVersion = jstlVersion(); private static final int MAX_WRAPPER_LINES = 250; @@ -206,23 +209,46 @@ public class LogsHelper extends HelperBase { rv[2] = DataHelper.escapeHTML(f.getName()).replace(" ", "%20"); return rv; } - + /** * @since 0.9.35 */ public String getBuiltBy() { - File libDir = _context.getLibDir(); - File f = new File(libDir, "i2p.jar"); - Attributes att = FileDumpHelper.attributes(f); + return getAtt("Built-By"); + } + + /** + * @since 0.9.58 + */ + public String getBuildDate() { + return getAtt("Build-Date"); + } + + /** + * @since 0.9.58 + */ + public String getRevision() { + return getAtt("Base-Revision"); + } + + /** + * @since 0.9.58 pulled out from above + */ + private String getAtt(String a) { + if (att == null) { + File libDir = _context.getLibDir(); + File f = new File(libDir, "i2p.jar"); + att = FileDumpHelper.attributes(f); + } if (att != null) { - String s = FileDumpHelper.getAtt(att, "Built-By"); + String s = FileDumpHelper.getAtt(att, a); if (s != null) { return s; } } return "Undefined"; } - + private final static String NL = System.getProperty("line.separator"); /** formats in forward order */ diff --git a/apps/routerconsole/java/src/net/i2p/router/web/helpers/NetDbRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/helpers/NetDbRenderer.java index 11b2faf03ac394c0315add737f38d1c041f9efed..751c6af59a9558f54dac8d477a754bf817f9136c 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/helpers/NetDbRenderer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/helpers/NetDbRenderer.java @@ -52,7 +52,7 @@ import net.i2p.router.web.WebAppStarter; import net.i2p.util.Addresses; import net.i2p.util.ConvertToHash; import net.i2p.util.Log; -import net.i2p.util.ObjectCounter; +import net.i2p.util.ObjectCounterUnsafe; import net.i2p.util.Translate; import net.i2p.util.VersionComparator; @@ -935,8 +935,8 @@ class NetDbRenderer { buf.setLength(0); } - ObjectCounter<String> versions = new ObjectCounter<String>(); - ObjectCounter<String> countries = new ObjectCounter<String>(); + ObjectCounterUnsafe<String> versions = new ObjectCounterUnsafe<String>(); + ObjectCounterUnsafe<String> countries = new ObjectCounterUnsafe<String>(); int[] transportCount = new int[TNAMES.length]; int skipped = 0; @@ -1137,10 +1137,10 @@ class NetDbRenderer { */ private class CountryCountComparator implements Comparator<String> { private static final long serialVersionUID = 1L; - private final ObjectCounter<String> counts; + private final ObjectCounterUnsafe<String> counts; private final Collator coll; - public CountryCountComparator(ObjectCounter<String> counts) { + public CountryCountComparator(ObjectCounterUnsafe<String> counts) { super(); this.counts = counts; coll = Collator.getInstance(new Locale(Messages.getLanguage(_context))); diff --git a/apps/routerconsole/java/src/net/i2p/router/web/helpers/SummaryHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/helpers/SummaryHelper.java index 689ea3d5342ff46c3d6c8c516ae74577e219c292..98eacce491db1db91ef327746d4ea7297c0ac8f5 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/helpers/SummaryHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/helpers/SummaryHelper.java @@ -237,7 +237,7 @@ public class SummaryHelper extends HelperBase { long skew = _context.commSystem().getFramedAveragePeerClockSkew(33); // Display the actual skew, not the offset if (Math.abs(skew) > 30*1000) - return new NetworkStateMessage(NetworkState.CLOCKSKEW, _t("ERR-Clock Skew of {0}", DataHelper.formatDuration2(Math.abs(skew)))); + return new NetworkStateMessage(NetworkState.CLOCKSKEW, fixup(_t("ERR-Clock Skew of {0}", DataHelper.formatDuration2(Math.abs(skew))))); if (_context.router().isHidden()) return new NetworkStateMessage(NetworkState.HIDDEN, _t("Hidden")); RouterInfo routerInfo = _context.router().getRouterInfo(); @@ -272,22 +272,22 @@ public class SummaryHelper extends HelperBase { // TODO set IPv6 arg based on configuration? if (TransportUtil.isPubliclyRoutable(ip, true)) return new NetworkStateMessage(NetworkState.RUNNING, txstatus); - return new NetworkStateMessage(NetworkState.ERROR, _t("ERR-Private TCP Address")); + return new NetworkStateMessage(NetworkState.ERROR, fixup(_t("ERR-Private TCP Address"))); case IPV4_SNAT_IPV6_UNKNOWN: case DIFFERENT: - return new NetworkStateMessage(NetworkState.ERROR, _t("ERR-SymmetricNAT")); + return new NetworkStateMessage(NetworkState.ERROR, fixup(_t("ERR-SymmetricNAT"))); case REJECT_UNSOLICITED: state = NetworkState.FIREWALLED; case IPV4_DISABLED_IPV6_FIREWALLED: if (routerInfo.getTargetAddress("NTCP") != null) - return new NetworkStateMessage(NetworkState.WARN, _t("WARN-Firewalled with Inbound TCP Enabled")); + return new NetworkStateMessage(NetworkState.WARN, fixup(_t("WARN-Firewalled with Inbound TCP Enabled"))); // fall through... case IPV4_FIREWALLED_IPV6_OK: case IPV4_FIREWALLED_IPV6_UNKNOWN: if (((FloodfillNetworkDatabaseFacade)_context.netDb()).floodfillEnabled()) - return new NetworkStateMessage(NetworkState.WARN, _t("WARN-Firewalled and Floodfill")); + return new NetworkStateMessage(NetworkState.WARN, fixup(_t("WARN-Firewalled and Floodfill"))); //if (_context.router().getRouterInfo().getCapabilities().indexOf('O') >= 0) // return new NetworkStateMessage(NetworkState.WARN, _t("WARN-Firewalled and Fast")); return new NetworkStateMessage(state, txstatus); @@ -296,7 +296,7 @@ public class SummaryHelper extends HelperBase { return new NetworkStateMessage(NetworkState.TESTING, _t("Disconnected - check network connection")); case HOSED: - return new NetworkStateMessage(NetworkState.ERROR, _t("ERR-UDP Port In Use - Set i2np.udp.internalPort=xxxx in advanced config and restart")); + return new NetworkStateMessage(NetworkState.ERROR, fixup(_t("ERR-UDP Port In Use - Set i2np.udp.internalPort=xxxx in advanced config and restart"))); case UNKNOWN: state = NetworkState.TESTING; @@ -306,17 +306,39 @@ public class SummaryHelper extends HelperBase { List<RouterAddress> ra = routerInfo.getTargetAddresses("SSU", "SSU2"); if (ra.isEmpty() && _context.router().getUptime() > 5*60*1000) { if (getActivePeers() <= 0) - return new NetworkStateMessage(NetworkState.ERROR, _t("ERR-No Active Peers, Check Network Connection and Firewall")); + return new NetworkStateMessage(NetworkState.ERROR, fixup(_t("ERR-No Active Peers, Check Network Connection and Firewall"))); else if (_context.getProperty(ConfigNetHelper.PROP_I2NP_NTCP_HOSTNAME) == null || _context.getProperty(ConfigNetHelper.PROP_I2NP_NTCP_PORT) == null) - return new NetworkStateMessage(NetworkState.ERROR, _t("ERR-UDP Disabled and Inbound TCP host/port not set")); + return new NetworkStateMessage(NetworkState.ERROR, fixup(_t("ERR-UDP Disabled and Inbound TCP host/port not set"))); else - return new NetworkStateMessage(NetworkState.WARN, _t("WARN-Firewalled with UDP Disabled")); + return new NetworkStateMessage(NetworkState.WARN, fixup(_t("WARN-Firewalled with UDP Disabled"))); } return new NetworkStateMessage(state, txstatus); } } + /** + * Make the already-translated ERR- and WARN- strings a little prettier + * @since 0.9.58 + */ + private static String fixup(String s) { + if (s.startsWith("ERR-")) { + s = s.substring(4); + } else if (s.startsWith("ERR -")) { + s = s.substring(5); + } else if (s.startsWith("WARN-")) { + s = s.substring(5); + } else if (s.startsWith("WARN -")) { + s = s.substring(6); + } else { + // translated + int d = s.indexOf('-'); + if (d > 0 && d < 10) + s = s.substring(d + 1); + } + return s; + } + /** * Retrieve amount of used memory. * @since 0.9.32 uncommented diff --git a/apps/routerconsole/java/src/net/i2p/router/web/helpers/SybilRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/helpers/SybilRenderer.java index d48a415f9d853148573ab815cbf3479cb02fe1ae..3461d95e82dedce30c988e2c4dad2aecc7f12087 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/helpers/SybilRenderer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/helpers/SybilRenderer.java @@ -46,7 +46,6 @@ import net.i2p.stat.RateAverages; import net.i2p.stat.RateStat; import net.i2p.util.ConvertToHash; import net.i2p.util.Log; -import net.i2p.util.ObjectCounter; import net.i2p.util.SystemVersion; import net.i2p.util.Translate; import net.i2p.util.VersionComparator; diff --git a/apps/routerconsole/java/src/net/i2p/router/web/helpers/TunnelRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/helpers/TunnelRenderer.java index 8c59725dabe35488a3e997945550ab39ba675cba..e69d33c30f7dd30a268afd6a6276307e5bb7c96d 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/helpers/TunnelRenderer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/helpers/TunnelRenderer.java @@ -26,6 +26,7 @@ import net.i2p.router.web.HelperBase; import net.i2p.router.web.Messages; import net.i2p.stat.Rate; import net.i2p.stat.RateStat; +import net.i2p.util.ObjectCounterUnsafe; /** * For /tunnels.jsp, used by TunnelHelper. @@ -138,8 +139,9 @@ class TunnelRenderer { recv + "</span></td>"); else out.write("<td class=\"cells\" align=\"center\">n/a</td>"); - if (cfg.getReceiveFrom() != null) - out.write("<td class=\"cells\" align=\"center\"><span class=\"tunnel_peer\">" + netDbLink(cfg.getReceiveFrom()) +"</span></td>"); + Hash from = cfg.getReceiveFrom(); + if (from != null) + out.write("<td class=\"cells\" align=\"center\"><span class=\"tunnel_peer\">" + netDbLink(from) +"</span></td>"); else out.write("<td class=\"cells\"> </td>"); long send = cfg.getSendTunnelId(); @@ -147,8 +149,9 @@ class TunnelRenderer { out.write("<td class=\"cells\" align=\"center\" title=\"" + _t("Tunnel identity") + "\"><span class=\"tunnel_id\">" + send +"</span></td>"); else out.write("<td class=\"cells\"> </td>"); - if (cfg.getSendTo() != null) - out.write("<td class=\"cells\" align=\"center\"><span class=\"tunnel_peer\">" + netDbLink(cfg.getSendTo()) +"</span></td>"); + Hash to = cfg.getSendTo(); + if (to != null) + out.write("<td class=\"cells\" align=\"center\"><span class=\"tunnel_peer\">" + netDbLink(to) +"</span></td>"); else out.write("<td class=\"cells\"> </td>"); long timeLeft = cfg.getExpiration() - now; @@ -164,9 +167,9 @@ class TunnelRenderer { lifetime = 10*60; long bps = 1024L * count / lifetime; out.write("<td class=\"cells\" align=\"center\">" + DataHelper.formatSize2Decimal(bps) + "Bps</td>"); - if (cfg.getSendTo() == null) + if (to == null) out.write("<td class=\"cells\" align=\"center\">" + _t("Outbound Endpoint") + "</td>"); - else if (cfg.getReceiveFrom() == null) + else if (from == null) out.write("<td class=\"cells\" align=\"center\">" + _t("Inbound Gateway") + "</td>"); else out.write("<td class=\"cells\" align=\"center\">" + _t("Participant") + "</td>"); @@ -181,6 +184,49 @@ class TunnelRenderer { else if (displayed <= 0) out.write("<div class=\"statusnotes\"><b>" + _t("none") + "</b></div>\n"); out.write("<div class=\"statusnotes\"><b>" + _t("Lifetime bandwidth usage") + ": " + DataHelper.formatSize2(processed*1024) + "B</b></div>\n"); + + if (debug && participating.size() > 1) { + // peer table sorted by number of tunnels + ObjectCounterUnsafe<Hash> counts = new ObjectCounterUnsafe<Hash>(); + ObjectCounterUnsafe<Hash> bws = new ObjectCounterUnsafe<Hash>(); + for (int i = 0; i < participating.size(); i++) { + HopConfig cfg = participating.get(i); + Hash from = cfg.getReceiveFrom(); + Hash to = cfg.getSendTo(); + int msgs = cfg.getProcessedMessagesCount(); + if (from != null) { + counts.increment(from); + if (msgs > 0) + bws.add(from, msgs); + } + if (to != null) { + counts.increment(to); + if (msgs > 0) + bws.add(to, msgs); + } + } + // sort and output + out.write("<h3 class=\"tabletitle\">Peers in multiple participating tunnels (including inactive)</h3>\n"); + out.write("<table class=\"tunneldisplay tunnels_participating\"><tr><th>" + _t("Router") + "</th><th>" + _t("Tunnels") + "</th><th>" + + _t("Usage") + "</th></tr>\n"); + displayed = 0; + List<Hash> sort = counts.sortedObjects(); + for (Hash h : sort) { + int count = counts.count(h); + if (count <= 1) + break; + if (++displayed > DISPLAY_LIMIT) + break; + out.write("<tr><td class=\"cells\" align=\"center\"><span class=\"tunnel_peer\">" + netDbLink(h) + "</span></td>\n"); + out.write("<td class=\"cells\" align=\"center\">" + count + "</td>\n"); + out.write("<td class=\"cells\" align=\"center\">" + DataHelper.formatSize2(bws.count(h) * 1024) + "B</td></tr>\n"); + } + out.write("</table>\n"); + if (displayed <= 0) + out.write("<div class=\"statusnotes\"><b>" + _t("none") + "</b></div>\n"); + } + + } else { // bwShare > 12 out.write("<div class=\"statusnotes noparticipate\"><b>" + _t("Not enough shared bandwidth to build participating tunnels.") + "</b> <a href=\"config\">[" + _t("Configure") + "]</a></div>\n"); diff --git a/apps/routerconsole/jsp/debug.jsp b/apps/routerconsole/jsp/debug.jsp index c71739a2bb447d02dfbcd81d370834b7e9a06a35..b621ae6972ffd554ed22ff299eeac0a9df009524 100644 --- a/apps/routerconsole/jsp/debug.jsp +++ b/apps/routerconsole/jsp/debug.jsp @@ -16,12 +16,12 @@ <div class="main" id="debug"> <div class="confignav"> -<span class="tab"><a href="#debug_portmapper">Port Mapper</a></span> -<span class="tab"><a href="#appmanager">App Manager</a></span> -<span class="tab"><a href="#updatemanager">Update Manager</a></span> -<span class="tab"><a href="#skm">Router Session Key Manager</a></span> -<span class="tab"><a href="#cskm0">Client Session Key Managers</a></span> -<span class="tab"><a href="#dht">Router DHT</a></span> +<span class="tab"><a href="/debug">Port Mapper</a></span> +<span class="tab"><a href="/debug?d=1">App Manager</a></span> +<span class="tab"><a href="/debug?d=2">Update Manager</a></span> +<span class="tab"><a href="/debug?d=3">Router Session Key Manager</a></span> +<span class="tab"><a href="/debug?d=4">Client Session Key Managers</a></span> +<span class="tab"><a href="/debug?d=5">Router DHT</a></span> </div> <% @@ -30,6 +30,9 @@ */ net.i2p.router.RouterContext ctx = (net.i2p.router.RouterContext) net.i2p.I2PAppContext.getGlobalContext(); +String dd = request.getParameter("d"); +if (dd == null || dd.equals("0")) { + /* * Print out the status for the PortMapper */ @@ -40,6 +43,8 @@ */ net.i2p.util.InternalServerSocket.renderStatusHTML(out); +} else if (dd.equals("1")) { + /* * Print out the status for the AppManager */ @@ -48,6 +53,7 @@ ctx.routerAppManager().renderStatusHTML(out); out.print("</div>"); +} else if (dd.equals("2")) { /* * Print out the status for the UpdateManager @@ -63,14 +69,20 @@ out.print("</div>"); } +} else if (dd.equals("3")) { + /* * Print out the status for all the SessionKeyManagers */ out.print("<div class=\"debug_section\" id=\"skm\">"); out.print("<h2>Router Session Key Manager</h2>"); ctx.sessionKeyManager().renderStatusHTML(out); - java.util.Set<net.i2p.data.Destination> clients = ctx.clientManager().listClients(); out.print("</div>"); + +} else if (dd.equals("4")) { + + out.print("<h2>Client Session Key Managers</h2>"); + java.util.Set<net.i2p.data.Destination> clients = ctx.clientManager().listClients(); int i = 0; for (net.i2p.data.Destination dest : clients) { net.i2p.data.Hash h = dest.calculateHash(); @@ -92,6 +104,7 @@ out.print("</div>"); } } +} else if (dd.equals("5")) { /* * Print out the status for the NetDB @@ -99,5 +112,7 @@ out.print("<h2 id=\"dht\">Router DHT</h2>"); ctx.netDb().renderStatusHTML(out); +} + %> </div></body></html> diff --git a/apps/routerconsole/jsp/logs.jsp b/apps/routerconsole/jsp/logs.jsp index 781e2f51af7a82a3cfd0efe04141736bff1aa590..36b82fce34e10dbbc28380fadf83cb4bc0920983 100644 --- a/apps/routerconsole/jsp/logs.jsp +++ b/apps/routerconsole/jsp/logs.jsp @@ -54,7 +54,14 @@ %><tr><td><b>Encoding:</b></td><td><%=System.getProperty("file.encoding")%></td></tr> <tr><td><b>Charset:</b></td><td><%=java.nio.charset.Charset.defaultCharset().name()%></td></tr> <tr><td><b>Service:</b></td><td><%=net.i2p.util.SystemVersion.isService()%></td></tr> -<tr><td><b>Built By:</b></td><td><jsp:getProperty name="logsHelper" property="builtBy" /></tbody></table> +<% + String rev = logsHelper.getRevision(); + if (rev.length() == 40) { +%><tr><td><b>Revision:</b></td><td><%=rev%></td></tr> +<% + } +%><tr><td><b>Built:</b></td><td><jsp:getProperty name="logsHelper" property="buildDate" /></td></tr> +<tr><td><b>Built By:</b></td><td><jsp:getProperty name="logsHelper" property="builtBy" /></td></tr></tbody></table> <h3 class="tabletitle"><%=intl._t("Critical Logs")%><% String consoleNonce = net.i2p.router.web.CSSHelper.getNonce(); diff --git a/apps/routerconsole/jsp/summary.jsi b/apps/routerconsole/jsp/summary.jsi index 12fdebeb5e51af7ae8e3971edc648633e72bf28a..8cbfab8863eb7646111214579ed603345bf62cdf 100644 --- a/apps/routerconsole/jsp/summary.jsi +++ b/apps/routerconsole/jsp/summary.jsi @@ -28,8 +28,10 @@ // update disable boolean intl.setDisableRefresh(d); } +/* if (false && !intl.getDisableRefresh()) out.print("<noscript><iframe src=\"/summaryframe.jsp" + newDelay + "\" height=\"1500\" width=\"200\" scrolling=\"auto\" frameborder=\"0\" title=\"sidepanel\"></noscript>\n"); +*/ } %> <div class="routersummary"> @@ -46,6 +48,7 @@ out.print("</a>"); } +/* // d and allowIFrame defined above if (false && !intl.getDisableRefresh()) { out.print("</div><noscript></iframe></noscript>\n"); @@ -63,7 +66,10 @@ out.print("</button>\n" + "</form></div></noscript></div>\n"); } else { +*/ out.print("</div>\n"); +/* } +*/ %> </div> diff --git a/apps/routerconsole/jsp/themes/console/light/console.css b/apps/routerconsole/jsp/themes/console/light/console.css index 4ffd64d0b14b68f8d00295093de8e12150d52d9b..298ddf755e54594e2580483848964f8b75f1116e 100644 --- a/apps/routerconsole/jsp/themes/console/light/console.css +++ b/apps/routerconsole/jsp/themes/console/light/console.css @@ -7563,7 +7563,6 @@ b.netdb_transport { word-break: break-all; margin-bottom: 5px; padding-bottom: 0; - max-height: 600px; overflow: auto; } diff --git a/apps/sam/java/build.xml b/apps/sam/java/build.xml index 02359f492f2266f4c7be86e1ba02e5e48a90520a..89233a415f1e62f3998a99220bd318627d7889f1 100644 --- a/apps/sam/java/build.xml +++ b/apps/sam/java/build.xml @@ -58,13 +58,20 @@ </target> <target name="listChangedFiles" depends="jarUpToDate" if="shouldListChanges" > - <exec executable="mtn" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > - <arg value="list" /> - <arg value="changed" /> + <exec executable="git" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="status" /> + <arg value="-s" /> + <arg value="--porcelain" /> + <arg value="-uno" /> <arg value="." /> </exec> + <!-- trim flags --> + <exec executable="sed" inputstring="${workspace.changes}" outputproperty="workspace.changes.sed" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="-e" /> + <arg value="s/^[MTADRCU ]*//" /> + </exec> <!-- \n in an attribute value generates an invalid manifest --> - <exec executable="tr" inputstring="${workspace.changes}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > + <exec executable="tr" inputstring="${workspace.changes.sed}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > <arg value="-s" /> <arg value="[:space:]" /> <arg value="," /> @@ -115,7 +122,7 @@ <not> <isset property="jar.uptodate" /> </not> - <isset property="mtn.available" /> + <isset property="git.available" /> </and> </condition> </target> diff --git a/apps/streaming/java/build.xml b/apps/streaming/java/build.xml index 914867ae93f82c59f6d6325198dac548c7b8bbaf..ecfa0ebfd06b1fa758f8cbd1b676271a4c3a882f 100644 --- a/apps/streaming/java/build.xml +++ b/apps/streaming/java/build.xml @@ -191,13 +191,20 @@ <!-- end unit tests --> <target name="listChangedFiles" depends="jarUpToDate" if="shouldListChanges" > - <exec executable="mtn" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > - <arg value="list" /> - <arg value="changed" /> + <exec executable="git" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="status" /> + <arg value="-s" /> + <arg value="--porcelain" /> + <arg value="-uno" /> <arg value="." /> </exec> + <!-- trim flags --> + <exec executable="sed" inputstring="${workspace.changes}" outputproperty="workspace.changes.sed" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="-e" /> + <arg value="s/^[MTADRCU ]*//" /> + </exec> <!-- \n in an attribute value generates an invalid manifest --> - <exec executable="tr" inputstring="${workspace.changes}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > + <exec executable="tr" inputstring="${workspace.changes.sed}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > <arg value="-s" /> <arg value="[:space:]" /> <arg value="," /> @@ -234,7 +241,7 @@ <not> <isset property="jar.uptodate" /> </not> - <isset property="mtn.available" /> + <isset property="git.available" /> </and> </condition> </target> diff --git a/apps/susidns/src/build.xml b/apps/susidns/src/build.xml index 6ddce6822fb8556b66ecd7efb33b90b7ac9dda62..eb603048af3fa4c9d3bd10b892465d0ea4d14698 100644 --- a/apps/susidns/src/build.xml +++ b/apps/susidns/src/build.xml @@ -150,20 +150,27 @@ <target name="all" depends="war"/> <target name="listChangedFiles" depends="warUpToDate" if="shouldListChanges" > - <exec executable="mtn" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > - <arg value="list" /> - <arg value="changed" /> + <exec executable="git" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="status" /> + <arg value="-s" /> + <arg value="--porcelain" /> + <arg value="-uno" /> <arg value="." /> </exec> + <!-- trim flags --> + <exec executable="sed" inputstring="${workspace.changes}" outputproperty="workspace.changes.sed" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="-e" /> + <arg value="s/^[MTADRCU ]*//" /> + </exec> <!-- \n in an attribute value generates an invalid manifest --> - <exec executable="tr" inputstring="${workspace.changes}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > + <exec executable="tr" inputstring="${workspace.changes.sed}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > <arg value="-s" /> <arg value="[:space:]" /> <arg value="," /> </exec> </target> - <target name="war" depends="compile, precompilejsp, bundle, warUpToDate" unless="war.uptodate" > + <target name="war" depends="compile, precompilejsp, bundle, warUpToDate, listChangedFiles" unless="war.uptodate" > <!-- set if unset --> <property name="workspace.changes.tr" value="" /> <war destfile="${project}.war" webxml="WEB-INF/web-out.xml"> @@ -187,14 +194,14 @@ <target name="warUpToDate"> <uptodate property="war.uptodate" targetfile="${project}.war"> - <srcfiles dir= "." includes="WEB-INF/web-out.xml WEB-INF/**/*.class js/* svg/*" /> + <srcfiles dir= "." includes="WEB-INF/web-out.xml WEB-INF/**/*.class js/* svg/* themes/**/*" /> </uptodate> <condition property="shouldListChanges" > <and> <not> <isset property="war.uptodate" /> </not> - <isset property="mtn.available" /> + <isset property="git.available" /> </and> </condition> </target> diff --git a/apps/susimail/build.xml b/apps/susimail/build.xml index d248a426c7f1aaf8ee16d000b8bfe7232fd10f58..e88fb3f2757f08453c880ea70354243171e83a9e 100644 --- a/apps/susimail/build.xml +++ b/apps/susimail/build.xml @@ -78,13 +78,20 @@ </target> <target name="listChangedFiles" depends="warUpToDate" if="shouldListChanges" > - <exec executable="mtn" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > - <arg value="list" /> - <arg value="changed" /> + <exec executable="git" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="status" /> + <arg value="-s" /> + <arg value="--porcelain" /> + <arg value="-uno" /> <arg value="." /> </exec> + <!-- trim flags --> + <exec executable="sed" inputstring="${workspace.changes}" outputproperty="workspace.changes.sed" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="-e" /> + <arg value="s/^[MTADRCU ]*//" /> + </exec> <!-- \n in an attribute value generates an invalid manifest --> - <exec executable="tr" inputstring="${workspace.changes}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > + <exec executable="tr" inputstring="${workspace.changes.sed}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > <arg value="-s" /> <arg value="[:space:]" /> <arg value="," /> @@ -118,7 +125,7 @@ <not> <isset property="war.uptodate" /> </not> - <isset property="mtn.available" /> + <isset property="git.available" /> </and> </condition> </target> diff --git a/apps/systray/java/build.xml b/apps/systray/java/build.xml index 5897ef41b65f9f0b1936d2761b591008b343cafc..3f55ce618d5c229b045c61f1f3a39c24af24f883 100644 --- a/apps/systray/java/build.xml +++ b/apps/systray/java/build.xml @@ -46,13 +46,20 @@ </target> <target name="listChangedFiles" depends="jarUpToDate" if="shouldListChanges" > - <exec executable="mtn" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > - <arg value="list" /> - <arg value="changed" /> + <exec executable="git" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="status" /> + <arg value="-s" /> + <arg value="--porcelain" /> + <arg value="-uno" /> <arg value="." /> </exec> + <!-- trim flags --> + <exec executable="sed" inputstring="${workspace.changes}" outputproperty="workspace.changes.sed" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="-e" /> + <arg value="s/^[MTADRCU ]*//" /> + </exec> <!-- \n in an attribute value generates an invalid manifest --> - <exec executable="tr" inputstring="${workspace.changes}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > + <exec executable="tr" inputstring="${workspace.changes.sed}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > <arg value="-s" /> <arg value="[:space:]" /> <arg value="," /> @@ -85,7 +92,7 @@ <not> <isset property="jar.uptodate" /> </not> - <isset property="mtn.available" /> + <isset property="git.available" /> </and> </condition> </target> diff --git a/core/java/build.xml b/core/java/build.xml index 351eb7642c25cd4695216a4bb10bd09404c1d6d2..8b36ce5f0bb201f3c67e8c04aa106fa8dcafc65b 100644 --- a/core/java/build.xml +++ b/core/java/build.xml @@ -81,14 +81,22 @@ </javac> </target> - <target name="listChangedFiles" if="mtn.available" > - <exec executable="mtn" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > - <arg value="list" /> - <arg value="changed" /> + <target name="listChangedFiles" if="git.available" > + <exec executable="git" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="status" /> + <arg value="-s" /> + <arg value="--porcelain" /> + <arg value="-uno" /> <arg value="." /> + <arg value="../resources" /> + </exec> + <!-- trim flags --> + <exec executable="sed" inputstring="${workspace.changes}" outputproperty="workspace.changes.sed" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="-e" /> + <arg value="s/^[MTADRCU ]*//" /> </exec> <!-- \n in an attribute value generates an invalid manifest --> - <exec executable="tr" inputstring="${workspace.changes}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > + <exec executable="tr" inputstring="${workspace.changes.sed}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > <arg value="-s" /> <arg value="[:space:]" /> <arg value="," /> diff --git a/core/java/src/net/i2p/util/ObjectCounterUnsafe.java b/core/java/src/net/i2p/util/ObjectCounterUnsafe.java new file mode 100644 index 0000000000000000000000000000000000000000..3e2f532cdb00306b875ccd704456fbb52571550e --- /dev/null +++ b/core/java/src/net/i2p/util/ObjectCounterUnsafe.java @@ -0,0 +1,107 @@ +package net.i2p.util; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Count things. + * NOT thread safe, mostly for UI and Sybil. + * Dropin replacement for ObjectCounter. + * Much less object churn than ObjectCounter. + * Also provides add() and sortedObjects() + * + * @since 0.9.58 + */ +public class ObjectCounterUnsafe<K> { + private final HashMap<K, Int> map = new HashMap<K, Int>(); + + /** + * Add one. + * @return count after increment + */ + public int increment(K h) { + Int i = map.get(h); + if (i != null) { + return ++(i.c); + } + map.put(h, new Int(1)); + return 1; + } + + /** + * Add a value + * @return count after adding + */ + public int add(K h, int val) { + Int i = map.get(h); + if (i != null) { + i.c += val; + return i.c; + } + map.put(h, new Int(val)); + return val; + } + + /** + * @return current count + */ + public int count(K h) { + Int i = map.get(h); + if (i != null) + return i.c; + return 0; + } + + /** + * @return set of objects with counts > 0 + */ + public Set<K> objects() { + return map.keySet(); + } + + /** + * @return list of objects reverse sorted by count, highest to lowest + */ + public List<K> sortedObjects() { + List<K> rv = new ArrayList<K>(map.keySet()); + Collections.sort(rv, new ObjComparator()); + return rv; + } + + /** + * Start over. Reset the count for all keys to zero. + */ + public void clear() { + map.clear(); + } + + /** + * Reset the count for this key to zero + */ + public void clear(K h) { + map.remove(h); + } + + /** + * Modifiable integer + */ + private static class Int { + int c; + public Int(int i) { c = i; } + } + + /** + * reverse sort + */ + private class ObjComparator implements Comparator<K> { + public int compare(K l, K r) { + return (map.get(r).c - map.get(l).c); + } + } +} + diff --git a/history.txt b/history.txt index a8da92a3c9318bd2f0f9e0efa323d16a9da2cc79..38dbf09088438b5fa206ce482202dd11a0536c4f 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,24 @@ +2023-01-22 zzz + * Build: Fix list of changed files in manifests + * i2psnark: Add max files per torrent config + +2023-01-21 zzz + * Console: + - Remove ERR- and WARN- prefixes from status strings + - Catch graph error in Docker (Gitlab #383) + * i2psnark: Search box CSS + * NTCP: Do not rebind internal port if only SSU external port changed + * SSU: + - Eliminate Symmetric NAT errors for "full cone" NATs + - Fix rare peer test NPE + - Fix initial SSU2 MTU when SSU1 disabled + +2023-01-19 zzz + * Build: Add i2psnark-release target + +2023-01-18 zzz + * i2psnark: Search CSS and JS + 2023-01-17 zzz * i2psnark: - Add basic search box diff --git a/installer/java/build.xml b/installer/java/build.xml index 8a34405f308be7fe75662971aa4f7427f3637cf6..d3926a0f8992ab5af4770e2093de552a14615cc7 100644 --- a/installer/java/build.xml +++ b/installer/java/build.xml @@ -34,14 +34,21 @@ </javac> </target> - <target name="listChangedFiles" if="mtn.available" > - <exec executable="mtn" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > - <arg value="list" /> - <arg value="changed" /> + <target name="listChangedFiles" if="git.available" > + <exec executable="git" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="status" /> + <arg value="-s" /> + <arg value="--porcelain" /> + <arg value="-uno" /> <arg value="." /> </exec> + <!-- trim flags --> + <exec executable="sed" inputstring="${workspace.changes}" outputproperty="workspace.changes.sed" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="-e" /> + <arg value="s/^[MTADRCU ]*//" /> + </exec> <!-- \n in an attribute value generates an invalid manifest --> - <exec executable="tr" inputstring="${workspace.changes}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > + <exec executable="tr" inputstring="${workspace.changes.sed}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > <arg value="-s" /> <arg value="[:space:]" /> <arg value="," /> diff --git a/router/java/build.xml b/router/java/build.xml index 344960976615be7d9f194679155f3e645201921b..4b0cedf2bcf626ad41de03d38141952349cc2248 100644 --- a/router/java/build.xml +++ b/router/java/build.xml @@ -53,14 +53,22 @@ </javac> </target> - <target name="listChangedFiles" if="mtn.available" > - <exec executable="mtn" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > - <arg value="list" /> - <arg value="changed" /> + <target name="listChangedFiles" if="git.available" > + <exec executable="git" outputproperty="workspace.changes" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="status" /> + <arg value="-s" /> + <arg value="--porcelain" /> + <arg value="-uno" /> <arg value="." /> + <arg value="../resources" /> + </exec> + <!-- trim flags --> + <exec executable="sed" inputstring="${workspace.changes}" outputproperty="workspace.changes.sed" errorproperty="mtn.error2" failifexecutionfails="false" > + <arg value="-e" /> + <arg value="s/^[MTADRCU ]*//" /> </exec> <!-- \n in an attribute value generates an invalid manifest --> - <exec executable="tr" inputstring="${workspace.changes}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > + <exec executable="tr" inputstring="${workspace.changes.sed}" outputproperty="workspace.changes.tr" errorproperty="mtn.error2" failifexecutionfails="false" > <arg value="-s" /> <arg value="[:space:]" /> <arg value="," /> diff --git a/router/java/src/net/i2p/router/CommandLine.java b/router/java/src/net/i2p/router/CommandLine.java index 65c789e4123f7b451f31ab167d23b060d756bf9c..0d955338edfa67ef2c8b29fbec100512a79733ff 100644 --- a/router/java/src/net/i2p/router/CommandLine.java +++ b/router/java/src/net/i2p/router/CommandLine.java @@ -23,6 +23,7 @@ public class CommandLine extends net.i2p.util.CommandLine { "net.i2p.router.RouterVersion", "net.i2p.router.crypto.FamilyKeyCrypto", "net.i2p.router.naming.BlockfileNamingService", + "net.i2p.router.networkdb.reseed.Reseeder", "net.i2p.router.peermanager.ProfileOrganizer", "net.i2p.router.tasks.CryptoChecker", "net.i2p.router.time.NtpClient", diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java index 03c0ae981e5cf057e5ae1a677a3cf6a46e197a51..1de70e3bf38981f520395c4854781fe9445f166c 100644 --- a/router/java/src/net/i2p/router/Router.java +++ b/router/java/src/net/i2p/router/Router.java @@ -142,6 +142,8 @@ public class Router implements RouterClock.ClockShiftListener { private static final String PROP_JBIGI = "jbigi.loadedResource"; private static final String PROP_JBIGI_PROCESSOR = "jbigi.lastProcessor"; public static final String UPDATE_FILE = "i2pupdate.zip"; + //// remove after release //// + private static final boolean CONGESTION_CAPS = net.i2p.CoreVersion.PUBLISHED_VERSION.equals("0.9.58"); private static final int SHUTDOWN_WAIT_SECS = 60; @@ -1096,6 +1098,14 @@ public class Router implements RouterClock.ClockShiftListener { public static final char CAPABILITY_REACHABLE = 'R'; public static final char CAPABILITY_UNREACHABLE = 'U'; + + /** @since 0.9.58, proposal 162 */ + public static final char CAPABILITY_CONGESTION_MODERATE = 'D'; + /** @since 0.9.58, proposal 162 */ + public static final char CAPABILITY_CONGESTION_SEVERE = 'E'; + /** @since 0.9.58, proposal 162 */ + public static final char CAPABILITY_NO_TUNNELS = 'G'; + /** for testing */ public static final String PROP_FORCE_UNREACHABLE = "router.forceUnreachable"; @@ -1184,6 +1194,8 @@ public class Router implements RouterClock.ClockShiftListener { if (hidden || _context.getBooleanProperty(PROP_FORCE_UNREACHABLE)) { rv.append(CAPABILITY_UNREACHABLE); + if (CONGESTION_CAPS) + rv.append(CAPABILITY_NO_TUNNELS); return rv.toString(); } switch (_context.commSystem().getStatus()) { @@ -1214,6 +1226,31 @@ public class Router implements RouterClock.ClockShiftListener { // no explicit capability break; } + + char cong = 0; + int maxTunnels = _context.getProperty(RouterThrottleImpl.PROP_MAX_TUNNELS, RouterThrottleImpl.DEFAULT_MAX_TUNNELS); + if (maxTunnels <= 0) { + cong = CAPABILITY_NO_TUNNELS; + } else if (maxTunnels <= 50 || SystemVersion.isSlow()) { + cong = CAPABILITY_CONGESTION_MODERATE; + } else { + int numTunnels = _context.tunnelManager().getParticipatingCount(); + if (numTunnels > 9 * maxTunnels / 10) { + cong = CAPABILITY_CONGESTION_SEVERE; + } else if (numTunnels > 8 * maxTunnels / 10) { + cong = CAPABILITY_CONGESTION_MODERATE; + } else { + // TODO + } + } + if (cong != 0) { + if (CONGESTION_CAPS) { + rv.append(cong); + } else { + if (_log.shouldWarn()) + _log.warn("Congestion cap: " + cong); + } + } return rv.toString(); } diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index aee15848badbca4521bf1efa78db743907e65e98..35ab2b80b1541b415c48542b42a802e96ab15702 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 = "Git"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 2; + public final static long BUILD = 4; /** for example "-test" */ public final static String EXTRA = ""; diff --git a/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java b/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java index 6cbdaa59a3b21433e38ad89a84956294e65ec415..f9440e711753cd3f556cc9d02794879591e7e909 100644 --- a/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java +++ b/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java @@ -1219,15 +1219,102 @@ public class Reseeder { return Translate.getString(n, s, p, _context, BUNDLE_NAME); } -/****** - public static void main(String args[]) { - if ( (args != null) && (args.length == 1) && (!Boolean.parseBoolean(args[0])) ) { - System.out.println("Not reseeding, as requested"); - return; // not reseeding on request + /** + * @since 0.9.58 + */ + public static void main(String args[]) throws Exception { + if (args.length == 1 && args[0].equals("help")) { + System.out.println("Usage: reseeder [https://hostname/ ...]"); + System.exit(1); + } + File f = new File("certificates"); + if (!f.exists()) { + System.out.println("Must be run from $I2P or have symlink to $I2P/certificates in this directory"); + System.exit(1); + } + String[] urls = (args.length > 0) ? args : DataHelper.split(DEFAULT_SSL_SEED_URL, ","); + int pass = 0, fail = 0; + SSLEepGet.SSLState sslState = null; + I2PAppContext ctx = I2PAppContext.getGlobalContext(); + for (String url : urls) { + url += SU3_FILENAME + NETID_PARAM + '2'; + URI uri = new URI(url); + String host = uri.getHost(); + System.out.println("Testing " + host); + File su3 = new File(host + ".su3"); + su3.delete(); + try { + SSLEepGet get; + if (sslState == null) { + get = new SSLEepGet(ctx, su3.getPath(), url); + sslState = get.getSSLState(); + } else { + get = new SSLEepGet(ctx, su3.getPath(), url, sslState); + } + if (get.fetch()) { + int rc = get.getStatusCode(); + if (rc == 200) { + SU3File su3f = new SU3File(su3); + File zip = new File(host + ".zip"); + zip.delete(); + su3f.verifyAndMigrate(zip); + SU3File.main(new String[] {"showversion", su3.getPath()}); + String version = su3f.getVersionString(); + long ver = Long.parseLong(version.trim()) * 1000; + long cutoff = System.currentTimeMillis() - MAX_FILE_AGE / 4; + if (ver < cutoff) + throw new IOException("su3 file too old"); + java.util.zip.ZipFile zipf = new java.util.zip.ZipFile(zip); + java.util.Enumeration<? extends java.util.zip.ZipEntry> entries = zipf.entries(); + int ri = 0, old = 0; + while (entries.hasMoreElements()) { + java.util.zip.ZipEntry entry = (java.util.zip.ZipEntry) entries.nextElement(); + net.i2p.data.router.RouterInfo r = new net.i2p.data.router.RouterInfo(); + InputStream in = zipf.getInputStream(entry); + r.readBytes(in); + in.close(); + if (r.getPublished() > cutoff) + ri++; + else + old++; + } + zipf.close(); + if (old > 0) { + System.out.println("Test failed for " + host + ", returned " + old + " old router infos"); + fail++; + } else if (ri >= 50) { + System.out.println("Test passed for " + host + ", returned " + ri + " router infos"); + pass++; + } else { + System.out.println("Test failed for " + host + ", returned only " + ri + " router infos"); + fail++; + } + } else { + System.out.println("Test failed for " + host + " return code: " + rc); + su3.delete(); + fail++; + } + } else { + int rc = get.getStatusCode(); + System.out.println("Test failed for " + host + " return code: " + rc); + su3.delete(); + fail++; + } + } catch (Exception ioe) { + System.out.println("Test failed for " + host + ": " + ioe); + ioe.printStackTrace(); + if (su3.exists()) { + try { + SU3File.main(new String[] {"showversion", su3.getPath()}); + } catch (Exception e) {} + su3.delete(); + } + fail++; + } + System.out.println(); } - System.out.println("Reseeding"); - Reseeder reseedHandler = new Reseeder(); - reseedHandler.requestReseed(); + System.out.println("Passed: " + pass + "; Failed: " + fail); + if (fail > 0) + System.exit(1); } -******/ } diff --git a/router/java/src/net/i2p/router/startup/ClientAppConfig.java b/router/java/src/net/i2p/router/startup/ClientAppConfig.java index 291c2d66593dccdacdea91f7052e7233aff629a3..cc12c88cc07b43aa811b2c1a84c9806add779b10 100644 --- a/router/java/src/net/i2p/router/startup/ClientAppConfig.java +++ b/router/java/src/net/i2p/router/startup/ClientAppConfig.java @@ -15,7 +15,7 @@ import net.i2p.router.RouterContext; import net.i2p.util.FileSuffixFilter; import net.i2p.util.FileUtil; import net.i2p.util.Log; -import net.i2p.util.ObjectCounter; +import net.i2p.util.ObjectCounterUnsafe; import net.i2p.util.OrderedProperties; import net.i2p.util.SecureDirectory; import net.i2p.util.SystemVersion; @@ -349,7 +349,7 @@ public class ClientAppConfig { */ public synchronized static void writeClientAppConfig(I2PAppContext ctx, List<ClientAppConfig> apps) throws IOException { // Gather the set of config files - ObjectCounter<File> counter = new ObjectCounter<File>(); + ObjectCounterUnsafe<File> counter = new ObjectCounterUnsafe<File>(); for (ClientAppConfig cac : apps) { File f = cac.configFile; if (f == null) diff --git a/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java b/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java index 313531fdeb034455f7b1992cca13aff723b74599..a14281008a4a637f16c1ef8c950d4d7c9bc17754 100644 --- a/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java +++ b/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java @@ -46,7 +46,7 @@ class LoadRouterInfoJob extends JobImpl { private RouterInfo _us; private static final AtomicBoolean _keyLengthChecked = new AtomicBoolean(); // 1 chance in this many to rekey if the defaults changed - private static final int REKEY_PROBABILITY = 4; + private static final int REKEY_PROBABILITY = 1; public LoadRouterInfoJob(RouterContext ctx) { super(ctx); diff --git a/router/java/src/net/i2p/router/sybil/Analysis.java b/router/java/src/net/i2p/router/sybil/Analysis.java index 074eae207f57760b23455b33f1dd0150d4d23d6c..d66c4386b204609e088fda2f513aa74f489188a3 100644 --- a/router/java/src/net/i2p/router/sybil/Analysis.java +++ b/router/java/src/net/i2p/router/sybil/Analysis.java @@ -41,7 +41,7 @@ import net.i2p.stat.RateAverages; import net.i2p.stat.RateStat; import net.i2p.util.Addresses; import net.i2p.util.Log; -import net.i2p.util.ObjectCounter; +import net.i2p.util.ObjectCounterUnsafe; import net.i2p.util.SystemVersion; import net.i2p.util.Translate; @@ -683,7 +683,7 @@ public class Analysis extends JobImpl implements RouterApp { * @since 0.9.38 split out from renderIPGroups32() */ public Map<Integer, List<RouterInfo>> calculateIPGroups32(List<RouterInfo> ris, Map<Hash, Points> points) { - ObjectCounter<Integer> oc = new ObjectCounter<Integer>(); + ObjectCounterUnsafe<Integer> oc = new ObjectCounterUnsafe<Integer>(); for (RouterInfo info : ris) { byte[] ip = getIP(info); if (ip == null) @@ -732,7 +732,7 @@ public class Analysis extends JobImpl implements RouterApp { * @since 0.9.38 split out from renderIPGroups24() */ public Map<Integer, List<RouterInfo>> calculateIPGroups24(List<RouterInfo> ris, Map<Hash, Points> points) { - ObjectCounter<Integer> oc = new ObjectCounter<Integer>(); + ObjectCounterUnsafe<Integer> oc = new ObjectCounterUnsafe<Integer>(); for (RouterInfo info : ris) { byte[] ip = getIP(info); if (ip == null) @@ -785,7 +785,7 @@ public class Analysis extends JobImpl implements RouterApp { * @since 0.9.38 split out from renderIPGroups16() */ public Map<Integer, List<RouterInfo>> calculateIPGroups16(List<RouterInfo> ris, Map<Hash, Points> points) { - ObjectCounter<Integer> oc = new ObjectCounter<Integer>(); + ObjectCounterUnsafe<Integer> oc = new ObjectCounterUnsafe<Integer>(); for (RouterInfo info : ris) { byte[] ip = getIP(info); if (ip == null) @@ -828,7 +828,7 @@ public class Analysis extends JobImpl implements RouterApp { * @since 0.9.57 */ public Map<Long, List<RouterInfo>> calculateIPGroups64(List<RouterInfo> ris, Map<Hash, Points> points) { - ObjectCounter<Long> oc = new ObjectCounter<Long>(); + ObjectCounterUnsafe<Long> oc = new ObjectCounterUnsafe<Long>(); for (RouterInfo info : ris) { byte[] ip = getIPv6(info); if (ip == null) @@ -893,7 +893,7 @@ public class Analysis extends JobImpl implements RouterApp { * @since 0.9.57 */ public Map<Long, List<RouterInfo>> calculateIPGroups48(List<RouterInfo> ris, Map<Hash, Points> points) { - ObjectCounter<Long> oc = new ObjectCounter<Long>(); + ObjectCounterUnsafe<Long> oc = new ObjectCounterUnsafe<Long>(); for (RouterInfo info : ris) { byte[] ip = getIPv6(info); if (ip == null) 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 0de5f6300ba9a7fc1cdf854329ae38275f578b85..141bd411447d4c3fc80a2e78b24677e5a9d7d914 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java +++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java @@ -1099,6 +1099,15 @@ public class NTCPTransport extends TransportImpl { _log.warn("Already listening on " + addr); return null; } + // if UDP only changed external port and not internal port, + // do not rebind internally and restart, just change the address + int eport = _context.getProperty(UDPTransport.PROP_EXTERNAL_PORT, 0); + int iport = _context.getProperty(UDPTransport.PROP_INTERNAL_PORT, 0); + if (port == eport && iport > 0 && eport != iport) { + if (_log.shouldWarn()) + _log.warn("External port changed to " + eport + ", keep listening on internal port " + iport); + return null; + } // FIXME support multiple binds // FIXME just close and unregister stopWaitAndRestart(); @@ -1617,6 +1626,8 @@ public class NTCPTransport extends TransportImpl { String cport = _context.getProperty(PROP_I2NP_NTCP_PORT); if (cport != null && cport.length() > 0) { nport = cport; + if (port > 0 && !nport.equals(Integer.toString(port))) + _log.logAlways(Log.WARN, "UDP detected external port is " + port + " but TCP configured port is " + nport); } else if (_context.getBooleanPropertyDefaultTrue(PROP_I2NP_NTCP_AUTO_PORT)) { // 0.9.6 change // This wasn't quite right, as udpAddr is the EXTERNAL port and we really diff --git a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java index 4914b7628b47edf257dfd6fe7aafaf5eadd3b152..82491dc811cc807a5bb6baf4a22f098f3cc72195 100644 --- a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java +++ b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java @@ -826,10 +826,10 @@ class EstablishmentManager { if (_transport.isTooClose(to.getIP())) return; DatagramPacket pkt = fromPacket.getPacket(); - int off = pkt.getOffset(); int len = pkt.getLength(); if (len < MIN_LONG_DATA_LEN) return; + int off = pkt.getOffset(); byte data[] = pkt.getData(); int type = data[off + TYPE_OFFSET] & 0xff; if (type == SSU2Util.SESSION_REQUEST_FLAG_BYTE && len < MIN_SESSION_REQUEST_LEN) diff --git a/router/java/src/net/i2p/router/transport/udp/InboundEstablishState2.java b/router/java/src/net/i2p/router/transport/udp/InboundEstablishState2.java index 15555ca2c7784fc01f63c579519566b1e7355ac8..c4f8df7e6dfc3fb6c12a41ae4389bc45c6c52550 100644 --- a/router/java/src/net/i2p/router/transport/udp/InboundEstablishState2.java +++ b/router/java/src/net/i2p/router/transport/udp/InboundEstablishState2.java @@ -7,6 +7,7 @@ import java.net.InetSocketAddress; import java.net.SocketAddress; import java.net.UnknownHostException; import java.security.GeneralSecurityException; +import java.util.Arrays; import java.util.ArrayList; import java.util.List; @@ -829,6 +830,11 @@ class InboundEstablishState2 extends InboundEstablishState implements SSU2Payloa "\nGenerated header key 2 for A->B: " + Base64.encode(h_ab) + "\nGenerated header key 2 for B->A: " + Base64.encode(h_ba)); ****/ + Arrays.fill(ckd, (byte) 0); + Arrays.fill(k_ab, (byte) 0); + Arrays.fill(k_ba, (byte) 0); + Arrays.fill(d_ab, (byte) 0); + Arrays.fill(d_ba, (byte) 0); _handshakeState.destroy(); if (_createdSentCount == 1) _rtt = (int) ( _context.clock().now() - _lastSend ); diff --git a/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState2.java b/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState2.java index 0e98bac85870703e632c1bd0796f8c53a10f1d9b..092e20337565fdd8c890bc9e213ca05606fbbe8e 100644 --- a/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState2.java +++ b/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState2.java @@ -6,6 +6,7 @@ import java.net.InetSocketAddress; import java.net.SocketAddress; import java.net.UnknownHostException; import java.security.GeneralSecurityException; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -766,6 +767,11 @@ class OutboundEstablishState2 extends OutboundEstablishState implements SSU2Payl "\nGenerated header key 2 for A->B: " + Base64.encode(h_ab) + "\nGenerated header key 2 for B->A: " + Base64.encode(h_ba)); ****/ + Arrays.fill(ckd, (byte) 0); + Arrays.fill(k_ab, (byte) 0); + Arrays.fill(k_ba, (byte) 0); + Arrays.fill(d_ab, (byte) 0); + Arrays.fill(d_ba, (byte) 0); _handshakeState.destroy(); if (_requestSentCount == 1) _rtt = (int) ( _context.clock().now() - _lastSend ); diff --git a/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java b/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java index 4dfde740fa0a211ce567b19dee589f0aa4e12f34..9ddf763a7e9ce4172036c50249ccec7a39fefcde 100644 --- a/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java +++ b/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java @@ -1964,6 +1964,7 @@ class PeerTestManager { // More sanity checks here. // we compare to the test address, // however our address may have changed during the test + Hash charlieHash = test.getCharlieHash(); boolean portok = addrBlockPort == test.getAlicePort(); boolean IPok = DataHelper.eq(addrBlockIP, test.getAliceIP().getAddress()); if (!portok || !IPok) { @@ -1979,7 +1980,8 @@ class PeerTestManager { // Port different. Charlie probably symmetric natted. // The result will be OK // Note that charlie is probably not reachable - _transport.markUnreachable(test.getCharlieHash()); + if (charlieHash != null) + _transport.markUnreachable(charlieHash); // Reset port so testComplete() will return success. test.setAlicePortFromCharlie(test.getAlicePort()); // set bad so we don't call externalAddressReceived() @@ -1992,7 +1994,8 @@ class PeerTestManager { // Both IP and port changed, don't trust it // The result will be OK // Note that charlie is probably not reachable - _transport.markUnreachable(test.getCharlieHash()); + if (charlieHash != null) + _transport.markUnreachable(charlieHash); // Reset IP and port so testComplete() will return success. test.setAliceIPFromCharlie(test.getAliceIP()); test.setAlicePortFromCharlie(test.getAlicePort()); @@ -2009,8 +2012,8 @@ class PeerTestManager { } // We already call externalAddressReceived() for every outbound connection from EstablishmentManager // but we can use this also to update our address faster - if (!bad) - _transport.externalAddressReceived(state.getCharlieHash(), addrBlockIP, addrBlockPort); + if (!bad && charlieHash != null) + _transport.externalAddressReceived(charlieHash, addrBlockIP, addrBlockPort); } testComplete(); break; diff --git a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java index ddfce655580045c8740c885f425dc87cd2323973..cba2007dbc660e124fa9fd2f51de8dff55f3ba23 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java @@ -104,8 +104,8 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority private final SSUHMACGenerator _hmac; private int _mtu = PeerState.MIN_MTU; private int _mtu_ipv6 = PeerState.MIN_IPV6_MTU; - private int _mtu_ssu2 = PeerState2.MIN_SSU_IPV4_MTU; - private int _mtu_ssu2_ipv6 = PeerState2.MIN_SSU_IPV6_MTU; + private int _mtu_ssu2; + private int _mtu_ssu2_ipv6; private final int _defaultMTU; private boolean _mismatchLogged; private final int _networkID; @@ -282,6 +282,20 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority // various state bitmaps + private static final Set<Status> STATUS_IPV4_UNK = EnumSet.of(Status.UNKNOWN, + Status.DISCONNECTED, + Status.HOSED, + Status.IPV4_UNKNOWN_IPV6_OK, + Status.IPV4_UNKNOWN_IPV6_FIREWALLED); + + private static final Set<Status> STATUS_IPV6_UNK = EnumSet.of(Status.UNKNOWN, + Status.DISCONNECTED, + Status.HOSED, + Status.IPV4_OK_IPV6_UNKNOWN, + Status.IPV4_FIREWALLED_IPV6_UNKNOWN, + Status.IPV4_SNAT_IPV6_UNKNOWN, + Status.IPV4_DISABLED_IPV6_UNKNOWN); + private static final Set<Status> STATUS_IPV4_FW = EnumSet.of(Status.DIFFERENT, Status.REJECT_UNSOLICITED, Status.IPV4_FIREWALLED_IPV6_OK, @@ -323,10 +337,6 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority Status.IPV4_DISABLED_IPV6_FIREWALLED, Status.DISCONNECTED); - private static final Set<Status> STATUS_NEED_INTRO = EnumSet.of(Status.REJECT_UNSOLICITED, - Status.IPV4_FIREWALLED_IPV6_OK, - Status.IPV4_FIREWALLED_IPV6_UNKNOWN); - private static final Set<Status> STATUS_OK = EnumSet.of(Status.OK, Status.IPV4_DISABLED_IPV6_OK); @@ -444,6 +454,8 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority // SSU2 key and IV generation if required _enableSSU1 = dh != null; _defaultMTU = _enableSSU1 ? PeerState.LARGE_MTU : PeerState2.DEFAULT_MTU; + _mtu_ssu2 = _enableSSU1 ? PeerState2.MIN_SSU_IPV4_MTU : PeerState2.MIN_MTU; + _mtu_ssu2_ipv6 = _enableSSU1 ? PeerState2.MIN_SSU_IPV6_MTU : PeerState2.MIN_MTU; boolean enableSSU2 = xdh != null; if (enableSSU2) { // if any ipv4 address is lower than 1280 MTU, disable @@ -539,8 +551,9 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority if (port <= 0) { port = TransportUtil.selectRandomPort(_context, STYLE); Map<String, String> changes = new HashMap<String, String>(2); - changes.put(PROP_INTERNAL_PORT, Integer.toString(port)); - changes.put(PROP_EXTERNAL_PORT, Integer.toString(port)); + String sport = Integer.toString(port); + changes.put(PROP_INTERNAL_PORT, sport); + changes.put(PROP_EXTERNAL_PORT, sport); _context.router().saveConfig(changes, null); _log.logAlways(Log.INFO, "UDP selected random port " + port); } @@ -756,12 +769,14 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority return; } if (newPort > 0 && - (newPort != port || newPort != oldIPort || newPort != oldEPort)) { + (newPort != port || newPort != oldIPort)) { // attempt to use it as our external port - this will be overridden by // externalAddressReceived(...) Map<String, String> changes = new HashMap<String, String>(); - changes.put(PROP_INTERNAL_PORT, Integer.toString(newPort)); - changes.put(PROP_EXTERNAL_PORT, Integer.toString(newPort)); + String sport = Integer.toString(newPort); + changes.put(PROP_INTERNAL_PORT, sport); + if (oldEPort <= 0) + changes.put(PROP_EXTERNAL_PORT, sport); _context.router().saveConfig(changes, null); } @@ -1424,7 +1439,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority if (!isIPv6) { if (from.equals(_lastFromv4) || !eq(_lastOurIPv4, _lastOurPortv4, ourIP, ourPort)) { if (_log.shouldLog(Log.INFO)) - _log.info("The router " + from + " told us we have a new IP - " + _log.info("The router " + from + " told us we have a new IP/port - " + Addresses.toString(ourIP, ourPort) + ". Wait until somebody else tells us the same thing."); } else { changeIt = true; @@ -1436,7 +1451,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority } else { if (from.equals(_lastFromv6) || !eq(_lastOurIPv6, _lastOurPortv6, ourIP, ourPort)) { if (_log.shouldLog(Log.INFO)) - _log.info("The router " + from + " told us we have a new IP - " + _log.info("The router " + from + " told us we have a new IP/port - " + Addresses.toString(ourIP, ourPort) + ". Wait until somebody else tells us the same thing."); } else { changeIt = true; @@ -1468,12 +1483,12 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority * @return true if updated */ private boolean changeAddress(byte ourIP[], int ourPort) { - // this defaults to true when we are firewalled and false otherwise. - boolean fixedPort = getIsPortFixed(); boolean updated = false; boolean fireTest = false; boolean isIPv6 = ourIP.length == 16; + // this defaults to true when we are firewalled or unknown and false otherwise. + boolean fixedPort = getIsPortFixed(isIPv6); synchronized (_rebuildLock) { RouterAddress current = getCurrentExternalAddress(isIPv6); @@ -1537,8 +1552,18 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority //if ( (_reachabilityStatus != CommSystemFacade.STATUS_OK) || // (_externalListenHost == null) || (_externalListenPort <= 0) || // (_context.clock().now() - _reachabilityStatusLastUpdated > 2*TEST_FREQUENCY) ) { - // they told us something different and our tests are either old or failing + + // they told us something different and our tests are either old or failing if (rebuild) { + if (externalListenPort > 0 && ourPort > 0 && + externalListenPort != ourPort && + _context.getProperty(PROP_EXTERNAL_PORT, 0) != ourPort) { + // save the external port setting only + _context.router().saveConfig(PROP_EXTERNAL_PORT, Integer.toString(ourPort)); + _context.router().eventLog().addEvent(EventLog.CHANGE_PORT, "IPv" + + (isIPv6 ? '6' : '4') + + " port " + ourPort); + } if (_enableSSU2) { // flush SSU2 tokens if (ourPort != externalListenPort) { @@ -1666,13 +1691,23 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority * our firewall is changing our port), unless overridden by the property. * We must have an accurate external port when firewalled, or else * our signature of the SessionCreated packet will be invalid. + * + * As of 0.9.58, returns false if status is UNKNOWN */ - private boolean getIsPortFixed() { + private boolean getIsPortFixed(boolean isIPv6) { String prop = _context.getProperty(PROP_FIXED_PORT); if (prop != null) return Boolean.parseBoolean(prop); Status status = getReachabilityStatus(); - return !STATUS_NEED_INTRO.contains(status); + if (isIPv6) { + if (STATUS_IPV6_UNK.contains(status)) + return false; + return !STATUS_IPV6_FW.contains(status); + } else { + if (STATUS_IPV4_UNK.contains(status)) + return false; + return !STATUS_IPV4_FW.contains(status); + } } /** @@ -4000,7 +4035,8 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority // to prevent thrashing if ((STATUS_OK.contains(old) && STATUS_FW.contains(status)) || (STATUS_OK.contains(status) && STATUS_FW.contains(old)) || - (STATUS_FW.contains(status) && STATUS_FW.contains(old))) { + (STATUS_FW.contains(status) && STATUS_FW.contains(old)) || + (!isIPv6 && STATUS_IPV4_UNK.contains(old) && !STATUS_IPV4_UNK.contains(status))) { if (status != _reachabilityStatusPending) { if (_log.shouldLog(Log.WARN)) _log.warn("Old status: " + old + " status pending confirmation: " + status + diff --git a/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java b/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java index ce287f2d6585185034d222f5ecfa8792a7396d23..e04816b9222d1e6455f35e31a8ffabfb9664d9d6 100644 --- a/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java +++ b/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java @@ -949,7 +949,7 @@ public class TunnelDispatcher implements Service { long now = getContext().clock().now() + LEAVE_BATCH_TIME; // leave all expiring in next 10 sec long nextTime = now + 10*60*1000; while ((cur = _configs.peek()) != null) { - long exp = cur.getExpiration() + (2 * Router.CLOCK_FUDGE_FACTOR) + LEAVE_BATCH_TIME; + long exp = cur.getExpiration() + (3 * Router.CLOCK_FUDGE_FACTOR / 2) + LEAVE_BATCH_TIME; if (exp < now) { _configs.poll(); if (_log.shouldLog(Log.INFO)) diff --git a/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java b/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java index 7d655ff96b51210f738dd7dced0b029022d64982..395d93a1304c8ba05ba799345d6b5522080081ab 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java +++ b/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java @@ -226,7 +226,7 @@ class BuildExecutor implements Runnable { } } - _context.statManager().addRateData("tunnel.concurrentBuilds", concurrent, 0); + _context.statManager().addRateData("tunnel.concurrentBuilds", concurrent); long lag = _context.jobQueue().getMaxLag(); if ( (lag > 2000) && (_context.router().getUptime() > 5*60*1000) ) { @@ -420,7 +420,7 @@ class BuildExecutor implements Runnable { continue; } long pTime = System.currentTimeMillis() - bef; - _context.statManager().addRateData("tunnel.buildConfigTime", pTime, 0); + _context.statManager().addRateData("tunnel.buildConfigTime", pTime); if (_log.shouldLog(Log.DEBUG)) _log.debug("Configuring new tunnel " + i + " for " + pool + ": " + cfg); buildTunnel(cfg); @@ -544,7 +544,7 @@ class BuildExecutor implements Runnable { return; if (cfg.getLength() > 1) { long buildTime = System.currentTimeMillis() - beforeBuild; - _context.statManager().addRateData("tunnel.buildRequestTime", buildTime, 0); + _context.statManager().addRateData("tunnel.buildRequestTime", buildTime); } long id = cfg.getReplyMessageId(); if (id > 0) { @@ -649,7 +649,7 @@ class BuildExecutor implements Runnable { if (rv != null) { long requestedOn = rv.getExpiration() - 10*60*1000; long rtt = _context.clock().now() - requestedOn; - _context.statManager().addRateData("tunnel.buildReplySlow", rtt, 0); + _context.statManager().addRateData("tunnel.buildReplySlow", rtt); if (_log.shouldInfo()) _log.info("Got reply late (rtt = " + rtt + ") for: " + rv); } diff --git a/router/java/src/net/i2p/router/tunnel/pool/BuildRequestor.java b/router/java/src/net/i2p/router/tunnel/pool/BuildRequestor.java index 33920f2b70f6db83b55175135e953634c070b8d5..c2e01b69a995da372498acbbf42031e7c9fd5462 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/BuildRequestor.java +++ b/router/java/src/net/i2p/router/tunnel/pool/BuildRequestor.java @@ -541,7 +541,7 @@ abstract class BuildRequestor { public void runJob() { _exec.buildComplete(_cfg, OTHER_FAILURE); getContext().profileManager().tunnelTimedOut(_cfg.getPeer(1)); - getContext().statManager().addRateData("tunnel.buildFailFirstHop", 1, 0); + getContext().statManager().addRateData("tunnel.buildFailFirstHop", 1); // static, no _log //System.err.println("Cant contact first hop for " + _cfg); } diff --git a/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java b/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java index 34372fda414d807d9549c71d024344dd95e9bb25..8c48ae150369749835933e7fda899f9d989691d7 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java +++ b/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java @@ -166,6 +166,7 @@ public class TunnelPool { private TunnelInfo selectTunnel(boolean allowRecurseOnFail) { boolean avoidZeroHop = !_settings.getAllowZeroHop(); + long now = _context.clock().now(); synchronized (_tunnels) { if (_tunnels.isEmpty()) { if (_log.shouldLog(Log.WARN)) @@ -181,7 +182,7 @@ public class TunnelPool { if (_lastSelectedIdx >= _tunnels.size()) _lastSelectedIdx = 0; TunnelInfo info = _tunnels.get(_lastSelectedIdx); - if ( (info.getLength() > 1) && (info.getExpiration() > _context.clock().now()) ) { + if (info.getLength() > 1 && info.getExpiration() > now) { // avoid outbound tunnels where the 1st hop is backlogged if (_settings.isInbound() || !_context.commSystem().isBacklogged(info.getPeer(1))) { return info; @@ -201,7 +202,7 @@ public class TunnelPool { // randomly for (int i = 0; i < _tunnels.size(); i++) { TunnelInfo info = _tunnels.get(i); - if (info.getExpiration() > _context.clock().now()) { + if (info.getExpiration() > now) { // avoid outbound tunnels where the 1st hop is backlogged if (_settings.isInbound() || info.getLength() <= 1 || !_context.commSystem().isBacklogged(info.getPeer(1))) { @@ -243,12 +244,13 @@ public class TunnelPool { TunnelInfo selectTunnel(Hash closestTo) { boolean avoidZeroHop = !_settings.getAllowZeroHop(); TunnelInfo rv = null; + long now = _context.clock().now(); synchronized (_tunnels) { if (!_tunnels.isEmpty()) { if (_tunnels.size() > 1) Collections.sort(_tunnels, new TunnelInfoComparator(closestTo, avoidZeroHop)); for (TunnelInfo info : _tunnels) { - if (info.getExpiration() > _context.clock().now()) { + if (info.getExpiration() > now) { rv = info; break; } @@ -616,7 +618,7 @@ public class TunnelPool { long et = now - _lastRateUpdate; if (et > 2*60*1000) { long bw = 1024 * (_lifetimeProcessed - _lastLifetimeProcessed) * 1000 / et; // Bps - _context.statManager().addRateData(_rateName, bw, 0); + _context.statManager().addRateData(_rateName, bw); _lastRateUpdate = now; _lastLifetimeProcessed = _lifetimeProcessed; } @@ -969,7 +971,7 @@ public class TunnelPool { + " soon " + expireSoon + " later " + expireLater + " std " + wanted + " inProgress " + inProgress + " fallback " + fallback + " for " + toString()); - _context.statManager().addRateData(rateName, rv + inProgress, 0); + _context.statManager().addRateData(rateName, rv + inProgress); return rv; } @@ -1022,7 +1024,7 @@ public class TunnelPool { int rv = countHowManyToBuild(allowZeroHop, expire30s, expire90s, expire150s, expire210s, expire270s, expireLater, wanted, inProgress, fallback); - _context.statManager().addRateData(rateName, (rv > 0 || inProgress > 0) ? 1 : 0, 0); + _context.statManager().addRateData(rateName, (rv > 0 || inProgress > 0) ? 1 : 0); return rv; } diff --git a/router/java/src/net/i2p/router/tunnel/pool/TunnelPoolManager.java b/router/java/src/net/i2p/router/tunnel/pool/TunnelPoolManager.java index 27460c6a824e3137205b214193312c8fd82866c5..e6a13f91a9ee7d0fedce81443e48be415b18be8e 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/TunnelPoolManager.java +++ b/router/java/src/net/i2p/router/tunnel/pool/TunnelPoolManager.java @@ -24,7 +24,7 @@ import net.i2p.router.TunnelPoolSettings; import net.i2p.router.tunnel.TunnelDispatcher; import net.i2p.util.I2PThread; import net.i2p.util.Log; -import net.i2p.util.ObjectCounter; +import net.i2p.util.ObjectCounterUnsafe; import net.i2p.util.SimpleTimer; /** @@ -645,7 +645,7 @@ public class TunnelPoolManager implements TunnelManagerFacade { } /** @return total number of non-fallback expl. + client tunnels */ - private int countTunnelsPerPeer(ObjectCounter<Hash> lc) { + private int countTunnelsPerPeer(ObjectCounterUnsafe<Hash> lc) { List<TunnelPool> pools = new ArrayList<TunnelPool>(); listPools(pools); int tunnelCount = 0; @@ -681,7 +681,7 @@ public class TunnelPoolManager implements TunnelManagerFacade { * @return Set of peers that should not be allowed in another tunnel */ public Set<Hash> selectPeersInTooManyTunnels() { - ObjectCounter<Hash> lc = new ObjectCounter<Hash>(); + ObjectCounterUnsafe<Hash> lc = new ObjectCounterUnsafe<Hash>(); int tunnelCount = countTunnelsPerPeer(lc); Set<Hash> rv = new HashSet<Hash>(); if (tunnelCount >= 4 && _context.router().getUptime() > 10*60*1000) {