From e03c25e397b3e395355940d0747cc1eb276d7ba9 Mon Sep 17 00:00:00 2001 From: zzz Date: Mon, 27 Feb 2017 19:48:28 +0000 Subject: [PATCH 1/8] debian files update --- debian-alt/doc/launchpad.txt | 2 +- debian-alt/precise/changelog | 6 ++++++ debian-alt/trusty/changelog | 6 ++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/debian-alt/doc/launchpad.txt b/debian-alt/doc/launchpad.txt index bf98e1aa2..1f54f72c7 100644 --- a/debian-alt/doc/launchpad.txt +++ b/debian-alt/doc/launchpad.txt @@ -150,7 +150,7 @@ Down at bottom, click 'create milestone' Date targeted: Actual release date Tags: empty Summary: empty -Click 'register milestone' +Click 'create milestone' Now you are back on https://launchpad.net/i2p/trunk At your milestone, 'release now' Date released: Actual release date diff --git a/debian-alt/precise/changelog b/debian-alt/precise/changelog index 438f478f7..4474e2faf 100644 --- a/debian-alt/precise/changelog +++ b/debian-alt/precise/changelog @@ -1,3 +1,9 @@ +i2p (0.9.29p-1~precise+1) precise; urgency=medium + + * Backport to Precise + + -- zzz on i2p Tue, 27 Feb 2017 12:12:12 +0000 + i2p (0.9.28p-1~precise+1) precise; urgency=medium * Backport to Precise diff --git a/debian-alt/trusty/changelog b/debian-alt/trusty/changelog index d11690073..dc3e1c8ab 100644 --- a/debian-alt/trusty/changelog +++ b/debian-alt/trusty/changelog @@ -1,3 +1,9 @@ +i2p (0.9.29-1ubuntu1) trusty; urgency=medium + + * New upstream version 0.9.29 + + -- zzz on i2p (key signing) Mon, 27 Feb 2017 12:12:12 +0000 + i2p (0.9.28-1ubuntu1) trusty; urgency=medium * New upstream version 0.9.28 From 8d928eadbae0d75817c897f32dadc77b70f6e523 Mon Sep 17 00:00:00 2001 From: zzz Date: Mon, 27 Feb 2017 19:49:05 +0000 Subject: [PATCH 2/8] minor fixes after review --- apps/routerconsole/jsp/createreseed.jsp | 1 - core/java/src/net/i2p/util/SystemVersion.java | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/routerconsole/jsp/createreseed.jsp b/apps/routerconsole/jsp/createreseed.jsp index 67653b155..605ed6100 100644 --- a/apps/routerconsole/jsp/createreseed.jsp +++ b/apps/routerconsole/jsp/createreseed.jsp @@ -20,7 +20,6 @@ try { response.addHeader("Pragma", "no-cache"); response.setContentType("application/zip; name=\"i2preseed.zip\""); response.addHeader("Content-Disposition", "attachment; filename=\"i2preseed.zip\""); - byte buf[] = new byte[16*1024]; in = new java.io.FileInputStream(zip); java.io.OutputStream cout = response.getOutputStream(); net.i2p.data.DataHelper.copy(in, cout); diff --git a/core/java/src/net/i2p/util/SystemVersion.java b/core/java/src/net/i2p/util/SystemVersion.java index 3438511a4..3c1880f2d 100644 --- a/core/java/src/net/i2p/util/SystemVersion.java +++ b/core/java/src/net/i2p/util/SystemVersion.java @@ -20,6 +20,9 @@ public abstract class SystemVersion { * @since 0.9.28 */ public static final String DAEMON_USER = "i2psvc"; + /* + * @since 0.9.29 + */ public static final String GENTOO_USER = "i2p"; private static final boolean _isWin = System.getProperty("os.name").startsWith("Win"); From 2de25ca453d4a57555fc4612ad21ed7c292b4f70 Mon Sep 17 00:00:00 2001 From: zzz Date: Mon, 27 Feb 2017 19:50:21 +0000 Subject: [PATCH 3/8] addressbook: Add date parameter to authentication strings --- core/java/src/net/i2p/client/naming/HostTxtEntry.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/java/src/net/i2p/client/naming/HostTxtEntry.java b/core/java/src/net/i2p/client/naming/HostTxtEntry.java index 3023649d4..96a954959 100644 --- a/core/java/src/net/i2p/client/naming/HostTxtEntry.java +++ b/core/java/src/net/i2p/client/naming/HostTxtEntry.java @@ -396,6 +396,8 @@ public class HostTxtEntry { throw new IllegalStateException(); props.setProperty(PROP_NAME, name); props.setProperty(PROP_DEST, dest); + if (!props.containsKey(PROP_DATE)) + props.setProperty(PROP_DATE, Long.toString(System.currentTimeMillis() / 1000)); StringWriter buf = new StringWriter(1024); try { writeProps(buf); @@ -418,6 +420,8 @@ public class HostTxtEntry { throw new IllegalStateException(); if (props.containsKey(sigprop)) throw new IllegalStateException(); + if (!props.containsKey(PROP_DATE)) + props.setProperty(PROP_DATE, Long.toString(System.currentTimeMillis() / 1000)); StringWriter buf = new StringWriter(1024); buf.append(name); buf.append(KV_SEPARATOR); From e995a4cf926b36d47bd1ebfc1a36cfa11be3e67d Mon Sep 17 00:00:00 2001 From: zzz Date: Mon, 27 Feb 2017 19:51:38 +0000 Subject: [PATCH 4/8] i2psnark: Fix disappearing start button --- apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java | 9 +++++---- history.txt | 4 ++++ router/java/src/net/i2p/router/RouterVersion.java | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java index 78dbdf30b..42a558f5e 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java +++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java @@ -2595,17 +2595,18 @@ public class SnarkManager implements CompleteListener { DHT dht = _util.getDHT(); if (dht != null) dht.stop(); - // Schedule this even for final shutdown, as there's a chance - // that it's just this webapp that is stopping. - _context.simpleTimer2().addEvent(new Disconnector(), 60*1000); addMessage(_t("Closing I2P tunnel after notifying trackers.")); if (finalShutdown) { long toWait = 5*1000; if (SystemVersion.isARM()) toWait *= 2; try { Thread.sleep(toWait); } catch (InterruptedException ie) {} + _util.disconnect(); + _stopping = false; + } else { + // Only schedule this if not a final shutdown + _context.simpleTimer2().addEvent(new Disconnector(), 60*1000); } - _util.disconnect(); } else { _util.disconnect(); _stopping = false; diff --git a/history.txt b/history.txt index 113e5a547..7cbfdac87 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,7 @@ +2017-02-27 zzz + * i2psnark: Fix disappearing start button + * addressbook: Add date parameter to authentication strings + * 2017-02-27 0.9.29 released 2017-02-27 zzz diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index a411b0099..87e5bffca 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 0; + public final static long BUILD = 1; /** for example "-test" */ public final static String EXTRA = ""; From a6e62afc1f38323ccb861f4da771af85187d8ac0 Mon Sep 17 00:00:00 2001 From: zzz Date: Wed, 1 Mar 2017 12:58:16 +0000 Subject: [PATCH 5/8] Servlet: Catch OOM in MultiPartRequest --- apps/jetty/java/src/net/i2p/servlet/RequestWrapper.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/jetty/java/src/net/i2p/servlet/RequestWrapper.java b/apps/jetty/java/src/net/i2p/servlet/RequestWrapper.java index 5ba917d4b..a40a67e43 100644 --- a/apps/jetty/java/src/net/i2p/servlet/RequestWrapper.java +++ b/apps/jetty/java/src/net/i2p/servlet/RequestWrapper.java @@ -43,7 +43,7 @@ import org.mortbay.servlet.MultiPartRequest; * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=349110 * * So we could either extend and fix MultiPartFilter, and rewrite everything here, - * or copy MultiParRequest into our war and fix it so it compiles with Jetty 6. + * or copy MultiPartRequest into our war and fix it so it compiles with Jetty 6. * We do the latter. * * The filter would have been added in web.xml, @@ -71,8 +71,11 @@ public class RequestWrapper { if( contentType != null && contentType.toLowerCase(Locale.US).startsWith( "multipart/form-data" ) ) { try { mpr = new MultiPartRequest( httpRequest ); + } catch (OutOfMemoryError oome) { + // TODO Throw ioe from constructor? + oome.printStackTrace(); } catch (IOException e) { - // TODO Auto-generated catch block + // TODO Throw ioe from constructor? e.printStackTrace(); } } From 920572d3bc3f439e4bffcda5e06935b178c27cac Mon Sep 17 00:00:00 2001 From: zzz Date: Thu, 2 Mar 2017 13:27:30 +0000 Subject: [PATCH 6/8] UDPAddress: Make most fields final --- .../i2p/router/transport/udp/UDPAddress.java | 97 +++++++++++-------- 1 file changed, 58 insertions(+), 39 deletions(-) diff --git a/router/java/src/net/i2p/router/transport/udp/UDPAddress.java b/router/java/src/net/i2p/router/transport/udp/UDPAddress.java index 2765418c8..5eb5aa57e 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPAddress.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPAddress.java @@ -21,12 +21,12 @@ class UDPAddress { private InetAddress _hostAddress; private final int _port; private final byte[] _introKey; - private String _introHosts[]; - private InetAddress _introAddresses[]; - private int _introPorts[]; - private byte[] _introKeys[]; - private long _introTags[]; - private int _mtu; + private final String _introHosts[]; + private final InetAddress _introAddresses[]; + private final int _introPorts[]; + private final byte[] _introKeys[]; + private final long _introTags[]; + private final int _mtu; public static final String PROP_PORT = RouterAddress.PROP_PORT; public static final String PROP_HOST = RouterAddress.PROP_HOST; @@ -61,22 +61,31 @@ class UDPAddress { } public UDPAddress(RouterAddress addr) { - // TODO make everything final if (addr == null) { _host = null; _port = 0; _introKey = null; + _introHosts = null; + _introAddresses = null; + _introPorts = null; + _introKeys = null; + _introTags = null; + _mtu = 0; return; } _host = addr.getHost(); _port = addr.getPort(); + + int cmtu = 0; try { String mtu = addr.getOption(PROP_MTU); if (mtu != null) { boolean isIPv6 = _host != null && _host.contains(":"); - _mtu = MTU.rectify(isIPv6, Integer.parseInt(mtu)); + cmtu = MTU.rectify(isIPv6, Integer.parseInt(mtu)); } } catch (NumberFormatException nfe) {} + _mtu = cmtu; + String key = addr.getOption(PROP_INTRO_KEY); if (key != null) { byte[] ik = Base64.decode(key.trim()); @@ -88,6 +97,11 @@ class UDPAddress { _introKey = null; } + byte[][] cintroKeys = null; + long[] cintroTags = null; + int[] cintroPorts = null; + String[] cintroHosts = null; + InetAddress[] cintroAddresses = null; for (int i = MAX_INTRODUCERS - 1; i >= 0; i--) { String host = addr.getOption(PROP_INTRO_HOST[i]); if (host == null) continue; @@ -114,52 +128,57 @@ class UDPAddress { } catch (NumberFormatException nfe) { continue; } - if (_introHosts == null) { - _introHosts = new String[i+1]; - _introPorts = new int[i+1]; - _introAddresses = new InetAddress[i+1]; - _introKeys = new byte[i+1][]; - _introTags = new long[i+1]; + if (cintroHosts == null) { + cintroHosts = new String[i+1]; + cintroPorts = new int[i+1]; + cintroAddresses = new InetAddress[i+1]; + cintroKeys = new byte[i+1][]; + cintroTags = new long[i+1]; } - _introHosts[i] = host; - _introPorts[i] = p; - _introKeys[i] = ikey; - _introTags[i] = tag; + cintroHosts[i] = host; + cintroPorts[i] = p; + cintroKeys[i] = ikey; + cintroTags[i] = tag; } int numOK = 0; - if (_introHosts != null) { - for (int i = 0; i < _introHosts.length; i++) { - if ( (_introKeys[i] != null) && - (_introPorts[i] > 0) && - (_introTags[i] > 0) && - (_introHosts[i] != null) ) + if (cintroHosts != null) { + for (int i = 0; i < cintroHosts.length; i++) { + if ( (cintroKeys[i] != null) && + (cintroPorts[i] > 0) && + (cintroTags[i] > 0) && + (cintroHosts[i] != null) ) numOK++; } - if (numOK != _introHosts.length) { + if (numOK != cintroHosts.length) { String hosts[] = new String[numOK]; int ports[] = new int[numOK]; long tags[] = new long[numOK]; byte keys[][] = new byte[numOK][]; int cur = 0; - for (int i = 0; i < _introHosts.length; i++) { - if ( (_introKeys[i] != null) && - (_introPorts[i] > 0) && - (_introTags[i] > 0) && - (_introHosts[i] != null) ) { - hosts[cur] = _introHosts[i]; - ports[cur] = _introPorts[i]; - tags[cur] = _introTags[i]; - keys[cur] = _introKeys[i]; + for (int i = 0; i < cintroHosts.length; i++) { + if ( (cintroKeys[i] != null) && + (cintroPorts[i] > 0) && + (cintroTags[i] > 0) && + (cintroHosts[i] != null) ) { + hosts[cur] = cintroHosts[i]; + ports[cur] = cintroPorts[i]; + tags[cur] = cintroTags[i]; + keys[cur] = cintroKeys[i]; } } - _introKeys = keys; - _introTags = tags; - _introPorts = ports; - _introHosts = hosts; - _introAddresses = new InetAddress[numOK]; + cintroKeys = keys; + cintroTags = tags; + cintroPorts = ports; + cintroHosts = hosts; + cintroAddresses = new InetAddress[numOK]; } } + _introKeys = cintroKeys; + _introTags = cintroTags; + _introPorts = cintroPorts; + _introHosts = cintroHosts; + _introAddresses = cintroAddresses; } public String getHost() { return _host; } From 69ad95710a258a549d3e2f813a31c43cd0f8a03f Mon Sep 17 00:00:00 2001 From: zzz Date: Thu, 2 Mar 2017 14:14:28 +0000 Subject: [PATCH 7/8] UDPAddress: Fix bug in "Error handling for failed intro packets" cur variable wasn't being incremented. from Revision: 0f0232b342477486c38b51afa3d298285cc8fbcf from Date: 09/15/2005 Simplify error handling code javadocs --- .../i2p/router/transport/udp/UDPAddress.java | 46 ++++++++++++++----- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/router/java/src/net/i2p/router/transport/udp/UDPAddress.java b/router/java/src/net/i2p/router/transport/udp/UDPAddress.java index 5eb5aa57e..c6f7a9e8c 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPAddress.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPAddress.java @@ -128,6 +128,7 @@ class UDPAddress { } catch (NumberFormatException nfe) { continue; } + if (cintroHosts == null) { cintroHosts = new String[i+1]; cintroPorts = new int[i+1]; @@ -143,6 +144,11 @@ class UDPAddress { int numOK = 0; if (cintroHosts != null) { + // Validate the intro parameters, and shrink the + // introAddresses array if they aren't all valid, + // since we use the length for the valid count. + // We don't bother shrinking the other arrays, + // we just remove the invalid entries. for (int i = 0; i < cintroHosts.length; i++) { if ( (cintroKeys[i] != null) && (cintroPorts[i] > 0) && @@ -151,26 +157,22 @@ class UDPAddress { numOK++; } if (numOK != cintroHosts.length) { - String hosts[] = new String[numOK]; - int ports[] = new int[numOK]; - long tags[] = new long[numOK]; - byte keys[][] = new byte[numOK][]; int cur = 0; for (int i = 0; i < cintroHosts.length; i++) { if ( (cintroKeys[i] != null) && (cintroPorts[i] > 0) && (cintroTags[i] > 0) && (cintroHosts[i] != null) ) { - hosts[cur] = cintroHosts[i]; - ports[cur] = cintroPorts[i]; - tags[cur] = cintroTags[i]; - keys[cur] = cintroKeys[i]; + if (cur != i) { + // just shift these down + cintroHosts[cur] = cintroHosts[i]; + cintroPorts[cur] = cintroPorts[i]; + cintroTags[cur] = cintroTags[i]; + cintroKeys[cur] = cintroKeys[i]; + } + cur++; } } - cintroKeys = keys; - cintroTags = tags; - cintroPorts = ports; - cintroHosts = hosts; cintroAddresses = new InetAddress[numOK]; } } @@ -201,16 +203,36 @@ class UDPAddress { int getIntroducerCount() { return (_introAddresses == null ? 0 : _introAddresses.length); } + /** + * @throws NullPointerException if getIntroducerCount() == 0 + * @throws ArrayIndexOutOfBoundsException if i < 0 or i >= getIntroducerCount() + * @return null if invalid + */ InetAddress getIntroducerHost(int i) { if (_introAddresses[i] == null) _introAddresses[i] = getByName(_introHosts[i]); return _introAddresses[i]; } + /** + * @throws NullPointerException if getIntroducerCount() == 0 + * @throws ArrayIndexOutOfBoundsException if i < 0 or i >= getIntroducerCount() + * @return greater than zero + */ int getIntroducerPort(int i) { return _introPorts[i]; } + /** + * @throws NullPointerException if getIntroducerCount() == 0 + * @throws ArrayIndexOutOfBoundsException if i < 0 or i >= getIntroducerCount() + * @return non-null + */ byte[] getIntroducerKey(int i) { return _introKeys[i]; } + /** + * @throws NullPointerException if getIntroducerCount() == 0 + * @throws ArrayIndexOutOfBoundsException if i < 0 or i >= getIntroducerCount() + * @return greater than zero + */ long getIntroducerTag(int i) { return _introTags[i]; } /** From f7cdf221eb72f7567c9707e9f7771f694818ad34 Mon Sep 17 00:00:00 2001 From: zzz Date: Thu, 2 Mar 2017 14:24:27 +0000 Subject: [PATCH 8/8] UDPAddress: Add method to get introducer expiration (proposal 133) --- .../i2p/router/transport/udp/UDPAddress.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/router/java/src/net/i2p/router/transport/udp/UDPAddress.java b/router/java/src/net/i2p/router/transport/udp/UDPAddress.java index c6f7a9e8c..0f238d5de 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPAddress.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPAddress.java @@ -26,6 +26,7 @@ class UDPAddress { private final int _introPorts[]; private final byte[] _introKeys[]; private final long _introTags[]; + private final long _introExps[]; private final int _mtu; public static final String PROP_PORT = RouterAddress.PROP_PORT; @@ -41,22 +42,27 @@ class UDPAddress { public static final String PROP_INTRO_PORT_PREFIX = "iport"; public static final String PROP_INTRO_KEY_PREFIX = "ikey"; public static final String PROP_INTRO_TAG_PREFIX = "itag"; + /** @since 0.9.30 */ + public static final String PROP_INTRO_EXP_PREFIX = "iexp"; static final int MAX_INTRODUCERS = 3; private static final String[] PROP_INTRO_HOST; private static final String[] PROP_INTRO_PORT; private static final String[] PROP_INTRO_IKEY; private static final String[] PROP_INTRO_TAG; + private static final String[] PROP_INTRO_EXP; static { // object churn PROP_INTRO_HOST = new String[MAX_INTRODUCERS]; PROP_INTRO_PORT = new String[MAX_INTRODUCERS]; PROP_INTRO_IKEY = new String[MAX_INTRODUCERS]; PROP_INTRO_TAG = new String[MAX_INTRODUCERS]; + PROP_INTRO_EXP = new String[MAX_INTRODUCERS]; for (int i = 0; i < MAX_INTRODUCERS; i++) { PROP_INTRO_HOST[i] = PROP_INTRO_HOST_PREFIX + i; PROP_INTRO_PORT[i] = PROP_INTRO_PORT_PREFIX + i; PROP_INTRO_IKEY[i] = PROP_INTRO_KEY_PREFIX + i; PROP_INTRO_TAG[i] = PROP_INTRO_TAG_PREFIX + i; + PROP_INTRO_EXP[i] = PROP_INTRO_EXP_PREFIX + i; } } @@ -70,6 +76,7 @@ class UDPAddress { _introPorts = null; _introKeys = null; _introTags = null; + _introExps = null; _mtu = 0; return; } @@ -102,6 +109,7 @@ class UDPAddress { int[] cintroPorts = null; String[] cintroHosts = null; InetAddress[] cintroAddresses = null; + long[] cintroExps = null; for (int i = MAX_INTRODUCERS - 1; i >= 0; i--) { String host = addr.getOption(PROP_INTRO_HOST[i]); if (host == null) continue; @@ -128,6 +136,14 @@ class UDPAddress { } catch (NumberFormatException nfe) { continue; } + // expiration is optional + long exp = 0; + t = addr.getOption(PROP_INTRO_EXP[i]); + if (t != null) { + try { + exp = Long.parseLong(t) * 1000L; + } catch (NumberFormatException nfe) {} + } if (cintroHosts == null) { cintroHosts = new String[i+1]; @@ -135,11 +151,13 @@ class UDPAddress { cintroAddresses = new InetAddress[i+1]; cintroKeys = new byte[i+1][]; cintroTags = new long[i+1]; + cintroExps = new long[i+1]; } cintroHosts[i] = host; cintroPorts[i] = p; cintroKeys[i] = ikey; cintroTags[i] = tag; + cintroExps[i] = exp; } int numOK = 0; @@ -169,6 +187,7 @@ class UDPAddress { cintroPorts[cur] = cintroPorts[i]; cintroTags[cur] = cintroTags[i]; cintroKeys[cur] = cintroKeys[i]; + cintroExps[cur] = cintroExps[i]; } cur++; } @@ -181,6 +200,7 @@ class UDPAddress { _introPorts = cintroPorts; _introHosts = cintroHosts; _introAddresses = cintroAddresses; + _introExps = cintroExps; } public String getHost() { return _host; } @@ -234,6 +254,14 @@ class UDPAddress { * @return greater than zero */ long getIntroducerTag(int i) { return _introTags[i]; } + + /** + * @throws NullPointerException if getIntroducerCount() == 0 + * @throws ArrayIndexOutOfBoundsException if i < 0 or i >= getIntroducerCount() + * @return ms since epoch, zero if unset + * @since 0.9.30 + */ + long getIntroducerExpiration(int i) { return _introExps[i]; } /** * @return 0 if unset or invalid; recitified via MTU.rectify()