From e4ebb9a77d8bcce87856485b31940dc345890664 Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 7 Nov 2015 17:08:27 +0000 Subject: [PATCH 01/33] Utils: Add caching string split() --- core/java/src/net/i2p/data/DataHelper.java | 36 ++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/core/java/src/net/i2p/data/DataHelper.java b/core/java/src/net/i2p/data/DataHelper.java index 750d53ede..672a187d8 100644 --- a/core/java/src/net/i2p/data/DataHelper.java +++ b/core/java/src/net/i2p/data/DataHelper.java @@ -37,6 +37,8 @@ import java.util.Iterator; import java.util.Locale; import java.util.Map; import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; +import java.util.regex.Pattern; import java.util.zip.Deflater; import net.i2p.I2PAppContext; @@ -1889,4 +1891,38 @@ public class DataHelper { } return rv; } + + /** + * Same as s.split(regex) but caches the compiled pattern for speed. + * This saves about 10 microseconds (Bulldozer) on subsequent invocations. + * + * @param s non-null + * @param regex non-null + * @throws java.util.regex.PatternSyntaxException unchecked + * @since 0.9.24 + */ + public static String[] split(String s, String regex) { + return split(s, regex, 0); + } + + private static final ConcurrentHashMap patterns = new ConcurrentHashMap(); + + /** + * Same as s.split(regex, limit) but caches the compiled pattern for speed. + * This saves about 10 microseconds (Bulldozer) on subsequent invocations. + * + * @param s non-null + * @param regex non-null + * @param limit result threshold + * @throws java.util.regex.PatternSyntaxException unchecked + * @since 0.9.24 + */ + public static String[] split(String s, String regex, int limit) { + Pattern p = patterns.get(regex); + if (p == null) { + p = Pattern.compile(regex); + patterns.putIfAbsent(regex, p); + } + return p.split(s, limit); + } } From 1e5a35c7f8d82d593001b7c94c97525e58adfa89 Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 7 Nov 2015 17:45:48 +0000 Subject: [PATCH 02/33] Use new split() --- .../java/src/net/i2p/addressbook/ConfigIterator.java | 4 +++- .../java/src/net/i2p/addressbook/ConfigParser.java | 3 ++- .../java/src/org/klomp/snark/SnarkManager.java | 12 ++++++------ .../java/src/org/klomp/snark/TrackerClient.java | 2 +- .../java/src/org/klomp/snark/dht/NodeInfo.java | 2 +- .../src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java | 4 ++-- .../net/i2p/i2ptunnel/I2PTunnelHTTPClientBase.java | 2 +- .../src/net/i2p/i2ptunnel/I2PTunnelHTTPServer.java | 2 +- .../src/net/i2p/i2ptunnel/I2PTunnelIRCServer.java | 3 ++- .../i2ptunnel/java/src/net/i2p/i2ptunnel/I2Ping.java | 3 ++- .../java/src/net/i2p/i2ptunnel/irc/IRCFilter.java | 8 ++++---- .../java/src/net/i2p/router/web/ConfigNetHelper.java | 2 +- .../src/net/i2p/router/web/ConfigSummaryHandler.java | 2 +- .../java/src/net/i2p/router/web/EventLogHelper.java | 2 +- .../java/src/net/i2p/router/web/HomeHelper.java | 6 ++++-- .../java/src/net/i2p/router/web/SearchHelper.java | 4 +++- .../java/src/net/i2p/router/web/SummaryHelper.java | 4 +++- apps/susimail/src/src/i2p/susi/webmail/Mail.java | 7 ++++--- apps/susimail/src/src/i2p/susi/webmail/MailPart.java | 2 +- apps/susimail/src/src/i2p/susi/webmail/WebMail.java | 2 +- .../src/src/i2p/susi/webmail/smtp/SMTPClient.java | 2 +- core/java/src/net/i2p/util/EepGet.java | 2 +- core/java/src/net/i2p/util/I2PSSLSocketFactory.java | 3 ++- core/java/src/net/i2p/util/NativeBigInteger.java | 3 ++- .../java/src/net/i2p/router/startup/WorkingDir.java | 4 ++-- router/java/src/net/i2p/router/time/Zones.java | 3 ++- router/java/src/net/i2p/router/transport/GeoIP.java | 5 +++-- .../java/src/net/i2p/router/transport/GeoIPv6.java | 2 +- router/java/src/net/i2p/router/transport/UPnP.java | 2 +- .../net/i2p/router/transport/udp/UDPTransport.java | 4 ++-- router/java/src/net/i2p/router/util/EventLog.java | 5 +++-- 31 files changed, 64 insertions(+), 47 deletions(-) diff --git a/apps/addressbook/java/src/net/i2p/addressbook/ConfigIterator.java b/apps/addressbook/java/src/net/i2p/addressbook/ConfigIterator.java index 30c21d19b..10119d844 100644 --- a/apps/addressbook/java/src/net/i2p/addressbook/ConfigIterator.java +++ b/apps/addressbook/java/src/net/i2p/addressbook/ConfigIterator.java @@ -32,6 +32,8 @@ import java.util.Locale; import java.util.Map; import java.util.NoSuchElementException; +import net.i2p.data.DataHelper; + /** * A class to iterate through a hosts.txt or config file without * reading the whole thing into memory. @@ -69,7 +71,7 @@ class ConfigIterator implements Iterator>, Closeable { String inputLine = input.readLine(); while (inputLine != null) { inputLine = ConfigParser.stripComments(inputLine); - String[] splitLine = inputLine.split("="); + String[] splitLine = DataHelper.split(inputLine, "="); if (splitLine.length == 2) { next = new ConfigEntry(splitLine[0].trim().toLowerCase(Locale.US), splitLine[1].trim()); return true; diff --git a/apps/addressbook/java/src/net/i2p/addressbook/ConfigParser.java b/apps/addressbook/java/src/net/i2p/addressbook/ConfigParser.java index e2cd8ab2a..625b6e3d0 100644 --- a/apps/addressbook/java/src/net/i2p/addressbook/ConfigParser.java +++ b/apps/addressbook/java/src/net/i2p/addressbook/ConfigParser.java @@ -35,6 +35,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import net.i2p.data.DataHelper; import net.i2p.util.SecureFile; import net.i2p.util.SecureFileOutputStream; import net.i2p.util.SystemVersion; @@ -93,7 +94,7 @@ class ConfigParser { inputLine = input.readLine(); while (inputLine != null) { inputLine = stripComments(inputLine); - String[] splitLine = inputLine.split("="); + String[] splitLine = DataHelper.split(inputLine, "="); if (splitLine.length == 2) { result.put(splitLine[0].trim().toLowerCase(Locale.US), splitLine[1].trim()); } diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java index 688cf7e95..5f5bb94d9 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java +++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java @@ -189,7 +189,7 @@ public class SnarkManager implements CompleteListener { for (int i = 1; i < DEFAULT_TRACKERS.length; i += 2) { if (DEFAULT_TRACKERS[i-1].equals("TheBland") && !SigType.ECDSA_SHA256_P256.isAvailable()) continue; - String urls[] = DEFAULT_TRACKERS[i].split("=", 2); + String urls[] = DataHelper.split(DEFAULT_TRACKERS[i], "=", 2); ann.add(urls[0]); } DEFAULT_TRACKER_ANNOUNCES = Collections.unmodifiableSet(ann); @@ -1078,7 +1078,7 @@ public class SnarkManager implements CompleteListener { val = dflt; if (val == null) return Collections.emptyList(); - return Arrays.asList(val.split(",")); + return Arrays.asList(DataHelper.split(val, ",")); } /** @@ -1611,7 +1611,7 @@ public class SnarkManager implements CompleteListener { return; int filecount = metainfo.getFiles().size(); int[] rv = new int[filecount]; - String[] arr = pri.split(","); + String[] arr = DataHelper.split(pri, ","); for (int i = 0; i < filecount && i < arr.length; i++) { if (arr[i].length() > 0) { try { @@ -2342,12 +2342,12 @@ public class SnarkManager implements CompleteListener { if ( (trackers == null) || (trackers.trim().length() <= 0) ) { setDefaultTrackerMap(true); } else { - String[] toks = trackers.split(","); + String[] toks = DataHelper.split(trackers, ","); for (int i = 0; i < toks.length; i += 2) { String name = toks[i].trim().replace(",", ","); String url = toks[i+1].trim().replace(",", ","); if ( (name.length() > 0) && (url.length() > 0) ) { - String urls[] = url.split("=", 2); + String urls[] = DataHelper.split(url, "=", 2); String url2 = urls.length > 1 ? urls[1] : ""; _trackerMap.put(name, new Tracker(name, urls[0], url2)); } @@ -2367,7 +2367,7 @@ public class SnarkManager implements CompleteListener { String name = DEFAULT_TRACKERS[i]; if (name.equals("TheBland") && !SigType.ECDSA_SHA256_P256.isAvailable()) continue; - String urls[] = DEFAULT_TRACKERS[i+1].split("=", 2); + String urls[] = DataHelper.split(DEFAULT_TRACKERS[i+1], "=", 2); String url2 = urls.length > 1 ? urls[1] : null; _trackerMap.put(name, new Tracker(name, urls[0], url2)); } diff --git a/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java b/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java index ab1116722..11efe94f6 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java +++ b/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java @@ -912,7 +912,7 @@ public class TrackerClient implements Runnable { if (path == null || path.length() < 517 || !path.startsWith("/")) return null; - String[] parts = path.substring(1).split("[/\\?&;]", 2); + String[] parts = DataHelper.split(path.substring(1), "[/\\?&;]", 2); return ConvertToHash.getHash(parts[0]); } return null; diff --git a/apps/i2psnark/java/src/org/klomp/snark/dht/NodeInfo.java b/apps/i2psnark/java/src/org/klomp/snark/dht/NodeInfo.java index c6fce8f14..cd2f73da3 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/dht/NodeInfo.java +++ b/apps/i2psnark/java/src/org/klomp/snark/dht/NodeInfo.java @@ -102,7 +102,7 @@ class NodeInfo extends SimpleDataStructure { */ public NodeInfo(String s) throws DataFormatException { super(); - String[] parts = s.split(":", 4); + String[] parts = DataHelper.split(s, ":", 4); if (parts.length != 4) throw new DataFormatException("Bad format"); byte[] nid = Base64.decode(parts[0]); diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java index 4183ce399..19ebd8b7c 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java @@ -414,7 +414,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn _log.debug(getPrefix(requestId) + "First line [" + line + "]"); } - String[] params = line.split(" ", 3); + String[] params = DataHelper.split(line, " ", 3); if(params.length != 3) { break; } @@ -1252,7 +1252,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn String s = getTunnel().getClientOptions().getProperty(PROP_SSL_OUTPROXIES); if (s == null) return null; - String[] p = s.split("[,; \r\n\t]"); + String[] p = DataHelper.split(s, "[,; \r\n\t]"); if (p.length == 0) return null; // todo doesn't check for "" diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClientBase.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClientBase.java index 5e39cf3b8..e68e38d6b 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClientBase.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClientBase.java @@ -285,7 +285,7 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem // We send Accept-Charset: UTF-8 in the 407 so hopefully it comes back that way inside the B64 ? try { String dec = new String(decoded, "UTF-8"); - String[] parts = dec.split(":"); + String[] parts = DataHelper.split(dec, ":"); String user = parts[0]; String pw = parts[1]; // first try pw for that user diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPServer.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPServer.java index 35dd6f132..dc2c7fa9a 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPServer.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPServer.java @@ -664,7 +664,7 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer { */ @Override protected String filterResponseLine(String line) { - String[] s = line.split(" ", 3); + String[] s = DataHelper.split(line, " ", 3); if (s.length > 1 && (s[1].startsWith("3") || s[1].startsWith("5"))) _dataExpected = 0; diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCServer.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCServer.java index 2288c27ec..79d974e90 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCServer.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCServer.java @@ -13,6 +13,7 @@ import java.util.Properties; import net.i2p.client.streaming.I2PSocket; import net.i2p.crypto.SHA256Generator; +import net.i2p.data.DataHelper; import net.i2p.data.Destination; import net.i2p.data.Hash; import net.i2p.data.Base32; @@ -277,7 +278,7 @@ public class I2PTunnelIRCServer extends I2PTunnelServer implements Runnable { //if (_log.shouldLog(Log.DEBUG)) // _log.debug("Got line: " + s); - String field[]=s.split(" ",5); + String field[] = DataHelper.split(s, " ", 5); String command; int idx=0; diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2Ping.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2Ping.java index dd59042d8..da615301e 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2Ping.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2Ping.java @@ -19,6 +19,7 @@ import net.i2p.I2PException; import net.i2p.client.I2PSession; import net.i2p.client.I2PSessionException; import net.i2p.client.streaming.I2PSocketManager; +import net.i2p.data.DataHelper; import net.i2p.data.Destination; import net.i2p.util.EventDispatcher; import net.i2p.util.I2PAppThread; @@ -93,7 +94,7 @@ public class I2Ping extends I2PTunnelClientBase { int localPort = 0; int remotePort = 0; boolean error = false; - String[] argv = cmd.split(" "); + String[] argv = DataHelper.split(cmd, " "); Getopt g = new Getopt("ping", argv, "t:m:n:chl:f:p:"); int c; while ((c = g.getopt()) != -1) { diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/irc/IRCFilter.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/irc/IRCFilter.java index 3112c9dda..eef558837 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/irc/IRCFilter.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/irc/IRCFilter.java @@ -33,7 +33,7 @@ abstract class IRCFilter { */ public static String inboundFilter(String s, StringBuffer expectedPong, DCCHelper helper) { - String field[]=s.split(" ",4); + String field[] = DataHelper.split(s, " ", 4); String command; int idx=0; final String[] allowedCommands = @@ -274,7 +274,7 @@ abstract class IRCFilter { */ public static String outboundFilter(String s, StringBuffer expectedPong, DCCHelper helper) { - String field[]=s.split(" ",3); + String field[] = DataHelper.split(s, " ",3); if(field[0].length()==0) return null; // W T F? @@ -420,7 +420,7 @@ abstract class IRCFilter { int ctcp = msg.indexOf(0x01); if (ctcp > 0) msg = msg.substring(0, ctcp); - String[] args = msg.split(" ", 5); + String[] args = DataHelper.split(msg, " ", 5); if (args.length <= 0) return null; String type = args[0]; @@ -512,7 +512,7 @@ abstract class IRCFilter { int ctcp = msg.indexOf(0x01); if (ctcp > 0) msg = msg.substring(0, ctcp); - String[] args = msg.split(" ", 5); + String[] args = DataHelper.split(msg, " ", 5); if (args.length <= 0) return null; String type = args[0]; diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHelper.java index c3abb58f5..fbb94ddef 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHelper.java @@ -207,7 +207,7 @@ public class ConfigNetHelper extends HelperBase { configs = Collections.emptySet(); } else { configs = new HashSet(4); - String[] ca = cs.split("[,; \r\n\t]"); + String[] ca = DataHelper.split(cs, "[,; \r\n\t]"); for (int i = 0; i < ca.length; i++) { String c = ca[i]; if (c.length() > 0) { diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigSummaryHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigSummaryHandler.java index 7747d22b2..1f75c3c82 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigSummaryHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigSummaryHandler.java @@ -108,7 +108,7 @@ public class ConfigSummaryHandler extends FormHandler { } } } else if (moving) { - String parts[] = _action.split("_"); + String parts[] = DataHelper.split(_action, "_"); try { int from = Integer.parseInt(parts[1]); int to = 0; diff --git a/apps/routerconsole/java/src/net/i2p/router/web/EventLogHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/EventLogHelper.java index f42e1cd6e..ca738304e 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/EventLogHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/EventLogHelper.java @@ -202,7 +202,7 @@ public class EventLogHelper extends FormHandler { buf.append(fmt.format(new Date(time))); buf.append(""); if (isAll) { - String[] s = event.split(" ", 2); + String[] s = DataHelper.split(event, " ", 2); String xs = _xevents.get(s[0]); if (xs == null) xs = s[0]; diff --git a/apps/routerconsole/java/src/net/i2p/router/web/HomeHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/HomeHelper.java index b6afcf5ca..f937acb27 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/HomeHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/HomeHelper.java @@ -135,8 +135,10 @@ public class HomeHelper extends HelperBase { return renderConfig(apps); } + private static final String SS = Character.toString(S); + static Collection buildApps(RouterContext ctx, String config) { - String[] args = config.split("" + S); + String[] args = DataHelper.split(config, SS); Set apps = new TreeSet(new AppComparator()); for (int i = 0; i < args.length - 3; i += 4) { String name = Messages.getString(args[i], ctx); @@ -149,7 +151,7 @@ public class HomeHelper extends HelperBase { } static Collection buildSearchApps(String config) { - String[] args = config.split("" + S); + String[] args = DataHelper.split(config, SS); Set apps = new TreeSet(new AppComparator()); for (int i = 0; i < args.length - 1; i += 2) { String name = args[i]; diff --git a/apps/routerconsole/java/src/net/i2p/router/web/SearchHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/SearchHelper.java index e04809d6f..b9e40f959 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/SearchHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/SearchHelper.java @@ -43,9 +43,11 @@ public class SearchHelper extends HelperBase { _query = s; } + private static final String SS = Character.toString(S); + private void buildEngineMap() { String config = _context.getProperty(PROP_ENGINES, ENGINES_DEFAULT); - String[] args = config.split("" + S); + String[] args = DataHelper.split(config, SS); for (int i = 0; i < args.length - 1; i += 2) { String name = args[i]; String url = args[i+1]; diff --git a/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java index 7e97d9573..75a55709f 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java @@ -861,6 +861,8 @@ public class SummaryHelper extends HelperBase { public void storeNewsHelper(NewsHelper n) { _newshelper = n; } public NewsHelper getNewsHelper() { return _newshelper; } + private static final String SS = Character.toString(S); + public List getSummaryBarSections(String page) { String config = ""; if ("home".equals(page)) { @@ -870,7 +872,7 @@ public class SummaryHelper extends HelperBase { if (config == null) config = _context.getProperty(PROP_SUMMARYBAR + "default", DEFAULT_FULL); } - return Arrays.asList(config.split("" + S)); + return Arrays.asList(DataHelper.split(config, SS)); } static void saveSummaryBarSections(RouterContext ctx, String page, Map sections) { diff --git a/apps/susimail/src/src/i2p/susi/webmail/Mail.java b/apps/susimail/src/src/i2p/susi/webmail/Mail.java index 8632ac9c4..88eb0ecdd 100644 --- a/apps/susimail/src/src/i2p/susi/webmail/Mail.java +++ b/apps/susimail/src/src/i2p/susi/webmail/Mail.java @@ -42,6 +42,7 @@ import java.util.Locale; import java.util.TimeZone; import net.i2p.I2PAppContext; +import net.i2p.data.DataHelper; /** * data structure to hold a single message, mostly used with folder view and sorting @@ -190,7 +191,7 @@ class Mail { address.indexOf( "\r" ) != -1 ) return false; - String[] tokens = address.split( "[ \t]+" ); + String[] tokens = DataHelper.split(address, "[ \t]+"); int addresses = 0; @@ -208,7 +209,7 @@ class Mail { */ public static String getAddress(String address ) { - String[] tokens = address.split( "[ \t]+" ); + String[] tokens = DataHelper.split(address, "[ \t]+"); for( int i = 0; i < tokens.length; i++ ) { if( tokens[i].matches( "^[^@< \t]+@[^> \t]+$" ) ) @@ -232,7 +233,7 @@ class Mail { public static boolean getRecipientsFromList( ArrayList recipients, String text, boolean ok ) { if( text != null && text.length() > 0 ) { - String[] ccs = text.split( "," ); + String[] ccs = DataHelper.split(text, ","); for( int i = 0; i < ccs.length; i++ ) { String recipient = ccs[i].trim(); if( validateAddress( recipient ) ) { diff --git a/apps/susimail/src/src/i2p/susi/webmail/MailPart.java b/apps/susimail/src/src/i2p/susi/webmail/MailPart.java index 0ec32abe9..ff348a502 100644 --- a/apps/susimail/src/src/i2p/susi/webmail/MailPart.java +++ b/apps/susimail/src/src/i2p/susi/webmail/MailPart.java @@ -79,7 +79,7 @@ class MailPart { beginBody = bb; ReadBuffer decodedHeaders = EncodingFactory.getEncoding( "HEADERLINE" ).decode( buffer.content, begin, beginBody - begin ); - headerLines = new String( decodedHeaders.content, decodedHeaders.offset, decodedHeaders.length ).split( "\r\n" ); + headerLines = DataHelper.split(new String(decodedHeaders.content, decodedHeaders.offset, decodedHeaders.length), "\r\n"); String boundary = null; String x_encoding = null; diff --git a/apps/susimail/src/src/i2p/susi/webmail/WebMail.java b/apps/susimail/src/src/i2p/susi/webmail/WebMail.java index 9ff4b933b..e70ee3063 100644 --- a/apps/susimail/src/src/i2p/susi/webmail/WebMail.java +++ b/apps/susimail/src/src/i2p/susi/webmail/WebMail.java @@ -996,7 +996,7 @@ public class WebMail extends HttpServlet PrintWriter pw2 = new PrintWriter( text2 ); showPart( pw2, part, 0, TEXT_ONLY ); pw2.flush(); - String[] lines = text2.toString().split( "\r\n" ); + String[] lines = DataHelper.split(text2.toString(), "\r\n"); for( int i = 0; i < lines.length; i++ ) pw.println( "> " + lines[i] ); pw.flush(); diff --git a/apps/susimail/src/src/i2p/susi/webmail/smtp/SMTPClient.java b/apps/susimail/src/src/i2p/susi/webmail/smtp/SMTPClient.java index 046dcbef5..eb58c8ed5 100644 --- a/apps/susimail/src/src/i2p/susi/webmail/smtp/SMTPClient.java +++ b/apps/susimail/src/src/i2p/susi/webmail/smtp/SMTPClient.java @@ -282,7 +282,7 @@ public class SMTPClient { error += e.getMessage(); } if( !mailSent && lastResponse.length() > 0 ) { - String[] lines = lastResponse.split( "\r" ); + String[] lines = DataHelper.split(lastResponse, "\r"); for( int i = 0; i < lines.length; i++ ) error += lines[i] + '\n'; } diff --git a/core/java/src/net/i2p/util/EepGet.java b/core/java/src/net/i2p/util/EepGet.java index 88cae89fe..386ec0308 100644 --- a/core/java/src/net/i2p/util/EepGet.java +++ b/core/java/src/net/i2p/util/EepGet.java @@ -1131,7 +1131,7 @@ public class EepGet { private int handleStatus(String line) { if (_log.shouldLog(Log.DEBUG)) _log.debug("Status line: [" + line.trim() + "]"); - String[] toks = line.split(" ", 3); + String[] toks = DataHelper.split(line, " ", 3); if (toks.length < 2) { if (_log.shouldLog(Log.WARN)) _log.warn("ERR: status "+ line); diff --git a/core/java/src/net/i2p/util/I2PSSLSocketFactory.java b/core/java/src/net/i2p/util/I2PSSLSocketFactory.java index 774415f4d..1b8342808 100644 --- a/core/java/src/net/i2p/util/I2PSSLSocketFactory.java +++ b/core/java/src/net/i2p/util/I2PSSLSocketFactory.java @@ -83,6 +83,7 @@ import javax.net.ssl.TrustManagerFactory; import net.i2p.I2PAppContext; import net.i2p.crypto.KeyStoreUtil; +import net.i2p.data.DataHelper; import org.apache.http.conn.ssl.DefaultHostnameVerifier; import org.apache.http.conn.util.PublicSuffixList; @@ -443,7 +444,7 @@ public class I2PSSLSocketFactory { try { if (line.charAt(0) == '#') continue; - String[] s = line.split(","); + String[] s = DataHelper.split(line, ","); String lc = s[0].toLowerCase(Locale.US); tlds.add(lc); i++; diff --git a/core/java/src/net/i2p/util/NativeBigInteger.java b/core/java/src/net/i2p/util/NativeBigInteger.java index afb380cf9..96129b5ac 100644 --- a/core/java/src/net/i2p/util/NativeBigInteger.java +++ b/core/java/src/net/i2p/util/NativeBigInteger.java @@ -35,6 +35,7 @@ import freenet.support.CPUInformation.UnknownCPUException; import net.i2p.I2PAppContext; import net.i2p.crypto.CryptoConstants; +import net.i2p.data.DataHelper; /** *

BigInteger that takes advantage of the jbigi library for the modPow operation, @@ -734,7 +735,7 @@ public class NativeBigInteger extends BigInteger { in = new BufferedReader(new InputStreamReader(new FileInputStream("/proc/cpuinfo"), "ISO-8859-1"), 4096); String line = null; while ( (line = in.readLine()) != null) { - String[] parts = line.split(":", 2); + String[] parts = DataHelper.split(line, ":", 2); if (parts.length < 2) continue; String key = parts[0].trim().toLowerCase(Locale.US); diff --git a/router/java/src/net/i2p/router/startup/WorkingDir.java b/router/java/src/net/i2p/router/startup/WorkingDir.java index 8e3a19c93..a7ca9f330 100644 --- a/router/java/src/net/i2p/router/startup/WorkingDir.java +++ b/router/java/src/net/i2p/router/startup/WorkingDir.java @@ -211,7 +211,7 @@ public class WorkingDir { String[] files = dir.list(); if (files == null) return false; - String migrated[] = MIGRATE_BASE.split(","); + String migrated[] = DataHelper.split(MIGRATE_BASE, ","); for (String file: files) { for (int i = 0; i < migrated.length; i++) { if (file.equals(migrated[i])) @@ -282,7 +282,7 @@ public class WorkingDir { private static boolean migrate(String list, File olddir, File todir) { boolean rv = true; - String files[] = list.split(","); + String files[] = DataHelper.split(list, ","); for (int i = 0; i < files.length; i++) { File from = new File(olddir, files[i]); if (!copy(from, todir)) { diff --git a/router/java/src/net/i2p/router/time/Zones.java b/router/java/src/net/i2p/router/time/Zones.java index 85d5e388e..d04c67408 100644 --- a/router/java/src/net/i2p/router/time/Zones.java +++ b/router/java/src/net/i2p/router/time/Zones.java @@ -10,6 +10,7 @@ import java.util.Locale; import java.util.Map; import net.i2p.I2PAppContext; +import net.i2p.data.DataHelper; import net.i2p.router.transport.GeoIP; /** @@ -105,7 +106,7 @@ class Zones { try { if (line.charAt(0) == '#') continue; - String[] s = line.split(","); + String[] s = DataHelper.split(line, ","); String ucContinent = s[1].toUpperCase(Locale.US).trim(); String zone = _continentToZone.get(ucContinent); if (zone == null) diff --git a/router/java/src/net/i2p/router/transport/GeoIP.java b/router/java/src/net/i2p/router/transport/GeoIP.java index 3213be64e..6a2040164 100644 --- a/router/java/src/net/i2p/router/transport/GeoIP.java +++ b/router/java/src/net/i2p/router/transport/GeoIP.java @@ -17,6 +17,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; import net.i2p.I2PAppContext; +import net.i2p.data.DataHelper; import net.i2p.data.Hash; import net.i2p.router.Router; import net.i2p.router.RouterContext; @@ -209,7 +210,7 @@ public class GeoIP { if (line.charAt(0) == '#') { continue; } - String[] s = line.split(","); + String[] s = DataHelper.split(line, ","); String lc = s[0].toLowerCase(Locale.US); _codeToName.put(lc, s[1]); _codeCache.put(lc, lc); @@ -274,7 +275,7 @@ public class GeoIP { if (buf.charAt(0) == '#') { continue; } - String[] s = buf.split(","); + String[] s = DataHelper.split(buf, ","); long ip1 = Long.parseLong(s[0]); long ip2 = Long.parseLong(s[1]); while (idx < search.length && search[idx].longValue() < ip1) { diff --git a/router/java/src/net/i2p/router/transport/GeoIPv6.java b/router/java/src/net/i2p/router/transport/GeoIPv6.java index b93e3f004..af3120480 100644 --- a/router/java/src/net/i2p/router/transport/GeoIPv6.java +++ b/router/java/src/net/i2p/router/transport/GeoIPv6.java @@ -170,7 +170,7 @@ class GeoIPv6 { if (buf.charAt(0) == '#') { continue; } - String[] s = buf.split(","); + String[] s = DataHelper.split(buf, ","); String ips1 = s[0].replace("\"", "").trim(); String ips2 = s[1].replace("\"", "").trim(); byte[] ip1 = InetAddress.getByName(ips1).getAddress(); diff --git a/router/java/src/net/i2p/router/transport/UPnP.java b/router/java/src/net/i2p/router/transport/UPnP.java index 26c7610b5..b94d8cec0 100644 --- a/router/java/src/net/i2p/router/transport/UPnP.java +++ b/router/java/src/net/i2p/router/transport/UPnP.java @@ -224,7 +224,7 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener { boolean ignore = false; String toIgnore = _context.getProperty(PROP_IGNORE); if (toIgnore != null) { - String[] ignores = toIgnore.split("[,; \r\n\t]"); + String[] ignores = DataHelper.split(toIgnore, "[,; \r\n\t]"); for (int i = 0; i < ignores.length; i++) { if (ignores[i].equals(udn)) { ignore = true; 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 edcfef26b..b68626ab5 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java @@ -340,7 +340,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority List bindToAddrs = new ArrayList(4); if (bindTo != null) { - String[] bta = bindTo.split("[,; \r\n\t]"); + String[] bta = DataHelper.split(bindTo, "[,; \r\n\t]"); for (int i = 0; i < bta.length; i++) { String bt = bta[i]; if (bt.length() <= 0) @@ -1896,7 +1896,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority if (explicitAddressSpecified()) { host = _context.getProperty(PROP_EXTERNAL_HOST); if (host != null) { - String[] hosts = host.split("[,; \r\n\t]"); + String[] hosts = DataHelper.split(host, "[,; \r\n\t]"); RouterAddress rv = null; for (int i = 0; i < hosts.length; i++) { String h = hosts[i]; diff --git a/router/java/src/net/i2p/router/util/EventLog.java b/router/java/src/net/i2p/router/util/EventLog.java index 1cad4b9b4..14f829dbe 100644 --- a/router/java/src/net/i2p/router/util/EventLog.java +++ b/router/java/src/net/i2p/router/util/EventLog.java @@ -13,6 +13,7 @@ import java.util.SortedMap; import java.util.TreeMap; import net.i2p.I2PAppContext; +import net.i2p.data.DataHelper; import net.i2p.util.SecureFileOutputStream; /** @@ -125,7 +126,7 @@ public class EventLog { String line = null; while ( (line = br.readLine()) != null) { try { - String[] s = line.split(" ", 3); + String[] s = DataHelper.split(line, " ", 3); if (!s[1].equals(event)) continue; long time = Long.parseLong(s[0]); @@ -167,7 +168,7 @@ public class EventLog { String line = null; while ( (line = br.readLine()) != null) { try { - String[] s = line.split(" ", 2); + String[] s = DataHelper.split(line, " ", 2); if (s.length < 2) continue; long time = Long.parseLong(s[0]); From 8e7718856044b21c14b4dfa55cacd3cca6afd014 Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 7 Nov 2015 22:38:05 +0000 Subject: [PATCH 03/33] Replace URL with URI where possible URL bad for anon and has traps like equals() --- .../src/org/klomp/snark/I2PSnarkUtil.java | 8 +-- .../src/org/klomp/snark/TrackerClient.java | 20 +++---- .../i2p/client/streaming/I2PSocketEepGet.java | 30 ++++++---- .../i2p/router/web/ConfigReseedHandler.java | 10 ++-- .../src/net/i2p/apps/systray/UrlLauncher.java | 17 +++--- core/java/src/net/i2p/util/EepGet.java | 46 +++++++++------ core/java/src/net/i2p/util/EepHead.java | 26 ++++++--- core/java/src/net/i2p/util/PartialEepGet.java | 12 +++- core/java/src/net/i2p/util/SSLEepGet.java | 22 +++---- .../networkdb/reseed/ReseedChecker.java | 4 +- .../i2p/router/networkdb/reseed/Reseeder.java | 58 +++++++++---------- .../src/net/i2p/router/transport/UPnP.java | 12 ++-- 12 files changed, 151 insertions(+), 114 deletions(-) diff --git a/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java b/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java index 96f380435..07fc3058a 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java +++ b/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java @@ -3,8 +3,8 @@ package org.klomp.snark; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; +import java.net.URI; +import java.net.URISyntaxException; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -590,10 +590,10 @@ public class I2PSnarkUtil { */ public boolean isKnownOpenTracker(String url) { try { - URL u = new URL(url); + URI u = new URI(url); String host = u.getHost(); return host != null && SnarkManager.KNOWN_OPENTRACKERS.contains(host); - } catch (MalformedURLException mue) { + } catch (URISyntaxException use) { return false; } } diff --git a/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java b/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java index 11efe94f6..2e75906c8 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java +++ b/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java @@ -23,8 +23,8 @@ package org.klomp.snark; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; +import java.net.URI; +import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -880,13 +880,13 @@ public class TrackerClient implements Runnable { * @since 0.7.12 */ public static boolean isValidAnnounce(String ann) { - URL url; + URI url; try { - url = new URL(ann); - } catch (MalformedURLException mue) { + url = new URI(ann); + } catch (URISyntaxException use) { return false; } - return url.getProtocol().equals("http") && + return "http".equals(url.getScheme()) && url.getHost() != null && (url.getHost().endsWith(".i2p") || url.getHost().equals("i2p")); } @@ -896,13 +896,13 @@ public class TrackerClient implements Runnable { * @since 0.9.5 */ private static Hash getHostHash(String ann) { - URL url; + URI url; try { - url = new URL(ann); - } catch (MalformedURLException mue) { + url = new URI(ann); + } catch (URISyntaxException use) { return null; } - if (!url.getProtocol().equals("http")) + if (!"http".equals(url.getScheme())) return null; String host = url.getHost(); if (host.endsWith(".i2p")) diff --git a/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketEepGet.java b/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketEepGet.java index 1b67bd226..052eef96c 100644 --- a/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketEepGet.java +++ b/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketEepGet.java @@ -5,7 +5,8 @@ import java.io.IOException; import java.io.OutputStream; import java.net.MalformedURLException; import java.net.UnknownHostException; -import java.net.URL; +import java.net.URI; +import java.net.URISyntaxException; import java.util.Locale; import java.util.Properties; @@ -112,8 +113,8 @@ public class I2PSocketEepGet extends EepGet { if (_socket != null) try { _socket.close(); } catch (IOException ioe) {} try { - URL url = new URL(_actualURL); - if ("http".equals(url.getProtocol())) { + URI url = new URI(_actualURL); + if ("http".equals(url.getScheme())) { String host = url.getHost(); int port = url.getPort(); if (port <= 0 || port > 65535) @@ -123,13 +124,13 @@ public class I2PSocketEepGet extends EepGet { // Rewrite the url to strip out the /i2p/, // as the naming service accepts B64KEY (but not B64KEY.i2p atm) if ("i2p".equals(host)) { - String file = url.getFile(); + String file = url.getPath(); try { int slash = 1 + file.substring(1).indexOf("/"); host = file.substring(1, slash); _actualURL = "http://" + host + file.substring(slash); } catch (IndexOutOfBoundsException ioobe) { - throw new IOException("Bad /i2p/ format: " + _actualURL); + throw new MalformedURLException("Bad /i2p/ format: " + _actualURL); } } @@ -173,12 +174,14 @@ public class I2PSocketEepGet extends EepGet { opts.setPort(port); _socket = _socketManager.connect(dest, opts); } else { - throw new IOException("Unsupported protocol: " + _actualURL); + throw new MalformedURLException("Unsupported protocol: " + _actualURL); } - } catch (MalformedURLException mue) { - throw new IOException("Request URL is invalid: " + _actualURL); + } catch (URISyntaxException use) { + IOException ioe = new MalformedURLException("Bad URL"); + ioe.initCause(use); + throw ioe; } catch (I2PException ie) { - throw new IOException(ie.toString()); + throw new IOException("I2P error", ie); } _proxyIn = _socket.getInputStream(); @@ -202,7 +205,14 @@ public class I2PSocketEepGet extends EepGet { @Override protected String getRequest() throws IOException { StringBuilder buf = new StringBuilder(2048); - URL url = new URL(_actualURL); + URI url; + try { + url = new URI(_actualURL); + } catch (URISyntaxException use) { + IOException ioe = new MalformedURLException("Bad URL"); + ioe.initCause(use); + throw ioe; + } //String host = url.getHost(); String path = url.getPath(); String query = url.getQuery(); diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigReseedHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigReseedHandler.java index f7d03555e..ab5e83408 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigReseedHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigReseedHandler.java @@ -2,8 +2,8 @@ package net.i2p.router.web; import java.io.InputStream; import java.io.IOException; -import java.net.URL; -import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -37,10 +37,10 @@ public class ConfigReseedHandler extends FormHandler { addFormError(_t("You must enter a URL")); return; } - URL url; + URI url; try { - url = new URL(val); - } catch (MalformedURLException mue) { + url = new URI(val); + } catch (URISyntaxException mue) { addFormError(_t("Bad URL {0}", val)); return; } diff --git a/apps/systray/java/src/net/i2p/apps/systray/UrlLauncher.java b/apps/systray/java/src/net/i2p/apps/systray/UrlLauncher.java index 7604169b0..7169bc8f3 100644 --- a/apps/systray/java/src/net/i2p/apps/systray/UrlLauncher.java +++ b/apps/systray/java/src/net/i2p/apps/systray/UrlLauncher.java @@ -18,7 +18,8 @@ import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.Socket; import java.net.SocketAddress; -import java.net.URL; +import java.net.URI; +import java.net.URISyntaxException; import java.util.Locale; import net.i2p.I2PAppContext; @@ -115,18 +116,16 @@ public class UrlLauncher implements ClientApp { * @return success */ private static boolean waitForServer(String urlString) { - URL url; + URI url; try { - url = new URL(urlString); - } catch (MalformedURLException e) { + url = new URI(urlString); + } catch (URISyntaxException e) { return false; } String host = url.getHost(); int port = url.getPort(); if (port <= 0) { - port = url.getDefaultPort(); - if (port <= 0) - return false; + port = "https".equals(url.getScheme()) ? 443 : 80; } SocketAddress sa; try { @@ -261,8 +260,8 @@ public class UrlLauncher implements ClientApp { private static boolean validateUrlFormat(String urlString) { try { // just to check validity - new URL(urlString); - } catch (MalformedURLException e) { + new URI(urlString); + } catch (URISyntaxException e) { return false; } return true; diff --git a/core/java/src/net/i2p/util/EepGet.java b/core/java/src/net/i2p/util/EepGet.java index 386ec0308..81ec7c8e4 100644 --- a/core/java/src/net/i2p/util/EepGet.java +++ b/core/java/src/net/i2p/util/EepGet.java @@ -15,7 +15,8 @@ import java.net.InetSocketAddress; import java.net.MalformedURLException; import java.net.Socket; import java.net.UnknownHostException; -import java.net.URL; +import java.net.URI; +import java.net.URISyntaxException; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Date; @@ -321,12 +322,12 @@ public class EepGet { * @return a filename to save the resource as on local filesystem */ public static String suggestName(String url) { - URL nameURL = null; // URL object + URI nameURL = null; String name; // suggested name try { - nameURL = new URL(url); - } catch (MalformedURLException e) { + nameURL = new URI(url); + } catch (URISyntaxException e) { System.err.println("Please enter a properly formed URL."); System.exit(1); } @@ -722,24 +723,25 @@ public class EepGet { if (_redirectLocation != null) { // we also are here after a 407 - //try { + try { if (_redirectLocation.startsWith("http://")) { _actualURL = _redirectLocation; } else { // the Location: field has been required to be an absolute URI at least since // RFC 1945 (HTTP/1.0 1996), so it isn't clear what the point of this is. // This oddly adds a ":" even if no port, but that seems to work. - URL url = new URL(_actualURL); + URI url = new URI(_actualURL); if (_redirectLocation.startsWith("/")) _actualURL = "http://" + url.getHost() + ":" + url.getPort() + _redirectLocation; else // this blows up completely on a redirect to https://, for example _actualURL = "http://" + url.getHost() + ":" + url.getPort() + "/" + _redirectLocation; } - // an MUE is an IOE - //} catch (MalformedURLException mue) { - // throw new IOException("Redirected from an invalid URL"); - //} + } catch (URISyntaxException use) { + IOException ioe = new MalformedURLException("Redirected to invalid URL"); + ioe.initCause(use); + throw ioe; + } AuthState as = _authState; if (_responseCode == 407) { @@ -1226,9 +1228,9 @@ public class EepGet { if (_shouldProxy) { _proxy = InternalSocket.getSocket(_proxyHost, _proxyPort); } else { - //try { - URL url = new URL(_actualURL); - if ("http".equals(url.getProtocol())) { + try { + URI url = new URI(_actualURL); + if ("http".equals(url.getScheme())) { String host = url.getHost(); String hostlc = host.toLowerCase(Locale.US); if (hostlc.endsWith(".i2p")) @@ -1248,10 +1250,11 @@ public class EepGet { } else { throw new MalformedURLException("URL is not supported:" + _actualURL); } - // an MUE is an IOE - //} catch (MalformedURLException mue) { - // throw new IOException("Request URL is invalid"); - //} + } catch (URISyntaxException use) { + IOException ioe = new MalformedURLException("Request URL is invalid"); + ioe.initCause(use); + throw ioe; + } } _proxyIn = _proxy.getInputStream(); if (!(_proxy instanceof InternalSocket)) @@ -1273,7 +1276,14 @@ public class EepGet { boolean post = false; if ( (_postData != null) && (_postData.length() > 0) ) post = true; - URL url = new URL(_actualURL); + URI url; + try { + url = new URI(_actualURL); + } catch (URISyntaxException use) { + IOException ioe = new MalformedURLException("Bad URL"); + ioe.initCause(use); + throw ioe; + } String host = url.getHost(); if (host == null || host.length() <= 0) throw new MalformedURLException("Bad URL, no host"); diff --git a/core/java/src/net/i2p/util/EepHead.java b/core/java/src/net/i2p/util/EepHead.java index c1ddb6282..2c49d708b 100644 --- a/core/java/src/net/i2p/util/EepHead.java +++ b/core/java/src/net/i2p/util/EepHead.java @@ -6,7 +6,9 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; -import java.net.URL; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; import gnu.getopt.Getopt; @@ -176,24 +178,25 @@ public class EepHead extends EepGet { // Should we even follow redirects for HEAD? if (_redirectLocation != null) { - //try { + try { if (_redirectLocation.startsWith("http://")) { _actualURL = _redirectLocation; } else { // the Location: field has been required to be an absolute URI at least since // RFC 1945 (HTTP/1.0 1996), so it isn't clear what the point of this is. // This oddly adds a ":" even if no port, but that seems to work. - URL url = new URL(_actualURL); + URI url = new URI(_actualURL); if (_redirectLocation.startsWith("/")) _actualURL = "http://" + url.getHost() + ":" + url.getPort() + _redirectLocation; else // this blows up completely on a redirect to https://, for example _actualURL = "http://" + url.getHost() + ":" + url.getPort() + "/" + _redirectLocation; } - // an MUE is an IOE - //} catch (MalformedURLException mue) { - // throw new IOException("Redirected from an invalid URL"); - //} + } catch (URISyntaxException use) { + IOException ioe = new MalformedURLException("Redirected to invalid URL"); + ioe.initCause(use); + throw ioe; + } AuthState as = _authState; if (_responseCode == 407) { if (!_shouldProxy) @@ -252,7 +255,14 @@ public class EepHead extends EepGet { @Override protected String getRequest() throws IOException { StringBuilder buf = new StringBuilder(512); - URL url = new URL(_actualURL); + URI url; + try { + url = new URI(_actualURL); + } catch (URISyntaxException use) { + IOException ioe = new MalformedURLException("Bad URL"); + ioe.initCause(use); + throw ioe; + } String host = url.getHost(); int port = url.getPort(); String path = url.getPath(); diff --git a/core/java/src/net/i2p/util/PartialEepGet.java b/core/java/src/net/i2p/util/PartialEepGet.java index baab6e039..0371dbf32 100644 --- a/core/java/src/net/i2p/util/PartialEepGet.java +++ b/core/java/src/net/i2p/util/PartialEepGet.java @@ -6,7 +6,8 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.MalformedURLException; -import java.net.URL; +import java.net.URI; +import java.net.URISyntaxException; import java.util.Locale; import gnu.getopt.Getopt; @@ -167,7 +168,14 @@ public class PartialEepGet extends EepGet { @Override protected String getRequest() throws IOException { StringBuilder buf = new StringBuilder(2048); - URL url = new URL(_actualURL); + URI url; + try { + url = new URI(_actualURL); + } catch (URISyntaxException use) { + IOException ioe = new MalformedURLException("Bad URL"); + ioe.initCause(use); + throw ioe; + } String host = url.getHost(); if (host == null || host.length() <= 0) throw new MalformedURLException("Bad URL, no host"); diff --git a/core/java/src/net/i2p/util/SSLEepGet.java b/core/java/src/net/i2p/util/SSLEepGet.java index 3a6e7ebd9..4cc31e90b 100644 --- a/core/java/src/net/i2p/util/SSLEepGet.java +++ b/core/java/src/net/i2p/util/SSLEepGet.java @@ -46,7 +46,8 @@ import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.net.InetSocketAddress; import java.net.MalformedURLException; -import java.net.URL; +import java.net.URI; +import java.net.URISyntaxException; import java.security.KeyStore; import java.security.GeneralSecurityException; import java.security.cert.CertificateException; @@ -553,11 +554,11 @@ public class SSLEepGet extends EepGet { String req = getRequest(); - //try { - URL url = new URL(_actualURL); - String host = null; - int port = 0; - if ("https".equals(url.getProtocol())) { + String host; + int port; + try { + URI url = new URI(_actualURL); + if ("https".equals(url.getScheme())) { host = url.getHost(); if (host.toLowerCase(Locale.US).endsWith(".i2p")) throw new MalformedURLException("I2P addresses unsupported"); @@ -589,10 +590,11 @@ public class SSLEepGet extends EepGet { } else { throw new MalformedURLException("Only https supported: " + _actualURL); } - // an MUE is an IOE - //} catch (MalformedURLException mue) { - // throw new IOException("Request URL is invalid"); - //} + } catch (URISyntaxException use) { + IOException ioe = new MalformedURLException("Redirected to invalid URL"); + ioe.initCause(use); + throw ioe; + } _proxyIn = _proxy.getInputStream(); _proxyOut = _proxy.getOutputStream(); diff --git a/router/java/src/net/i2p/router/networkdb/reseed/ReseedChecker.java b/router/java/src/net/i2p/router/networkdb/reseed/ReseedChecker.java index d6fc00f4e..25cd334ac 100644 --- a/router/java/src/net/i2p/router/networkdb/reseed/ReseedChecker.java +++ b/router/java/src/net/i2p/router/networkdb/reseed/ReseedChecker.java @@ -3,7 +3,7 @@ package net.i2p.router.networkdb.reseed; import java.io.File; import java.io.InputStream; import java.io.IOException; -import java.net.URL; +import java.net.URI; import java.util.concurrent.atomic.AtomicBoolean; import net.i2p.data.DataHelper; @@ -131,7 +131,7 @@ public class ReseedChecker { * @throws IllegalArgumentException if it doesn't end with zip or su3 * @since 0.9.19 */ - public boolean requestReseed(URL url) throws IllegalArgumentException { + public boolean requestReseed(URI url) throws IllegalArgumentException { if (_inProgress.compareAndSet(false, true)) { Reseeder reseeder = new Reseeder(_context, this); try { 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 59e697253..dfe72e155 100644 --- a/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java +++ b/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java @@ -7,10 +7,8 @@ import java.io.FileOutputStream; import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; -import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; -import java.net.URL; import java.util.Arrays; import java.util.ArrayList; import java.util.Collections; @@ -153,7 +151,7 @@ public class Reseeder { * @throws IllegalArgumentException if it doesn't end with zip or su3 * @since 0.9.19 */ - void requestReseed(URL url) throws IllegalArgumentException { + void requestReseed(URI url) throws IllegalArgumentException { ReseedRunner reseedRunner = new ReseedRunner(url); // set to daemon so it doesn't hang a shutdown Thread reseed = new I2PAppThread(reseedRunner, "Reseed", true); @@ -239,7 +237,7 @@ public class Reseeder { /** bytes per sec for each su3 downloaded */ private final List _bandwidths; private static final int MAX_DATE_SETS = 2; - private final URL _url; + private final URI _url; /** * Start a reseed from the default URL list @@ -256,7 +254,7 @@ public class Reseeder { * @throws IllegalArgumentException if it doesn't end with zip or su3 * @since 0.9.19 */ - public ReseedRunner(URL url) throws IllegalArgumentException { + public ReseedRunner(URI url) throws IllegalArgumentException { String lc = url.getPath().toLowerCase(Locale.US); if (!(lc.endsWith(".zip") || lc.endsWith(".su3"))) throw new IllegalArgumentException("Reseed URL must end with .zip or .su3"); @@ -412,7 +410,7 @@ public class Reseeder { * @return count of routerinfos successfully fetched, or -1 if no valid URLs */ private int reseed(boolean echoStatus) { - List URLList = new ArrayList(); + List URLList = new ArrayList(); String URLs = _context.getProperty(PROP_RESEED_URL); boolean defaulted = URLs == null; boolean SSLDisable = _context.getBooleanProperty(PROP_SSL_DISABLE); @@ -429,29 +427,29 @@ public class Reseeder { if (!u.endsWith("/")) u = u + '/'; try { - URLList.add(new URL(u)); - } catch (MalformedURLException mue) {} + URLList.add(new URI(u)); + } catch (URISyntaxException mue) {} } Collections.shuffle(URLList, _context.random()); if (!SSLDisable && !SSLRequired) { // put the non-SSL at the end of the SSL - List URLList2 = new ArrayList(); + List URLList2 = new ArrayList(); tok = new StringTokenizer(DEFAULT_SEED_URL, " ,"); while (tok.hasMoreTokens()) { String u = tok.nextToken().trim(); if (!u.endsWith("/")) u = u + '/'; try { - URLList2.add(new URL(u)); - } catch (MalformedURLException mue) {} + URLList2.add(new URI(u)); + } catch (URISyntaxException mue) {} } Collections.shuffle(URLList2, _context.random()); URLList.addAll(URLList2); } } else { // custom list given - List SSLList = new ArrayList(); - List nonSSLList = new ArrayList(); + List SSLList = new ArrayList(); + List nonSSLList = new ArrayList(); StringTokenizer tok = new StringTokenizer(URLs, " ,"); while (tok.hasMoreTokens()) { // format tokens @@ -461,12 +459,12 @@ public class Reseeder { // check if ssl or not then add to respective list if (u.startsWith("https")) { try { - SSLList.add(new URL(u)); - } catch (MalformedURLException mue) {} + SSLList.add(new URI(u)); + } catch (URISyntaxException mue) {} } else { try { - nonSSLList.add(new URL(u)); - } catch (MalformedURLException mue) {} + nonSSLList.add(new URI(u)); + } catch (URISyntaxException mue) {} } } // shuffle lists @@ -482,8 +480,8 @@ public class Reseeder { } if (!isSNISupported()) { try { - URLList.remove(new URL("https://netdb.i2p2.no/")); - } catch (MalformedURLException mue) {} + URLList.remove(new URI("https://netdb.i2p2.no/")); + } catch (URISyntaxException mue) {} } if (URLList.isEmpty()) { System.out.println("No valid reseed URLs"); @@ -501,19 +499,19 @@ public class Reseeder { * @param echoStatus apparently always false * @return count of routerinfos successfully fetched */ - private int reseed(List URLList, boolean echoStatus) { + private int reseed(List URLList, boolean echoStatus) { int total = 0; for (int i = 0; i < URLList.size() && _isRunning; i++) { if (_context.router().gracefulShutdownInProgress()) { System.out.println("Reseed aborted, shutdown in progress"); return total; } - URL url = URLList.get(i); + URI url = URLList.get(i); int dl = 0; if (ENABLE_SU3) { try { - dl = reseedSU3(new URL(url.toString() + SU3_FILENAME), echoStatus); - } catch (MalformedURLException mue) {} + dl = reseedSU3(new URI(url.toString() + SU3_FILENAME), echoStatus); + } catch (URISyntaxException mue) {} } if (ENABLE_NON_SU3) { if (dl <= 0) @@ -557,7 +555,7 @@ public class Reseeder { * @param echoStatus apparently always false * @return count of routerinfos successfully fetched **/ - private int reseedOne(URL seedURL, boolean echoStatus) { + private int reseedOne(URI seedURL, boolean echoStatus) { try { // Don't use context clock as we may be adjusting the time final long timeLimit = System.currentTimeMillis() + MAX_TIME_PER_HOST; @@ -659,7 +657,7 @@ public class Reseeder { * @return count of routerinfos successfully fetched * @since 0.9.14 **/ - public int reseedSU3(URL seedURL, boolean echoStatus) { + public int reseedSU3(URI seedURL, boolean echoStatus) { return reseedSU3OrZip(seedURL, true, echoStatus); } @@ -673,7 +671,7 @@ public class Reseeder { * @return count of routerinfos successfully fetched * @since 0.9.19 **/ - public int reseedZip(URL seedURL, boolean echoStatus) { + public int reseedZip(URI seedURL, boolean echoStatus) { return reseedSU3OrZip(seedURL, false, echoStatus); } @@ -687,7 +685,7 @@ public class Reseeder { * @return count of routerinfos successfully fetched * @since 0.9.19 **/ - private int reseedSU3OrZip(URL seedURL, boolean isSU3, boolean echoStatus) { + private int reseedSU3OrZip(URI seedURL, boolean isSU3, boolean echoStatus) { int fetched = 0; int errors = 0; File contentRaw = null; @@ -869,7 +867,7 @@ public class Reseeder { if (ourHash != null && DataHelper.eq(hash, ourHash.getData())) return false; - URL url = new URL(seedURL + (seedURL.endsWith("/") ? "" : "/") + ROUTERINFO_PREFIX + peer + ROUTERINFO_SUFFIX); + URI url = new URI(seedURL + (seedURL.endsWith("/") ? "" : "/") + ROUTERINFO_PREFIX + peer + ROUTERINFO_SUFFIX); byte data[] = readURL(url); if (data == null || data.length <= 0) @@ -878,7 +876,7 @@ public class Reseeder { } /** @return null on error */ - private byte[] readURL(URL url) throws IOException { + private byte[] readURL(URI url) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(4*1024); EepGet get; boolean ssl = url.toString().startsWith("https"); @@ -923,7 +921,7 @@ public class Reseeder { * @return null on error * @since 0.9.14 */ - private File fetchURL(URL url) throws IOException { + private File fetchURL(URI url) throws IOException { File out = new File(_context.getTempDir(), "reseed-" + _context.random().nextInt() + ".tmp"); EepGet get; boolean ssl = url.toString().startsWith("https"); diff --git a/router/java/src/net/i2p/router/transport/UPnP.java b/router/java/src/net/i2p/router/transport/UPnP.java index b94d8cec0..8aab1d1d4 100644 --- a/router/java/src/net/i2p/router/transport/UPnP.java +++ b/router/java/src/net/i2p/router/transport/UPnP.java @@ -4,9 +4,9 @@ package net.i2p.router.transport; import java.net.InetAddress; -import java.net.MalformedURLException; import java.net.UnknownHostException; -import java.net.URL; +import java.net.URI; +import java.net.URISyntaxException; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -823,17 +823,17 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener { String him = _router.getURLBase(); if (him != null && him.length() > 0) { try { - URL url = new URL(him); + URI url = new URI(him); hisIP = url.getHost(); - } catch (MalformedURLException mue) {} + } catch (URISyntaxException use) {} } if (hisIP == null) { him = _router.getLocation(); if (him != null && him.length() > 0) { try { - URL url = new URL(him); + URI url = new URI(him); hisIP = url.getHost(); - } catch (MalformedURLException mue) {} + } catch (URISyntaxException use) {} } } if (hisIP == null) From a3b55ccdea86a0ff8e71fdd13e2219d6a63e1efb Mon Sep 17 00:00:00 2001 From: zzz Date: Sun, 8 Nov 2015 16:43:49 +0000 Subject: [PATCH 04/33] cleanup --- .../router/transport/udp/PacketBuilder.java | 71 ++++++------------- 1 file changed, 21 insertions(+), 50 deletions(-) diff --git a/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java b/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java index 3029f96c3..ac64e7d42 100644 --- a/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java +++ b/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java @@ -57,10 +57,11 @@ to the various messages - a one byte flag and a four byte sending timestamp (*seconds* since the unix epoch). The flag byte contains the following bitfields:

-  bits 0-3: payload type
-     bit 4: rekey?
-     bit 5: extended options included
-  bits 6-7: reserved
+Bit order: 76543210
+  bits 7-4: payload type
+     bit 3: rekey?
+     bit 2: extended options included
+  bits 1-0: reserved
 

If the rekey flag is set, 64 bytes of keying material follow the @@ -166,6 +167,19 @@ class PacketBuilder { private static final String PROP_PADDING = "i2np.udp.padding"; private static final boolean DEFAULT_ENABLE_PADDING = true; + /** + * The nine message types, 0-8, shifted to bits 7-4 for convenience + */ + private static final byte SESSION_REQUEST_FLAG_BYTE = UDPPacket.PAYLOAD_TYPE_SESSION_REQUEST << 4; + private static final byte SESSION_CREATED_FLAG_BYTE = UDPPacket.PAYLOAD_TYPE_SESSION_CREATED << 4; + private static final byte SESSION_CONFIRMED_FLAG_BYTE = UDPPacket.PAYLOAD_TYPE_SESSION_CONFIRMED << 4; + private static final byte PEER_RELAY_REQUEST_FLAG_BYTE = UDPPacket.PAYLOAD_TYPE_RELAY_REQUEST << 4; + private static final byte PEER_RELAY_RESPONSE_FLAG_BYTE = UDPPacket.PAYLOAD_TYPE_RELAY_RESPONSE << 4; + private static final byte PEER_RELAY_INTRO_FLAG_BYTE = UDPPacket.PAYLOAD_TYPE_RELAY_INTRO << 4; + private static final byte DATA_FLAG_BYTE = UDPPacket.PAYLOAD_TYPE_DATA << 4; + private static final byte PEER_TEST_FLAG_BYTE = UDPPacket.PAYLOAD_TYPE_TEST << 4; + private static final byte SESSION_DESTROY_FLAG_BYTE = (byte) (UDPPacket.PAYLOAD_TYPE_SESSION_DESTROY << 4); + /** * @param transport may be null for unit testing only */ @@ -332,7 +346,7 @@ class PacketBuilder { int availableForExplicitAcks = availableForAcks; // make the packet - UDPPacket packet = buildPacketHeader((byte)(UDPPacket.PAYLOAD_TYPE_DATA << 4)); + UDPPacket packet = buildPacketHeader(DATA_FLAG_BYTE); DatagramPacket pkt = packet.getPacket(); byte data[] = pkt.getData(); int off = HEADER_SIZE; @@ -573,7 +587,7 @@ class PacketBuilder { * @param ackBitfields list of ACKBitfield instances to either fully or partially ACK */ public UDPPacket buildACK(PeerState peer, List ackBitfields) { - UDPPacket packet = buildPacketHeader((byte)(UDPPacket.PAYLOAD_TYPE_DATA << 4)); + UDPPacket packet = buildPacketHeader(DATA_FLAG_BYTE); DatagramPacket pkt = packet.getPacket(); byte data[] = pkt.getData(); int off = HEADER_SIZE; @@ -667,12 +681,6 @@ class PacketBuilder { return packet; } - /** - * full flag info for a sessionCreated message. this can be fixed, - * since we never rekey on startup, and don't need any extended options - */ - private static final byte SESSION_CREATED_FLAG_BYTE = (UDPPacket.PAYLOAD_TYPE_SESSION_CREATED << 4); - /** * Build a new SessionCreated packet for the given peer, encrypting it * as necessary. @@ -768,12 +776,6 @@ class PacketBuilder { return packet; } - /** - * full flag info for a sessionRequest message. this can be fixed, - * since we never rekey on startup, and don't need any extended options - */ - private static final byte SESSION_REQUEST_FLAG_BYTE = (UDPPacket.PAYLOAD_TYPE_SESSION_REQUEST << 4); - /** * Build a new SessionRequest packet for the given peer, encrypting it * as necessary. @@ -854,13 +856,6 @@ class PacketBuilder { return packets; } - - /** - * full flag info for a sessionConfirmed message. this can be fixed, - * since we never rekey on startup, and don't need any extended options - */ - private static final byte SESSION_CONFIRMED_FLAG_BYTE = (UDPPacket.PAYLOAD_TYPE_SESSION_CONFIRMED << 4); - /** * Build a new SessionConfirmed packet for the given peer * @@ -1018,7 +1013,7 @@ class PacketBuilder { * @since 0.9.2 */ private UDPPacket buildSessionDestroyPacket(SessionKey cipherKey, SessionKey macKey, InetAddress addr, int port) { - UDPPacket packet = buildPacketHeader((byte)(UDPPacket.PAYLOAD_TYPE_SESSION_DESTROY << 4)); + UDPPacket packet = buildPacketHeader(SESSION_DESTROY_FLAG_BYTE); int off = HEADER_SIZE; // no body in this message @@ -1034,12 +1029,6 @@ class PacketBuilder { return packet; } - /** - * full flag info for a peerTest message. this can be fixed, - * since we never rekey on test, and don't need any extended options - */ - private static final byte PEER_TEST_FLAG_BYTE = (UDPPacket.PAYLOAD_TYPE_TEST << 4); - /** * Build a packet as if we are Alice and we either want Bob to begin a * peer test or Charlie to finish a peer test. @@ -1197,12 +1186,6 @@ class PacketBuilder { packet.setMessageType(TYPE_TCB); return packet; } - - /** - * full flag info for a relay request message. this can be fixed, - * since we never rekey on relay request, and don't need any extended options - */ - private static final byte PEER_RELAY_REQUEST_FLAG_BYTE = (UDPPacket.PAYLOAD_TYPE_RELAY_REQUEST << 4); // specify these if we know what our external receive ip/port is and if its different // from what bob is going to think @@ -1330,12 +1313,6 @@ class PacketBuilder { return packet; } - /** - * full flag info for a relay intro message. this can be fixed, - * since we never rekey on relay request, and don't need any extended options - */ - private static final byte PEER_RELAY_INTRO_FLAG_BYTE = (UDPPacket.PAYLOAD_TYPE_RELAY_INTRO << 4); - UDPPacket buildRelayIntro(RemoteHostId alice, PeerState charlie, UDPPacketReader.RelayRequestReader request) { UDPPacket packet = buildPacketHeader(PEER_RELAY_INTRO_FLAG_BYTE); DatagramPacket pkt = packet.getPacket(); @@ -1370,12 +1347,6 @@ class PacketBuilder { packet.setMessageType(TYPE_INTRO); return packet; } - - /** - * full flag info for a relay response message. this can be fixed, - * since we never rekey on relay response, and don't need any extended options - */ - private static final byte PEER_RELAY_RESPONSE_FLAG_BYTE = (UDPPacket.PAYLOAD_TYPE_RELAY_RESPONSE << 4); UDPPacket buildRelayResponse(RemoteHostId alice, PeerState charlie, long nonce, SessionKey cipherKey, SessionKey macKey) { From 63ddf11799b4d560289be06636189c87ccd4ecdc Mon Sep 17 00:00:00 2001 From: zzz Date: Sun, 8 Nov 2015 18:14:19 +0000 Subject: [PATCH 05/33] use float for efficiency --- core/java/src/net/i2p/data/DataHelper.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/java/src/net/i2p/data/DataHelper.java b/core/java/src/net/i2p/data/DataHelper.java index 980a01c52..f2c83a48e 100644 --- a/core/java/src/net/i2p/data/DataHelper.java +++ b/core/java/src/net/i2p/data/DataHelper.java @@ -1617,11 +1617,11 @@ public class DataHelper { * NOTE: formatDuration2() recommended in most cases for readability */ public static String formatSize(long bytes) { - double val = bytes; + float val = bytes; int scale = 0; - while (val >= 1024) { + while (val >= 1024.0f) { scale++; - val /= 1024; + val /= 1024.0f; } DecimalFormat fmt = new DecimalFormat("##0.00"); From bdde11c0ef1c8808f2f870e043d4984ff49c7eb8 Mon Sep 17 00:00:00 2001 From: zzz Date: Sun, 8 Nov 2015 18:14:42 +0000 Subject: [PATCH 06/33] Fix NPE from URL->URI conversion new URL(null) throws MUE new URI(null) throws NPE --- apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java b/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java index 2e75906c8..fc48c6d87 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java +++ b/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java @@ -875,16 +875,18 @@ public class TrackerClient implements Runnable { } /** - * @param ann an announce URL + * @param ann an announce URL, may be null, returns false if null * @return true for i2p hosts only * @since 0.7.12 */ public static boolean isValidAnnounce(String ann) { + if (ann == null) + return false; URI url; try { - url = new URI(ann); + url = new URI(ann); } catch (URISyntaxException use) { - return false; + return false; } return "http".equals(url.getScheme()) && url.getHost() != null && (url.getHost().endsWith(".i2p") || url.getHost().equals("i2p")); From a3e16614aeb98ec4616a088263a964c188b6fb6e Mon Sep 17 00:00:00 2001 From: zzz Date: Sun, 8 Nov 2015 18:30:51 +0000 Subject: [PATCH 07/33] SSU: Prep for extended options --- .../router/transport/udp/PacketBuilder.java | 36 ++++++++++-- .../i2p/router/transport/udp/UDPPacket.java | 16 +++++- .../router/transport/udp/UDPPacketReader.java | 57 +++++++++++++++---- 3 files changed, 91 insertions(+), 18 deletions(-) diff --git a/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java b/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java index ac64e7d42..07f9ec341 100644 --- a/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java +++ b/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java @@ -783,10 +783,13 @@ class PacketBuilder { * @return ready to send packet, or null if there was a problem */ public UDPPacket buildSessionRequestPacket(OutboundEstablishState state) { + // TODO + //byte[] options = new byte[3]; + //UDPPacket packet = buildPacketHeader(SESSION_REQUEST_FLAG_BYTE, options); UDPPacket packet = buildPacketHeader(SESSION_REQUEST_FLAG_BYTE); DatagramPacket pkt = packet.getPacket(); byte data[] = pkt.getData(); - int off = HEADER_SIZE; + int off = HEADER_SIZE; // + 1 + options.length; byte toIP[] = state.getSentIP(); if (!_transport.isValid(toIP)) { @@ -1433,24 +1436,49 @@ class PacketBuilder { /** * Create a new packet and add the flag byte and the time stamp. * Caller should add data starting at HEADER_SIZE. - * At this point, adding support for extended options and rekeying is unlikely, - * but if we do, we'll have to change this. + * Does not include extended options or rekeying. * * @param flagByte contains type and flags * @since 0.8.1 */ private UDPPacket buildPacketHeader(byte flagByte) { + return buildPacketHeader(flagByte, null); + } + + /** + * Create a new packet and add the flag byte and the time stamp. + * Caller should add data starting at HEADER_SIZE. + * (if extendedOptions != null, at HEADER_SIZE + 1 + extendedOptions.length) + * Does not include rekeying. + * + * @param flagByte contains type and flags + * @param extendedOptions May be null. If non-null, we will add the associated flag here. + * 255 bytes max. + * @since 0.9.24 + */ + private UDPPacket buildPacketHeader(byte flagByte, byte[] extendedOptions) { UDPPacket packet = UDPPacket.acquire(_context, false); byte data[] = packet.getPacket().getData(); Arrays.fill(data, 0, data.length, (byte)0x0); int off = UDPPacket.MAC_SIZE + UDPPacket.IV_SIZE; // header + if (extendedOptions != null) + flagByte |= UDPPacket.HEADER_FLAG_EXTENDED_OPTIONS; data[off] = flagByte; off++; long now = (_context.clock().now() + 500) / 1000; DataHelper.toLong(data, off, 4, now); - // todo: add support for rekeying and extended options + // todo: add support for rekeying + // extended options + if (extendedOptions != null) { + off+= 4; + int len = extendedOptions.length; + if (len > 255) + throw new IllegalArgumentException(); + data[off++] = (byte) len; + System.arraycopy(extendedOptions, 0, data, off, len); + } return packet; } diff --git a/router/java/src/net/i2p/router/transport/udp/UDPPacket.java b/router/java/src/net/i2p/router/transport/udp/UDPPacket.java index e2e1b3f59..fae13ab1f 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPPacket.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPPacket.java @@ -89,14 +89,26 @@ class UDPPacket implements CDQEntry { /** @since 0.8.1 */ public static final int PAYLOAD_TYPE_SESSION_DESTROY = 8; + // various flag fields for use in the header + /** + * Defined in the spec from the beginning, Unused + * @since 0.9.24 + */ + public static final byte HEADER_FLAG_REKEY = (1 << 3); + /** + * Defined in the spec from the beginning, Used starting in 0.9.24 + * @since 0.9.24 + */ + public static final byte HEADER_FLAG_EXTENDED_OPTIONS = (1 << 2); + // various flag fields for use in the data packets public static final byte DATA_FLAG_EXPLICIT_ACK = (byte)(1 << 7); public static final byte DATA_FLAG_ACK_BITFIELDS = (1 << 6); - // unused + /** unused */ public static final byte DATA_FLAG_ECN = (1 << 4); public static final byte DATA_FLAG_WANT_ACKS = (1 << 3); public static final byte DATA_FLAG_WANT_REPLY = (1 << 2); - // unused + /** unused */ public static final byte DATA_FLAG_EXTENDED = (1 << 1); public static final byte BITFIELD_CONTINUATION = (byte)(1 << 7); diff --git a/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java b/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java index adacea03f..18c27806a 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java @@ -67,13 +67,19 @@ class UDPPacketReader { return (_message[_payloadBeginOffset] & 0xFF) >>> 4; } - /** does this packet include rekeying data? */ - public boolean readRekeying() { - return (_message[_payloadBeginOffset] & (1 << 3)) != 0; + /** + * Does this packet include rekeying data in the header? + * Unused, should always be false. + */ + public boolean isRekeyingIncluded() { + return (_message[_payloadBeginOffset] & UDPPacket.HEADER_FLAG_REKEY) != 0; } - public boolean readExtendedOptionsIncluded() { - return (_message[_payloadBeginOffset] & (1 << 2)) != 0; + /** + * Does this packet include extended options in the header? + */ + public boolean isExtendedOptionsIncluded() { + return (_message[_payloadBeginOffset] & UDPPacket.HEADER_FLAG_EXTENDED_OPTIONS) != 0; } /** @return seconds */ @@ -81,19 +87,46 @@ class UDPPacketReader { return DataHelper.fromLong(_message, _payloadBeginOffset + 1, 4); } - public void readKeyingMaterial(byte target[], int targetOffset) { - if (!readRekeying()) - throw new IllegalStateException("This packet is not rekeying!"); - System.arraycopy(_message, _payloadBeginOffset + 1 + 4, target, targetOffset, KEYING_MATERIAL_LENGTH); + /** + * Returns rekeying data (64 bytes), or null if none. + * Unused, should always return null. + * + * @deprecated unused + */ + @Deprecated + public byte[] readKeyingMaterial() { + if (!isRekeyingIncluded()) + return null; + byte[] rv = new byte[KEYING_MATERIAL_LENGTH]; + System.arraycopy(_message, _payloadBeginOffset + 1 + 4, rv, 0, KEYING_MATERIAL_LENGTH); + return rv; + } + + /** + * Returns extended option data, 0-255 bytes, or null if none. + * + * @return extended options or null if none is included + * @since 0.9.24 + */ + public byte[] readExtendedOptions() { + if (!isExtendedOptionsIncluded()) + return null; + int offset = _payloadBeginOffset + 1 + 4; + if (isRekeyingIncluded()) + offset += KEYING_MATERIAL_LENGTH; + int optionsSize = _message[offset++] & 0xff; + byte[] rv = new byte[optionsSize]; + System.arraycopy(_message, offset, rv, 0, optionsSize); + return rv; } /** index into the message where the body begins */ private int readBodyOffset() { int offset = _payloadBeginOffset + 1 + 4; - if (readRekeying()) + if (isRekeyingIncluded()) offset += KEYING_MATERIAL_LENGTH; - if (readExtendedOptionsIncluded()) { - int optionsSize = (int)DataHelper.fromLong(_message, offset, 1); + if (isExtendedOptionsIncluded()) { + int optionsSize = _message[offset] & 0xff; offset += optionsSize + 1; } return offset; From e120a8a3a324bf5e881aae2e17dc20be478c324f Mon Sep 17 00:00:00 2001 From: zzz Date: Sun, 8 Nov 2015 18:49:05 +0000 Subject: [PATCH 08/33] Don't use DataHelper.readLong() for 1-byte reads, for efficiency --- .../router/transport/udp/UDPPacketReader.java | 100 +++++++++--------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java b/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java index 18c27806a..39eddeda5 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java @@ -185,13 +185,13 @@ class UDPPacketReader { public int readIPSize() { int offset = readBodyOffset() + X_LENGTH; - return (int)DataHelper.fromLong(_message, offset, 1); + return _message[offset] & 0xff; } /** what IP bob is reachable on */ public void readIP(byte target[], int targetOffset) { int offset = readBodyOffset() + X_LENGTH; - int size = (int)DataHelper.fromLong(_message, offset, 1); + int size = _message[offset] & 0xff; offset++; System.arraycopy(_message, offset, target, targetOffset, size); } @@ -208,13 +208,13 @@ class UDPPacketReader { /** sizeof(IP) */ public int readIPSize() { int offset = readBodyOffset() + Y_LENGTH; - return (int)DataHelper.fromLong(_message, offset, 1); + return _message[offset] & 0xff; } /** what IP do they think we are coming on? */ public void readIP(byte target[], int targetOffset) { int offset = readBodyOffset() + Y_LENGTH; - int size = (int)DataHelper.fromLong(_message, offset, 1); + int size = _message[offset] & 0xff; offset++; System.arraycopy(_message, offset, target, targetOffset, size); } @@ -340,7 +340,7 @@ class UDPPacketReader { public int readACKCount() { if (!readACKsIncluded()) return 0; int off = readBodyOffset() + 1; - return (int)DataHelper.fromLong(_message, off, 1); + return _message[off] & 0xff; } public long readACK(int index) { @@ -355,12 +355,12 @@ class UDPPacketReader { if (!readACKBitfieldsIncluded()) return null; int off = readBodyOffset() + 1; if (readACKsIncluded()) { - int numACKs = (int)DataHelper.fromLong(_message, off, 1); + int numACKs = _message[off] & 0xff; off++; off += 4 * numACKs; } - int numBitfields = (int)DataHelper.fromLong(_message, off, 1); + int numBitfields = _message[off] & 0xff; off++; PacketACKBitfield rv[] = new PacketACKBitfield[numBitfields]; @@ -374,12 +374,12 @@ class UDPPacketReader { public int readFragmentCount() throws DataFormatException { int off = readBodyOffset() + 1; if (readACKsIncluded()) { - int numACKs = (int)DataHelper.fromLong(_message, off, 1); + int numACKs = _message[off] & 0xff; off++; off += 4 * numACKs; } if (readACKBitfieldsIncluded()) { - int numBitfields = (int)DataHelper.fromLong(_message, off, 1); + int numBitfields = _message[off] & 0xff; off++; for (int i = 0; i < numBitfields; i++) { @@ -388,7 +388,7 @@ class UDPPacketReader { } } if (readExtendedDataIncluded()) { - int size = (int)DataHelper.fromLong(_message, off, 1); + int size = _message[off] & 0xff; off++; off += size; } @@ -430,12 +430,12 @@ class UDPPacketReader { private int getFragmentBegin(int fragmentNum) throws DataFormatException { int off = readBodyOffset() + 1; if (readACKsIncluded()) { - int numACKs = (int)DataHelper.fromLong(_message, off, 1); + int numACKs = _message[off] & 0xff; off++; off += 4 * numACKs; } if (readACKBitfieldsIncluded()) { - int numBitfields = (int)DataHelper.fromLong(_message, off, 1); + int numBitfields = _message[off] & 0xff; off++; PacketACKBitfield bf[] = new PacketACKBitfield[numBitfields]; @@ -445,7 +445,7 @@ class UDPPacketReader { } } if (readExtendedDataIncluded()) { - int size = (int)DataHelper.fromLong(_message, off, 1); + int size = _message[off] & 0xff; off++; off += size; } @@ -476,7 +476,7 @@ class UDPPacketReader { buf.append(" "); int off = readBodyOffset() + 1; if (readACKsIncluded()) { - int numACKs = (int)DataHelper.fromLong(_message, off, 1); + int numACKs = _message[off] & 0xff; off++; buf.append("with ACKs for "); for (int i = 0; i < numACKs; i++) { @@ -485,7 +485,7 @@ class UDPPacketReader { } } if (readACKBitfieldsIncluded()) { - int numBitfields = (int)DataHelper.fromLong(_message, off, 1); + int numBitfields = _message[off] & 0xff; off++; buf.append("with partial ACKs for "); @@ -501,7 +501,7 @@ class UDPPacketReader { } } if (readExtendedDataIncluded()) { - int size = (int)DataHelper.fromLong(_message, off, 1); + int size = _message[off] & 0xff; off++; buf.append("with extended size of "); buf.append(size); @@ -509,7 +509,7 @@ class UDPPacketReader { off += size; } - int numFragments = (int)DataHelper.fromLong(_message, off, 1); + int numFragments = _message[off] & 0xff; off++; buf.append("with fragmentCount of "); buf.append(numFragments); @@ -653,13 +653,13 @@ class UDPPacketReader { public int readIPSize() { int offset = readBodyOffset() + NONCE_LENGTH; - return (int)DataHelper.fromLong(_message, offset, 1); + return _message[offset] & 0xff; } /** what IP Alice is reachable on */ public void readIP(byte target[], int targetOffset) { int offset = readBodyOffset() + NONCE_LENGTH; - int size = (int)DataHelper.fromLong(_message, offset, 1); + int size = _message[offset] & 0xff; offset++; System.arraycopy(_message, offset, target, targetOffset, size); } @@ -667,7 +667,7 @@ class UDPPacketReader { /** what IP Alice is reachable on */ public int readPort() { int offset = readBodyOffset() + NONCE_LENGTH; - int size = (int)DataHelper.fromLong(_message, offset, 1); + int size = _message[offset] & 0xff; offset++; offset += size; // skip the IP return (int)DataHelper.fromLong(_message, offset, 2); @@ -676,7 +676,7 @@ class UDPPacketReader { /** what Alice's intro key is (if known - if unknown, the key is INVALID_KEY) */ public void readIntroKey(byte target[], int targetOffset) { int offset = readBodyOffset() + NONCE_LENGTH; - int size = (int)DataHelper.fromLong(_message, offset, 1); + int size = _message[offset] & 0xff; offset++; offset += size; // skip the IP offset += 2; // skip the port @@ -694,7 +694,7 @@ class UDPPacketReader { } public int readIPSize() { int offset = readBodyOffset() + 4; - int rv = (int)DataHelper.fromLong(_message, offset, 1); + int rv = _message[offset] & 0xff; if (_log.shouldLog(Log.DEBUG)) _log.debug("read alice ip size: " + rv); return rv; @@ -703,7 +703,7 @@ class UDPPacketReader { /** what IP Alice is reachable on */ public void readIP(byte target[], int targetOffset) { int offset = readBodyOffset() + 4; - int size = (int)DataHelper.fromLong(_message, offset, 1); + int size = _message[offset] & 0xff; offset++; System.arraycopy(_message, offset, target, targetOffset, size); if (_log.shouldLog(Log.DEBUG)) @@ -711,7 +711,7 @@ class UDPPacketReader { } public int readPort() { int offset = readBodyOffset() + 4; - offset += DataHelper.fromLong(_message, offset, 1); + offset += _message[offset] & 0xff; offset++; int rv = (int)DataHelper.fromLong(_message, offset, 2); if (_log.shouldLog(Log.DEBUG)) @@ -722,10 +722,10 @@ class UDPPacketReader { /** unused */ public int readChallengeSize() { int offset = readBodyOffset() + 4; - offset += DataHelper.fromLong(_message, offset, 1); + offset += _message[offset] & 0xff; offset++; offset += 2; - int rv = (int)DataHelper.fromLong(_message, offset, 1); + int rv = _message[offset] & 0xff; if (_log.shouldLog(Log.DEBUG)) _log.debug("read challenge size: " + rv); return rv; @@ -734,10 +734,10 @@ class UDPPacketReader { /** unused */ public void readChallengeSize(byte target[], int targetOffset) { int offset = readBodyOffset() + 4; - offset += DataHelper.fromLong(_message, offset, 1); + offset += _message[offset] & 0xff; offset++; offset += 2; - int sz = (int)DataHelper.fromLong(_message, offset, 1); + int sz = _message[offset] & 0xff; offset++; System.arraycopy(_message, offset, target, targetOffset, sz); if (_log.shouldLog(Log.DEBUG)) @@ -745,10 +745,10 @@ class UDPPacketReader { } public void readAliceIntroKey(byte target[], int targetOffset) { int offset = readBodyOffset() + 4; - offset += DataHelper.fromLong(_message, offset, 1); + offset += _message[offset] & 0xff; offset++; offset += 2; - int sz = (int)DataHelper.fromLong(_message, offset, 1); + int sz = _message[offset] & 0xff; offset++; offset += sz; System.arraycopy(_message, offset, target, targetOffset, SessionKey.KEYSIZE_BYTES); @@ -758,10 +758,10 @@ class UDPPacketReader { } public long readNonce() { int offset = readBodyOffset() + 4; - offset += DataHelper.fromLong(_message, offset, 1); + offset += _message[offset] & 0xff; offset++; offset += 2; - int sz = (int)DataHelper.fromLong(_message, offset, 1); + int sz = _message[offset] & 0xff; offset++; offset += sz; offset += SessionKey.KEYSIZE_BYTES; @@ -776,19 +776,19 @@ class UDPPacketReader { public class RelayIntroReader { public int readIPSize() { int offset = readBodyOffset(); - return (int)DataHelper.fromLong(_message, offset, 1); + return _message[offset] & 0xff; } /** what IP Alice is reachable on */ public void readIP(byte target[], int targetOffset) { int offset = readBodyOffset(); - int size = (int)DataHelper.fromLong(_message, offset, 1); + int size = _message[offset] & 0xff; offset++; System.arraycopy(_message, offset, target, targetOffset, size); } public int readPort() { int offset = readBodyOffset(); - offset += DataHelper.fromLong(_message, offset, 1); + offset += _message[offset] & 0xff; offset++; return (int)DataHelper.fromLong(_message, offset, 2); } @@ -796,19 +796,19 @@ class UDPPacketReader { /** unused */ public int readChallengeSize() { int offset = readBodyOffset(); - offset += DataHelper.fromLong(_message, offset, 1); + offset += _message[offset] & 0xff; offset++; offset += 2; - return (int)DataHelper.fromLong(_message, offset, 1); + return _message[offset] & 0xff; } /** unused */ public void readChallengeSize(byte target[], int targetOffset) { int offset = readBodyOffset(); - offset += DataHelper.fromLong(_message, offset, 1); + offset += _message[offset] & 0xff; offset++; offset += 2; - int sz = (int)DataHelper.fromLong(_message, offset, 1); + int sz = _message[offset] & 0xff; offset++; System.arraycopy(_message, offset, target, targetOffset, sz); } @@ -819,19 +819,19 @@ class UDPPacketReader { public class RelayResponseReader { public int readCharlieIPSize() { int offset = readBodyOffset(); - return (int)DataHelper.fromLong(_message, offset, 1); + return _message[offset] & 0xff; } /** what IP charlie is reachable on */ public void readCharlieIP(byte target[], int targetOffset) { int offset = readBodyOffset(); - int size = (int)DataHelper.fromLong(_message, offset, 1); + int size = _message[offset] & 0xff; offset++; System.arraycopy(_message, offset, target, targetOffset, size); } /** what port charlie is reachable on */ public int readCharliePort() { int offset = readBodyOffset(); - offset += DataHelper.fromLong(_message, offset, 1); + offset += _message[offset] & 0xff; offset++; return (int)DataHelper.fromLong(_message, offset, 2); } @@ -839,38 +839,38 @@ class UDPPacketReader { /** @deprecated unused */ public int readAliceIPSize() { int offset = readBodyOffset(); - offset += DataHelper.fromLong(_message, offset, 1); + offset += _message[offset] & 0xff; offset++; offset += 2; - return (int)DataHelper.fromLong(_message, offset, 1); + return _message[offset] & 0xff; } /** @deprecated unused */ public void readAliceIP(byte target[], int targetOffset) { int offset = readBodyOffset(); - offset += DataHelper.fromLong(_message, offset, 1); + offset += _message[offset] & 0xff; offset++; offset += 2; - int sz = (int)DataHelper.fromLong(_message, offset, 1); + int sz = _message[offset] & 0xff; offset++; System.arraycopy(_message, offset, target, targetOffset, sz); } /** @deprecated unused */ public int readAlicePort() { int offset = readBodyOffset(); - offset += DataHelper.fromLong(_message, offset, 1); + offset += _message[offset] & 0xff; offset++; offset += 2; - int sz = (int)DataHelper.fromLong(_message, offset, 1); + int sz = _message[offset] & 0xff; offset++; offset += sz; return (int)DataHelper.fromLong(_message, offset, 2); } public long readNonce() { int offset = readBodyOffset(); - offset += DataHelper.fromLong(_message, offset, 1); + offset += _message[offset] & 0xff; offset++; offset += 2; - int sz = (int)DataHelper.fromLong(_message, offset, 1); + int sz = _message[offset] & 0xff; offset++; offset += sz; offset += 2; From 1aed266f70e466abf778554be165b2592c26b8b2 Mon Sep 17 00:00:00 2001 From: zzz Date: Sun, 8 Nov 2015 19:17:32 +0000 Subject: [PATCH 09/33] Consolidate increments of offset, for efficiency --- .../router/transport/udp/UDPPacketReader.java | 39 +++++++------------ 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java b/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java index 39eddeda5..34f8d7bf7 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java @@ -539,8 +539,7 @@ class UDPPacketReader { buf.append(" payload: "); int off = getFragmentBegin(0); // first fragment - off += 4; // messageId - off++; // fragment info + off += 4 + 1; // messageId + fragment info int size = ((int)DataHelper.fromLong(_message, off, 2)) & 0x3FFF; off += 2; buf.append(Base64.encode(_message, off, size)); @@ -677,9 +676,8 @@ class UDPPacketReader { public void readIntroKey(byte target[], int targetOffset) { int offset = readBodyOffset() + NONCE_LENGTH; int size = _message[offset] & 0xff; - offset++; + offset += 1 + 2; // skip the size + port offset += size; // skip the IP - offset += 2; // skip the port System.arraycopy(_message, offset, target, targetOffset, SessionKey.KEYSIZE_BYTES); } } @@ -723,8 +721,7 @@ class UDPPacketReader { public int readChallengeSize() { int offset = readBodyOffset() + 4; offset += _message[offset] & 0xff; - offset++; - offset += 2; + offset += 1 + 2; int rv = _message[offset] & 0xff; if (_log.shouldLog(Log.DEBUG)) _log.debug("read challenge size: " + rv); @@ -735,8 +732,7 @@ class UDPPacketReader { public void readChallengeSize(byte target[], int targetOffset) { int offset = readBodyOffset() + 4; offset += _message[offset] & 0xff; - offset++; - offset += 2; + offset += 1 + 2; int sz = _message[offset] & 0xff; offset++; System.arraycopy(_message, offset, target, targetOffset, sz); @@ -746,8 +742,7 @@ class UDPPacketReader { public void readAliceIntroKey(byte target[], int targetOffset) { int offset = readBodyOffset() + 4; offset += _message[offset] & 0xff; - offset++; - offset += 2; + offset += 1 + 2; int sz = _message[offset] & 0xff; offset++; offset += sz; @@ -759,8 +754,7 @@ class UDPPacketReader { public long readNonce() { int offset = readBodyOffset() + 4; offset += _message[offset] & 0xff; - offset++; - offset += 2; + offset += 1 + 2; int sz = _message[offset] & 0xff; offset++; offset += sz; @@ -797,8 +791,7 @@ class UDPPacketReader { public int readChallengeSize() { int offset = readBodyOffset(); offset += _message[offset] & 0xff; - offset++; - offset += 2; + offset += 1 + 2; return _message[offset] & 0xff; } @@ -806,8 +799,7 @@ class UDPPacketReader { public void readChallengeSize(byte target[], int targetOffset) { int offset = readBodyOffset(); offset += _message[offset] & 0xff; - offset++; - offset += 2; + offset += 1 + 2; int sz = _message[offset] & 0xff; offset++; System.arraycopy(_message, offset, target, targetOffset, sz); @@ -840,16 +832,14 @@ class UDPPacketReader { public int readAliceIPSize() { int offset = readBodyOffset(); offset += _message[offset] & 0xff; - offset++; - offset += 2; + offset += 1 + 2; return _message[offset] & 0xff; } /** @deprecated unused */ public void readAliceIP(byte target[], int targetOffset) { int offset = readBodyOffset(); offset += _message[offset] & 0xff; - offset++; - offset += 2; + offset += 1 + 2; int sz = _message[offset] & 0xff; offset++; System.arraycopy(_message, offset, target, targetOffset, sz); @@ -858,8 +848,7 @@ class UDPPacketReader { public int readAlicePort() { int offset = readBodyOffset(); offset += _message[offset] & 0xff; - offset++; - offset += 2; + offset += 1 + 2; int sz = _message[offset] & 0xff; offset++; offset += sz; @@ -868,12 +857,10 @@ class UDPPacketReader { public long readNonce() { int offset = readBodyOffset(); offset += _message[offset] & 0xff; - offset++; - offset += 2; + offset += 1 + 2; int sz = _message[offset] & 0xff; - offset++; + offset += 1 + 2; // sz + port offset += sz; - offset += 2; return DataHelper.fromLong(_message, offset, 4); } } From 1451dc6eceb80cce3d0ceecdcd108b9620faeadd Mon Sep 17 00:00:00 2001 From: zzz Date: Sun, 8 Nov 2015 20:43:42 +0000 Subject: [PATCH 10/33] More: Don't use DataHelper.readLong() for 1-byte reads, for efficiency --- .../java/src/net/i2p/client/streaming/impl/Packet.java | 4 ++-- core/java/src/net/i2p/data/Certificate.java | 2 +- .../src/net/i2p/data/i2np/DatabaseSearchReplyMessage.java | 2 +- router/java/src/net/i2p/data/i2np/DeliveryInstructions.java | 2 +- router/java/src/net/i2p/data/i2np/FastI2NPMessageImpl.java | 2 +- router/java/src/net/i2p/data/i2np/I2NPMessageHandler.java | 2 +- router/java/src/net/i2p/data/i2np/I2NPMessageImpl.java | 4 ++-- .../src/net/i2p/data/i2np/VariableTunnelBuildMessage.java | 2 +- .../net/i2p/data/i2np/VariableTunnelBuildReplyMessage.java | 2 +- .../java/src/net/i2p/router/message/GarlicMessageParser.java | 2 +- router/java/src/net/i2p/router/tunnel/BuildReplyHandler.java | 2 +- router/java/src/net/i2p/router/tunnel/FragmentHandler.java | 2 +- 12 files changed, 14 insertions(+), 14 deletions(-) diff --git a/apps/streaming/java/src/net/i2p/client/streaming/impl/Packet.java b/apps/streaming/java/src/net/i2p/client/streaming/impl/Packet.java index a872b2d77..a887dc3d2 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/impl/Packet.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/impl/Packet.java @@ -585,7 +585,7 @@ class Packet { cur += 4; setAckThrough(DataHelper.fromLong(buffer, cur, 4)); cur += 4; - int numNacks = (int)DataHelper.fromLong(buffer, cur, 1); + int numNacks = buffer[cur] & 0xff; cur++; if (length < 22 + numNacks*4) throw new IllegalArgumentException("Too small with " + numNacks + " nacks: " + length); @@ -599,7 +599,7 @@ class Packet { } else { setNacks(null); } - setResendDelay((int)DataHelper.fromLong(buffer, cur, 1)); + setResendDelay(buffer[cur] & 0xff); cur++; setFlags((int)DataHelper.fromLong(buffer, cur, 2)); cur += 2; diff --git a/core/java/src/net/i2p/data/Certificate.java b/core/java/src/net/i2p/data/Certificate.java index aa2624b8a..aefc34ce6 100644 --- a/core/java/src/net/i2p/data/Certificate.java +++ b/core/java/src/net/i2p/data/Certificate.java @@ -215,7 +215,7 @@ public class Certificate extends DataStructureImpl { throw new DataFormatException("Cert is too small [" + source.length + " off=" + offset + "]"); int cur = offset; - _type = (int)DataHelper.fromLong(source, cur, 1); + _type = source[cur] & 0xff; cur++; int length = (int)DataHelper.fromLong(source, cur, 2); cur += 2; diff --git a/router/java/src/net/i2p/data/i2np/DatabaseSearchReplyMessage.java b/router/java/src/net/i2p/data/i2np/DatabaseSearchReplyMessage.java index 4a5c94638..1df280349 100644 --- a/router/java/src/net/i2p/data/i2np/DatabaseSearchReplyMessage.java +++ b/router/java/src/net/i2p/data/i2np/DatabaseSearchReplyMessage.java @@ -68,7 +68,7 @@ public class DatabaseSearchReplyMessage extends FastI2NPMessageImpl { curIndex += Hash.HASH_LENGTH; //_key = new Hash(keyData); - int num = (int)DataHelper.fromLong(data, curIndex, 1); + int num = data[curIndex] & 0xff; curIndex++; _peerHashes.clear(); diff --git a/router/java/src/net/i2p/data/i2np/DeliveryInstructions.java b/router/java/src/net/i2p/data/i2np/DeliveryInstructions.java index 9669d6f91..5f5941512 100644 --- a/router/java/src/net/i2p/data/i2np/DeliveryInstructions.java +++ b/router/java/src/net/i2p/data/i2np/DeliveryInstructions.java @@ -209,7 +209,7 @@ public class DeliveryInstructions extends DataStructureImpl { public int readBytes(byte data[], int offset) throws DataFormatException { int cur = offset; - long flags = DataHelper.fromLong(data, cur, 1); + int flags = data[cur] & 0xff; cur++; //if (_log.shouldLog(Log.DEBUG)) // _log.debug("Read flags: " + flags + " mode: " + flagMode(flags)); diff --git a/router/java/src/net/i2p/data/i2np/FastI2NPMessageImpl.java b/router/java/src/net/i2p/data/i2np/FastI2NPMessageImpl.java index 564d0f726..912a9e2b9 100644 --- a/router/java/src/net/i2p/data/i2np/FastI2NPMessageImpl.java +++ b/router/java/src/net/i2p/data/i2np/FastI2NPMessageImpl.java @@ -85,7 +85,7 @@ public abstract class FastI2NPMessageImpl extends I2NPMessageImpl { throw new I2NPMessageException("Payload is too short " + maxLen); int cur = offset; if (type < 0) { - type = (int)DataHelper.fromLong(data, cur, 1); + type = data[cur] & 0xff; cur++; } _uniqueId = DataHelper.fromLong(data, cur, 4); diff --git a/router/java/src/net/i2p/data/i2np/I2NPMessageHandler.java b/router/java/src/net/i2p/data/i2np/I2NPMessageHandler.java index fe1225f74..f1ea685f9 100644 --- a/router/java/src/net/i2p/data/i2np/I2NPMessageHandler.java +++ b/router/java/src/net/i2p/data/i2np/I2NPMessageHandler.java @@ -109,7 +109,7 @@ public class I2NPMessageHandler { public int readMessage(byte data[], int offset, int maxLen) throws I2NPMessageException { int cur = offset; // we will assume that maxLen is >= 1 here. It's checked to be >= 16 in readBytes() - int type = (int)DataHelper.fromLong(data, cur, 1); + int type = data[cur] & 0xff; cur++; _lastReadBegin = System.currentTimeMillis(); I2NPMessage msg = I2NPMessageImpl.createMessage(_context, type); diff --git a/router/java/src/net/i2p/data/i2np/I2NPMessageImpl.java b/router/java/src/net/i2p/data/i2np/I2NPMessageImpl.java index 5f14c3fef..062e310b1 100644 --- a/router/java/src/net/i2p/data/i2np/I2NPMessageImpl.java +++ b/router/java/src/net/i2p/data/i2np/I2NPMessageImpl.java @@ -197,7 +197,7 @@ public abstract class I2NPMessageImpl extends DataStructureImpl implements I2NPM throw new I2NPMessageException("Payload is too short " + maxLen); int cur = offset; if (type < 0) { - type = (int)DataHelper.fromLong(data, cur, 1); + type = data[cur] & 0xff; cur++; } _uniqueId = DataHelper.fromLong(data, cur, 4); @@ -413,7 +413,7 @@ public abstract class I2NPMessageImpl extends DataStructureImpl implements I2NPM */ public static I2NPMessage fromRawByteArray(I2PAppContext ctx, byte buffer[], int offset, int len, I2NPMessageHandler handler) throws I2NPMessageException { - int type = (int)DataHelper.fromLong(buffer, offset, 1); + int type = buffer[offset] & 0xff; offset++; I2NPMessage msg = createMessage(ctx, type); if (msg == null) diff --git a/router/java/src/net/i2p/data/i2np/VariableTunnelBuildMessage.java b/router/java/src/net/i2p/data/i2np/VariableTunnelBuildMessage.java index b33cba761..52aa565de 100644 --- a/router/java/src/net/i2p/data/i2np/VariableTunnelBuildMessage.java +++ b/router/java/src/net/i2p/data/i2np/VariableTunnelBuildMessage.java @@ -29,7 +29,7 @@ public class VariableTunnelBuildMessage extends TunnelBuildMessage { @Override public void readMessage(byte[] data, int offset, int dataSize, int type) throws I2NPMessageException { // message type will be checked in super() - int r = (int)DataHelper.fromLong(data, offset, 1); + int r = data[offset] & 0xff; if (r <= 0 || r > MAX_RECORD_COUNT) throw new I2NPMessageException("Bad record count " + r); RECORD_COUNT = r; diff --git a/router/java/src/net/i2p/data/i2np/VariableTunnelBuildReplyMessage.java b/router/java/src/net/i2p/data/i2np/VariableTunnelBuildReplyMessage.java index 368104a2a..575f55630 100644 --- a/router/java/src/net/i2p/data/i2np/VariableTunnelBuildReplyMessage.java +++ b/router/java/src/net/i2p/data/i2np/VariableTunnelBuildReplyMessage.java @@ -31,7 +31,7 @@ public class VariableTunnelBuildReplyMessage extends TunnelBuildReplyMessage { @Override public void readMessage(byte[] data, int offset, int dataSize, int type) throws I2NPMessageException { // message type will be checked in super() - int r = (int)DataHelper.fromLong(data, offset, 1); + int r = data[offset] & 0xff; if (r <= 0 || r > MAX_RECORD_COUNT) throw new I2NPMessageException("Bad record count " + r); RECORD_COUNT = r; diff --git a/router/java/src/net/i2p/router/message/GarlicMessageParser.java b/router/java/src/net/i2p/router/message/GarlicMessageParser.java index df83702a2..ef0e5f0b7 100644 --- a/router/java/src/net/i2p/router/message/GarlicMessageParser.java +++ b/router/java/src/net/i2p/router/message/GarlicMessageParser.java @@ -75,7 +75,7 @@ public class GarlicMessageParser { private CloveSet readCloveSet(byte data[]) throws DataFormatException { int offset = 0; - int numCloves = (int)DataHelper.fromLong(data, offset, 1); + int numCloves = data[offset] & 0xff; offset++; if (_log.shouldLog(Log.DEBUG)) _log.debug("# cloves to read: " + numCloves); diff --git a/router/java/src/net/i2p/router/tunnel/BuildReplyHandler.java b/router/java/src/net/i2p/router/tunnel/BuildReplyHandler.java index 2196a851e..8514d6db1 100644 --- a/router/java/src/net/i2p/router/tunnel/BuildReplyHandler.java +++ b/router/java/src/net/i2p/router/tunnel/BuildReplyHandler.java @@ -120,7 +120,7 @@ public class BuildReplyHandler { return -1; } else { SimpleByteCache.release(h); - int rv = (int)DataHelper.fromLong(data, TunnelBuildReplyMessage.RECORD_SIZE - 1, 1); + int rv = data[TunnelBuildReplyMessage.RECORD_SIZE - 1] & 0xff; if (log.shouldLog(Log.DEBUG)) log.debug(reply.getUniqueId() + ": Verified: " + rv + " for record " + recordNum + "/" + hop); return rv; diff --git a/router/java/src/net/i2p/router/tunnel/FragmentHandler.java b/router/java/src/net/i2p/router/tunnel/FragmentHandler.java index 6e0d0675f..eef132712 100644 --- a/router/java/src/net/i2p/router/tunnel/FragmentHandler.java +++ b/router/java/src/net/i2p/router/tunnel/FragmentHandler.java @@ -340,7 +340,7 @@ class FragmentHandler { offset += 4; } if (extended) { - int extendedSize = (int)DataHelper.fromLong(preprocessed, offset, 1); + int extendedSize = preprocessed[offset] & 0xff; offset++; offset += extendedSize; // we don't interpret these yet, but skip them for now } From c1afbd37d75bef479abff814f595b25ad0d7bea9 Mon Sep 17 00:00:00 2001 From: zzz Date: Wed, 11 Nov 2015 13:48:38 +0000 Subject: [PATCH 11/33] SSU: Version check to send extended options --- .../router/transport/udp/EstablishmentManager.java | 14 +++++++++++++- .../transport/udp/OutboundEstablishState.java | 8 +++++++- .../i2p/router/transport/udp/PacketBuilder.java | 2 ++ 3 files changed, 22 insertions(+), 2 deletions(-) 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 89076f9ce..53e7e9d8d 100644 --- a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java +++ b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java @@ -29,6 +29,7 @@ import net.i2p.router.util.DecayingBloomFilter; import net.i2p.util.Addresses; import net.i2p.util.I2PThread; import net.i2p.util.Log; +import net.i2p.util.VersionComparator; /** * Coordinate the establishment of new sessions - both inbound and outbound. @@ -126,6 +127,14 @@ class EstablishmentManager { /** for the DSM and or netdb store */ private static final int DATA_MESSAGE_TIMEOUT = 10*1000; + /** + * Java I2P has always parsed the length of the extended options field, + * but i2pd hasn't recognized it until this release. + * No matter, the options weren't defined until this release anyway. + */ + private static final String VERSION_ALLOW_EXTENDED_OPTIONS = "0.9.24"; + + public EstablishmentManager(RouterContext ctx, UDPTransport transport) { _context = ctx; _log = ctx.logManager().getLog(EstablishmentManager.class); @@ -356,8 +365,10 @@ class EstablishmentManager { _transport.failed(msg, "Peer has bad key, cannot establish"); return; } + boolean allowExtendedOptions = VersionComparator.comp(toRouterInfo.getVersion(), + VERSION_ALLOW_EXTENDED_OPTIONS) >= 0; state = new OutboundEstablishState(_context, maybeTo, to, - toIdentity, + toIdentity, allowExtendedOptions, sessionKey, addr, _transport.getDHFactory()); OutboundEstablishState oldState = _outboundStates.putIfAbsent(to, state); boolean isNew = oldState == null; @@ -477,6 +488,7 @@ class EstablishmentManager { // Don't offer to relay to privileged ports. // Only offer for an IPv4 session. // TODO if already we have their RI, only offer if they need it (no 'C' cap) + // TODO if extended options, only if they asked for it if (_transport.canIntroduce() && state.getSentPort() >= 1024 && state.getSentIP().length == 4) { // ensure > 0 diff --git a/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java b/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java index 63497b5ea..cfb0d2f57 100644 --- a/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java +++ b/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java @@ -56,6 +56,7 @@ class OutboundEstablishState { private RemoteHostId _remoteHostId; private final RemoteHostId _claimedAddress; private final RouterIdentity _remotePeer; + private final boolean _allowExtendedOptions; private final SessionKey _introKey; private final Queue _queuedMessages; private OutboundState _currentState; @@ -112,7 +113,8 @@ class OutboundEstablishState { */ public OutboundEstablishState(RouterContext ctx, RemoteHostId claimedAddress, RemoteHostId remoteHostId, - RouterIdentity remotePeer, SessionKey introKey, UDPAddress addr, + RouterIdentity remotePeer, boolean allowExtendedOptions, + SessionKey introKey, UDPAddress addr, DHSessionKeyBuilder.Factory dh) { _context = ctx; _log = ctx.logManager().getLog(OutboundEstablishState.class); @@ -125,6 +127,7 @@ class OutboundEstablishState { } _claimedAddress = claimedAddress; _remoteHostId = remoteHostId; + _allowExtendedOptions = allowExtendedOptions; _remotePeer = remotePeer; _introKey = introKey; _queuedMessages = new LinkedBlockingQueue(); @@ -157,6 +160,9 @@ class OutboundEstablishState { /** @return -1 if unset */ public long getIntroNonce() { return _introductionNonce; } + + /** @since 0.9.24 */ + public boolean isExtendedOptionsAllowed() { return _allowExtendedOptions; } /** * Queue a message to be sent after the session is established. diff --git a/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java b/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java index 07f9ec341..594388716 100644 --- a/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java +++ b/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java @@ -784,6 +784,8 @@ class PacketBuilder { */ public UDPPacket buildSessionRequestPacket(OutboundEstablishState state) { // TODO + // boolean ext = state.isExtendedOptionsAllowed(); + // if (ext) //byte[] options = new byte[3]; //UDPPacket packet = buildPacketHeader(SESSION_REQUEST_FLAG_BYTE, options); UDPPacket packet = buildPacketHeader(SESSION_REQUEST_FLAG_BYTE); From 37a4fcb469e18a3822682659ffffbc13279c6664 Mon Sep 17 00:00:00 2001 From: zzz Date: Thu, 12 Nov 2015 16:02:01 +0000 Subject: [PATCH 12/33] i2psnark: Minor details page reformatting --- .../org/klomp/snark/web/I2PSnarkServlet.java | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) 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 b0335f6a8..5da8e2f43 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java +++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java @@ -2714,7 +2714,7 @@ public class I2PSnarkServlet extends BasicServlet { if (snark != null) { // first table - torrent info buf.append("\n"); - buf.append(""); } @@ -2769,7 +2769,7 @@ public class I2PSnarkServlet extends BasicServlet { if (alist != null && !alist.isEmpty()) { buf.append("\n"); @@ -2808,7 +2808,7 @@ public class I2PSnarkServlet extends BasicServlet { String date = fmt.format(new Date(dat)); buf.append("\n"); @@ -2819,7 +2819,7 @@ public class I2PSnarkServlet extends BasicServlet { cby = com.substring(0, 128); buf.append("\n"); @@ -2829,7 +2829,7 @@ public class I2PSnarkServlet extends BasicServlet { String date = fmt.format(new Date(dates[0])); buf.append("\n"); @@ -2838,7 +2838,7 @@ public class I2PSnarkServlet extends BasicServlet { String date = fmt.format(new Date(dates[1])); buf.append("\n"); @@ -2852,7 +2852,7 @@ public class I2PSnarkServlet extends BasicServlet { buf.append("&tr=").append(announce); buf.append("\">") .append(toImg("magnet", _t("Magnet link"))) - .append("Magnet:\n"); } else { - buf.append("\n"); } @@ -2874,7 +2876,7 @@ public class I2PSnarkServlet extends BasicServlet { buf.append("
") + buf.append("
") .append(_t("Torrent")) .append(": ") .append(DataHelper.escapeHTML(snark.getBaseName())) @@ -2724,7 +2724,7 @@ public class I2PSnarkServlet extends BasicServlet { String baseName = encodePath((new File(fullPath)).getName()); buf.append("
"); toThemeImg(buf, "file"); - buf.append(" ") + buf.append("") .append(_t("Torrent file")) .append(": ") .append(DataHelper.escapeHTML(fullPath)) @@ -2732,7 +2732,7 @@ public class I2PSnarkServlet extends BasicServlet { if (snark.getStorage() != null) { buf.append("
"); toThemeImg(buf, "file"); - buf.append(" ") + buf.append("") .append(_t("Data location")) .append(": ") .append(DataHelper.escapeHTML(snark.getStorage().getBase().getPath())) @@ -2741,7 +2741,7 @@ public class I2PSnarkServlet extends BasicServlet { String hex = I2PSnarkUtil.toHex(snark.getInfoHash()); buf.append("
"); toThemeImg(buf, "details"); - buf.append(" ") + buf.append("") .append(_t("Info hash")) .append(": ") .append(hex.toUpperCase(Locale.US)) @@ -2761,7 +2761,7 @@ public class I2PSnarkServlet extends BasicServlet { buf.append(trackerLink); else toThemeImg(buf, "details"); - buf.append(" ").append(_t("Primary Tracker")).append(": "); + buf.append("").append(_t("Primary Tracker")).append(": "); buf.append(getShortTrackerLink(announce, snark.getInfoHash())); buf.append("
"); toThemeImg(buf, "details"); - buf.append(" ") + buf.append("") .append(_t("Tracker List")).append(": "); for (List alist2 : alist) { buf.append('['); @@ -2794,7 +2794,7 @@ public class I2PSnarkServlet extends BasicServlet { com = com.substring(0, 1024); buf.append("
"); toThemeImg(buf, "details"); - buf.append(" ") + buf.append("") .append(_t("Comment")).append(": ") .append(DataHelper.stripHTML(com)) .append("
"); toThemeImg(buf, "details"); - buf.append(" ") + buf.append("") .append(_t("Created")).append(": ") .append(date) .append("
"); toThemeImg(buf, "details"); - buf.append(" ") + buf.append("") .append(_t("Created By")).append(": ") .append(DataHelper.stripHTML(cby)) .append("
"); toThemeImg(buf, "details"); - buf.append(" ") + buf.append("") .append(_t("Added")).append(": ") .append(date) .append("
"); toThemeImg(buf, "details"); - buf.append(" ") + buf.append("") .append(_t("Completed")).append(": ") .append(date) .append("
Magnet: ") .append("
") + buf.append("
"); + toThemeImg(buf, "details"); + buf.append("") .append(_t("Private torrent")) .append("
"); toThemeImg(buf, "size"); - buf.append(" ") + buf.append("") .append(_t("Size")) .append(": ") .append(formatSize(snark.getTotalLength())); @@ -2943,20 +2945,19 @@ public class I2PSnarkServlet extends BasicServlet { // buttons if (showStopStart) { - buf.append("
"); - toThemeImg(buf, "file"); + buf.append("
"); if (snark.isChecking()) { - buf.append(" ").append(_t("Checking")).append("… ") + buf.append("").append(_t("Checking")).append("… ") .append((new DecimalFormat("0.00%")).format(snark.getCheckingProgress())) .append("   ") .append(_t("Refresh page for results")).append(""); } else if (snark.isStarting()) { - buf.append(" ").append(_t("Starting")).append("…"); + buf.append("").append(_t("Starting")).append("…"); } else if (snark.isAllocating()) { - buf.append(" ").append(_t("Allocating")).append("…"); + buf.append("").append(_t("Allocating")).append("…"); } else { boolean isRunning = !snark.isStopped(); - buf.append(" \n"); else From 51c5da3f7216e687a2ccab385ab0f7a3f34e605a Mon Sep 17 00:00:00 2001 From: zzz Date: Thu, 12 Nov 2015 18:49:13 +0000 Subject: [PATCH 13/33] lint: don't catch Exception, catch RuntimeException or checked exception. omits SAM, BOB, reflection, commented-out code, and a few other places --- .../src/org/klomp/snark/SnarkManager.java | 12 +++++----- .../java/src/org/klomp/snark/Storage.java | 4 ++-- .../src/org/klomp/snark/dht/NodeInfo.java | 2 +- .../net/i2p/i2ptunnel/GunzipOutputStream.java | 8 +++---- .../java/src/net/i2p/i2ptunnel/I2PTunnel.java | 2 +- .../net/i2p/i2ptunnel/I2PTunnelClient.java | 14 ++++++++++- .../i2p/i2ptunnel/I2PTunnelHTTPServer.java | 4 ++-- .../net/i2p/i2ptunnel/I2PTunnelIRCClient.java | 20 +++++++++++++++- .../i2ptunnel/I2PTunnelOutproxyRunner.java | 2 +- .../net/i2p/i2ptunnel/I2PTunnelRunner.java | 2 +- .../net/i2p/i2ptunnel/I2PTunnelServer.java | 2 +- .../net/i2p/i2ptunnel/TunnelController.java | 2 +- .../i2p/i2ptunnel/irc/I2PTunnelDCCClient.java | 10 +++++++- .../net/i2p/i2ptunnel/ui/GeneralHelper.java | 4 +++- .../src/net/i2p/i2ptunnel/web/EditBean.java | 6 ++++- .../src/net/i2p/i2ptunnel/web/IndexBean.java | 12 +++++++--- .../i2p/client/streaming/I2PSocketEepGet.java | 2 +- .../streaming/I2PSocketManagerFactory.java | 4 +++- .../src/net/i2p/router/web/CSSHelper.java | 4 ++-- .../src/net/i2p/router/web/PluginStarter.java | 4 ++-- .../streaming/impl/I2PSocketManagerFull.java | 9 ++++++- .../src/i2p/susi/dns/AddressbookBean.java | 4 ++-- .../src/i2p/susi/dns/NamingServiceBean.java | 2 +- .../src/src/i2p/susi/util/Config.java | 4 ++-- .../src/src/i2p/susi/webmail/Mail.java | 2 +- .../src/src/i2p/susi/webmail/WebMail.java | 2 +- .../webmail/encoding/DecodingException.java | 4 +++- .../i2p/susi/webmail/encoding/HeaderLine.java | 4 +++- .../src/i2p/susi/webmail/smtp/SMTPClient.java | 2 +- .../src/net/i2p/apps/systray/ConfigFile.java | 4 ++-- .../src/net/i2p/apps/systray/SysTray.java | 4 ++-- .../src/net/i2p/apps/systray/UrlLauncher.java | 16 ++++++------- .../net/i2p/client/impl/I2PSessionImpl.java | 2 +- .../i2p/client/impl/I2PSessionMuxedImpl.java | 2 +- .../naming/SingleFileNamingService.java | 4 ++-- core/java/src/net/i2p/crypto/DSAEngine.java | 2 +- core/java/src/net/i2p/crypto/ECConstants.java | 5 ++-- .../src/net/i2p/crypto/ElGamalAESEngine.java | 10 ++++---- core/java/src/net/i2p/crypto/EncType.java | 2 +- .../java/src/net/i2p/crypto/KeyGenerator.java | 4 ++-- .../java/src/net/i2p/crypto/KeyStoreUtil.java | 24 +++++++++++++------ core/java/src/net/i2p/crypto/SigType.java | 5 +++- .../src/net/i2p/crypto/TrustedUpdate.java | 8 +++++-- .../i2p/crypto/eddsa/math/GroupElement.java | 2 +- .../java/src/net/i2p/data/PrivateKeyFile.java | 14 +++++++---- .../net/i2p/data/i2cp/I2CPMessageReader.java | 4 ++-- .../src/net/i2p/stat/BufferedStatLog.java | 2 +- core/java/src/net/i2p/util/EepGet.java | 2 +- core/java/src/net/i2p/util/EepHead.java | 2 +- .../src/net/i2p/util/FortunaRandomSource.java | 5 ++-- core/java/src/net/i2p/util/LogWriterBase.java | 2 +- core/java/src/net/i2p/util/PartialEepGet.java | 2 +- .../i2p/util/ResettableGZIPInputStream.java | 8 +++---- core/java/src/net/i2p/util/SSLEepGet.java | 4 ++-- core/java/src/net/i2p/util/ShellCommand.java | 4 ++-- .../net/metanotion/io/block/BlockFile.java | 2 +- .../java/src/net/i2p/installer/Exec.java | 2 +- .../networkdb/kademlia/BundleRouterInfos.java | 4 ++-- .../src/net/i2p/data/i2np/GarlicClove.java | 4 ++-- .../net/i2p/data/i2np/I2NPMessageHandler.java | 4 ++-- .../net/i2p/data/i2np/I2NPMessageReader.java | 2 +- .../src/net/i2p/data/router/RouterInfo.java | 5 +++- .../src/net/i2p/router/InNetMessagePool.java | 4 ++-- router/java/src/net/i2p/router/Router.java | 5 ++-- .../net/i2p/router/dummy/VMCommSystem.java | 3 ++- .../kademlia/PersistentDataStore.java | 4 ++-- .../i2p/router/networkdb/reseed/Reseeder.java | 2 +- .../peermanager/ProfilePersistenceHelper.java | 4 ++-- .../router/startup/RebuildRouterInfoJob.java | 8 ++++++- .../src/net/i2p/router/transport/UPnP.java | 2 +- .../net/i2p/router/transport/UPnPManager.java | 2 +- .../router/transport/ntcp/EventPumper.java | 4 ++-- .../router/transport/ntcp/NTCPConnection.java | 4 ++-- .../i2p/router/transport/udp/ACKSender.java | 2 +- .../router/transport/udp/MessageReceiver.java | 2 +- .../router/transport/udp/PacketHandler.java | 2 +- .../router/transport/udp/PacketPusher.java | 2 +- .../i2p/router/tunnel/pool/BuildHandler.java | 2 +- 78 files changed, 235 insertions(+), 136 deletions(-) diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java index 5f5bb94d9..f8996d14b 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java +++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java @@ -2051,7 +2051,7 @@ public class SnarkManager implements CompleteListener { synchronized (_snarks) { ok = monitorTorrents(dir); } - } catch (Exception e) { + } catch (RuntimeException e) { _log.error("Error in the DirectoryMonitor", e); ok = false; } @@ -2060,7 +2060,7 @@ public class SnarkManager implements CompleteListener { try { addMagnets(); doMagnets = false; - } catch (Exception e) { + } catch (RuntimeException e) { _log.error("Error in the DirectoryMonitor", e); } if (!_snarks.isEmpty()) @@ -2266,7 +2266,7 @@ public class SnarkManager implements CompleteListener { // Snark.fatal() throws a RuntimeException // don't let one bad torrent kill the whole loop addTorrent(name, null, !shouldAutoStart()); - } catch (Exception e) { + } catch (RuntimeException e) { addMessage(_t("Error: Could not add the torrent {0}", name) + ": " + e); _log.error("Unable to add the torrent " + name, e); rv = false; @@ -2285,7 +2285,7 @@ public class SnarkManager implements CompleteListener { // Snark.fatal() throws a RuntimeException // don't let one bad torrent kill the whole loop stopTorrent(name, true); - } catch (Exception e) { + } catch (RuntimeException e) { // don't bother with message } } @@ -2467,7 +2467,7 @@ public class SnarkManager implements CompleteListener { public void run() { try { run2(); - } catch (Exception e) { + } catch (RuntimeException e) { _log.error("Error starting", e); } } @@ -2595,7 +2595,7 @@ public class SnarkManager implements CompleteListener { } else { addMessageNoEscape(_t("Finished recheck of torrent {0}, unchanged", link)); } - } catch (Exception e) { + } catch (IOException e) { _log.error("Error rechecking " + snark.getBaseName(), e); addMessage(_t("Error checking the torrent {0}", snark.getBaseName()) + ": " + e); } diff --git a/apps/i2psnark/java/src/org/klomp/snark/Storage.java b/apps/i2psnark/java/src/org/klomp/snark/Storage.java index 1edf12b5b..f8771ded3 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/Storage.java +++ b/apps/i2psnark/java/src/org/klomp/snark/Storage.java @@ -748,7 +748,7 @@ public class Storage implements Closeable } rv = repl; } - } catch (Exception ex) { + } catch (RuntimeException ex) { ex.printStackTrace(); } } @@ -1483,7 +1483,7 @@ public class Storage implements Closeable break; } // switch } // while - } catch (Exception e) { + } catch (RuntimeException e) { e.printStackTrace(); error = true; } diff --git a/apps/i2psnark/java/src/org/klomp/snark/dht/NodeInfo.java b/apps/i2psnark/java/src/org/klomp/snark/dht/NodeInfo.java index cd2f73da3..708d2d276 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/dht/NodeInfo.java +++ b/apps/i2psnark/java/src/org/klomp/snark/dht/NodeInfo.java @@ -225,7 +225,7 @@ class NodeInfo extends SimpleDataStructure { NodeInfo ni = (NodeInfo) o; // assume dest matches, ignore it return this.hash.equals(ni.hash) && nID.equals(ni.nID) && port == ni.port; - } catch (Exception e) { + } catch (RuntimeException e) { return false; } } diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/GunzipOutputStream.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/GunzipOutputStream.java index e0798567d..6f5a4c3a7 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/GunzipOutputStream.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/GunzipOutputStream.java @@ -105,7 +105,7 @@ class GunzipOutputStream extends InflaterOutputStream { public long getTotalRead() { try { return inf.getBytesRead(); - } catch (Exception e) { + } catch (RuntimeException e) { return 0; } } @@ -116,7 +116,7 @@ class GunzipOutputStream extends InflaterOutputStream { public long getTotalExpanded() { try { return inf.getBytesWritten(); - } catch (Exception e) { + } catch (RuntimeException e) { // possible NPE in some implementations return 0; } @@ -128,7 +128,7 @@ class GunzipOutputStream extends InflaterOutputStream { public long getRemaining() { try { return inf.getRemaining(); - } catch (Exception e) { + } catch (RuntimeException e) { // possible NPE in some implementations return 0; } @@ -140,7 +140,7 @@ class GunzipOutputStream extends InflaterOutputStream { public boolean getFinished() { try { return inf.finished(); - } catch (Exception e) { + } catch (RuntimeException e) { // possible NPE in some implementations return true; } diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java index 7c0062075..e8680e3d3 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java @@ -1873,7 +1873,7 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { try { result.fromByteArray(content); return result; - } catch (Exception ex) { + } catch (RuntimeException ex) { if (log.shouldLog(Log.INFO)) log.info("File is not a binary destination - trying base64"); try { diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClient.java index 93785e326..4b1284cfe 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClient.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClient.java @@ -3,6 +3,7 @@ */ package net.i2p.i2ptunnel; +import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException; import java.util.ArrayList; @@ -10,6 +11,7 @@ import java.util.List; import java.util.Properties; import java.util.StringTokenizer; +import net.i2p.I2PException; import net.i2p.client.streaming.I2PSocket; import net.i2p.client.streaming.I2PSocketAddress; import net.i2p.data.Destination; @@ -122,7 +124,17 @@ public class I2PTunnelClient extends I2PTunnelClientBase { // we are called from an unlimited thread pool, so run inline //t.start(); t.run(); - } catch (Exception ex) { + } catch (IOException ex) { + if (_log.shouldLog(Log.INFO)) + _log.info("Error connecting", ex); + //l.log("Error connecting: " + ex.getMessage()); + closeSocket(s); + if (i2ps != null) { + synchronized (sockLock) { + mySockets.remove(sockLock); + } + } + } catch (I2PException ex) { if (_log.shouldLog(Log.INFO)) _log.info("Error connecting", ex); //l.log("Error connecting: " + ex.getMessage()); diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPServer.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPServer.java index dc2c7fa9a..2ae6abba4 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPServer.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPServer.java @@ -742,7 +742,7 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer { public long getTotalRead() { try { return def.getTotalIn(); - } catch (Exception e) { + } catch (RuntimeException e) { // j2se 1.4.2_08 on linux is sometimes throwing an NPE in the getTotalIn() implementation return 0; } @@ -750,7 +750,7 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer { public long getTotalCompressed() { try { return def.getTotalOut(); - } catch (Exception e) { + } catch (RuntimeException e) { // j2se 1.4.2_08 on linux is sometimes throwing an NPE in the getTotalOut() implementation return 0; } diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCClient.java index 7f4c2c22a..f53a72cd1 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCClient.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCClient.java @@ -8,6 +8,7 @@ import java.util.List; import java.util.Properties; import java.util.StringTokenizer; +import net.i2p.I2PException; import net.i2p.client.streaming.I2PSocket; import net.i2p.client.streaming.I2PSocketAddress; import net.i2p.data.DataHelper; @@ -142,7 +143,7 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase { // we are called from an unlimited thread pool, so run inline //out.start(); out.run(); - } catch (Exception ex) { + } catch (IOException ex) { // generally NoRouteToHostException if (_log.shouldLog(Log.WARN)) _log.warn("Error connecting", ex); @@ -160,6 +161,23 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase { mySockets.remove(sockLock); } } + } catch (I2PException ex) { + if (_log.shouldLog(Log.WARN)) + _log.warn("Error connecting", ex); + //l.log("Error connecting: " + ex.getMessage()); + try { + // Send a response so the user doesn't just see a disconnect + // and blame his router or the network. + String name = addr != null ? addr.getHostName() : "undefined"; + String msg = ":" + name + " 499 you :" + ex + "\r\n"; + s.getOutputStream().write(DataHelper.getUTF8(msg)); + } catch (IOException ioe) {} + closeSocket(s); + if (i2ps != null) { + synchronized (sockLock) { + mySockets.remove(sockLock); + } + } } } diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelOutproxyRunner.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelOutproxyRunner.java index 2ed668b7a..d8d9369a0 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelOutproxyRunner.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelOutproxyRunner.java @@ -182,7 +182,7 @@ public class I2PTunnelOutproxyRunner extends I2PAppThread { } catch (IllegalStateException ise) { if (_log.shouldLog(Log.WARN)) _log.warn("gnu?", ise); - } catch (Exception e) { + } catch (RuntimeException e) { if (_log.shouldLog(Log.ERROR)) _log.error("Internal error", e); } finally { diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelRunner.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelRunner.java index 2acd7cfc8..b8bfdaebf 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelRunner.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelRunner.java @@ -326,7 +326,7 @@ public class I2PTunnelRunner extends I2PAppThread implements I2PSocket.SocketErr // at net.i2p.i2ptunnel.I2PTunnelRunner.run(I2PTunnelRunner.java:167) if (_log.shouldLog(Log.WARN)) _log.warn("gnu?", ise); - } catch (Exception e) { + } catch (RuntimeException e) { if (_log.shouldLog(Log.ERROR)) _log.error("Internal error", e); } finally { diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java index 76a52c32b..3b9217238 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java @@ -517,7 +517,7 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable { break; } catch(SocketTimeoutException ste) { // ignored, we never set the timeout - } catch (Exception e) { + } catch (RuntimeException e) { // streaming borkage if (_log.shouldLog(Log.ERROR)) _log.error("Uncaught exception accepting", e); diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelController.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelController.java index d5ca354c5..4a6e85211 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelController.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelController.java @@ -230,7 +230,7 @@ public class TunnelController implements Logging { } try { doStartTunnel(); - } catch (Exception e) { + } catch (RuntimeException e) { _log.error("Error starting the tunnel " + getName(), e); log("Error starting the tunnel " + getName() + ": " + e.getMessage()); // if we don't acquire() then the release() in stopTunnel() won't work diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/irc/I2PTunnelDCCClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/irc/I2PTunnelDCCClient.java index f5b434e3b..24ac12e61 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/irc/I2PTunnelDCCClient.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/irc/I2PTunnelDCCClient.java @@ -6,6 +6,7 @@ package net.i2p.i2ptunnel.irc; import java.net.Socket; import java.io.IOException; +import net.i2p.I2PException; import net.i2p.client.streaming.I2PSocket; import net.i2p.client.streaming.I2PSocketManager; import net.i2p.client.streaming.I2PSocketOptions; @@ -80,7 +81,14 @@ public class I2PTunnelDCCClient extends I2PTunnelClientBase { // we are called from an unlimited thread pool, so run inline //t.start(); t.run(); - } catch (Exception ex) { + } catch (IOException ex) { + _log.error("Could not make DCC connection to " + _dest + ':' + _remotePort, ex); + closeSocket(s); + if (i2ps != null) { + try { i2ps.close(); } catch (IOException ioe) {} + } + notifyEvent(CONNECT_STOP_EVENT, Integer.valueOf(getLocalPort())); + } catch (I2PException ex) { _log.error("Could not make DCC connection to " + _dest + ':' + _remotePort, ex); closeSocket(s); if (i2ps != null) { diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/ui/GeneralHelper.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/ui/GeneralHelper.java index b2b38398e..eb481f6ea 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/ui/GeneralHelper.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/ui/GeneralHelper.java @@ -9,6 +9,7 @@ import java.util.Properties; import java.util.TreeMap; import net.i2p.I2PAppContext; +import net.i2p.I2PException; import net.i2p.client.I2PClient; import net.i2p.crypto.SigType; import net.i2p.data.DataHelper; @@ -341,7 +342,8 @@ public class GeneralHelper { rv = pkf.getDestination(); if (rv != null) return rv; - } catch (Exception e) {} + } catch (I2PException e) { + } catch (IOException e) {} } } return null; diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java index fb9b137b2..d960dc93a 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java @@ -8,8 +8,11 @@ package net.i2p.i2ptunnel.web; * */ +import java.io.IOException; import java.util.List; import java.util.Set; + +import net.i2p.I2PException; import net.i2p.crypto.SigType; import net.i2p.data.Base64; import net.i2p.data.DataHelper; @@ -87,7 +90,8 @@ public class EditBean extends IndexBean { //System.err.println("Signing " + spoof + " with " + Base64.encode(privKey.getData())); Signature sig = _context.dsa().sign(spoof.getBytes("UTF-8"), privKey); return Base64.encode(sig.getData()); - } catch (Exception e) {} + } catch (I2PException e) { + } catch (IOException e) {} } return ""; } diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java index 15eb3f29e..2f2509c08 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java @@ -9,12 +9,14 @@ package net.i2p.i2ptunnel.web; */ import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Properties; import net.i2p.I2PAppContext; +import net.i2p.I2PException; import net.i2p.app.ClientAppManager; import net.i2p.app.Outproxy; import net.i2p.data.Certificate; @@ -266,7 +268,7 @@ public class IndexBean { if (_action != null) { try { buf.append(processAction()).append('\n'); - } catch (Exception e) { + } catch (RuntimeException e) { _log.log(Log.CRIT, "Error processing " + _action, e); buf.append("Error: ").append(e.toString()).append('\n'); } @@ -972,7 +974,9 @@ public class IndexBean { PrivateKeyFile pkf = new PrivateKeyFile(keyFile); try { pkf.createIfAbsent(); - } catch (Exception e) { + } catch (I2PException e) { + return "Create private key file failed: " + e; + } catch (IOException e) { return "Create private key file failed: " + e; } switch (_certType) { @@ -1011,7 +1015,9 @@ public class IndexBean { try { pkf.write(); newdest = pkf.getDestination(); - } catch (Exception e) { + } catch (I2PException e) { + return "Modification failed: " + e; + } catch (IOException e) { return "Modification failed: " + e; } return "Destination modified - " + diff --git a/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketEepGet.java b/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketEepGet.java index 052eef96c..1d3c77a16 100644 --- a/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketEepGet.java +++ b/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketEepGet.java @@ -274,7 +274,7 @@ public class I2PSocketEepGet extends EepGet { url = args[i]; } } - } catch (Exception e) { + } catch (RuntimeException e) { e.printStackTrace(); usage(); return; diff --git a/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketManagerFactory.java b/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketManagerFactory.java index 91c18cfe4..4e6d3b51f 100644 --- a/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketManagerFactory.java +++ b/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketManagerFactory.java @@ -195,7 +195,9 @@ public class I2PSocketManagerFactory { ByteArrayOutputStream keyStream = new ByteArrayOutputStream(1024); try { client.createDestination(keyStream, getSigType(opts)); - } catch (Exception e) { + } catch (I2PException e) { + throw new I2PSessionException("Error creating keys", e); + } catch (IOException e) { throw new I2PSessionException("Error creating keys", e); } myPrivateKeyStream = new ByteArrayInputStream(keyStream.toByteArray()); diff --git a/apps/routerconsole/java/src/net/i2p/router/web/CSSHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/CSSHelper.java index 7870363b5..2218f06a7 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/CSSHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/CSSHelper.java @@ -107,7 +107,7 @@ public class CSSHelper extends HelperBase { if (Integer.parseInt(r) < MIN_REFRESH) r = "" + MIN_REFRESH; _context.router().saveConfig(PROP_REFRESH, r); - } catch (Exception e) { + } catch (RuntimeException e) { } } @@ -117,7 +117,7 @@ public class CSSHelper extends HelperBase { try { if (Integer.parseInt(r) < MIN_REFRESH) r = "" + MIN_REFRESH; - } catch (Exception e) { + } catch (RuntimeException e) { r = "" + MIN_REFRESH; } return r; diff --git a/apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java b/apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java index 386eb664e..2af0d5df4 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java @@ -423,7 +423,7 @@ public class PluginStarter implements Runnable { addPath(f.toURI().toURL()); log.error("INFO: Adding translation plugin to classpath: " + f); added = true; - } catch (Exception e) { + } catch (RuntimeException e) { log.error("Plugin " + appName + " bad classpath element: " + f, e); } } @@ -961,7 +961,7 @@ public class PluginStarter implements Runnable { urls.add(f.toURI().toURL()); if (log.shouldLog(Log.WARN)) log.warn("INFO: Adding plugin to classpath: " + f); - } catch (Exception e) { + } catch (IOException e) { log.error("Plugin client " + clientName + " bad classpath element: " + f, e); } } diff --git a/apps/streaming/java/src/net/i2p/client/streaming/impl/I2PSocketManagerFull.java b/apps/streaming/java/src/net/i2p/client/streaming/impl/I2PSocketManagerFull.java index 89310ebda..7473bb79c 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/impl/I2PSocketManagerFull.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/impl/I2PSocketManagerFull.java @@ -9,6 +9,7 @@ import java.net.NoRouteToHostException; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketTimeoutException; +import java.security.GeneralSecurityException; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -259,7 +260,13 @@ public class I2PSocketManagerFull implements I2PSocketManager { Certificate.NULL_CERT.writeBytes(keyStream); priv.writeBytes(keyStream); keys[1].writeBytes(keyStream); // signing priv - } catch (Exception e) { + } catch (GeneralSecurityException e) { + throw new I2PSessionException("Error creating keys", e); + } catch (I2PException e) { + throw new I2PSessionException("Error creating keys", e); + } catch (IOException e) { + throw new I2PSessionException("Error creating keys", e); + } catch (RuntimeException e) { throw new I2PSessionException("Error creating keys", e); } privateKeyStream = new ByteArrayInputStream(keyStream.toByteArray()); diff --git a/apps/susidns/src/java/src/i2p/susi/dns/AddressbookBean.java b/apps/susidns/src/java/src/i2p/susi/dns/AddressbookBean.java index 360310682..205fcc8a7 100644 --- a/apps/susidns/src/java/src/i2p/susi/dns/AddressbookBean.java +++ b/apps/susidns/src/java/src/i2p/susi/dns/AddressbookBean.java @@ -164,7 +164,7 @@ public class AddressbookBean extends BaseBean message = generateLoadMessage(); } - catch (Exception e) { + catch (IOException e) { warn(e); } finally { if (fis != null) @@ -316,7 +316,7 @@ public class AddressbookBean extends BaseBean try { save(); message += "
" + _t("Address book saved."); - } catch (Exception e) { + } catch (IOException e) { warn(e); message += "
" + _t("ERROR: Could not write addressbook file."); } diff --git a/apps/susidns/src/java/src/i2p/susi/dns/NamingServiceBean.java b/apps/susidns/src/java/src/i2p/susi/dns/NamingServiceBean.java index 14eaebbd7..0fd326201 100644 --- a/apps/susidns/src/java/src/i2p/susi/dns/NamingServiceBean.java +++ b/apps/susidns/src/java/src/i2p/susi/dns/NamingServiceBean.java @@ -205,7 +205,7 @@ public class NamingServiceBean extends AddressbookBean message = generateLoadMessage(); } - catch (Exception e) { + catch (RuntimeException e) { warn(e); } if( message.length() > 0 ) diff --git a/apps/susimail/src/src/i2p/susi/util/Config.java b/apps/susimail/src/src/i2p/susi/util/Config.java index a84ccede4..26171e87f 100644 --- a/apps/susimail/src/src/i2p/susi/util/Config.java +++ b/apps/susimail/src/src/i2p/susi/util/Config.java @@ -98,7 +98,7 @@ public class Config { try { iv = Config.class.getResourceAsStream("/susimail.properties"); properties.load(iv); - } catch (Exception e) { + } catch (IOException e) { Debug.debug(Debug.ERROR, "Could not open WEB-INF/classes/susimail.properties (possibly in jar), reason: " + e); } finally { if(iv != null) try { iv.close(); } catch(IOException ioe) {} @@ -109,7 +109,7 @@ public class Config { config = new OrderedProperties(); DataHelper.loadProps(config, cfg); } - } catch (Exception e) { + } catch (IOException e) { Debug.debug(Debug.ERROR, "Could not open susimail.config, reason: " + e); } } diff --git a/apps/susimail/src/src/i2p/susi/webmail/Mail.java b/apps/susimail/src/src/i2p/susi/webmail/Mail.java index 88eb0ecdd..e0386b223 100644 --- a/apps/susimail/src/src/i2p/susi/webmail/Mail.java +++ b/apps/susimail/src/src/i2p/susi/webmail/Mail.java @@ -127,7 +127,7 @@ class Mail { part = new MailPart(rb); } catch (DecodingException de) { Debug.debug(Debug.ERROR, "Decode error: " + de); - } catch (Exception e) { + } catch (RuntimeException e) { Debug.debug(Debug.ERROR, "Parse error: " + e); } } diff --git a/apps/susimail/src/src/i2p/susi/webmail/WebMail.java b/apps/susimail/src/src/i2p/susi/webmail/WebMail.java index e70ee3063..bdcab5e89 100644 --- a/apps/susimail/src/src/i2p/susi/webmail/WebMail.java +++ b/apps/susimail/src/src/i2p/susi/webmail/WebMail.java @@ -614,7 +614,7 @@ public class WebMail extends HttpServlet showBody = false; reason = _t("Charset \\''{0}\\'' not supported.", quoteHTML( mailPart.charset )) + br; } - catch (Exception e1) { + catch (IOException e1) { showBody = false; reason += _t("Part ({0}) not shown, because of {1}", ident, e1.toString()) + br; } diff --git a/apps/susimail/src/src/i2p/susi/webmail/encoding/DecodingException.java b/apps/susimail/src/src/i2p/susi/webmail/encoding/DecodingException.java index d0d89dd00..46277d7e5 100644 --- a/apps/susimail/src/src/i2p/susi/webmail/encoding/DecodingException.java +++ b/apps/susimail/src/src/i2p/susi/webmail/encoding/DecodingException.java @@ -23,10 +23,12 @@ */ package i2p.susi.webmail.encoding; +import java.io.IOException; + /** * @author susi */ -public class DecodingException extends Exception { +public class DecodingException extends IOException { private static final long serialVersionUID = 1L; public DecodingException( String msg ) { diff --git a/apps/susimail/src/src/i2p/susi/webmail/encoding/HeaderLine.java b/apps/susimail/src/src/i2p/susi/webmail/encoding/HeaderLine.java index 4ed370dd2..e7db3672d 100644 --- a/apps/susimail/src/src/i2p/susi/webmail/encoding/HeaderLine.java +++ b/apps/susimail/src/src/i2p/susi/webmail/encoding/HeaderLine.java @@ -233,7 +233,9 @@ public class HeaderLine implements Encoding { length -= distance; lastCharWasQuoted = true; continue; - } catch (Exception e1) { + } catch (IOException e1) { + Debug.debug(Debug.ERROR, e1.toString()); + } catch (RuntimeException e1) { Debug.debug(Debug.ERROR, e1.toString()); } } diff --git a/apps/susimail/src/src/i2p/susi/webmail/smtp/SMTPClient.java b/apps/susimail/src/src/i2p/susi/webmail/smtp/SMTPClient.java index eb58c8ed5..fc4757735 100644 --- a/apps/susimail/src/src/i2p/susi/webmail/smtp/SMTPClient.java +++ b/apps/susimail/src/src/i2p/susi/webmail/smtp/SMTPClient.java @@ -210,7 +210,7 @@ public class SMTPClient { try { socket = new Socket( host, port ); - } catch (Exception e) { + } catch (IOException e) { error += _t("Cannot connect") + ": " + e.getMessage() + '\n'; ok = false; } diff --git a/apps/systray/java/src/net/i2p/apps/systray/ConfigFile.java b/apps/systray/java/src/net/i2p/apps/systray/ConfigFile.java index 642bea630..0389c8dd7 100644 --- a/apps/systray/java/src/net/i2p/apps/systray/ConfigFile.java +++ b/apps/systray/java/src/net/i2p/apps/systray/ConfigFile.java @@ -62,7 +62,7 @@ public class ConfigFile { try { fileInputStream = new FileInputStream(_configFile); _properties.load(fileInputStream); - } catch (Exception e) { + } catch (IOException e) { rv = false; } finally { if (fileInputStream != null) { @@ -79,7 +79,7 @@ public class ConfigFile { try { fileOutputStream = new FileOutputStream(_configFile); _properties.store(fileOutputStream, null); - } catch (Exception e) { + } catch (IOException e) { rv = false; } finally { if (fileOutputStream != null) { diff --git a/apps/systray/java/src/net/i2p/apps/systray/SysTray.java b/apps/systray/java/src/net/i2p/apps/systray/SysTray.java index 8d030d091..701c28b87 100644 --- a/apps/systray/java/src/net/i2p/apps/systray/SysTray.java +++ b/apps/systray/java/src/net/i2p/apps/systray/SysTray.java @@ -88,14 +88,14 @@ public class SysTray implements SysTrayMenuListener { try { if (urlLauncher.openUrl(url)) return; - } catch (Exception ex) { + } catch (RuntimeException ex) { // Fall through. } } else { try { if (urlLauncher.openUrl(url, _browserString)) return; - } catch (Exception ex) { + } catch (RuntimeException ex) { // Fall through. } } diff --git a/apps/systray/java/src/net/i2p/apps/systray/UrlLauncher.java b/apps/systray/java/src/net/i2p/apps/systray/UrlLauncher.java index 7169bc8f3..aa8f5ef12 100644 --- a/apps/systray/java/src/net/i2p/apps/systray/UrlLauncher.java +++ b/apps/systray/java/src/net/i2p/apps/systray/UrlLauncher.java @@ -149,7 +149,7 @@ public class UrlLauncher implements ClientApp { Thread.sleep(2*1000); } catch (InterruptedException ie) {} return true; - } catch (Exception e) {} + } catch (IOException e) {} if (System.currentTimeMillis() > done) break; try { @@ -171,9 +171,9 @@ public class UrlLauncher implements ClientApp { * @return true if the operation was successful, otherwise * false. * - * @throws Exception + * @throws IOException */ - public boolean openUrl(String url) throws Exception { + public boolean openUrl(String url) throws IOException { waitForServer(url); if (validateUrlFormat(url)) { String cbrowser = _context.getProperty(PROP_BROWSER); @@ -217,7 +217,7 @@ public class UrlLauncher implements ClientApp { // No worries. } foo.delete(); - } catch (Exception e) { + } catch (IOException e) { // Defaults to IE. } finally { if (bufferedReader != null) @@ -246,9 +246,9 @@ public class UrlLauncher implements ClientApp { * @return true if the operation was successful, * otherwise false. * - * @throws Exception + * @throws IOException */ - public boolean openUrl(String url, String browser) throws Exception { + public boolean openUrl(String url, String browser) throws IOException { waitForServer(url); if (validateUrlFormat(url)) { if (_shellCommand.executeSilentAndWaitTimed(browser + " " + url, 5)) @@ -289,7 +289,7 @@ public class UrlLauncher implements ClientApp { String url = _args[0]; openUrl(url); changeState(STOPPED); - } catch (Exception e) { + } catch (IOException e) { changeState(CRASHED, e); } } @@ -354,6 +354,6 @@ public class UrlLauncher implements ClientApp { launcher.openUrl(args[0]); else launcher.openUrl("http://127.0.0.1:7657/index.jsp"); - } catch (Exception e) {} + } catch (IOException e) {} } } diff --git a/core/java/src/net/i2p/client/impl/I2PSessionImpl.java b/core/java/src/net/i2p/client/impl/I2PSessionImpl.java index 046683ea4..13d805619 100644 --- a/core/java/src/net/i2p/client/impl/I2PSessionImpl.java +++ b/core/java/src/net/i2p/client/impl/I2PSessionImpl.java @@ -862,7 +862,7 @@ public abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2 if ((duration > 100) && _log.shouldLog(Log.INFO)) _log.info("Message availability notification for " + msgId.intValue() + " took " + duration + " to " + _sessionListener); - } catch (Exception e) { + } catch (RuntimeException e) { _log.log(Log.CRIT, "Error notifying app of message availability", e); } } else { diff --git a/core/java/src/net/i2p/client/impl/I2PSessionMuxedImpl.java b/core/java/src/net/i2p/client/impl/I2PSessionMuxedImpl.java index 07003ae2d..9b6f1ff0c 100644 --- a/core/java/src/net/i2p/client/impl/I2PSessionMuxedImpl.java +++ b/core/java/src/net/i2p/client/impl/I2PSessionMuxedImpl.java @@ -399,7 +399,7 @@ class I2PSessionMuxedImpl extends I2PSessionImpl2 { try { _demultiplexer.messageAvailable(I2PSessionMuxedImpl.this, msg.id, msg.size, msg.proto, msg.fromPort, msg.toPort); - } catch (Exception e) { + } catch (RuntimeException e) { _log.error("Error notifying app of message availability", e); } } diff --git a/core/java/src/net/i2p/client/naming/SingleFileNamingService.java b/core/java/src/net/i2p/client/naming/SingleFileNamingService.java index 219c61bbc..38a174b7e 100644 --- a/core/java/src/net/i2p/client/naming/SingleFileNamingService.java +++ b/core/java/src/net/i2p/client/naming/SingleFileNamingService.java @@ -91,7 +91,7 @@ public class SingleFileNamingService extends NamingService { key = getKey(hostname.substring(4)); if (key != null) return lookupBase64(key); - } catch (Exception ioe) { + } catch (IOException ioe) { if (_file.exists()) _log.error("Error loading hosts file " + _file, ioe); else if (_log.shouldLog(Log.WARN)) @@ -123,7 +123,7 @@ public class SingleFileNamingService extends NamingService { return line.substring(0, split); } return null; - } catch (Exception ioe) { + } catch (IOException ioe) { if (_file.exists()) _log.error("Error loading hosts file " + _file, ioe); else if (_log.shouldLog(Log.WARN)) diff --git a/core/java/src/net/i2p/crypto/DSAEngine.java b/core/java/src/net/i2p/crypto/DSAEngine.java index d7dfe657a..76f2004f8 100644 --- a/core/java/src/net/i2p/crypto/DSAEngine.java +++ b/core/java/src/net/i2p/crypto/DSAEngine.java @@ -257,7 +257,7 @@ public class DSAEngine { _log.warn("Took too long to verify the signature (" + diff + "ms)"); } return ok; - } catch (Exception e) { + } catch (RuntimeException e) { _log.log(Log.CRIT, "Error verifying the signature", e); return false; } diff --git a/core/java/src/net/i2p/crypto/ECConstants.java b/core/java/src/net/i2p/crypto/ECConstants.java index d9b111e23..8bca0b0ac 100644 --- a/core/java/src/net/i2p/crypto/ECConstants.java +++ b/core/java/src/net/i2p/crypto/ECConstants.java @@ -3,6 +3,7 @@ package net.i2p.crypto; import java.lang.reflect.Constructor; import java.math.BigInteger; import java.security.AlgorithmParameters; +import java.security.GeneralSecurityException; import java.security.Provider; import java.security.Security; import java.security.spec.ECField; @@ -278,7 +279,7 @@ class ECConstants { AlgorithmParameters ap; try { ap = AlgorithmParameters.getInstance("EC"); - } catch (Exception e) { + } catch (GeneralSecurityException e) { if (BC_AVAILABLE) { log("Named curve " + name + " is not available, trying BC", e); ap = AlgorithmParameters.getInstance("EC", "BC"); @@ -292,7 +293,7 @@ class ECConstants { ECParameterSpec rv = ap.getParameterSpec(ECParameterSpec.class); log("Named curve " + name + " loaded"); return rv; - } catch (Exception e) { + } catch (GeneralSecurityException e) { log("Named curve " + name + " is not available", e); return null; } diff --git a/core/java/src/net/i2p/crypto/ElGamalAESEngine.java b/core/java/src/net/i2p/crypto/ElGamalAESEngine.java index 126a06a36..0fe652bb2 100644 --- a/core/java/src/net/i2p/crypto/ElGamalAESEngine.java +++ b/core/java/src/net/i2p/crypto/ElGamalAESEngine.java @@ -327,12 +327,12 @@ public class ElGamalAESEngine { //ByteArrayInputStream bais = new ByteArrayInputStream(decrypted); int cur = 0; long numTags = DataHelper.fromLong(decrypted, cur, 2); - if ((numTags < 0) || (numTags > MAX_TAGS_RECEIVED)) throw new Exception("Invalid number of session tags"); + if ((numTags < 0) || (numTags > MAX_TAGS_RECEIVED)) throw new IllegalArgumentException("Invalid number of session tags"); if (numTags > 0) tags = new ArrayList((int)numTags); cur += 2; //_log.debug("# tags: " + numTags); if (numTags * SessionTag.BYTE_LENGTH > decrypted.length - 2) { - throw new Exception("# tags: " + numTags + " is too many for " + (decrypted.length - 2)); + throw new IllegalArgumentException("# tags: " + numTags + " is too many for " + (decrypted.length - 2)); } for (int i = 0; i < numTags; i++) { byte tag[] = new byte[SessionTag.BYTE_LENGTH]; @@ -344,7 +344,7 @@ public class ElGamalAESEngine { cur += 4; //_log.debug("len: " + len); if ((len < 0) || (len > decrypted.length - cur - Hash.HASH_LENGTH - 1)) - throw new Exception("Invalid size of payload (" + len + ", remaining " + (decrypted.length-cur) +")"); + throw new IllegalArgumentException("Invalid size of payload (" + len + ", remaining " + (decrypted.length-cur) +")"); //byte hashval[] = new byte[Hash.HASH_LENGTH]; //System.arraycopy(decrypted, cur, hashval, 0, Hash.HASH_LENGTH); //readHash = new Hash(); @@ -379,8 +379,8 @@ public class ElGamalAESEngine { return unencrData; } - throw new Exception("Hash does not match"); - } catch (Exception e) { + throw new RuntimeException("Hash does not match"); + } catch (RuntimeException e) { if (_log.shouldLog(Log.WARN)) _log.warn("Unable to decrypt AES block", e); return null; } diff --git a/core/java/src/net/i2p/crypto/EncType.java b/core/java/src/net/i2p/crypto/EncType.java index cb9c0ad96..fc07d5d5a 100644 --- a/core/java/src/net/i2p/crypto/EncType.java +++ b/core/java/src/net/i2p/crypto/EncType.java @@ -108,7 +108,7 @@ public enum EncType { return true; try { getParams(); - } catch (Exception e) { + } catch (InvalidParameterSpecException e) { return false; } return true; diff --git a/core/java/src/net/i2p/crypto/KeyGenerator.java b/core/java/src/net/i2p/crypto/KeyGenerator.java index 60742c2fb..c198d0b34 100644 --- a/core/java/src/net/i2p/crypto/KeyGenerator.java +++ b/core/java/src/net/i2p/crypto/KeyGenerator.java @@ -343,7 +343,7 @@ public class KeyGenerator { public static void main(String args[]) { try { main2(args); - } catch (Exception e) { + } catch (RuntimeException e) { e.printStackTrace(); } } @@ -381,7 +381,7 @@ public class KeyGenerator { try { System.out.println("Testing " + type); testSig(type, runs); - } catch (Exception e) { + } catch (GeneralSecurityException e) { System.out.println("error testing " + type); e.printStackTrace(); } diff --git a/core/java/src/net/i2p/crypto/KeyStoreUtil.java b/core/java/src/net/i2p/crypto/KeyStoreUtil.java index 06b73cea8..d994018cf 100644 --- a/core/java/src/net/i2p/crypto/KeyStoreUtil.java +++ b/core/java/src/net/i2p/crypto/KeyStoreUtil.java @@ -98,7 +98,8 @@ public class KeyStoreUtil { try { ks.load(null, DEFAULT_KEYSTORE_PASSWORD.toCharArray()); success = addCerts(new File(System.getProperty("java.home"), "etc/security/cacerts"), ks) > 0; - } catch (Exception e) {} + } catch (IOException e) { + } catch (GeneralSecurityException e) {} } else { success = loadCerts(new File(System.getProperty("java.home"), "etc/security/cacerts.bks"), ks); } @@ -113,7 +114,8 @@ public class KeyStoreUtil { try { // must be initted ks.load(null, DEFAULT_KEYSTORE_PASSWORD.toCharArray()); - } catch (Exception e) {} + } catch (IOException e) { + } catch (GeneralSecurityException e) {} error("All key store loads failed, will only load local certificates", null); } return ks; @@ -140,13 +142,15 @@ public class KeyStoreUtil { try { // not clear if null is allowed for password ks.load(null, DEFAULT_KEYSTORE_PASSWORD.toCharArray()); - } catch (Exception foo) {} + } catch (IOException foo) { + } catch (GeneralSecurityException e) {} return false; } catch (IOException ioe) { error("KeyStore load error, no default keys: " + file.getAbsolutePath(), ioe); try { ks.load(null, DEFAULT_KEYSTORE_PASSWORD.toCharArray()); - } catch (Exception foo) {} + } catch (IOException foo) { + } catch (GeneralSecurityException e) {} return false; } finally { try { if (fis != null) fis.close(); } catch (IOException foo) {} @@ -171,7 +175,7 @@ public class KeyStoreUtil { count++; } } - } catch (Exception foo) {} + } catch (GeneralSecurityException e) {} return count; } @@ -316,7 +320,10 @@ public class KeyStoreUtil { error("Not overwriting key " + alias + ", already exists in " + ks, null); return false; } - } catch (Exception e) { + } catch (IOException e) { + error("Not overwriting key \"" + alias + "\", already exists in " + ks, e); + return false; + } catch (GeneralSecurityException e) { error("Not overwriting key \"" + alias + "\", already exists in " + ks, e); return false; } @@ -354,7 +361,10 @@ public class KeyStoreUtil { success = getPrivateKey(ks, ksPW, alias, keyPW) != null; if (!success) error("Key gen failed to get private key", null); - } catch (Exception e) { + } catch (IOException e) { + error("Key gen failed to get private key", e); + success = false; + } catch (GeneralSecurityException e) { error("Key gen failed to get private key", e); success = false; } diff --git a/core/java/src/net/i2p/crypto/SigType.java b/core/java/src/net/i2p/crypto/SigType.java index 48ad93e0a..05dd1906e 100644 --- a/core/java/src/net/i2p/crypto/SigType.java +++ b/core/java/src/net/i2p/crypto/SigType.java @@ -1,5 +1,6 @@ package net.i2p.crypto; +import java.security.GeneralSecurityException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.Signature; @@ -215,7 +216,9 @@ public enum SigType { } getDigestInstance(); getHashInstance(); - } catch (Exception e) { + } catch (GeneralSecurityException e) { + return false; + } catch (RuntimeException e) { return false; } return true; diff --git a/core/java/src/net/i2p/crypto/TrustedUpdate.java b/core/java/src/net/i2p/crypto/TrustedUpdate.java index b365a662a..5174292a2 100644 --- a/core/java/src/net/i2p/crypto/TrustedUpdate.java +++ b/core/java/src/net/i2p/crypto/TrustedUpdate.java @@ -344,7 +344,11 @@ riCe6OlAEiNpcc6mMyIYYWFICbrDFTrDR3wXqwc/Jkcx6L5VVWoagpSzbo3yGhc= System.out.println("\r\nPrivate key written to: " + privateKeyFile); System.out.println("Public key written to: " + publicKeyFile); System.out.println("\r\nPublic key: " + signingPublicKey.toBase64() + "\r\n"); - } catch (Exception e) { + } catch (IOException e) { + System.err.println("Error writing keys:"); + e.printStackTrace(); + return false; + } catch (DataFormatException e) { System.err.println("Error writing keys:"); e.printStackTrace(); return false; @@ -758,7 +762,7 @@ riCe6OlAEiNpcc6mMyIYYWFICbrDFTrDR3wXqwc/Jkcx6L5VVWoagpSzbo3yGhc= bytesToSignInputStream = new SequenceInputStream(versionHeaderInputStream, fileInputStream); signature = _context.dsa().sign(bytesToSignInputStream, signingPrivateKey); - } catch (Exception e) { + } catch (IOException e) { if (_log.shouldLog(Log.ERROR)) _log.error("Error signing", e); diff --git a/core/java/src/net/i2p/crypto/eddsa/math/GroupElement.java b/core/java/src/net/i2p/crypto/eddsa/math/GroupElement.java index 268005ed7..ec81b5d40 100644 --- a/core/java/src/net/i2p/crypto/eddsa/math/GroupElement.java +++ b/core/java/src/net/i2p/crypto/eddsa/math/GroupElement.java @@ -722,7 +722,7 @@ public class GroupElement implements Serializable { if (!this.repr.equals(ge.repr)) { try { ge = ge.toRep(this.repr); - } catch (Exception e) { + } catch (RuntimeException e) { return false; } } diff --git a/core/java/src/net/i2p/data/PrivateKeyFile.java b/core/java/src/net/i2p/data/PrivateKeyFile.java index f42d8da15..b77fd1350 100644 --- a/core/java/src/net/i2p/data/PrivateKeyFile.java +++ b/core/java/src/net/i2p/data/PrivateKeyFile.java @@ -9,6 +9,7 @@ import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; import java.security.GeneralSecurityException; +import java.security.NoSuchAlgorithmException; import java.util.Locale; import java.util.Map; import java.util.Properties; @@ -174,7 +175,10 @@ public class PrivateKeyFile { pkf.write(); verifySignature(pkf.getDestination()); } - } catch (Exception e) { + } catch (I2PException e) { + e.printStackTrace(); + System.exit(1); + } catch (IOException e) { e.printStackTrace(); System.exit(1); } @@ -358,7 +362,7 @@ public class PrivateKeyFile { HashCash hc; try { hc = HashCash.mintCash(resource, effort); - } catch (Exception e) { + } catch (NoSuchAlgorithmException e) { return null; } System.out.println("Generation took: " + DataHelper.formatDuration(System.currentTimeMillis() - begin)); @@ -391,7 +395,9 @@ public class PrivateKeyFile { Destination d2; try { d2 = pkf2.getDestination(); - } catch (Exception e) { + } catch (I2PException e) { + return null; + } catch (IOException e) { return null; } if (d2 == null) @@ -500,7 +506,7 @@ public class PrivateKeyFile { long low = Long.MAX_VALUE; try { low = HashCash.estimateTime(hashEffort); - } catch (Exception e) {} + } catch (NoSuchAlgorithmException e) {} // takes a lot longer than the estimate usually... // maybe because the resource string is much longer than used in the estimate? return "It is estimated that generating a HashCash Certificate with value " + hashEffort + diff --git a/core/java/src/net/i2p/data/i2cp/I2CPMessageReader.java b/core/java/src/net/i2p/data/i2cp/I2CPMessageReader.java index 4dfbb8501..4bfdbc158 100644 --- a/core/java/src/net/i2p/data/i2cp/I2CPMessageReader.java +++ b/core/java/src/net/i2p/data/i2cp/I2CPMessageReader.java @@ -160,7 +160,7 @@ public class I2CPMessageReader { public void run() { try { run2(); - } catch (Exception e) { + } catch (RuntimeException e) { _log.log(Log.CRIT, "Uncaught I2CP error", e); _listener.readError(I2CPMessageReader.this, e); cancelRunner(); @@ -193,7 +193,7 @@ public class I2CPMessageReader { } catch (OutOfMemoryError oom) { // ooms seen here... maybe log and keep going? throw oom; - } catch (Exception e) { + } catch (RuntimeException e) { _log.log(Log.CRIT, "Unhandled error reading I2CP stream", e); _listener.disconnected(I2CPMessageReader.this); cancelRunner(); diff --git a/core/java/src/net/i2p/stat/BufferedStatLog.java b/core/java/src/net/i2p/stat/BufferedStatLog.java index 7c9b7b723..5734e8948 100644 --- a/core/java/src/net/i2p/stat/BufferedStatLog.java +++ b/core/java/src/net/i2p/stat/BufferedStatLog.java @@ -145,7 +145,7 @@ public class BufferedStatLog implements StatLog { if (_log.shouldLog(Log.DEBUG)) _log.debug("writing " + writeStart +"->"+ writeEnd); writeEvents(writeStart, writeEnd); - } catch (Exception e) { + } catch (RuntimeException e) { _log.error("error writing " + writeStart +"->"+ writeEnd, e); } } diff --git a/core/java/src/net/i2p/util/EepGet.java b/core/java/src/net/i2p/util/EepGet.java index 81ec7c8e4..d9d9ba6fe 100644 --- a/core/java/src/net/i2p/util/EepGet.java +++ b/core/java/src/net/i2p/util/EepGet.java @@ -273,7 +273,7 @@ public class EepGet { break; } // switch } // while - } catch (Exception e) { + } catch (RuntimeException e) { e.printStackTrace(); error = true; } diff --git a/core/java/src/net/i2p/util/EepHead.java b/core/java/src/net/i2p/util/EepHead.java index 2c49d708b..ef6f5067d 100644 --- a/core/java/src/net/i2p/util/EepHead.java +++ b/core/java/src/net/i2p/util/EepHead.java @@ -109,7 +109,7 @@ public class EepHead extends EepGet { break; } // switch } // while - } catch (Exception e) { + } catch (RuntimeException e) { e.printStackTrace(); error = true; } diff --git a/core/java/src/net/i2p/util/FortunaRandomSource.java b/core/java/src/net/i2p/util/FortunaRandomSource.java index 9688e8764..e386e325c 100644 --- a/core/java/src/net/i2p/util/FortunaRandomSource.java +++ b/core/java/src/net/i2p/util/FortunaRandomSource.java @@ -11,6 +11,7 @@ package net.i2p.util; import gnu.crypto.prng.AsyncFortunaStandalone; +import java.io.IOException; import java.security.SecureRandom; import net.i2p.I2PAppContext; @@ -266,7 +267,7 @@ public class FortunaRandomSource extends RandomSource implements EntropyHarveste synchronized(_fortuna) { _fortuna.addRandomBytes(data, offset, len); } - } catch (Exception e) { + } catch (RuntimeException e) { // AIOOBE seen, root cause unknown, ticket #1576 Log log = _context.logManager().getLog(FortunaRandomSource.class); log.warn("feedEntropy()", e); @@ -290,6 +291,6 @@ public class FortunaRandomSource extends RandomSource implements EntropyHarveste rand.nextBytes(buf); System.out.write(buf); } - } catch (Exception e) { e.printStackTrace(); } + } catch (IOException e) { e.printStackTrace(); } } } diff --git a/core/java/src/net/i2p/util/LogWriterBase.java b/core/java/src/net/i2p/util/LogWriterBase.java index b9b98e10d..cc4fb93e6 100644 --- a/core/java/src/net/i2p/util/LogWriterBase.java +++ b/core/java/src/net/i2p/util/LogWriterBase.java @@ -75,7 +75,7 @@ abstract class LogWriterBase implements Runnable { if (_write && shouldReadConfig) rereadConfig(); } - } catch (Exception e) { + } catch (RuntimeException e) { System.err.println("Error writing the log: " + e); e.printStackTrace(); } diff --git a/core/java/src/net/i2p/util/PartialEepGet.java b/core/java/src/net/i2p/util/PartialEepGet.java index 0371dbf32..4d0967763 100644 --- a/core/java/src/net/i2p/util/PartialEepGet.java +++ b/core/java/src/net/i2p/util/PartialEepGet.java @@ -107,7 +107,7 @@ public class PartialEepGet extends EepGet { break; } // switch } // while - } catch (Exception e) { + } catch (RuntimeException e) { e.printStackTrace(); error = true; } diff --git a/core/java/src/net/i2p/util/ResettableGZIPInputStream.java b/core/java/src/net/i2p/util/ResettableGZIPInputStream.java index 645bd29f3..13eecb518 100644 --- a/core/java/src/net/i2p/util/ResettableGZIPInputStream.java +++ b/core/java/src/net/i2p/util/ResettableGZIPInputStream.java @@ -124,7 +124,7 @@ public class ResettableGZIPInputStream extends InflaterInputStream { public long getTotalRead() { try { return inf.getBytesRead(); - } catch (Exception e) { + } catch (RuntimeException e) { return 0; } } @@ -136,7 +136,7 @@ public class ResettableGZIPInputStream extends InflaterInputStream { public long getTotalExpanded() { try { return inf.getBytesWritten(); - } catch (Exception e) { + } catch (RuntimeException e) { // possible NPE in some implementations return 0; } @@ -149,7 +149,7 @@ public class ResettableGZIPInputStream extends InflaterInputStream { public long getRemaining() { try { return inf.getRemaining(); - } catch (Exception e) { + } catch (RuntimeException e) { // possible NPE in some implementations return 0; } @@ -162,7 +162,7 @@ public class ResettableGZIPInputStream extends InflaterInputStream { public boolean getFinished() { try { return inf.finished(); - } catch (Exception e) { + } catch (RuntimeException e) { // possible NPE in some implementations return true; } diff --git a/core/java/src/net/i2p/util/SSLEepGet.java b/core/java/src/net/i2p/util/SSLEepGet.java index 4cc31e90b..c62da0c12 100644 --- a/core/java/src/net/i2p/util/SSLEepGet.java +++ b/core/java/src/net/i2p/util/SSLEepGet.java @@ -180,7 +180,7 @@ public class SSLEepGet extends EepGet { break; } // switch } // while - } catch (Exception e) { + } catch (RuntimeException e) { e.printStackTrace(); error = true; } @@ -370,7 +370,7 @@ public class SSLEepGet extends EepGet { System.out.println(" Valid To: " + cert.getNotAfter()); try { cert.checkValidity(); - } catch (Exception e) { + } catch (GeneralSecurityException e) { System.out.println(" WARNING: Certificate is not currently valid, it cannot be used"); } CertUtil.saveCert(cert, new File(name)); diff --git a/core/java/src/net/i2p/util/ShellCommand.java b/core/java/src/net/i2p/util/ShellCommand.java index 955830fe1..4a5daac55 100644 --- a/core/java/src/net/i2p/util/ShellCommand.java +++ b/core/java/src/net/i2p/util/ShellCommand.java @@ -439,7 +439,7 @@ public class ShellCommand { System.out.println("ShellCommand waiting for \"" + name + '\"'); try { process.waitFor(); - } catch (Exception e) { + } catch (InterruptedException e) { if (DEBUG) { System.out.println("ShellCommand exception waiting for \"" + name + '\"'); e.printStackTrace(); @@ -457,7 +457,7 @@ public class ShellCommand { if (process.exitValue() > 0) return false; } - } catch (Exception e) { + } catch (IOException e) { // probably IOException, file not found from exec() if (DEBUG) { System.out.println("ShellCommand execute exception for \"" + name + '\"'); diff --git a/core/java/src/net/metanotion/io/block/BlockFile.java b/core/java/src/net/metanotion/io/block/BlockFile.java index 018702204..122f30796 100644 --- a/core/java/src/net/metanotion/io/block/BlockFile.java +++ b/core/java/src/net/metanotion/io/block/BlockFile.java @@ -147,7 +147,7 @@ public class BlockFile implements Closeable { bf.bfck(true); bf.close(); raif.close(); - } catch (Exception e) { + } catch (IOException e) { e.printStackTrace(); } } diff --git a/installer/java/src/net/i2p/installer/Exec.java b/installer/java/src/net/i2p/installer/Exec.java index b8488ceff..05113b9c6 100644 --- a/installer/java/src/net/i2p/installer/Exec.java +++ b/installer/java/src/net/i2p/installer/Exec.java @@ -21,7 +21,7 @@ public class Exec { try { proc.exitValue(); } catch (Throwable t) { } Runtime.getRuntime().halt(0); - } catch (Exception e) { + } catch (RuntimeException e) { e.printStackTrace(); } } diff --git a/installer/tools/java/src/net/i2p/router/networkdb/kademlia/BundleRouterInfos.java b/installer/tools/java/src/net/i2p/router/networkdb/kademlia/BundleRouterInfos.java index f916e976f..ac405f0ee 100644 --- a/installer/tools/java/src/net/i2p/router/networkdb/kademlia/BundleRouterInfos.java +++ b/installer/tools/java/src/net/i2p/router/networkdb/kademlia/BundleRouterInfos.java @@ -109,7 +109,7 @@ public class BundleRouterInfos { RouterInfo ri = new RouterInfo(); ri.readBytes(fis, true); // true = verify sig on read me = ri.getIdentity().getHash(); - } catch (Exception e) { + } catch (RuntimeException e) { //System.out.println("Can't determine our identity"); } finally { if (fis != null) try { fis.close(); } catch (IOException ioe) {} @@ -209,7 +209,7 @@ public class BundleRouterInfos { copied++; else System.out.println("Failed copy of " + file + " to " + toDir); - } catch (Exception e) { + } catch (RuntimeException e) { System.out.println("Skipping bad " + file); } finally { if (fis != null) try { fis.close(); } catch (IOException ioe) {} diff --git a/router/java/src/net/i2p/data/i2np/GarlicClove.java b/router/java/src/net/i2p/data/i2np/GarlicClove.java index 628874d81..d19435321 100644 --- a/router/java/src/net/i2p/data/i2np/GarlicClove.java +++ b/router/java/src/net/i2p/data/i2np/GarlicClove.java @@ -158,7 +158,7 @@ public class GarlicClove extends DataStructureImpl { if (m.length <= 0) throw new RuntimeException("foo, returned 0 length"); out.write(m); - } catch (Exception e) { + } catch (RuntimeException e) { throw new DataFormatException("Unable to write the clove: " + _msg + " to " + out, e); } DataHelper.writeLong(out, 4, _cloveId); @@ -187,7 +187,7 @@ public class GarlicClove extends DataStructureImpl { byte m[] = _msg.toByteArray(); System.arraycopy(m, 0, rv, offset, m.length); offset += m.length; - } catch (Exception e) { throw new RuntimeException("Unable to write: " + _msg + ": " + e.getMessage()); } + } catch (RuntimeException e) { throw new RuntimeException("Unable to write: " + _msg + ": " + e.getMessage()); } DataHelper.toLong(rv, offset, 4, _cloveId); offset += 4; DataHelper.toDate(rv, offset, _expiration.getTime()); diff --git a/router/java/src/net/i2p/data/i2np/I2NPMessageHandler.java b/router/java/src/net/i2p/data/i2np/I2NPMessageHandler.java index f1ea685f9..224918ef4 100644 --- a/router/java/src/net/i2p/data/i2np/I2NPMessageHandler.java +++ b/router/java/src/net/i2p/data/i2np/I2NPMessageHandler.java @@ -59,7 +59,7 @@ public class I2NPMessageHandler { _lastSize = msg.readBytes(in, type, _messageBuffer); } catch (I2NPMessageException ime) { throw ime; - } catch (Exception e) { + } catch (RuntimeException e) { if (_log.shouldLog(Log.WARN)) _log.warn("Error reading the stream", e); throw new I2NPMessageException("Unknown error reading the " + msg.getClass().getSimpleName(), e); @@ -131,7 +131,7 @@ public class I2NPMessageHandler { cur += _lastSize; } catch (I2NPMessageException ime) { throw ime; - } catch (Exception e) { + } catch (RuntimeException e) { if (_log.shouldLog(Log.WARN)) _log.warn("Error reading the stream", e); throw new I2NPMessageException("Unknown error reading the " + msg.getClass().getSimpleName(), e); diff --git a/router/java/src/net/i2p/data/i2np/I2NPMessageReader.java b/router/java/src/net/i2p/data/i2np/I2NPMessageReader.java index f253cfed2..d23a489d6 100644 --- a/router/java/src/net/i2p/data/i2np/I2NPMessageReader.java +++ b/router/java/src/net/i2p/data/i2np/I2NPMessageReader.java @@ -163,7 +163,7 @@ public class I2NPMessageReader { _log.warn("IO Error handling message", ioe); _listener.disconnected(I2NPMessageReader.this); cancelRunner(); - } catch (Exception e) { + } catch (RuntimeException e) { _log.log(Log.CRIT, "error reading msg!", e); _listener.readError(I2NPMessageReader.this, e); _listener.disconnected(I2NPMessageReader.this); diff --git a/router/java/src/net/i2p/data/router/RouterInfo.java b/router/java/src/net/i2p/data/router/RouterInfo.java index 0d60c6dc0..f2f9cdb7f 100644 --- a/router/java/src/net/i2p/data/router/RouterInfo.java +++ b/router/java/src/net/i2p/data/router/RouterInfo.java @@ -724,7 +724,10 @@ public class RouterInfo extends DatabaseEntry { System.err.println("Router info " + args[i] + " is invalid"); fail = true; } - } catch (Exception e) { + } catch (IOException e) { + System.err.println("Error reading " + args[i] + ": " + e); + fail = true; + } catch (DataFormatException e) { System.err.println("Error reading " + args[i] + ": " + e); fail = true; } finally { diff --git a/router/java/src/net/i2p/router/InNetMessagePool.java b/router/java/src/net/i2p/router/InNetMessagePool.java index fb4c2a632..bfd3d696e 100644 --- a/router/java/src/net/i2p/router/InNetMessagePool.java +++ b/router/java/src/net/i2p/router/InNetMessagePool.java @@ -434,7 +434,7 @@ public class InNetMessagePool implements Service { } catch (OutOfMemoryError oome) { throw oome; - } catch (Exception e) { + } catch (RuntimeException e) { if (_log.shouldLog(Log.CRIT)) _log.log(Log.CRIT, "Error in the tunnel gateway dispatcher", e); } @@ -467,7 +467,7 @@ public class InNetMessagePool implements Service { } catch (OutOfMemoryError oome) { throw oome; - } catch (Exception e) { + } catch (RuntimeException e) { if (_log.shouldLog(Log.CRIT)) _log.log(Log.CRIT, "Error in the tunnel data dispatcher", e); } diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java index 426da4a75..99073c366 100644 --- a/router/java/src/net/i2p/router/Router.java +++ b/router/java/src/net/i2p/router/Router.java @@ -9,6 +9,7 @@ package net.i2p.router; */ import java.io.File; +import java.io.IOException; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -648,7 +649,7 @@ public class Router implements RouterClock.ClockShiftListener { //else // System.err.println("WARNING: Configuration file " + filename + " does not exist"); } - } catch (Exception ioe) { + } catch (IOException ioe) { if (log != null) log.error("Error loading the router configuration from " + filename, ioe); else @@ -1351,7 +1352,7 @@ public class Router implements RouterClock.ClockShiftListener { ordered.putAll(_config); DataHelper.storeProps(ordered, new File(_configFilename)); } - } catch (Exception ioe) { + } catch (IOException ioe) { // warning, _log will be null when called from constructor if (_log != null) _log.error("Error saving the config to " + _configFilename, ioe); diff --git a/router/java/src/net/i2p/router/dummy/VMCommSystem.java b/router/java/src/net/i2p/router/dummy/VMCommSystem.java index 13b8aff0a..29f232370 100644 --- a/router/java/src/net/i2p/router/dummy/VMCommSystem.java +++ b/router/java/src/net/i2p/router/dummy/VMCommSystem.java @@ -8,6 +8,7 @@ import java.util.Map; import net.i2p.data.Hash; import net.i2p.data.i2np.I2NPMessage; +import net.i2p.data.i2np.I2NPMessageException; import net.i2p.data.i2np.I2NPMessageHandler; import net.i2p.router.CommSystemFacade; import net.i2p.router.JobImpl; @@ -121,7 +122,7 @@ public class VMCommSystem extends CommSystemFacade { ReceiveJob.this.getContext().statManager().addRateData("transport.receiveMessageLarge", 1, 1); _ctx.inNetMessagePool().add(msg, null, _from); - } catch (Exception e) { + } catch (I2NPMessageException e) { _log.error("Error reading/formatting a VM message? Something is not right...", e); } } diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java b/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java index a04a339cc..f915b03f7 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java @@ -543,7 +543,7 @@ public class PersistentDataStore extends TransientDataStore { if (_log.shouldLog(Log.INFO)) _log.info("Unable to read the router reference in " + _routerFile.getName(), ioe); corrupt = true; - } catch (Exception e) { + } catch (RuntimeException e) { // key certificate problems, etc., don't let one bad RI kill the whole thing if (_log.shouldLog(Log.INFO)) _log.info("Unable to read the router reference in " + _routerFile.getName(), e); @@ -666,7 +666,7 @@ public class PersistentDataStore extends TransientDataStore { return null; Hash h = Hash.create(b); return h; - } catch (Exception e) { + } catch (RuntimeException e) { // static //_log.warn("Unable to fetch the key from [" + filename + "]", e); return null; 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 dfe72e155..1060d444f 100644 --- a/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java +++ b/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java @@ -626,7 +626,7 @@ public class Reseeder { if (fetched % 60 == 0) System.out.println(); } - } catch (Exception e) { + } catch (RuntimeException e) { if (_log.shouldLog(Log.INFO)) _log.info("Failed fetch", e); errors++; diff --git a/router/java/src/net/i2p/router/peermanager/ProfilePersistenceHelper.java b/router/java/src/net/i2p/router/peermanager/ProfilePersistenceHelper.java index 305d0f343..af9cd33aa 100644 --- a/router/java/src/net/i2p/router/peermanager/ProfilePersistenceHelper.java +++ b/router/java/src/net/i2p/router/peermanager/ProfilePersistenceHelper.java @@ -301,7 +301,7 @@ class ProfilePersistenceHelper { _log.debug("Loaded the profile for " + peer.toBase64() + " from " + file.getName()); return profile; - } catch (Exception e) { + } catch (IOException e) { if (_log.shouldLog(Log.WARN)) _log.warn("Error loading properties from " + file.getAbsolutePath(), e); file.delete(); @@ -369,7 +369,7 @@ class ProfilePersistenceHelper { return null; Hash h = Hash.create(b); return h; - } catch (Exception dfe) { + } catch (RuntimeException dfe) { _log.warn("Invalid base64 [" + key + "]", dfe); return null; } diff --git a/router/java/src/net/i2p/router/startup/RebuildRouterInfoJob.java b/router/java/src/net/i2p/router/startup/RebuildRouterInfoJob.java index ef0826cf5..a3302ae40 100644 --- a/router/java/src/net/i2p/router/startup/RebuildRouterInfoJob.java +++ b/router/java/src/net/i2p/router/startup/RebuildRouterInfoJob.java @@ -98,7 +98,13 @@ class RebuildRouterInfoJob extends JobImpl { KeyData kd = LoadRouterInfoJob.readKeyData(keyFile, keyFile2); info = new RouterInfo(); info.setIdentity(kd.routerIdentity); - } catch (Exception e) { + } catch (DataFormatException e) { + _log.log(Log.CRIT, "Error reading in the key data from " + keyFile.getAbsolutePath(), e); + keyFile.delete(); + keyFile2.delete(); + rebuildRouterInfo(alreadyRunning); + return; + } catch (IOException e) { _log.log(Log.CRIT, "Error reading in the key data from " + keyFile.getAbsolutePath(), e); keyFile.delete(); keyFile2.delete(); diff --git a/router/java/src/net/i2p/router/transport/UPnP.java b/router/java/src/net/i2p/router/transport/UPnP.java index 8aab1d1d4..58cc32c75 100644 --- a/router/java/src/net/i2p/router/transport/UPnP.java +++ b/router/java/src/net/i2p/router/transport/UPnP.java @@ -476,7 +476,7 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener { ServiceStateTable table; try { table = serv.getServiceStateTable(); - } catch (Exception e) { + } catch (RuntimeException e) { // getSCPDNode() returns null, // NPE at org.cybergarage.upnp.Service.getServiceStateTable(Service.java:526) sb.append(" : no state"); diff --git a/router/java/src/net/i2p/router/transport/UPnPManager.java b/router/java/src/net/i2p/router/transport/UPnPManager.java index 9d7a6918a..cd9963b06 100644 --- a/router/java/src/net/i2p/router/transport/UPnPManager.java +++ b/router/java/src/net/i2p/router/transport/UPnPManager.java @@ -88,7 +88,7 @@ class UPnPManager { _isRunning = _upnp.runPlugin(); if (_log.shouldLog(Log.INFO)) _log.info("UPnP runPlugin took " + (_context.clock().now() - b)); - } catch (Exception e) { + } catch (RuntimeException e) { // NPE in UPnP (ticket #728), can't let it bring us down if (!_errorLogged) { _log.error("UPnP error, please report", e); diff --git a/router/java/src/net/i2p/router/transport/ntcp/EventPumper.java b/router/java/src/net/i2p/router/transport/ntcp/EventPumper.java index 053d4a373..dcc2226c4 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/EventPumper.java +++ b/router/java/src/net/i2p/router/transport/ntcp/EventPumper.java @@ -335,7 +335,7 @@ class EventPumper implements Runnable { con.close(); key.cancel(); } - } catch (Exception ke) { + } catch (IOException ke) { _log.error("Error closing key " + key + " on pumper shutdown", ke); } } @@ -344,7 +344,7 @@ class EventPumper implements Runnable { if (_log.shouldLog(Log.DEBUG)) _log.debug("Closing down the event pumper with no selection keys remaining"); } - } catch (Exception e) { + } catch (IOException e) { _log.error("Error closing keys on pumper shutdown", e); } _wantsConRegister.clear(); diff --git a/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java b/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java index 703ee5050..37504a111 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java +++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java @@ -463,7 +463,7 @@ class NTCPConnection implements Closeable { _transport.afterSend(msg, successful, allowRequeue, msg.getLifetime()); if (_consecutiveBacklog > 10) { // waaay too backlogged boolean wantsWrite = false; - try { wantsWrite = ( (_conKey.interestOps() & SelectionKey.OP_WRITE) != 0); } catch (Exception e) {} + try { wantsWrite = ( (_conKey.interestOps() & SelectionKey.OP_WRITE) != 0); } catch (RuntimeException e) {} if (_log.shouldLog(Log.WARN)) { int blocks = _writeBufs.size(); _log.warn("Too backlogged for too long (" + _consecutiveBacklog + " messages for " + DataHelper.formatDuration(queueTime()) + ", sched? " + wantsWrite + ", blocks: " + blocks + ") sending to " + _remotePeer.calculateHash()); @@ -521,7 +521,7 @@ class NTCPConnection implements Closeable { + ", wantsWrite? " + (0 != (_conKey.interestOps()&SelectionKey.OP_WRITE)) + ", currentOut set? " + currentOutboundSet + ", writeBufs: " + writeBufs + " on " + toString()); - } catch (Exception e) {} // java.nio.channels.CancelledKeyException + } catch (RuntimeException e) {} // java.nio.channels.CancelledKeyException } //_context.statManager().addRateData("ntcp.sendBacklogTime", queueTime); return true; diff --git a/router/java/src/net/i2p/router/transport/udp/ACKSender.java b/router/java/src/net/i2p/router/transport/udp/ACKSender.java index 8e608ab13..60976d285 100644 --- a/router/java/src/net/i2p/router/transport/udp/ACKSender.java +++ b/router/java/src/net/i2p/router/transport/udp/ACKSender.java @@ -148,7 +148,7 @@ class ACKSender implements Runnable { try { // bulk operations may throw an exception _peersToACK.addAll(notYet); - } catch (Exception e) {} + } catch (RuntimeException e) {} if (_log.shouldLog(Log.DEBUG)) _log.debug("sleeping, pending size = " + notYet.size()); notYet.clear(); diff --git a/router/java/src/net/i2p/router/transport/udp/MessageReceiver.java b/router/java/src/net/i2p/router/transport/udp/MessageReceiver.java index 1b6bb03c0..d2a3b0414 100644 --- a/router/java/src/net/i2p/router/transport/udp/MessageReceiver.java +++ b/router/java/src/net/i2p/router/transport/udp/MessageReceiver.java @@ -243,7 +243,7 @@ class MessageReceiver { } _context.messageHistory().droppedInboundMessage(state.getMessageId(), state.getFrom(), "error: " + ime.toString() + ": " + state.toString()); return null; - } catch (Exception e) { + } catch (RuntimeException e) { // e.g. AIOOBE if (_log.shouldLog(Log.WARN)) _log.warn("Error handling a message: " + state, e); diff --git a/router/java/src/net/i2p/router/transport/udp/PacketHandler.java b/router/java/src/net/i2p/router/transport/udp/PacketHandler.java index 736171b80..1f5f990bc 100644 --- a/router/java/src/net/i2p/router/transport/udp/PacketHandler.java +++ b/router/java/src/net/i2p/router/transport/udp/PacketHandler.java @@ -215,7 +215,7 @@ class PacketHandler { _state = 5; handlePacket(_reader, packet); _state = 6; - } catch (Exception e) { + } catch (RuntimeException e) { _state = 7; if (_log.shouldLog(Log.ERROR)) _log.error("Crazy error handling a packet: " + packet, e); diff --git a/router/java/src/net/i2p/router/transport/udp/PacketPusher.java b/router/java/src/net/i2p/router/transport/udp/PacketPusher.java index f28ee9645..5c770175c 100644 --- a/router/java/src/net/i2p/router/transport/udp/PacketPusher.java +++ b/router/java/src/net/i2p/router/transport/udp/PacketPusher.java @@ -43,7 +43,7 @@ class PacketPusher implements Runnable { send(packets.get(i)); } } - } catch (Exception e) { + } catch (RuntimeException e) { _log.error("SSU Output Queue Error", e); } } diff --git a/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java b/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java index 5b2bdfb2a..d4985ab51 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java +++ b/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java @@ -213,7 +213,7 @@ class BuildHandler implements Runnable { while (_isRunning && !_manager.isShutdown()) { try { handleInboundRequest(); - } catch (Exception e) { + } catch (RuntimeException e) { _log.log(Log.CRIT, "B0rked in the tunnel handler", e); } } From c609781927326185b9ec8afe5ce7d18004395e21 Mon Sep 17 00:00:00 2001 From: zzz Date: Thu, 12 Nov 2015 20:02:11 +0000 Subject: [PATCH 14/33] fix compile --- apps/systray/java/src/net/i2p/apps/systray/SysTray.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/systray/java/src/net/i2p/apps/systray/SysTray.java b/apps/systray/java/src/net/i2p/apps/systray/SysTray.java index 701c28b87..da7f6c37b 100644 --- a/apps/systray/java/src/net/i2p/apps/systray/SysTray.java +++ b/apps/systray/java/src/net/i2p/apps/systray/SysTray.java @@ -11,6 +11,7 @@ package net.i2p.apps.systray; import java.awt.Frame; import java.io.File; +import java.io.IOException; import net.i2p.I2PAppContext; import net.i2p.util.SimpleTimer; @@ -88,14 +89,14 @@ public class SysTray implements SysTrayMenuListener { try { if (urlLauncher.openUrl(url)) return; - } catch (RuntimeException ex) { + } catch (IOException ex) { // Fall through. } } else { try { if (urlLauncher.openUrl(url, _browserString)) return; - } catch (RuntimeException ex) { + } catch (IOException ex) { // Fall through. } } From ded249dd3d2b3c0008fd1e2ff024d78163fe5e7a Mon Sep 17 00:00:00 2001 From: zzz Date: Thu, 12 Nov 2015 21:00:46 +0000 Subject: [PATCH 15/33] add systray dependency tracking to build --- apps/systray/java/build.xml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/apps/systray/java/build.xml b/apps/systray/java/build.xml index 9fccf66fc..c5eb70731 100644 --- a/apps/systray/java/build.xml +++ b/apps/systray/java/build.xml @@ -5,11 +5,26 @@ + + + + + + + + + + + + - + Date: Sat, 14 Nov 2015 02:07:01 +0000 Subject: [PATCH 16/33] Profiles: Don't allow creation of our own profile TunnelCreatorConfig: - locking - comment out unused code - don't set bandwidth stats in profile for ourselves TunnelDispatcher: - don't set tunnel stats in profile for ourselves BuildHandler, TunnelPool: Minor optimizations --- .../router/peermanager/ProfileOrganizer.java | 15 +++++ .../src/net/i2p/router/tunnel/HopConfig.java | 8 ++- .../router/tunnel/TunnelCreatorConfig.java | 61 ++++++++++++------- .../i2p/router/tunnel/pool/BuildHandler.java | 8 ++- .../i2p/router/tunnel/pool/TunnelPool.java | 2 +- 5 files changed, 64 insertions(+), 30 deletions(-) diff --git a/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java b/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java index 87f751bdc..ea800858b 100644 --- a/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java +++ b/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java @@ -156,6 +156,11 @@ public class ProfileOrganizer { * Blocking if a reorganize is happening. */ public PeerProfile getProfile(Hash peer) { + if (peer.equals(_us)) { + if (_log.shouldWarn()) + _log.warn("Who wanted our own profile?", new Exception("I did")); + return null; + } getReadLock(); try { return locked_getProfile(peer); @@ -168,6 +173,11 @@ public class ProfileOrganizer { * @since 0.8.12 */ public PeerProfile getProfileNonblocking(Hash peer) { + if (peer.equals(_us)) { + if (_log.shouldWarn()) + _log.warn("Who wanted our own profile?", new Exception("I did")); + return null; + } if (tryReadLock()) { try { return locked_getProfile(peer); @@ -184,6 +194,11 @@ public class ProfileOrganizer { if (profile == null) return null; Hash peer = profile.getPeer(); + if (peer.equals(_us)) { + if (_log.shouldWarn()) + _log.warn("Who added our own profile?", new Exception("I did")); + return null; + } if (_log.shouldLog(Log.DEBUG)) _log.debug("New profile created for " + peer); diff --git a/router/java/src/net/i2p/router/tunnel/HopConfig.java b/router/java/src/net/i2p/router/tunnel/HopConfig.java index 447f6a083..133c6484a 100644 --- a/router/java/src/net/i2p/router/tunnel/HopConfig.java +++ b/router/java/src/net/i2p/router/tunnel/HopConfig.java @@ -50,12 +50,14 @@ public class HopConfig { public void setReceiveTunnelId(byte id[]) { _receiveTunnelId = id; } public void setReceiveTunnelId(TunnelId id) { _receiveTunnelId = DataHelper.toLong(4, id.getTunnelId()); } - /** what is the previous peer in the tunnel (if any)? */ + /** what is the previous peer in the tunnel (null if gateway) */ public Hash getReceiveFrom() { return _receiveFrom; } public void setReceiveFrom(Hash from) { _receiveFrom = from; } - /** what is the next tunnel ID we are sending to? */ + /** what is the next tunnel ID we are sending to? (null if endpoint) */ public byte[] getSendTunnelId() { return _sendTunnelId; } + + /** what is the next tunnel we are sending to? (null if endpoint) */ public TunnelId getSendTunnel() { if (_sendTunnel == null) _sendTunnel = getTunnel(_sendTunnelId); @@ -70,7 +72,7 @@ public class HopConfig { return new TunnelId(DataHelper.fromLong(id, 0, id.length)); } - /** what is the next peer in the tunnel (if any)? */ + /** what is the next peer in the tunnel (null if endpoint) */ public Hash getSendTo() { return _sendTo; } public void setSendTo(Hash to) { _sendTo = to; } diff --git a/router/java/src/net/i2p/router/tunnel/TunnelCreatorConfig.java b/router/java/src/net/i2p/router/tunnel/TunnelCreatorConfig.java index 9340477c6..758d2096b 100644 --- a/router/java/src/net/i2p/router/tunnel/TunnelCreatorConfig.java +++ b/router/java/src/net/i2p/router/tunnel/TunnelCreatorConfig.java @@ -30,16 +30,32 @@ public class TunnelCreatorConfig implements TunnelInfo { private long _replyMessageId; private final boolean _isInbound; private int _messagesProcessed; - private volatile long _verifiedBytesTransferred; + private long _verifiedBytesTransferred; private boolean _failed; private int _failures; private boolean _reused; private int _priority; + //private static final int THROUGHPUT_COUNT = 3; + // Fastest 1 minute throughput, in bytes per minute, ordered with fastest first. + //private final double _peakThroughput[] = new double[THROUGHPUT_COUNT]; + private long _peakThroughputCurrentTotal; + private long _peakThroughputLastCoallesce = System.currentTimeMillis(); + // Make configurable? - but can't easily get to pool options from here + private static final int MAX_CONSECUTIVE_TEST_FAILURES = 3; + private static final SimpleDateFormat _fmt = new SimpleDateFormat("HH:mm:ss", Locale.UK); + /** + * For exploratory only (null destination) + * @param length 1 minimum (0 hop is length 1) + */ public TunnelCreatorConfig(RouterContext ctx, int length, boolean isInbound) { this(ctx, length, isInbound, null); } + /** + * @param length 1 minimum (0 hop is length 1) + * @param destination null for exploratory + */ public TunnelCreatorConfig(RouterContext ctx, int length, boolean isInbound, Hash destination) { _context = ctx; if (length <= 0) @@ -131,10 +147,14 @@ public class TunnelCreatorConfig implements TunnelInfo { public void setReplyMessageId(long id) { _replyMessageId = id; } /** take note of a message being pumped through this tunnel */ - public void incrementProcessedMessages() { _messagesProcessed++; } - public int getProcessedMessagesCount() { return _messagesProcessed; } + public synchronized void incrementProcessedMessages() { _messagesProcessed++; } + public synchronized int getProcessedMessagesCount() { return _messagesProcessed; } - public void incrementVerifiedBytesTransferred(int bytes) { + /** + * This calls profile manager tunnelDataPushed1m() for each peer + * @return null for exploratory + */ + public synchronized void incrementVerifiedBytesTransferred(int bytes) { _verifiedBytesTransferred += bytes; _peakThroughputCurrentTotal += bytes; long now = System.currentTimeMillis(); @@ -144,38 +164,34 @@ public class TunnelCreatorConfig implements TunnelInfo { double normalized = tot * 60d*1000d / timeSince; _peakThroughputLastCoallesce = now; _peakThroughputCurrentTotal = 0; - if (_context != null) - for (int i = 0; i < _peers.length; i++) + if (_context != null) { + // skip ourselves + int start = _isInbound ? 0 : 1; + int end = _isInbound ? _peers.length - 1 : _peers.length; + for (int i = start; i < end; i++) { _context.profileManager().tunnelDataPushed1m(_peers[i], (int)normalized); + } + } } } - public long getVerifiedBytesTransferred() { return _verifiedBytesTransferred; } + public synchronized long getVerifiedBytesTransferred() { return _verifiedBytesTransferred; } - private static final int THROUGHPUT_COUNT = 3; - /** - * fastest 1 minute throughput, in bytes per minute, ordered with fastest - * first. - */ - private final double _peakThroughput[] = new double[THROUGHPUT_COUNT]; - private volatile long _peakThroughputCurrentTotal; - private volatile long _peakThroughputLastCoallesce = System.currentTimeMillis(); - public double getPeakThroughputKBps() { +/**** unused + public synchronized double getPeakThroughputKBps() { double rv = 0; for (int i = 0; i < THROUGHPUT_COUNT; i++) rv += _peakThroughput[i]; rv /= (60d*1024d*THROUGHPUT_COUNT); return rv; } - public void setPeakThroughputKBps(double kBps) { + + public synchronized void setPeakThroughputKBps(double kBps) { _peakThroughput[0] = kBps*60*1024; //for (int i = 0; i < THROUGHPUT_COUNT; i++) // _peakThroughput[i] = kBps*60; } - - - // Make configurable? - but can't easily get to pool options from here - private static final int MAX_CONSECUTIVE_TEST_FAILURES = 3; +****/ /** * The tunnel failed a test, so (maybe) stop using it @@ -264,11 +280,10 @@ public class TunnelCreatorConfig implements TunnelInfo { return buf.toString(); } - private static final SimpleDateFormat _fmt = new SimpleDateFormat("HH:mm:ss", Locale.UK); - private String getExpirationString() { return format(_expiration); } + static String format(long date) { Date d = new Date(date); synchronized (_fmt) { diff --git a/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java b/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java index d4985ab51..0848bbe1b 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java +++ b/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java @@ -795,7 +795,8 @@ class BuildHandler implements Runnable { cfg.setIVKey(req.readIVKey()); cfg.setLayerKey(req.readLayerKey()); if (isInGW) { - cfg.setReceiveFrom(null); + // default + //cfg.setReceiveFrom(null); } else { if (state.fromHash != null) { cfg.setReceiveFrom(state.fromHash); @@ -808,8 +809,9 @@ class BuildHandler implements Runnable { } cfg.setReceiveTunnelId(DataHelper.toLong(4, ourId)); if (isOutEnd) { - cfg.setSendTo(null); - cfg.setSendTunnelId(null); + // default + //cfg.setSendTo(null); + //cfg.setSendTunnelId(null); } else { cfg.setSendTo(nextPeer); cfg.setSendTunnelId(DataHelper.toLong(4, nextId)); 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 a1dae253c..aaf24387c 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java +++ b/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java @@ -1168,7 +1168,7 @@ public class TunnelPool { int j = peers.size() - 1 - i; cfg.setPeer(j, peers.get(i)); HopConfig hop = cfg.getConfig(j); - hop.setCreation(_context.clock().now()); + hop.setCreation(now); hop.setExpiration(expiration); hop.setIVKey(_context.keyGenerator().generateSessionKey()); hop.setLayerKey(_context.keyGenerator().generateSessionKey()); From 23cb4ca764bae1947edb0699ba51d5c5e31f3f6a Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 14 Nov 2015 02:07:28 +0000 Subject: [PATCH 17/33] ditto --- router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java b/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java index 4e945b9db..996b76859 100644 --- a/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java +++ b/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java @@ -452,7 +452,8 @@ public class TunnelDispatcher implements Service { _inboundGateways.remove(recvId); } else { // update stats based off getCompleteCount() + getFailedCount() - for (int i = 0; i < cfg.getLength(); i++) { + // skip last hop (us) + for (int i = 0; i < cfg.getLength() - 1; i++) { Hash peer = cfg.getPeer(i); PeerProfile profile = _context.profileOrganizer().getProfile(peer); if (profile != null) { From f5ae9c23fea69d83064d33360d3f0b03fcd5aaa6 Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 14 Nov 2015 02:50:08 +0000 Subject: [PATCH 18/33] fix installer tools compile --- .../i2p/router/networkdb/kademlia/BundleRouterInfos.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/installer/tools/java/src/net/i2p/router/networkdb/kademlia/BundleRouterInfos.java b/installer/tools/java/src/net/i2p/router/networkdb/kademlia/BundleRouterInfos.java index ac405f0ee..cab5991d3 100644 --- a/installer/tools/java/src/net/i2p/router/networkdb/kademlia/BundleRouterInfos.java +++ b/installer/tools/java/src/net/i2p/router/networkdb/kademlia/BundleRouterInfos.java @@ -24,6 +24,7 @@ import java.util.Properties; import gnu.getopt.Getopt; import net.i2p.I2PAppContext; +import net.i2p.data.DataFormatException; import net.i2p.data.Hash; import net.i2p.data.router.RouterAddress; import net.i2p.data.router.RouterInfo; @@ -109,7 +110,9 @@ public class BundleRouterInfos { RouterInfo ri = new RouterInfo(); ri.readBytes(fis, true); // true = verify sig on read me = ri.getIdentity().getHash(); - } catch (RuntimeException e) { + } catch (IOException e) { + //System.out.println("Can't determine our identity"); + } catch (DataFormatException e) { //System.out.println("Can't determine our identity"); } finally { if (fis != null) try { fis.close(); } catch (IOException ioe) {} @@ -209,7 +212,9 @@ public class BundleRouterInfos { copied++; else System.out.println("Failed copy of " + file + " to " + toDir); - } catch (RuntimeException e) { + } catch (IOException e) { + System.out.println("Skipping bad " + file); + } catch (DataFormatException e) { System.out.println("Skipping bad " + file); } finally { if (fis != null) try { fis.close(); } catch (IOException ioe) {} From 99c9b30e494a8ef50f3cd4038869b5870f4ab946 Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 14 Nov 2015 13:22:35 +0000 Subject: [PATCH 19/33] another installer build fix --- installer/java/src/net/i2p/installer/Exec.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/installer/java/src/net/i2p/installer/Exec.java b/installer/java/src/net/i2p/installer/Exec.java index 05113b9c6..de7419202 100644 --- a/installer/java/src/net/i2p/installer/Exec.java +++ b/installer/java/src/net/i2p/installer/Exec.java @@ -1,6 +1,7 @@ package net.i2p.installer; import java.io.File; +import java.io.IOException; /** *

This class can be used by the installer to execute shell commands.

@@ -20,7 +21,8 @@ public class Exec { // http://cephas.net/blog/2004/03/23/external_applications_javas_runtimeexec.html try { proc.exitValue(); } catch (Throwable t) { } Runtime.getRuntime().halt(0); - + } catch (IOException e) { + e.printStackTrace(); } catch (RuntimeException e) { e.printStackTrace(); } From 38a1a96db2f17ccddca20c2605cfb62868ada3a5 Mon Sep 17 00:00:00 2001 From: zzz Date: Mon, 16 Nov 2015 19:57:38 +0000 Subject: [PATCH 20/33] revert JobTiming being a clock shift listener, not needed --- router/java/src/net/i2p/router/JobTiming.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/router/java/src/net/i2p/router/JobTiming.java b/router/java/src/net/i2p/router/JobTiming.java index f934f1556..c9c0efb03 100644 --- a/router/java/src/net/i2p/router/JobTiming.java +++ b/router/java/src/net/i2p/router/JobTiming.java @@ -16,7 +16,7 @@ import net.i2p.util.Clock; * * For use by the router only. Not to be used by applications or plugins. */ -public class JobTiming implements Clock.ClockUpdateListener, RouterClock.ClockShiftListener { +public class JobTiming implements Clock.ClockUpdateListener { private volatile long _start; private volatile long _actualStart; private volatile long _actualEnd; @@ -82,8 +82,4 @@ public class JobTiming implements Clock.ClockUpdateListener, RouterClock.ClockSh if (_actualEnd != 0) _actualEnd += delta; } - - public void clockShift(long delta) { - offsetChanged(delta); - } } From 6fb0692d578fb554f8499cd02c5446cf559e96ab Mon Sep 17 00:00:00 2001 From: zzz Date: Mon, 16 Nov 2015 20:04:15 +0000 Subject: [PATCH 21/33] Centralize time zone code in DataHelper NewsManager should be a ClientApp, not a RouterApp --- .../org/klomp/snark/web/I2PSnarkServlet.java | 5 +---- .../src/net/i2p/i2ptunnel/ConnThrottler.java | 5 +---- .../src/net/i2p/router/news/NewsManager.java | 10 ++++------ .../src/net/i2p/router/update/NewsFetcher.java | 5 +---- .../src/net/i2p/router/web/EventLogHelper.java | 5 +---- .../src/net/i2p/router/web/NewsFeedHelper.java | 5 +---- .../net/i2p/router/web/SummaryBarRenderer.java | 5 +---- .../src/java/src/i2p/susi/dns/FormatDate.java | 6 ++---- .../susimail/src/src/i2p/susi/webmail/Mail.java | 9 +++------ core/java/src/net/i2p/data/DataHelper.java | 17 +++++++++++++++++ core/java/src/net/i2p/util/LogManager.java | 5 +---- 11 files changed, 33 insertions(+), 44 deletions(-) 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 5da8e2f43..538973660 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java +++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java @@ -18,7 +18,6 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; -import java.util.TimeZone; import java.util.TreeMap; import javax.servlet.ServletConfig; @@ -2801,9 +2800,7 @@ public class I2PSnarkServlet extends BasicServlet { } long dat = meta.getCreationDate(); SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm"); - String systemTimeZone = _context.getProperty("i2p.systemTimeZone"); - if (systemTimeZone != null) - fmt.setTimeZone(TimeZone.getTimeZone(systemTimeZone)); + fmt.setTimeZone(DataHelper.getSystemTimeZone(_context)); if (dat > 0) { String date = fmt.format(new Date(dat)); buf.append("
"); diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/ConnThrottler.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/ConnThrottler.java index c802a9995..de9188d8e 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/ConnThrottler.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/ConnThrottler.java @@ -7,7 +7,6 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.TimeZone; import net.i2p.I2PAppContext; import net.i2p.data.DataHelper; @@ -57,9 +56,7 @@ class ConnThrottler { _log = log; // for logging _fmt = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM); - String systemTimeZone = I2PAppContext.getGlobalContext().getProperty("i2p.systemTimeZone"); - if (systemTimeZone != null) - _fmt.setTimeZone(TimeZone.getTimeZone(systemTimeZone)); + _fmt.setTimeZone(DataHelper.getSystemTimeZone(I2PAppContext.getGlobalContext())); new Cleaner(); } diff --git a/apps/routerconsole/java/src/net/i2p/router/news/NewsManager.java b/apps/routerconsole/java/src/net/i2p/router/news/NewsManager.java index d85baadf5..35da6b387 100644 --- a/apps/routerconsole/java/src/net/i2p/router/news/NewsManager.java +++ b/apps/routerconsole/java/src/net/i2p/router/news/NewsManager.java @@ -10,13 +10,13 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; -import java.util.TimeZone; import net.i2p.I2PAppContext; +import net.i2p.app.ClientApp; import net.i2p.app.ClientAppManager; import net.i2p.app.ClientAppState; import static net.i2p.app.ClientAppState.*; -import net.i2p.router.app.RouterApp; +import net.i2p.data.DataHelper; import net.i2p.util.FileUtil; import net.i2p.util.Log; import net.i2p.util.TranslateReader; @@ -30,7 +30,7 @@ import org.cybergarage.xml.Node; * * @since 0.9.23 */ -public class NewsManager implements RouterApp { +public class NewsManager implements ClientApp { private final I2PAppContext _context; private final Log _log; @@ -233,9 +233,7 @@ public class NewsManager implements RouterApp { // Doesn't work if the date has a : in it, but SHORT hopefully does not DateFormat fmt = DateFormat.getDateInstance(DateFormat.SHORT); // the router sets the JVM time zone to UTC but saves the original here so we can get it - String systemTimeZone = _context.getProperty("i2p.systemTimeZone"); - if (systemTimeZone != null) - fmt.setTimeZone(TimeZone.getTimeZone(systemTimeZone)); + fmt.setTimeZone(DataHelper.getSystemTimeZone(_context)); try { Date date = fmt.parse(newsContent.substring(0, colon)); entry.updated = date.getTime(); diff --git a/apps/routerconsole/java/src/net/i2p/router/update/NewsFetcher.java b/apps/routerconsole/java/src/net/i2p/router/update/NewsFetcher.java index 66799737d..9b096a6b3 100644 --- a/apps/routerconsole/java/src/net/i2p/router/update/NewsFetcher.java +++ b/apps/routerconsole/java/src/net/i2p/router/update/NewsFetcher.java @@ -19,7 +19,6 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.StringTokenizer; -import java.util.TimeZone; import net.i2p.app.ClientAppManager; import net.i2p.crypto.SU3File; @@ -579,9 +578,7 @@ class NewsFetcher extends UpdateRunner { return; DateFormat fmt = DateFormat.getDateInstance(DateFormat.SHORT); // the router sets the JVM time zone to UTC but saves the original here so we can get it - String systemTimeZone = _context.getProperty("i2p.systemTimeZone"); - if (systemTimeZone != null) - fmt.setTimeZone(TimeZone.getTimeZone(systemTimeZone)); + fmt.setTimeZone(DataHelper.getSystemTimeZone(_context)); for (NewsEntry e : entries) { if (e.title == null || e.content == null) continue; diff --git a/apps/routerconsole/java/src/net/i2p/router/web/EventLogHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/EventLogHelper.java index ca738304e..01ac1614b 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/EventLogHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/EventLogHelper.java @@ -12,7 +12,6 @@ import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.TimeZone; import java.util.TreeMap; import net.i2p.data.DataHelper; @@ -189,9 +188,7 @@ public class EventLogHelper extends FormHandler { SimpleDateFormat fmt = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM); // the router sets the JVM time zone to UTC but saves the original here so we can get it - String systemTimeZone = _context.getProperty("i2p.systemTimeZone"); - if (systemTimeZone != null) - fmt.setTimeZone(TimeZone.getTimeZone(systemTimeZone)); + fmt.setTimeZone(DataHelper.getSystemTimeZone(_context)); List> entries = new ArrayList>(events.entrySet()); Collections.reverse(entries); diff --git a/apps/routerconsole/java/src/net/i2p/router/web/NewsFeedHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/NewsFeedHelper.java index 357887f9e..07dfa5854 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/NewsFeedHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/NewsFeedHelper.java @@ -4,7 +4,6 @@ import java.text.DateFormat; import java.util.Collections; import java.util.Date; import java.util.List; -import java.util.TimeZone; import net.i2p.I2PAppContext; import net.i2p.app.ClientAppManager; @@ -56,9 +55,7 @@ public class NewsFeedHelper extends HelperBase { if (!entries.isEmpty()) { DateFormat fmt = DateFormat.getDateInstance(DateFormat.SHORT); // the router sets the JVM time zone to UTC but saves the original here so we can get it - String systemTimeZone = ctx.getProperty("i2p.systemTimeZone"); - if (systemTimeZone != null) - fmt.setTimeZone(TimeZone.getTimeZone(systemTimeZone)); + fmt.setTimeZone(DataHelper.getSystemTimeZone(ctx)); int i = 0; for (NewsEntry entry : entries) { if (i++ < start) diff --git a/apps/routerconsole/java/src/net/i2p/router/web/SummaryBarRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/SummaryBarRenderer.java index 002f7983b..710ce2753 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/SummaryBarRenderer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/SummaryBarRenderer.java @@ -9,7 +9,6 @@ import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.TimeZone; import net.i2p.app.ClientAppManager; import net.i2p.crypto.SigType; @@ -634,9 +633,7 @@ public class SummaryBarRenderer { buf.append("
    \n"); DateFormat fmt = DateFormat.getDateInstance(DateFormat.SHORT); // the router sets the JVM time zone to UTC but saves the original here so we can get it - String systemTimeZone = _context.getProperty("i2p.systemTimeZone"); - if (systemTimeZone != null) - fmt.setTimeZone(TimeZone.getTimeZone(systemTimeZone)); + fmt.setTimeZone(DataHelper.getSystemTimeZone(_context)); int i = 0; final int max = 2; for (NewsEntry entry : entries) { diff --git a/apps/susidns/src/java/src/i2p/susi/dns/FormatDate.java b/apps/susidns/src/java/src/i2p/susi/dns/FormatDate.java index ad576dfb0..c7604a213 100644 --- a/apps/susidns/src/java/src/i2p/susi/dns/FormatDate.java +++ b/apps/susidns/src/java/src/i2p/susi/dns/FormatDate.java @@ -2,9 +2,9 @@ package i2p.susi.dns; import java.util.Date; import java.text.DateFormat; -import java.util.TimeZone; import net.i2p.I2PAppContext; +import net.i2p.data.DataHelper; /** * Format a date in local time zone @@ -17,9 +17,7 @@ public abstract class FormatDate static { DateFormat fmt = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM); // the router sets the JVM time zone to UTC but saves the original here so we can get it - String systemTimeZone = I2PAppContext.getGlobalContext().getProperty("i2p.systemTimeZone"); - if (systemTimeZone != null) - fmt.setTimeZone(TimeZone.getTimeZone(systemTimeZone)); + fmt.setTimeZone(DataHelper.getSystemTimeZone(I2PAppContext.getGlobalContext())); _dateFormat = fmt; } diff --git a/apps/susimail/src/src/i2p/susi/webmail/Mail.java b/apps/susimail/src/src/i2p/susi/webmail/Mail.java index e0386b223..c184831c3 100644 --- a/apps/susimail/src/src/i2p/susi/webmail/Mail.java +++ b/apps/susimail/src/src/i2p/susi/webmail/Mail.java @@ -276,12 +276,9 @@ class Mail { DateFormat localDateFormatter = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT); DateFormat longLocalDateFormatter = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM); // the router sets the JVM time zone to UTC but saves the original here so we can get it - String systemTimeZone = I2PAppContext.getGlobalContext().getProperty("i2p.systemTimeZone"); - if (systemTimeZone != null) { - TimeZone tz = TimeZone.getTimeZone(systemTimeZone); - localDateFormatter.setTimeZone(tz); - longLocalDateFormatter.setTimeZone(tz); - } + TimeZone tz = DataHelper.getSystemTimeZone(I2PAppContext.getGlobalContext()); + localDateFormatter.setTimeZone(tz); + longLocalDateFormatter.setTimeZone(tz); DateFormat mailDateFormatter = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.ENGLISH ); error = ""; diff --git a/core/java/src/net/i2p/data/DataHelper.java b/core/java/src/net/i2p/data/DataHelper.java index f2c83a48e..ee78a95c6 100644 --- a/core/java/src/net/i2p/data/DataHelper.java +++ b/core/java/src/net/i2p/data/DataHelper.java @@ -37,6 +37,7 @@ import java.util.Iterator; import java.util.Locale; import java.util.Map; import java.util.Properties; +import java.util.TimeZone; import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Pattern; import java.util.zip.Deflater; @@ -1924,4 +1925,20 @@ public class DataHelper { } return p.split(s, limit); } + + /** + * The system's time zone, which is probably different from the + * JVM time zone, because Router changes the JVM default to GMT. + * It saves the old default in the context properties where we can get it. + * Use this to format a time in local time zone with DateFormat.setTimeZone(). + * + * @return non-null + * @since 0.9.24 + */ + public static TimeZone getSystemTimeZone(I2PAppContext ctx) { + String systemTimeZone = ctx.getProperty("i2p.systemTimeZone"); + if (systemTimeZone != null) + return TimeZone.getTimeZone(systemTimeZone); + return TimeZone.getDefault(); + } } diff --git a/core/java/src/net/i2p/util/LogManager.java b/core/java/src/net/i2p/util/LogManager.java index ca2476de8..94a39cf0c 100644 --- a/core/java/src/net/i2p/util/LogManager.java +++ b/core/java/src/net/i2p/util/LogManager.java @@ -22,7 +22,6 @@ import java.util.Map; import java.util.Properties; import java.util.Queue; import java.util.Set; -import java.util.TimeZone; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.atomic.AtomicInteger; @@ -479,9 +478,7 @@ public class LogManager implements Flushable { if (!format.equals("")) fmt.applyPattern(format); // the router sets the JVM time zone to UTC but saves the original here so we can get it - String systemTimeZone = _context.getProperty("i2p.systemTimeZone"); - if (systemTimeZone != null) - fmt.setTimeZone(TimeZone.getTimeZone(systemTimeZone)); + fmt.setTimeZone(DataHelper.getSystemTimeZone(_context)); _dateFormatPattern = format; _dateFormat = fmt; return true; From 679fe9b0442b1b813cae28b99c221290de601c0d Mon Sep 17 00:00:00 2001 From: zzz Date: Tue, 17 Nov 2015 14:51:32 +0000 Subject: [PATCH 22/33] more release checks --- build.xml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/build.xml b/build.xml index ea10ca4bb..aefc60d52 100644 --- a/build.xml +++ b/build.xml @@ -868,6 +868,21 @@ + + + + + + + + + + + + + + + From 4c72c08d650eae436f392f5abe61b26b24939ffb Mon Sep 17 00:00:00 2001 From: zzz Date: Wed, 18 Nov 2015 13:43:14 +0000 Subject: [PATCH 23/33] i2psnark: Add skipped length on details page reorder some logging volatile --- .../java/src/org/klomp/snark/Peer.java | 2 +- .../src/org/klomp/snark/PeerConnectionIn.java | 35 ++++++++++--------- .../java/src/org/klomp/snark/Snark.java | 24 +++++++++++++ .../java/src/org/klomp/snark/Storage.java | 25 +++++++++++++ .../org/klomp/snark/web/I2PSnarkServlet.java | 9 +++++ 5 files changed, 77 insertions(+), 18 deletions(-) diff --git a/apps/i2psnark/java/src/org/klomp/snark/Peer.java b/apps/i2psnark/java/src/org/klomp/snark/Peer.java index cba955f69..fbbb1859a 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/Peer.java +++ b/apps/i2psnark/java/src/org/klomp/snark/Peer.java @@ -62,7 +62,7 @@ public class Peer implements Comparable // Keeps state for in/out connections. Non-null when the handshake // was successful, the connection setup and runs - PeerState state; + volatile PeerState state; /** shared across all peers on this torrent */ MagnetState magnetState; diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionIn.java b/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionIn.java index 1f47b59b6..da1b94333 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionIn.java +++ b/apps/i2psnark/java/src/org/klomp/snark/PeerConnectionIn.java @@ -39,7 +39,7 @@ class PeerConnectionIn implements Runnable private static final int MAX_MSG_SIZE = Math.max(PeerState.PARTSIZE + 9, MagnetState.CHUNK_SIZE + 100); // 100 for the ext msg dictionary - private Thread thread; + private volatile Thread thread; private volatile boolean quit; long lastRcvd; @@ -75,9 +75,12 @@ class PeerConnectionIn implements Runnable thread = Thread.currentThread(); try { - PeerState ps = peer.state; - while (!quit && ps != null) + while (!quit) { + final PeerState ps = peer.state; + if (ps == null) + break; + // Common variables used for some messages. int piece; int begin; @@ -91,9 +94,9 @@ class PeerConnectionIn implements Runnable if (i == 0) { - ps.keepAliveMessage(); if (_log.shouldLog(Log.DEBUG)) _log.debug("Received keepalive from " + peer); + ps.keepAliveMessage(); continue; } @@ -101,51 +104,51 @@ class PeerConnectionIn implements Runnable switch (b) { case Message.CHOKE: - ps.chokeMessage(true); if (_log.shouldLog(Log.DEBUG)) _log.debug("Received choke from " + peer); + ps.chokeMessage(true); break; case Message.UNCHOKE: - ps.chokeMessage(false); if (_log.shouldLog(Log.DEBUG)) _log.debug("Received unchoke from " + peer); + ps.chokeMessage(false); break; case Message.INTERESTED: - ps.interestedMessage(true); if (_log.shouldLog(Log.DEBUG)) _log.debug("Received interested from " + peer); + ps.interestedMessage(true); break; case Message.UNINTERESTED: - ps.interestedMessage(false); if (_log.shouldLog(Log.DEBUG)) _log.debug("Received not interested from " + peer); + ps.interestedMessage(false); break; case Message.HAVE: piece = din.readInt(); - ps.haveMessage(piece); if (_log.shouldLog(Log.DEBUG)) _log.debug("Received havePiece(" + piece + ") from " + peer); + ps.haveMessage(piece); break; case Message.BITFIELD: byte[] bitmap = new byte[i-1]; din.readFully(bitmap); - ps.bitfieldMessage(bitmap); if (_log.shouldLog(Log.DEBUG)) _log.debug("Received bitmap from " + peer + ": size=" + (i-1) /* + ": " + ps.bitfield */ ); + ps.bitfieldMessage(bitmap); break; case Message.REQUEST: piece = din.readInt(); begin = din.readInt(); len = din.readInt(); - ps.requestMessage(piece, begin, len); if (_log.shouldLog(Log.DEBUG)) _log.debug("Received request(" + piece + "," + begin + ") from " + peer); + ps.requestMessage(piece, begin, len); break; case Message.PIECE: @@ -156,9 +159,9 @@ class PeerConnectionIn implements Runnable if (req != null) { req.read(din); - ps.pieceMessage(req); if (_log.shouldLog(Log.DEBUG)) _log.debug("Received data(" + piece + "," + begin + ") from " + peer); + ps.pieceMessage(req); } else { @@ -175,16 +178,16 @@ class PeerConnectionIn implements Runnable piece = din.readInt(); begin = din.readInt(); len = din.readInt(); - ps.cancelMessage(piece, begin, len); if (_log.shouldLog(Log.DEBUG)) _log.debug("Received cancel(" + piece + "," + begin + ") from " + peer); + ps.cancelMessage(piece, begin, len); break; case Message.PORT: int port = din.readUnsignedShort(); - ps.portMessage(port); if (_log.shouldLog(Log.DEBUG)) _log.debug("Received port message from " + peer); + ps.portMessage(port); break; case Message.EXTENSION: @@ -247,11 +250,9 @@ class PeerConnectionIn implements Runnable if (_log.shouldLog(Log.INFO)) _log.info("IOError talking with " + peer, ioe); } - catch (Throwable t) + catch (RuntimeException t) { _log.error("Error talking with " + peer, t); - if (t instanceof OutOfMemoryError) - throw (OutOfMemoryError)t; } finally { diff --git a/apps/i2psnark/java/src/org/klomp/snark/Snark.java b/apps/i2psnark/java/src/org/klomp/snark/Snark.java index f8dadb627..b0f983313 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/Snark.java +++ b/apps/i2psnark/java/src/org/klomp/snark/Snark.java @@ -911,6 +911,30 @@ public class Snark return -1; } + /** + * Bytes not received and set to skipped. + * This is not the same as the total of all skipped files, + * since pieces may span multiple files. + * + * @return exact value. or 0 if no storage yet. + * @since 0.9.24 + */ + public long getSkippedLength() { + PeerCoordinator coord = coordinator; + if (coord != null) { + // fast way + long r = getRemainingLength(); + if (r <= 0) + return 0; + long n = coord.getNeededLength(); + return r - n; + } else if (storage != null) { + // slow way + return storage.getSkippedLength(); + } + return 0; + } + /** * Does not account (i.e. includes) for skipped files. * @return number of pieces still needed (magnet mode or not), or -1 if unknown diff --git a/apps/i2psnark/java/src/org/klomp/snark/Storage.java b/apps/i2psnark/java/src/org/klomp/snark/Storage.java index f8771ded3..acb5255d5 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/Storage.java +++ b/apps/i2psnark/java/src/org/klomp/snark/Storage.java @@ -518,6 +518,31 @@ public class Storage implements Closeable return rv; } + /** + * Call setPriority() for all changed files first, + * then call this. + * The length of all the pieces that are not yet downloaded, + * and are set to skipped. + * This is not the same as the total of all skipped files, + * since pieces may span multiple files. + * + * @return 0 on error, if complete, or if only one file + * @since 0.9.24 + */ + public long getSkippedLength() { + int[] pri = getPiecePriorities(); + if (pri == null) + return 0; + long rv = 0; + final int end = pri.length - 1; + for (int i = 0; i <= end; i++) { + if (pri[i] <= -9 && !bitfield.get(i)) { + rv += (i != end) ? piece_size : metainfo.getPieceLength(i); + } + } + return rv; + } + /** * The BitField that tells which pieces this storage contains. * Do not change this since this is the current state of the storage. 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 538973660..4d7727729 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java +++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java @@ -2916,6 +2916,15 @@ public class I2PSnarkServlet extends BasicServlet { .append(": ") .append(formatSize(needed)); } + long skipped = snark.getSkippedLength(); + if (skipped > 0) { + buf.append(" "); + toThemeImg(buf, "head_rx"); + buf.append(" ") + .append(_t("Skipped")) + .append(": ") + .append(formatSize(skipped)); + } if (meta != null) { List> files = meta.getFiles(); int fileCount = files != null ? files.size() : 1; From 1e89fac192eafb3935d67333f0339704f6d4afde Mon Sep 17 00:00:00 2001 From: zzz Date: Wed, 18 Nov 2015 18:12:23 +0000 Subject: [PATCH 24/33] SSU: Add support for requesting a relay tag via Session Request extended options (ticket #1465) --- .../transport/udp/EstablishmentManager.java | 13 +++++-- .../transport/udp/InboundEstablishState.java | 12 +++++++ .../transport/udp/OutboundEstablishState.java | 18 +++++++++- .../router/transport/udp/PacketBuilder.java | 19 ++++++---- .../i2p/router/transport/udp/UDPPacket.java | 8 +++++ .../router/transport/udp/UDPPacketReader.java | 35 ++++++++++++++----- 6 files changed, 86 insertions(+), 19 deletions(-) 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 53e7e9d8d..5ec58a9e9 100644 --- a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java +++ b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java @@ -131,8 +131,11 @@ class EstablishmentManager { * Java I2P has always parsed the length of the extended options field, * but i2pd hasn't recognized it until this release. * No matter, the options weren't defined until this release anyway. + * + * FIXME 0.9.22 for testing, change to 0.9.24 for release + * */ - private static final String VERSION_ALLOW_EXTENDED_OPTIONS = "0.9.24"; + private static final String VERSION_ALLOW_EXTENDED_OPTIONS = "0.9.22"; public EstablishmentManager(RouterContext ctx, UDPTransport transport) { @@ -367,8 +370,11 @@ class EstablishmentManager { } boolean allowExtendedOptions = VersionComparator.comp(toRouterInfo.getVersion(), VERSION_ALLOW_EXTENDED_OPTIONS) >= 0; + // w/o ext options, it's always 'requested', no need to set + boolean requestIntroduction = allowExtendedOptions && _transport.introducersRequired(); state = new OutboundEstablishState(_context, maybeTo, to, toIdentity, allowExtendedOptions, + requestIntroduction, sessionKey, addr, _transport.getDHFactory()); OutboundEstablishState oldState = _outboundStates.putIfAbsent(to, state); boolean isNew = oldState == null; @@ -488,8 +494,9 @@ class EstablishmentManager { // Don't offer to relay to privileged ports. // Only offer for an IPv4 session. // TODO if already we have their RI, only offer if they need it (no 'C' cap) - // TODO if extended options, only if they asked for it - if (_transport.canIntroduce() && state.getSentPort() >= 1024 && + // if extended options, only if they asked for it + if (state.isIntroductionRequested() && + _transport.canIntroduce() && state.getSentPort() >= 1024 && state.getSentIP().length == 4) { // ensure > 0 long tag = 1 + _context.random().nextLong(MAX_TAG_VALUE); diff --git a/router/java/src/net/i2p/router/transport/udp/InboundEstablishState.java b/router/java/src/net/i2p/router/transport/udp/InboundEstablishState.java index 590aa29ed..96d45c216 100644 --- a/router/java/src/net/i2p/router/transport/udp/InboundEstablishState.java +++ b/router/java/src/net/i2p/router/transport/udp/InboundEstablishState.java @@ -62,6 +62,8 @@ class InboundEstablishState { private final Queue _queuedMessages; // count for backoff private int _createdSentCount; + // default true + private boolean _introductionRequested = true; public enum InboundState { /** nothin known yet */ @@ -150,6 +152,10 @@ class InboundEstablishState { if (_bobIP == null) _bobIP = new byte[req.readIPSize()]; req.readIP(_bobIP, 0); + byte[] ext = req.readExtendedOptions(); + if (ext != null && ext.length >= UDPPacket.SESS_REQ_MIN_EXT_OPTIONS_LENGTH) { + _introductionRequested = (ext[1] & (byte) UDPPacket.SESS_REQ_EXT_FLAG_REQUEST_RELAY_TAG) != 0; + } if (_log.shouldLog(Log.DEBUG)) _log.debug("Receive sessionRequest, BobIP = " + Addresses.toString(_bobIP)); if (_currentState == InboundState.IB_STATE_UNKNOWN) @@ -160,6 +166,12 @@ class InboundEstablishState { public synchronized boolean sessionRequestReceived() { return _receivedX != null; } public synchronized byte[] getReceivedX() { return _receivedX; } public synchronized byte[] getReceivedOurIP() { return _bobIP; } + /** + * True (default) if no extended options in session request, + * or value of flag bit in the extended options. + * @since 0.9.24 + */ + public synchronized boolean isIntroductionRequested() { return _introductionRequested; } /** * Generates session key and mac key. diff --git a/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java b/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java index cfb0d2f57..d849bb836 100644 --- a/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java +++ b/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java @@ -57,6 +57,7 @@ class OutboundEstablishState { private final RemoteHostId _claimedAddress; private final RouterIdentity _remotePeer; private final boolean _allowExtendedOptions; + private final boolean _needIntroduction; private final SessionKey _introKey; private final Queue _queuedMessages; private OutboundState _currentState; @@ -108,12 +109,16 @@ class OutboundEstablishState { * @param claimedAddress an IP/port based RemoteHostId, or null if unknown * @param remoteHostId non-null, == claimedAddress if direct, or a hash-based one if indirect * @param remotePeer must have supported sig type + * @param allowExtenededOptions are we allowed to send extended options to Bob? + * @param needIntroduction should we ask Bob to be an introducer for us? + ignored unless allowExtendedOptions is true * @param introKey Bob's introduction key, as published in the netdb * @param addr non-null */ public OutboundEstablishState(RouterContext ctx, RemoteHostId claimedAddress, RemoteHostId remoteHostId, RouterIdentity remotePeer, boolean allowExtendedOptions, + boolean needIntroduction, SessionKey introKey, UDPAddress addr, DHSessionKeyBuilder.Factory dh) { _context = ctx; @@ -128,6 +133,7 @@ class OutboundEstablishState { _claimedAddress = claimedAddress; _remoteHostId = remoteHostId; _allowExtendedOptions = allowExtendedOptions; + _needIntroduction = needIntroduction; _remotePeer = remotePeer; _introKey = introKey; _queuedMessages = new LinkedBlockingQueue(); @@ -161,8 +167,18 @@ class OutboundEstablishState { /** @return -1 if unset */ public long getIntroNonce() { return _introductionNonce; } - /** @since 0.9.24 */ + /** + * Are we allowed to send extended options to this peer? + * @since 0.9.24 + */ public boolean isExtendedOptionsAllowed() { return _allowExtendedOptions; } + + /** + * Should we ask this peer to be an introducer for us? + * Ignored unless allowExtendedOptions is true + * @since 0.9.24 + */ + public boolean needIntroduction() { return _needIntroduction; } /** * Queue a message to be sent after the session is established. diff --git a/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java b/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java index 594388716..a777d819b 100644 --- a/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java +++ b/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java @@ -783,15 +783,20 @@ class PacketBuilder { * @return ready to send packet, or null if there was a problem */ public UDPPacket buildSessionRequestPacket(OutboundEstablishState state) { - // TODO - // boolean ext = state.isExtendedOptionsAllowed(); - // if (ext) - //byte[] options = new byte[3]; - //UDPPacket packet = buildPacketHeader(SESSION_REQUEST_FLAG_BYTE, options); - UDPPacket packet = buildPacketHeader(SESSION_REQUEST_FLAG_BYTE); + int off = HEADER_SIZE; + byte[] options; + boolean ext = state.isExtendedOptionsAllowed(); + if (ext) { + options = new byte[UDPPacket.SESS_REQ_MIN_EXT_OPTIONS_LENGTH]; + if (state.needIntroduction()) + options[1] = (byte) UDPPacket.SESS_REQ_EXT_FLAG_REQUEST_RELAY_TAG; + off += UDPPacket.SESS_REQ_MIN_EXT_OPTIONS_LENGTH + 1; + } else { + options = null; + } + UDPPacket packet = buildPacketHeader(SESSION_REQUEST_FLAG_BYTE, options); DatagramPacket pkt = packet.getPacket(); byte data[] = pkt.getData(); - int off = HEADER_SIZE; // + 1 + options.length; byte toIP[] = state.getSentIP(); if (!_transport.isValid(toIP)) { diff --git a/router/java/src/net/i2p/router/transport/udp/UDPPacket.java b/router/java/src/net/i2p/router/transport/udp/UDPPacket.java index fae13ab1f..a68b84820 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPPacket.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPPacket.java @@ -101,6 +101,14 @@ class UDPPacket implements CDQEntry { */ public static final byte HEADER_FLAG_EXTENDED_OPTIONS = (1 << 2); + // Extended options for session request + public static final int SESS_REQ_MIN_EXT_OPTIONS_LENGTH = 2; + // bytes 0-1 are flags + /** + * set to 1 to request a session tag, i.e. we want him to be an introducer for us + */ + public static final int SESS_REQ_EXT_FLAG_REQUEST_RELAY_TAG = 0x01; + // various flag fields for use in the data packets public static final byte DATA_FLAG_EXPLICIT_ACK = (byte)(1 << 7); public static final byte DATA_FLAG_ACK_BITFIELDS = (1 << 6); diff --git a/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java b/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java index 34f8d7bf7..616f48c4a 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java @@ -104,6 +104,7 @@ class UDPPacketReader { /** * Returns extended option data, 0-255 bytes, or null if none. + * Returned array does NOT include the length byte. * * @return extended options or null if none is included * @since 0.9.24 @@ -175,8 +176,26 @@ class UDPPacketReader { /* ------- Begin Reader Classes ------- */ + /** + * Base + * + * @since 0.9.24 + */ + public abstract class Reader { + /** + * Returns extended option data from the header, 0-255 bytes, or null if none. + * Returned array does NOT include the length byte. + * + * @return extended options or null if none is included + * @since 0.9.24 + */ + public byte[] readExtendedOptions() { + return UDPPacketReader.this.readExtendedOptions(); + } + } + /** Help read the SessionRequest payload */ - public class SessionRequestReader { + public class SessionRequestReader extends Reader { public static final int X_LENGTH = 256; public void readX(byte target[], int targetOffset) { int readOffset = readBodyOffset(); @@ -198,7 +217,7 @@ class UDPPacketReader { } /** Help read the SessionCreated payload */ - public class SessionCreatedReader { + public class SessionCreatedReader extends Reader { public static final int Y_LENGTH = 256; public void readY(byte target[], int targetOffset) { int readOffset = readBodyOffset(); @@ -253,7 +272,7 @@ class UDPPacketReader { } /** parse out the confirmed message */ - public class SessionConfirmedReader { + public class SessionConfirmedReader extends Reader { /** which fragment is this? */ public int readCurrentFragmentNum() { int readOffset = readBodyOffset(); @@ -306,7 +325,7 @@ class UDPPacketReader { } /** parse out the data message */ - public class DataReader { + public class DataReader extends Reader { /** * @return the data size, NOT including IP header, UDP header, IV, or MAC @@ -642,7 +661,7 @@ class UDPPacketReader { } /** Help read the PeerTest payload */ - public class PeerTestReader { + public class PeerTestReader extends Reader { private static final int NONCE_LENGTH = 4; public long readNonce() { @@ -683,7 +702,7 @@ class UDPPacketReader { } /** Help read the RelayRequest payload */ - public class RelayRequestReader { + public class RelayRequestReader extends Reader { public long readTag() { long rv = DataHelper.fromLong(_message, readBodyOffset(), 4); if (_log.shouldLog(Log.DEBUG)) @@ -767,7 +786,7 @@ class UDPPacketReader { } /** Help read the RelayIntro payload */ - public class RelayIntroReader { + public class RelayIntroReader extends Reader { public int readIPSize() { int offset = readBodyOffset(); return _message[offset] & 0xff; @@ -808,7 +827,7 @@ class UDPPacketReader { /** Help read the RelayResponse payload */ - public class RelayResponseReader { + public class RelayResponseReader extends Reader { public int readCharlieIPSize() { int offset = readBodyOffset(); return _message[offset] & 0xff; From 599989deba1080758d5fc185fc9564f22d798c88 Mon Sep 17 00:00:00 2001 From: zzz Date: Wed, 18 Nov 2015 20:04:45 +0000 Subject: [PATCH 25/33] comment re: SSU timestamps --- router/java/src/net/i2p/router/transport/udp/PacketBuilder.java | 1 + .../java/src/net/i2p/router/transport/udp/UDPPacketReader.java | 1 + 2 files changed, 2 insertions(+) diff --git a/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java b/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java index a777d819b..98cf82bb6 100644 --- a/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java +++ b/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java @@ -1474,6 +1474,7 @@ class PacketBuilder { flagByte |= UDPPacket.HEADER_FLAG_EXTENDED_OPTIONS; data[off] = flagByte; off++; + // Note, this is unsigned, so we're good until February 2106 long now = (_context.clock().now() + 500) / 1000; DataHelper.toLong(data, off, 4, now); // todo: add support for rekeying diff --git a/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java b/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java index 616f48c4a..c7c9d90cc 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java @@ -84,6 +84,7 @@ class UDPPacketReader { /** @return seconds */ public long readTimestamp() { + // Note, this is unsigned, so we're good until February 2106 return DataHelper.fromLong(_message, _payloadBeginOffset + 1, 4); } From 46f42432a2add0cfb724fe30c88a48273a668fec Mon Sep 17 00:00:00 2001 From: zzz Date: Wed, 18 Nov 2015 22:05:47 +0000 Subject: [PATCH 26/33] BOB: change default tunnel length to 3 (ticket #1707) --- apps/BOB/src/net/i2p/BOB/BOB.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/BOB/src/net/i2p/BOB/BOB.java b/apps/BOB/src/net/i2p/BOB/BOB.java index e1106c9bb..c8b06b5e9 100644 --- a/apps/BOB/src/net/i2p/BOB/BOB.java +++ b/apps/BOB/src/net/i2p/BOB/BOB.java @@ -247,11 +247,11 @@ public class BOB implements Runnable, ClientApp { save = true; } if (!props.containsKey("inbound.length")) { - props.setProperty("inbound.length", "1"); + props.setProperty("inbound.length", "3"); save = true; } if (!props.containsKey("outbound.length")) { - props.setProperty("outbound.length", "1"); + props.setProperty("outbound.length", "3"); save = true; } if (!props.containsKey("inbound.lengthVariance")) { From 8d9d3fcf95624f92da1d7d88d4d7629ba5688964 Mon Sep 17 00:00:00 2001 From: zzz Date: Thu, 19 Nov 2015 14:15:28 +0000 Subject: [PATCH 27/33] SSU: Add option to disable extended options Fix max payload type --- .../net/i2p/router/transport/udp/EstablishmentManager.java | 4 +++- router/java/src/net/i2p/router/transport/udp/UDPPacket.java | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) 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 5ec58a9e9..64c32cddf 100644 --- a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java +++ b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java @@ -136,6 +136,7 @@ class EstablishmentManager { * */ private static final String VERSION_ALLOW_EXTENDED_OPTIONS = "0.9.22"; + private static final String PROP_DISABLE_EXT_OPTS = "i2np.udp.disableExtendedOptions"; public EstablishmentManager(RouterContext ctx, UDPTransport transport) { @@ -369,7 +370,8 @@ class EstablishmentManager { return; } boolean allowExtendedOptions = VersionComparator.comp(toRouterInfo.getVersion(), - VERSION_ALLOW_EXTENDED_OPTIONS) >= 0; + VERSION_ALLOW_EXTENDED_OPTIONS) >= 0 + && !_context.getBooleanProperty(PROP_DISABLE_EXT_OPTS); // w/o ext options, it's always 'requested', no need to set boolean requestIntroduction = allowExtendedOptions && _transport.introducersRequired(); state = new OutboundEstablishState(_context, maybeTo, to, diff --git a/router/java/src/net/i2p/router/transport/udp/UDPPacket.java b/router/java/src/net/i2p/router/transport/udp/UDPPacket.java index a68b84820..238ec16fd 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPPacket.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPPacket.java @@ -85,9 +85,9 @@ class UDPPacket implements CDQEntry { public static final int PAYLOAD_TYPE_RELAY_INTRO = 5; public static final int PAYLOAD_TYPE_DATA = 6; public static final int PAYLOAD_TYPE_TEST = 7; - public static final int MAX_PAYLOAD_TYPE = PAYLOAD_TYPE_TEST; /** @since 0.8.1 */ public static final int PAYLOAD_TYPE_SESSION_DESTROY = 8; + public static final int MAX_PAYLOAD_TYPE = PAYLOAD_TYPE_SESSION_DESTROY; // various flag fields for use in the header /** From b59a8027bb865b2405dafb25f5cd576b318c8aad Mon Sep 17 00:00:00 2001 From: zzz Date: Thu, 19 Nov 2015 15:40:05 +0000 Subject: [PATCH 28/33] Update: Disable sud/su2 updates (ticket #1709) Add constraints for no Pack200 support and no certs --- .../net/i2p/router/update/NewsFetcher.java | 39 ++++++++++++------- .../src/net/i2p/router/web/UpdateHandler.java | 3 +- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/apps/routerconsole/java/src/net/i2p/router/update/NewsFetcher.java b/apps/routerconsole/java/src/net/i2p/router/update/NewsFetcher.java index 9b096a6b3..5c800bf03 100644 --- a/apps/routerconsole/java/src/net/i2p/router/update/NewsFetcher.java +++ b/apps/routerconsole/java/src/net/i2p/router/update/NewsFetcher.java @@ -225,6 +225,18 @@ class NewsFetcher extends UpdateRunner { _mgr.notifyVersionConstraint(this, _currentURI, ROUTER_SIGNED, "", ver, msg); return; } + if (!FileUtil.isPack200Supported()) { + String msg = _mgr._t("No Pack200 support in Java runtime."); + _log.logAlways(Log.WARN, "Cannot update to version " + ver + ": " + msg); + _mgr.notifyVersionConstraint(this, _currentURI, ROUTER_SIGNED, "", ver, msg); + return; + } + if (!ConfigUpdateHandler.USE_SU3_UPDATE) { + String msg = _mgr._t("No update certificates installed."); + _log.logAlways(Log.WARN, "Cannot update to version " + ver + ": " + msg); + _mgr.notifyVersionConstraint(this, _currentURI, ROUTER_SIGNED, "", ver, msg); + return; + } String minRouter = args.get(MIN_VERSION_KEY); if (minRouter != null) { if (VersionComparator.comp(RouterVersion.VERSION, minRouter) < 0) { @@ -251,7 +263,7 @@ class NewsFetcher extends UpdateRunner { // TODO clearnet URLs, notify with HTTP_CLEARNET and/or HTTPS_CLEARNET Map> sourceMap = new HashMap>(4); // Must do su3 first - if (ConfigUpdateHandler.USE_SU3_UPDATE) { + //if (ConfigUpdateHandler.USE_SU3_UPDATE) { sourceMap.put(HTTP, _mgr.getUpdateURLs(ROUTER_SIGNED_SU3, "", HTTP)); addMethod(TORRENT, args.get(SU3_KEY), sourceMap); addMethod(HTTP_CLEARNET, args.get(CLEARNET_HTTP_SU3_KEY), sourceMap); @@ -260,14 +272,14 @@ class NewsFetcher extends UpdateRunner { _mgr.notifyVersionAvailable(this, _currentURI, ROUTER_SIGNED_SU3, "", sourceMap, ver, ""); sourceMap.clear(); - } - // now do sud/su2 - sourceMap.put(HTTP, _mgr.getUpdateURLs(ROUTER_SIGNED, "", HTTP)); - String key = FileUtil.isPack200Supported() ? SU2_KEY : SUD_KEY; - addMethod(TORRENT, args.get(key), sourceMap); + //} + // now do sud/su2 - DISABLED + //sourceMap.put(HTTP, _mgr.getUpdateURLs(ROUTER_SIGNED, "", HTTP)); + //String key = FileUtil.isPack200Supported() ? SU2_KEY : SUD_KEY; + //addMethod(TORRENT, args.get(key), sourceMap); // notify about all sources at once - _mgr.notifyVersionAvailable(this, _currentURI, ROUTER_SIGNED, - "", sourceMap, ver, ""); + //_mgr.notifyVersionAvailable(this, _currentURI, ROUTER_SIGNED, + // "", sourceMap, ver, ""); } else { if (_log.shouldLog(Log.DEBUG)) _log.debug("Our version is current"); @@ -414,9 +426,8 @@ class NewsFetcher extends UpdateRunner { if (_tempFile.exists() && _tempFile.length() > 0) { File from; - // TODO check magic number instead? - // But then a corrupt file would be displayed as-is... - if (url.endsWith(".su3") || url.contains(".su3?")) { + // sud/su2 disabled + //if (url.endsWith(".su3") || url.contains(".su3?")) { try { from = processSU3(); } catch (IOException ioe) { @@ -424,9 +435,9 @@ class NewsFetcher extends UpdateRunner { _tempFile.delete(); return; } - } else { - from = _tempFile; - } + //} else { + // from = _tempFile; + //} boolean copied = FileUtil.rename(from, _newsFile); _tempFile.delete(); if (copied) { diff --git a/apps/routerconsole/java/src/net/i2p/router/web/UpdateHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/UpdateHandler.java index e1e2edc53..de13a6112 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/UpdateHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/UpdateHandler.java @@ -84,7 +84,8 @@ public class UpdateHandler { } else if (ConfigUpdateHandler.USE_SU3_UPDATE) { update(ROUTER_SIGNED_SU3); } else { - update(ROUTER_SIGNED); + // disabled, shouldn't get here + //update(ROUTER_SIGNED); } } } From 16549aa49ad8c3ce38dc704f3c938bfdaa8b970f Mon Sep 17 00:00:00 2001 From: zzz Date: Thu, 19 Nov 2015 17:11:26 +0000 Subject: [PATCH 29/33] Update text docs for Java 7 --- INSTALL-headless.txt | 9 +++++---- INSTALL.txt | 20 +++++++++++--------- README.txt | 3 ++- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/INSTALL-headless.txt b/INSTALL-headless.txt index 6f5457580..3ae8a14f0 100644 --- a/INSTALL-headless.txt +++ b/INSTALL-headless.txt @@ -25,21 +25,22 @@ where there are comments labeled "PORTABLE". Do this before you run I2P for the first time. To start I2P: - (*nix): sh i2prouter start + (*nix, BSD, Mac): sh i2prouter start (win*): I2P.exe - (non-x86 platforms PPC, ARM, etc): sh runplain.sh + (platforms without wrapper support): sh runplain.sh To stop I2P (gracefully): lynx http://localhost:7657/summaryframe (click "Shutdown") + or (*nix, BSD, Mac) sh i2prouter graceful To stop I2P immediately: - sh i2prouter stop + (*nix, BSD, Mac) sh i2prouter stop To uninstall I2P: rm -rf $I2PInstallDir ~/.i2p Supported JVMs: - All platforms: Java 1.6 or higher required; 1.7 or higher recommended + All platforms: Java 1.7 or higher required Windows: OpenJDK or Oracle from http://java.com/download Linux: OpenJDK or Oracle from http://java.com/download FreeBSD: OpenJDK or Oracle from http://java.com/download diff --git a/INSTALL.txt b/INSTALL.txt index 23701b041..d9960fc3a 100644 --- a/INSTALL.txt +++ b/INSTALL.txt @@ -1,8 +1,9 @@ I2P source installation instructions Prerequisites to build from source: - Java SDK (preferably Oracle/Sun or OpenJDK) 1.6.0 or higher + Java SDK (preferably Oracle/Sun or OpenJDK) 1.7.0 or higher Non-linux operating systems and JVMs: See https://trac.i2p2.de/wiki/java + Certain subsystems for embedded (core, router, mstreaming, streaming, i2ptunnel) require only Java 1.6 Apache Ant 1.7.0 or higher The xgettext, msgfmt, and msgmerge tools installed from the GNU gettext package http://www.gnu.org/software/gettext/ @@ -40,29 +41,30 @@ or on Windows, just double-click on i2pinstall.exe. Or move the i2pupdate.zip file into an existing installation directory and restart. To start I2P: - (*nix): sh i2prouter start + (*nix, BSD, Mac): sh i2prouter start (win*): I2P.exe or i2prouter.bat - (non-x86 platforms PPC, ARM, etc): sh runplain.sh + (platforms without wrapper support): sh runplain.sh To install I2P as a system service: - (*nix) sh i2prouter install + (*nix, BSD, Mac) sh i2prouter install (win*) install_i2p_service_winnt.bat To uninstall I2P as a system service: - (*nix) sh i2prouter remove + (*nix, BSD, Mac) sh i2prouter remove (win*) uninstall_i2p-service_winnt.bat To stop I2P (gracefully): lynx http://localhost:7657/summaryframe (click "Shutdown") + or (*nix, BSD, Mac) sh i2prouter graceful To stop I2P immediately: - sh i2prouter stop + (*nix, BSD, Mac) sh i2prouter stop To uninstall I2P: rm -rf $I2PInstallDir ~/.i2p Supported JVMs: - Windows: Latest available from http://java.com/download (1.5+ supported) - Linux: Latest available from http://java.com/download (1.5+ supported) - FreeBSD: 1.5-compatible (NIO required) + Windows: Latest available from http://java.com/download (1.7+ supported) + Linux: Latest available from http://java.com/download (1.7+ supported) + FreeBSD: 1.7-compatible (NIO required) Other operating systems and JVMs: See http://trac.i2p2.de/wiki/java diff --git a/README.txt b/README.txt index 0a99e21a4..b7a4b8e40 100644 --- a/README.txt +++ b/README.txt @@ -1,6 +1,7 @@ Prerequisites to build from source: - Java SDK (preferably Oracle/Sun or OpenJDK) 1.6.0 or higher + Java SDK (preferably Oracle/Sun or OpenJDK) 1.7.0 or higher Non-linux operating systems and JVMs: See https://trac.i2p2.de/wiki/java + Certain subsystems for embedded (core, router, mstreaming, streaming, i2ptunnel) require only Java 1.6 Apache Ant 1.7.0 or higher The xgettext, msgfmt, and msgmerge tools installed from the GNU gettext package http://www.gnu.org/software/gettext/ From a468b3e8b4f7111783bce2dd823138979271fd06 Mon Sep 17 00:00:00 2001 From: zzz Date: Thu, 19 Nov 2015 18:56:49 +0000 Subject: [PATCH 30/33] Build: Remove commons-logging classes from commons-logging.jar (ticket #1679) --- apps/jetty/build.xml | 5 +++++ build.xml | 2 -- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/jetty/build.xml b/apps/jetty/build.xml index 2fad37dfa..b1fdbcd46 100644 --- a/apps/jetty/build.xml +++ b/apps/jetty/build.xml @@ -149,9 +149,14 @@ + diff --git a/build.xml b/build.xml index aefc60d52..f6a8a5451 100644 --- a/build.xml +++ b/build.xml @@ -1465,9 +1465,7 @@ From 76491322595cc9488ffc660e6502391a43ac1dca Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 21 Nov 2015 14:33:22 +0000 Subject: [PATCH 31/33] OCMOSJ: One more place attempting to update our own profile --- .../message/OutboundClientMessageOneShotJob.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java b/router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java index 8a517a806..fd45bc752 100644 --- a/router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java +++ b/router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java @@ -949,15 +949,19 @@ public class OutboundClientMessageOneShotJob extends JobImpl { if (_outTunnel.getLength() > 0) size = ((size + 1023) / 1024) * 1024; // messages are in ~1KB blocks - for (int i = 0; i < _outTunnel.getLength(); i++) { + // skip ourselves at first hop + for (int i = 1; i < _outTunnel.getLength(); i++) { getContext().profileManager().tunnelTestSucceeded(_outTunnel.getPeer(i), sendTime); getContext().profileManager().tunnelDataPushed(_outTunnel.getPeer(i), sendTime, size); } _outTunnel.incrementVerifiedBytesTransferred(size); } - if (_inTunnel != null) - for (int i = 0; i < _inTunnel.getLength(); i++) + if (_inTunnel != null) { + // skip ourselves at last hop + for (int i = 0; i < _inTunnel.getLength() - 1; i++) { getContext().profileManager().tunnelTestSucceeded(_inTunnel.getPeer(i), sendTime); + } + } } public void setMessage(I2NPMessage msg) {} From d30c1ec3191c600e8530eae382a918ec8d5211ba Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 21 Nov 2015 17:37:56 +0000 Subject: [PATCH 32/33] EepGet: Fixes after URL to URI conversion --- .../src/net/i2p/client/streaming/I2PSocketEepGet.java | 11 ++++++++--- core/java/src/net/i2p/util/EepGet.java | 6 +++--- core/java/src/net/i2p/util/EepHead.java | 4 ++-- core/java/src/net/i2p/util/PartialEepGet.java | 4 ++-- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketEepGet.java b/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketEepGet.java index 1d3c77a16..73ede8bb0 100644 --- a/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketEepGet.java +++ b/apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketEepGet.java @@ -124,11 +124,14 @@ public class I2PSocketEepGet extends EepGet { // Rewrite the url to strip out the /i2p/, // as the naming service accepts B64KEY (but not B64KEY.i2p atm) if ("i2p".equals(host)) { - String file = url.getPath(); + String file = url.getRawPath(); try { int slash = 1 + file.substring(1).indexOf("/"); host = file.substring(1, slash); _actualURL = "http://" + host + file.substring(slash); + String query = url.getRawQuery(); + if (query != null) + _actualURL = _actualURL + '?' + query; } catch (IndexOutOfBoundsException ioobe) { throw new MalformedURLException("Bad /i2p/ format: " + _actualURL); } @@ -214,8 +217,8 @@ public class I2PSocketEepGet extends EepGet { throw ioe; } //String host = url.getHost(); - String path = url.getPath(); - String query = url.getQuery(); + String path = url.getRawPath(); + String query = url.getRawQuery(); if (query != null) path = path + '?' + query; if (!path.startsWith("/")) @@ -242,6 +245,8 @@ public class I2PSocketEepGet extends EepGet { if(!uaOverridden) buf.append("User-Agent: " + USER_AGENT + "\r\n"); buf.append("\r\n"); + if (_log.shouldDebug()) + _log.debug("Request: [" + buf.toString() + "]"); return buf.toString(); } diff --git a/core/java/src/net/i2p/util/EepGet.java b/core/java/src/net/i2p/util/EepGet.java index d9d9ba6fe..19816bb41 100644 --- a/core/java/src/net/i2p/util/EepGet.java +++ b/core/java/src/net/i2p/util/EepGet.java @@ -332,7 +332,7 @@ public class EepGet { System.exit(1); } - String path = nameURL.getPath(); // discard any URI queries + String path = nameURL.getRawPath(); // discard any URI queries // if no file specified, eepget scrapes webpage - use domain as name Pattern slashes = Pattern.compile("/+"); @@ -1288,8 +1288,8 @@ public class EepGet { if (host == null || host.length() <= 0) throw new MalformedURLException("Bad URL, no host"); int port = url.getPort(); - String path = url.getPath(); - String query = url.getQuery(); + String path = url.getRawPath(); + String query = url.getRawQuery(); if (_log.shouldLog(Log.DEBUG)) _log.debug("Requesting " + _actualURL); // RFC 2616 sec 5.1.2 - full URL if proxied, absolute path only if not proxied diff --git a/core/java/src/net/i2p/util/EepHead.java b/core/java/src/net/i2p/util/EepHead.java index ef6f5067d..3c5331493 100644 --- a/core/java/src/net/i2p/util/EepHead.java +++ b/core/java/src/net/i2p/util/EepHead.java @@ -265,8 +265,8 @@ public class EepHead extends EepGet { } String host = url.getHost(); int port = url.getPort(); - String path = url.getPath(); - String query = url.getQuery(); + String path = url.getRawPath(); + String query = url.getRawQuery(); if (_log.shouldLog(Log.DEBUG)) _log.debug("Requesting " + _actualURL); // RFC 2616 sec 5.1.2 - full URL if proxied, absolute path only if not proxied diff --git a/core/java/src/net/i2p/util/PartialEepGet.java b/core/java/src/net/i2p/util/PartialEepGet.java index 4d0967763..9d853137d 100644 --- a/core/java/src/net/i2p/util/PartialEepGet.java +++ b/core/java/src/net/i2p/util/PartialEepGet.java @@ -180,8 +180,8 @@ public class PartialEepGet extends EepGet { if (host == null || host.length() <= 0) throw new MalformedURLException("Bad URL, no host"); int port = url.getPort(); - String path = url.getPath(); - String query = url.getQuery(); + String path = url.getRawPath(); + String query = url.getRawQuery(); if (_log.shouldLog(Log.DEBUG)) _log.debug("Requesting " + _actualURL); // RFC 2616 sec 5.1.2 - full URL if proxied, absolute path only if not proxied From ce96234fdbe337fa3aa071a255363f487460e9a4 Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 21 Nov 2015 19:45:54 +0000 Subject: [PATCH 33/33] SSU ext. options: - don't ask for intro if he is indirect - ask for intro if our state is unknown - debug logging - change min to 0.9.23 for testing --- .../transport/udp/EstablishmentManager.java | 9 ++++--- .../transport/udp/InboundEstablishState.java | 2 ++ .../router/transport/udp/PacketBuilder.java | 5 +++- .../router/transport/udp/UDPTransport.java | 25 +++++++++++++++++++ 4 files changed, 37 insertions(+), 4 deletions(-) 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 64c32cddf..77fdd78ba 100644 --- a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java +++ b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java @@ -132,10 +132,11 @@ class EstablishmentManager { * but i2pd hasn't recognized it until this release. * No matter, the options weren't defined until this release anyway. * - * FIXME 0.9.22 for testing, change to 0.9.24 for release +********************************************************************************************************** + * FIXME 0.9.23 for testing, change to 0.9.24 for release * */ - private static final String VERSION_ALLOW_EXTENDED_OPTIONS = "0.9.22"; + private static final String VERSION_ALLOW_EXTENDED_OPTIONS = "0.9.23"; private static final String PROP_DISABLE_EXT_OPTS = "i2np.udp.disableExtendedOptions"; @@ -373,7 +374,9 @@ class EstablishmentManager { VERSION_ALLOW_EXTENDED_OPTIONS) >= 0 && !_context.getBooleanProperty(PROP_DISABLE_EXT_OPTS); // w/o ext options, it's always 'requested', no need to set - boolean requestIntroduction = allowExtendedOptions && _transport.introducersRequired(); + // don't ask if they are indirect + boolean requestIntroduction = allowExtendedOptions && !isIndirect && + _transport.introducersMaybeRequired(); state = new OutboundEstablishState(_context, maybeTo, to, toIdentity, allowExtendedOptions, requestIntroduction, diff --git a/router/java/src/net/i2p/router/transport/udp/InboundEstablishState.java b/router/java/src/net/i2p/router/transport/udp/InboundEstablishState.java index 96d45c216..332282c24 100644 --- a/router/java/src/net/i2p/router/transport/udp/InboundEstablishState.java +++ b/router/java/src/net/i2p/router/transport/udp/InboundEstablishState.java @@ -155,6 +155,8 @@ class InboundEstablishState { byte[] ext = req.readExtendedOptions(); if (ext != null && ext.length >= UDPPacket.SESS_REQ_MIN_EXT_OPTIONS_LENGTH) { _introductionRequested = (ext[1] & (byte) UDPPacket.SESS_REQ_EXT_FLAG_REQUEST_RELAY_TAG) != 0; + if (_log.shouldInfo()) + _log.info("got sess req. w/ ext. options, need intro? " + _introductionRequested + ' ' + this); } if (_log.shouldLog(Log.DEBUG)) _log.debug("Receive sessionRequest, BobIP = " + Addresses.toString(_bobIP)); diff --git a/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java b/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java index 98cf82bb6..0f7e0ac80 100644 --- a/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java +++ b/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java @@ -788,8 +788,11 @@ class PacketBuilder { boolean ext = state.isExtendedOptionsAllowed(); if (ext) { options = new byte[UDPPacket.SESS_REQ_MIN_EXT_OPTIONS_LENGTH]; - if (state.needIntroduction()) + boolean intro = state.needIntroduction(); + if (intro) options[1] = (byte) UDPPacket.SESS_REQ_EXT_FLAG_REQUEST_RELAY_TAG; + if (_log.shouldInfo()) + _log.info("send sess req. w/ ext. options, need intro? " + intro + ' ' + state); off += UDPPacket.SESS_REQ_MIN_EXT_OPTIONS_LENGTH + 1; } else { options = null; 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 b68626ab5..f6a94d7fb 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java @@ -2216,6 +2216,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority if (_log.shouldLog(Log.DEBUG)) _log.debug("Require introducers, because our status is " + status); return true; + default: if (!allowDirectUDP()) { if (_log.shouldLog(Log.DEBUG)) @@ -2226,6 +2227,30 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority } } + /** + * MIGHT we require introducers? + * This is like introducersRequired, but if we aren't sure, this returns true. + * Used only by EstablishmentManager. + * + * @since 0.9.24 + */ + boolean introducersMaybeRequired() { + Status status = getReachabilityStatus(); + switch (status) { + case REJECT_UNSOLICITED: + case DIFFERENT: + case IPV4_FIREWALLED_IPV6_OK: + case IPV4_FIREWALLED_IPV6_UNKNOWN: + case IPV4_UNKNOWN_IPV6_OK: + case IPV4_UNKNOWN_IPV6_FIREWALLED: + case UNKNOWN: + return true; + + default: + return !allowDirectUDP(); + } + } + /** * For EstablishmentManager * @since 0.9.3