diff --git a/history.txt b/history.txt index b8d45d3e7..86ff7641b 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,6 @@ +2013-10-01 zzz + * Startup: Fix rekeying on Windows (tickets #1056, 1057) + * 2013-09-30 0.9.8 released 2013-09-26 kytv 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 = ""; diff --git a/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java b/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java index 76b07cb1c..f41e4d125 100644 --- a/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java +++ b/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java @@ -13,6 +13,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.IOException; +import java.util.concurrent.atomic.AtomicBoolean; import net.i2p.crypto.KeyGenerator; import net.i2p.data.DataFormatException; @@ -28,9 +29,8 @@ import net.i2p.util.Log; public class LoadRouterInfoJob extends JobImpl { private final Log _log; - private boolean _keysExist; - private boolean _infoExists; private RouterInfo _us; + private static final AtomicBoolean _keyLengthChecked = new AtomicBoolean(); public LoadRouterInfoJob(RouterContext ctx) { super(ctx); @@ -61,11 +61,9 @@ public class LoadRouterInfoJob extends JobImpl { String keyFilename = getContext().getProperty(Router.PROP_KEYS_FILENAME, Router.PROP_KEYS_FILENAME_DEFAULT); File rif = new File(getContext().getRouterDir(), routerInfoFile); - if (rif.exists()) - _infoExists = true; + boolean infoExists = rif.exists(); File rkf = new File(getContext().getRouterDir(), keyFilename); - if (rkf.exists()) - _keysExist = true; + boolean keysExist = rkf.exists(); InputStream fis1 = null; InputStream fis2 = null; @@ -76,7 +74,7 @@ public class LoadRouterInfoJob extends JobImpl { // CRIT ...sport.udp.EstablishmentManager: Error in the establisher java.lang.NullPointerException // at net.i2p.router.transport.udp.PacketBuilder.buildSessionConfirmedPacket(PacketBuilder.java:574) // so pretend the RI isn't there if there is no keyfile - if (_infoExists && _keysExist) { + if (infoExists && keysExist) { fis1 = new BufferedInputStream(new FileInputStream(rif)); info = new RouterInfo(); info.readBytes(fis1); @@ -88,16 +86,21 @@ public class LoadRouterInfoJob extends JobImpl { _us = info; } - if (_keysExist) { + if (keysExist) { fis2 = new BufferedInputStream(new FileInputStream(rkf)); PrivateKey privkey = new PrivateKey(); privkey.readBytes(fis2); if (shouldRebuild(privkey)) { _us = null; + // windows... close before deleting + if (fis1 != null) { + try { fis1.close(); } catch (IOException ioe) {} + fis1 = null; + } + try { fis2.close(); } catch (IOException ioe) {} + fis2 = null; rif.delete(); rkf.delete(); - _infoExists = false; - _keysExist = false; return; } SigningPrivateKey signingPrivKey = new SigningPrivateKey(); @@ -112,17 +115,31 @@ public class LoadRouterInfoJob extends JobImpl { } catch (IOException ioe) { _log.log(Log.CRIT, "Error reading the router info from " + rif.getAbsolutePath() + " and the keys from " + rkf.getAbsolutePath(), ioe); _us = null; + // windows... close before deleting + if (fis1 != null) { + try { fis1.close(); } catch (IOException ioe2) {} + fis1 = null; + } + if (fis2 != null) { + try { fis2.close(); } catch (IOException ioe2) {} + fis2 = null; + } rif.delete(); rkf.delete(); - _infoExists = false; - _keysExist = false; } catch (DataFormatException dfe) { _log.log(Log.CRIT, "Corrupt router info or keys at " + rif.getAbsolutePath() + " / " + rkf.getAbsolutePath(), dfe); _us = null; + // windows... close before deleting + if (fis1 != null) { + try { fis1.close(); } catch (IOException ioe) {} + fis1 = null; + } + if (fis2 != null) { + try { fis2.close(); } catch (IOException ioe) {} + fis2 = null; + } rif.delete(); rkf.delete(); - _infoExists = false; - _keysExist = false; } finally { if (fis1 != null) try { fis1.close(); } catch (IOException ioe) {} if (fis2 != null) try { fis2.close(); } catch (IOException ioe) {} @@ -135,6 +152,11 @@ public class LoadRouterInfoJob extends JobImpl { * @since 0.9.8 */ private boolean shouldRebuild(PrivateKey privkey) { + // Prevent returning true more than once, ever. + // If we are called a second time, it's probably because we failed + // to delete router.keys for some reason. + if (!_keyLengthChecked.compareAndSet(false, true)) + return false; byte[] pkd = privkey.getData(); boolean haslong = false; for (int i = 0; i < 8; i++) { diff --git a/router/java/src/net/i2p/router/startup/RebuildRouterInfoJob.java b/router/java/src/net/i2p/router/startup/RebuildRouterInfoJob.java index ee92f6414..b611114d0 100644 --- a/router/java/src/net/i2p/router/startup/RebuildRouterInfoJob.java +++ b/router/java/src/net/i2p/router/startup/RebuildRouterInfoJob.java @@ -76,6 +76,7 @@ public class RebuildRouterInfoJob extends JobImpl { void rebuildRouterInfo() { rebuildRouterInfo(true); } + void rebuildRouterInfo(boolean alreadyRunning) { _log.debug("Rebuilding the new router info"); RouterInfo info = null; @@ -86,8 +87,8 @@ public class RebuildRouterInfoJob extends JobImpl { if (keyFile.exists()) { // ok, no need to rebuild a brand new identity, just update what we can - info = getContext().router().getRouterInfo(); - if (info == null) { + RouterInfo oldinfo = getContext().router().getRouterInfo(); + if (oldinfo == null) { info = new RouterInfo(); FileInputStream fis = null; try { @@ -116,6 +117,9 @@ public class RebuildRouterInfoJob extends JobImpl { } finally { if (fis != null) try { fis.close(); } catch (IOException ioe) {} } + } else { + // Make a new RI from the old identity, or else info.setAddresses() will throw an ISE + info = new RouterInfo(oldinfo); } try {