From 14ce5a243286d6ce0390ef89350eea5875503517 Mon Sep 17 00:00:00 2001 From: zzz Date: Tue, 10 Mar 2009 05:20:48 +0000 Subject: [PATCH 01/12] hello world --- android/AndroidManifest.xml | 15 ++ android/README.txt | 18 ++ android/build.xml | 280 +++++++++++++++++++++ android/res/layout/main.xml | 13 + android/res/values/strings.xml | 4 + android/src/net/i2p/router/I2PAndroid.java | 18 ++ 6 files changed, 348 insertions(+) create mode 100644 android/AndroidManifest.xml create mode 100644 android/README.txt create mode 100644 android/build.xml create mode 100644 android/res/layout/main.xml create mode 100644 android/res/values/strings.xml create mode 100644 android/src/net/i2p/router/I2PAndroid.java diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml new file mode 100644 index 000000000..b45a40613 --- /dev/null +++ b/android/AndroidManifest.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + diff --git a/android/README.txt b/android/README.txt new file mode 100644 index 000000000..68719911f --- /dev/null +++ b/android/README.txt @@ -0,0 +1,18 @@ +#Unzip the android SDK in ../../ +#So then the android tools will be in ../../android-sdk-linux_x86-1.1_r1/tools/ + +#then build the android apk file: +ant + +#then run the emulator: +../../android-sdk-linux_x86-1.1_r1/tools/emulator & + +#then wait a couple minutes until the emulator is up +#then install the I2P app +ant install + +#then run the debugger +$A/ddms & + +#to rebuild and reinstall to emulator: +ant reinstall diff --git a/android/build.xml b/android/build.xml new file mode 100644 index 000000000..9f4e7b0b9 --- /dev/null +++ b/android/build.xml @@ -0,0 +1,280 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Creating output directories if needed... + + + + + + + + + + + + Generating R.java / Manifest.java from the resources... + + + + + + + + + + + + + + + + + Compiling aidl files into Java classes... + + + + + + + + + + + + + + + + + + + + + + + + + Converting compiled files and external libraries into ${outdir}/${dex-file}... + + + + + + + + + + + + + Packaging resources and assets... + + + + + + + + + + + + + + + + + + + Packaging resources... + + + + + + + + + + + + + + + + + + + + + + + + + + Packaging ${out-debug-package}, and signing it with a debug key... + + + + + + + + + + + + + + + + Packaging ${out-unsigned-package} for release... + + + + + + + + + + + + + It will need to be signed with jarsigner before being published. + + + + + Installing ${out-debug-package} onto default emulator... + + + + + + + + Installing ${out-debug-package} onto default emulator... + + + + + + + + + + Uninstalling ${application-package} from the default emulator... + + + + + + + diff --git a/android/res/layout/main.xml b/android/res/layout/main.xml new file mode 100644 index 000000000..3bfc31cff --- /dev/null +++ b/android/res/layout/main.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/android/res/values/strings.xml b/android/res/values/strings.xml new file mode 100644 index 000000000..983a304b9 --- /dev/null +++ b/android/res/values/strings.xml @@ -0,0 +1,4 @@ + + + I2PAndroid + diff --git a/android/src/net/i2p/router/I2PAndroid.java b/android/src/net/i2p/router/I2PAndroid.java new file mode 100644 index 000000000..6b65bac52 --- /dev/null +++ b/android/src/net/i2p/router/I2PAndroid.java @@ -0,0 +1,18 @@ +package net.i2p.router; + +import android.app.Activity; +import android.os.Bundle; + +import net.i2p.router.Router; + +public class I2PAndroid extends Activity +{ + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + Router.main(null); + } +} From 82045b3fde703da3fffcd88f5ed1447941710dbf Mon Sep 17 00:00:00 2001 From: zzz Date: Tue, 10 Mar 2009 22:30:33 +0000 Subject: [PATCH 02/12] android logging --- android/README.txt | 2 +- android/build.xml | 20 +++- android/src/net/i2p/util/LogWriter.java | 152 ++++++++++++++++++++++++ 3 files changed, 167 insertions(+), 7 deletions(-) create mode 100644 android/src/net/i2p/util/LogWriter.java diff --git a/android/README.txt b/android/README.txt index 68719911f..c9a708263 100644 --- a/android/README.txt +++ b/android/README.txt @@ -12,7 +12,7 @@ ant ant install #then run the debugger -$A/ddms & +../../android-sdk-linux_x86-1.1_r1/tools/ddms & #to rebuild and reinstall to emulator: ant reinstall diff --git a/android/build.xml b/android/build.xml index 9f4e7b0b9..a7b411996 100644 --- a/android/build.xml +++ b/android/build.xml @@ -26,10 +26,10 @@ - + + value="${basedir}\${external-libs}" + else="${basedir}/${external-libs}" > @@ -105,6 +105,8 @@ + + @@ -144,13 +146,19 @@ destdir="${outdir-classes}" bootclasspath="${android-jar}"> - + - + + + + + + + @@ -162,7 +170,7 @@ - + diff --git a/android/src/net/i2p/util/LogWriter.java b/android/src/net/i2p/util/LogWriter.java new file mode 100644 index 000000000..847730d4f --- /dev/null +++ b/android/src/net/i2p/util/LogWriter.java @@ -0,0 +1,152 @@ +package net.i2p.util; + +/* + * public domain + * + */ + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.List; + +/** + * bridge to android logging + * + * @author zzz + */ +class LogWriter implements Runnable { + private final static long CONFIG_READ_ITERVAL = 10 * 1000; + private long _lastReadConfig = 0; + private long _numBytesInCurrentFile = 0; + private OutputStream _currentOut; // = System.out + private int _rotationNum = -1; + private String _logFilenamePattern; + private File _currentFile; + private LogManager _manager; + + private boolean _write; + + private LogWriter() { // nop + } + + public LogWriter(LogManager manager) { + _manager = manager; + } + + public void stopWriting() { + _write = false; + } + + public void run() { + _write = true; + try { + while (_write) { + flushRecords(); + rereadConfig(); + } + System.err.println("Done writing"); + } catch (Exception e) { + System.err.println("Error writing the logs: " + e.getMessage()); + e.printStackTrace(); + } + } + + public void flushRecords() { flushRecords(true); } + public void flushRecords(boolean shouldWait) { + try { + List records = _manager._removeAll(); + if (records == null) return; + for (int i = 0; i < records.size(); i++) { + LogRecord rec = (LogRecord) records.get(i); + writeRecord(rec); + } + } catch (Throwable t) { + t.printStackTrace(); + } finally { + if (shouldWait) { + try { + synchronized (this) { + this.wait(10*1000); + } + } catch (InterruptedException ie) { // nop + } + } + } + } + + + private void rereadConfig() { + long now = Clock.getInstance().now(); + if (now - _lastReadConfig > CONFIG_READ_ITERVAL) { + _manager.rereadConfig(); + _lastReadConfig = now; + } + } + + private void writeRecord(LogRecord rec) { + if (rec.getThrowable() == null) + log(rec.getPriority(), rec.getSourceName(), null, rec.getThreadName(), rec.getMessage()); + else + log(rec.getPriority(), rec.getSourceName(), null, rec.getThreadName(), rec.getMessage(), rec.getThrowable()); + } + + public void log(int priority, String className, String name, String threadName, String msg) { + if (className != null) + android.util.Log.println(toAndroidLevel(priority), + className, + threadName + ' ' + msg); + else if (name != null) + android.util.Log.println(toAndroidLevel(priority), + name, + threadName + ' ' + msg); + else + android.util.Log.println(toAndroidLevel(priority), + threadName, msg); + } + + public void log(int priority, String className, String name, String threadName, String msg, Throwable t) { + if (className != null) + android.util.Log.println(toAndroidLevel(priority), + className, + threadName + ' ' + msg + + msg + ' ' + t.toString() + ' ' + android.util.Log.getStackTraceString(t)); + else if (name != null) + android.util.Log.println(toAndroidLevel(priority), + name, + threadName + ' ' + msg + + msg + ' ' + t.toString() + ' ' + android.util.Log.getStackTraceString(t)); + else + android.util.Log.println(toAndroidLevel(priority), + threadName, + msg + ' ' + t.toString() + ' ' + android.util.Log.getStackTraceString(t)); + } + + private static int toAndroidLevel(int level) { + switch (level) { + case Log.DEBUG: + return android.util.Log.DEBUG; + case Log.INFO: + return android.util.Log.INFO; + case Log.WARN: + return android.util.Log.WARN; + case Log.ERROR: + case Log.CRIT: + default: + return android.util.Log.ERROR; + } + } + + private static final String replace(String pattern, int num) { + char c[] = pattern.toCharArray(); + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < c.length; i++) { + if ( (c[i] != '#') && (c[i] != '@') ) + buf.append(c[i]); + else + buf.append(num); + } + return buf.toString(); + } +} From d26ac84126713c10174664ee9520ef8d13f03961 Mon Sep 17 00:00:00 2001 From: zzz Date: Thu, 12 Mar 2009 18:22:49 +0000 Subject: [PATCH 03/12] two memory savers --- .../crypto/prng/AsyncFortunaStandalone.java | 18 +++++++++++------- .../src/net/i2p/util/DecayingBloomFilter.java | 9 +++++++-- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/core/java/src/gnu/crypto/prng/AsyncFortunaStandalone.java b/core/java/src/gnu/crypto/prng/AsyncFortunaStandalone.java index 417d0fc72..504b87d76 100644 --- a/core/java/src/gnu/crypto/prng/AsyncFortunaStandalone.java +++ b/core/java/src/gnu/crypto/prng/AsyncFortunaStandalone.java @@ -12,10 +12,11 @@ import net.i2p.util.Log; * has been eaten) */ public class AsyncFortunaStandalone extends FortunaStandalone implements Runnable { - private static final int BUFFERS = 16; + private static final int DEFAULT_BUFFERS = 16; private static final int BUFSIZE = 256*1024; - private final byte asyncBuffers[][] = new byte[BUFFERS][BUFSIZE]; - private final int status[] = new int[BUFFERS]; + private int _bufferCount; + private final byte asyncBuffers[][]; + private final int status[]; private int nextBuf = 0; private I2PAppContext _context; private Log _log; @@ -27,7 +28,10 @@ public class AsyncFortunaStandalone extends FortunaStandalone implements Runnabl public AsyncFortunaStandalone(I2PAppContext context) { super(); - for (int i = 0; i < BUFFERS; i++) + _bufferCount = context.getProperty("router.prng.buffers", DEFAULT_BUFFERS); + asyncBuffers = new byte[_bufferCount][BUFSIZE]; + status = new int[_bufferCount]; + for (int i = 0; i < _bufferCount; i++) status[i] = STATUS_NEED_FILL; _context = context; context.statManager().createRateStat("prng.bufferWaitTime", "", "Encryption", new long[] { 60*1000, 10*60*1000, 60*60*1000 } ); @@ -80,11 +84,11 @@ public class AsyncFortunaStandalone extends FortunaStandalone implements Runnabl status[nextBuf] = STATUS_LIVE; int prev=nextBuf-1; if (prev<0) - prev = BUFFERS-1; + prev = _bufferCount-1; if (status[prev] == STATUS_LIVE) status[prev] = STATUS_NEED_FILL; nextBuf++; - if (nextBuf >= BUFFERS) + if (nextBuf >= _bufferCount) nextBuf = 0; asyncBuffers.notify(); } @@ -95,7 +99,7 @@ public class AsyncFortunaStandalone extends FortunaStandalone implements Runnabl int toFill = -1; try { synchronized (asyncBuffers) { - for (int i = 0; i < BUFFERS; i++) { + for (int i = 0; i < _bufferCount; i++) { if (status[i] == STATUS_NEED_FILL) { status[i] = STATUS_FILLING; toFill = i; diff --git a/core/java/src/net/i2p/util/DecayingBloomFilter.java b/core/java/src/net/i2p/util/DecayingBloomFilter.java index 164c8e453..8c375a66d 100644 --- a/core/java/src/net/i2p/util/DecayingBloomFilter.java +++ b/core/java/src/net/i2p/util/DecayingBloomFilter.java @@ -30,6 +30,7 @@ public class DecayingBloomFilter { private boolean _keepDecaying; private DecayEvent _decayEvent; + private static final int DEFAULT_M = 23; private static final boolean ALWAYS_MISS = false; /** @@ -44,8 +45,12 @@ public class DecayingBloomFilter { _context = context; _log = context.logManager().getLog(DecayingBloomFilter.class); _entryBytes = entryBytes; - _current = new BloomSHA1(23, 11); //new BloomSHA1(23, 11); - _previous = new BloomSHA1(23, 11); //new BloomSHA1(23, 11); + // this is instantiated in four different places, they may have different + // requirements, but for now use this as a gross method of memory reduction. + // m == 23 => 2MB each BloomSHA1 (8MB total) + int m = context.getProperty("router.decayingBloomFilterM", DEFAULT_M); + _current = new BloomSHA1(m, 11); //new BloomSHA1(23, 11); + _previous = new BloomSHA1(m, 11); //new BloomSHA1(23, 11); _durationMs = durationMs; int numExtenders = (32+ (entryBytes-1))/entryBytes - 1; if (numExtenders < 0) From 5a8b3eb8f34d048df9559deb8581e09c99e34267 Mon Sep 17 00:00:00 2001 From: zzz Date: Fri, 13 Mar 2009 18:27:29 +0000 Subject: [PATCH 04/12] Move HMac to I2PHMac, as jrandom implemented changes that make it incompatible with the HMac in the android libraries. --- .../src/net/i2p/crypto/HMAC256Generator.java | 9 +++++---- core/java/src/net/i2p/crypto/HMACGenerator.java | 17 +++++++++-------- .../crypto/macs/{HMac.java => I2PHMac.java} | 10 +++++++--- 3 files changed, 21 insertions(+), 15 deletions(-) rename core/java/src/org/bouncycastle/crypto/macs/{HMac.java => I2PHMac.java} (95%) diff --git a/core/java/src/net/i2p/crypto/HMAC256Generator.java b/core/java/src/net/i2p/crypto/HMAC256Generator.java index 2fcaa7b5e..7d6f67a76 100644 --- a/core/java/src/net/i2p/crypto/HMAC256Generator.java +++ b/core/java/src/net/i2p/crypto/HMAC256Generator.java @@ -7,7 +7,8 @@ import net.i2p.data.Hash; import net.i2p.data.SessionKey; import org.bouncycastle.crypto.Digest; -import org.bouncycastle.crypto.macs.HMac; +import org.bouncycastle.crypto.Mac; +import org.bouncycastle.crypto.macs.I2PHMac; /** * Calculate the HMAC-SHA256 of a key+message. All the good stuff occurs @@ -19,15 +20,15 @@ public class HMAC256Generator extends HMACGenerator { public HMAC256Generator(I2PAppContext context) { super(context); } @Override - protected HMac acquire() { + protected Mac acquire() { synchronized (_available) { if (_available.size() > 0) - return (HMac)_available.remove(0); + return (Mac)_available.remove(0); } // the HMAC is hardcoded to use SHA256 digest size // for backwards compatability. next time we have a backwards // incompatible change, we should update this by removing ", 32" - return new HMac(new Sha256ForMAC()); + return new I2PHMac(new Sha256ForMAC()); } private class Sha256ForMAC extends Sha256Standalone implements Digest { diff --git a/core/java/src/net/i2p/crypto/HMACGenerator.java b/core/java/src/net/i2p/crypto/HMACGenerator.java index 8388590a2..52b29e19b 100644 --- a/core/java/src/net/i2p/crypto/HMACGenerator.java +++ b/core/java/src/net/i2p/crypto/HMACGenerator.java @@ -10,7 +10,8 @@ import net.i2p.data.Hash; import net.i2p.data.SessionKey; import org.bouncycastle.crypto.digests.MD5Digest; -import org.bouncycastle.crypto.macs.HMac; +import org.bouncycastle.crypto.Mac; +import org.bouncycastle.crypto.macs.I2PHMac; /** * Calculate the HMAC-MD5 of a key+message. All the good stuff occurs @@ -49,7 +50,7 @@ public class HMACGenerator { if ((key == null) || (key.getData() == null) || (data == null)) throw new NullPointerException("Null arguments for HMAC"); - HMac mac = acquire(); + Mac mac = acquire(); mac.init(key.getData()); mac.update(data, offset, length); //byte rv[] = new byte[Hash.HASH_LENGTH]; @@ -73,7 +74,7 @@ public class HMACGenerator { if ((key == null) || (key.getData() == null) || (curData == null)) throw new NullPointerException("Null arguments for HMAC"); - HMac mac = acquire(); + Mac mac = acquire(); mac.init(key.getData()); mac.update(curData, curOffset, curLength); byte rv[] = acquireTmp(); @@ -86,17 +87,17 @@ public class HMACGenerator { return eq; } - protected HMac acquire() { + protected Mac acquire() { synchronized (_available) { if (_available.size() > 0) - return (HMac)_available.remove(0); + return (Mac)_available.remove(0); } // the HMAC is hardcoded to use SHA256 digest size // for backwards compatability. next time we have a backwards // incompatible change, we should update this by removing ", 32" - return new HMac(new MD5Digest(), 32); + return new I2PHMac(new MD5Digest(), 32); } - private void release(HMac mac) { + private void release(Mac mac) { synchronized (_available) { if (_available.size() < 64) _available.add(mac); @@ -122,4 +123,4 @@ public class HMACGenerator { _availableTmp.add((Object)tmp); } } -} \ No newline at end of file +} diff --git a/core/java/src/org/bouncycastle/crypto/macs/HMac.java b/core/java/src/org/bouncycastle/crypto/macs/I2PHMac.java similarity index 95% rename from core/java/src/org/bouncycastle/crypto/macs/HMac.java rename to core/java/src/org/bouncycastle/crypto/macs/I2PHMac.java index 7176c8aca..a566e8a79 100644 --- a/core/java/src/org/bouncycastle/crypto/macs/HMac.java +++ b/core/java/src/org/bouncycastle/crypto/macs/I2PHMac.java @@ -42,8 +42,12 @@ import org.bouncycastle.crypto.Mac; * a frequently used buffer (called on doFinal). changes released into the public * domain in 2005. * + * This is renamed from HMac because the constructor HMac(digest, sz) does not exist + * in the standard bouncycastle library, thus it conflicts in JVMs that contain the + * standard library (Android). + * */ -public class HMac +public class I2PHMac implements Mac { private final static int BLOCK_LENGTH = 64; @@ -56,12 +60,12 @@ implements Mac private byte[] inputPad = new byte[BLOCK_LENGTH]; private byte[] outputPad = new byte[BLOCK_LENGTH]; - public HMac( + public I2PHMac( Digest digest) { this(digest, digest.getDigestSize()); } - public HMac( + public I2PHMac( Digest digest, int sz) { this.digest = digest; From b8f22bf3bf682291c6530cfeba92ce748586a8be Mon Sep 17 00:00:00 2001 From: zzz Date: Fri, 13 Mar 2009 18:56:16 +0000 Subject: [PATCH 05/12] - Add FileStreamFactory and I2PFile to deal with the problems from the code CWD is / but the only writable directory is /data/data/net.i2p.router/files/ - still a ton of places to be fixed, will be fixed up as things get working - Load some config files from resources at startup - Fix up logging - Add reseed capability, by copying some code over from routerconsole - Deal with conflicting bouncycastle libs --- android/AndroidManifest.xml | 4 +- android/build.xml | 61 ++++++++++- android/res/layout/main.xml | 5 + android/res/raw/logger_config | 3 + android/res/raw/router_config | 7 ++ android/src/net/i2p/router/I2PAndroid.java | 100 ++++++++++++++++++ .../src/net/i2p/router/web/ReseedChecker.java | 37 +++++++ .../src/net/i2p/util/FileStreamFactory.java | 64 +++++++++++ android/src/net/i2p/util/I2PFile.java | 29 +++++ android/src/net/i2p/util/LogWriter.java | 40 ++++--- .../src/net/i2p/router/web/ReseedHandler.java | 6 +- core/java/src/net/i2p/data/DataHelper.java | 3 +- .../src/net/i2p/util/FileStreamFactory.java | 36 +++++++ core/java/src/net/i2p/util/I2PFile.java | 24 +++++ core/java/src/net/i2p/util/LogManager.java | 8 +- .../java/src/net/i2p/router/KeyManager.java | 5 +- router/java/src/net/i2p/router/Router.java | 10 +- .../kademlia/PersistentDataStore.java | 12 ++- .../peermanager/ProfilePersistenceHelper.java | 12 ++- .../router/startup/CreateRouterInfoJob.java | 5 +- .../i2p/router/startup/LoadRouterInfoJob.java | 10 +- .../router/startup/RebuildRouterInfoJob.java | 8 +- .../router/transport/ntcp/EventPumper.java | 2 +- 23 files changed, 437 insertions(+), 54 deletions(-) create mode 100644 android/res/raw/logger_config create mode 100644 android/res/raw/router_config create mode 100644 android/src/net/i2p/router/web/ReseedChecker.java create mode 100644 android/src/net/i2p/util/FileStreamFactory.java create mode 100644 android/src/net/i2p/util/I2PFile.java create mode 100644 core/java/src/net/i2p/util/FileStreamFactory.java create mode 100644 core/java/src/net/i2p/util/I2PFile.java diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index b45a40613..cb63a80c1 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -3,9 +3,11 @@ package="net.i2p.router" android:versionCode="1" android:versionName="1.0.0"> + + android:label="@string/app_name" + android:launchMode="singleTask" > diff --git a/android/build.xml b/android/build.xml index a7b411996..5875c5fed 100644 --- a/android/build.xml +++ b/android/build.xml @@ -101,12 +101,15 @@ Creating output directories if needed... + + + @@ -140,7 +143,7 @@ - + - + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + Converting compiled files and external libraries into ${outdir}/${dex-file}... diff --git a/android/res/layout/main.xml b/android/res/layout/main.xml index 3bfc31cff..d76411527 100644 --- a/android/res/layout/main.xml +++ b/android/res/layout/main.xml @@ -9,5 +9,10 @@ android:layout_height="wrap_content" android:text="Hello World, I2PAndroid" /> + diff --git a/android/res/raw/logger_config b/android/res/raw/logger_config new file mode 100644 index 000000000..2aeabb9f6 --- /dev/null +++ b/android/res/raw/logger_config @@ -0,0 +1,3 @@ +logger.defaultLevel=INFO +logger.record.net.i2p.router.transport.FIFOBandwidthRefiller=ERROR +logger.record.net.i2p.stat.Rate=ERROR diff --git a/android/res/raw/router_config b/android/res/raw/router_config new file mode 100644 index 000000000..19c609542 --- /dev/null +++ b/android/res/raw/router_config @@ -0,0 +1,7 @@ +# initial router.config +# save memory +router.prng.buffers=2 +router.decayingBloomFilterM=20 +stat.full=false +# no I2CP +i2p.dummyClientFacade=true diff --git a/android/src/net/i2p/router/I2PAndroid.java b/android/src/net/i2p/router/I2PAndroid.java index 6b65bac52..c08670e36 100644 --- a/android/src/net/i2p/router/I2PAndroid.java +++ b/android/src/net/i2p/router/I2PAndroid.java @@ -1,18 +1,118 @@ package net.i2p.router; import android.app.Activity; +import android.content.Context; +import android.content.res.Resources; +import android.content.res.Resources.NotFoundException; import android.os.Bundle; +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.IOException; + import net.i2p.router.Router; +import net.i2p.router.web.ReseedChecker; +import net.i2p.util.I2PFile; public class I2PAndroid extends Activity { + static Context _context; + /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); + + _context = this; // Activity extends Context + debugStuff(); + initialize(); + Router.main(null); + System.err.println("Router.main finished"); + + ReseedChecker.checkReseed(); } + + public void onRestart() + { + System.err.println("onRestart called"); + super.onRestart(); + } + + public void onResume() + { + System.err.println("onResume called"); + super.onResume(); + } + + public void onPause() + { + System.err.println("onPause called"); + super.onPause(); + } + + public void onStop() + { + System.err.println("onStop called"); + super.onStop(); + } + + public void onDestroy() + { + System.err.println("onDestroy called"); + super.onDestroy(); + } + + public static Context getContext() { + return _context; + } + + private void debugStuff() { + System.err.println("java.vendor" + ": " + System.getProperty("java.vendor")); + System.err.println("java.version" + ": " + System.getProperty("java.version")); + System.err.println("os.arch" + ": " + System.getProperty("os.arch")); + System.err.println("os.name" + ": " + System.getProperty("os.name")); + System.err.println("os.version" + ": " + System.getProperty("os.version")); + System.err.println("user.dir" + ": " + System.getProperty("user.dir")); + System.err.println("user.home" + ": " + System.getProperty("user.home")); + System.err.println("user.name" + ": " + System.getProperty("user.name")); + } + + private void initialize() { + // Until we can edit the router.config on the device, + // copy it from the resource every time. + // File f = new I2PFile("router.config"); + // if (!f.exists()) { + copyResourceToFile(R.raw.router_config, "router.config"); + copyResourceToFile(R.raw.logger_config, "logger.config"); + copyResourceToFile(R.raw.blocklist_txt, "blocklist.txt"); + // } + } + + private void copyResourceToFile(int resID, String f) { + InputStream in = null; + FileOutputStream out = null; + + System.err.println("Creating file " + f + " from resource"); + byte buf[] = new byte[4096]; + try { + // Context methods + in = getResources().openRawResource(resID); + out = openFileOutput(f, 0); + + int read = 0; + while ( (read = in.read(buf)) != -1) + out.write(buf, 0, read); + + } catch (IOException ioe) { + } catch (Resources.NotFoundException nfe) { + } finally { + if (in != null) try { in.close(); } catch (IOException ioe) {} + if (out != null) try { out.close(); } catch (IOException ioe) {} + } + } + } diff --git a/android/src/net/i2p/router/web/ReseedChecker.java b/android/src/net/i2p/router/web/ReseedChecker.java new file mode 100644 index 000000000..96eccce51 --- /dev/null +++ b/android/src/net/i2p/router/web/ReseedChecker.java @@ -0,0 +1,37 @@ +package net.i2p.router.web; + +import java.io.File; + +import net.i2p.router.web.ReseedHandler; +import net.i2p.util.I2PFile; + +/** + * Copied from RouterConsoleRunner.java + */ +public class ReseedChecker { + + public static void checkReseed() { + + System.err.println("Checking to see if we should reseed"); + // we check the i2p installation directory (.) for a flag telling us not to reseed, + // but also check the home directory for that flag too, since new users installing i2p + // don't have an installation directory that they can put the flag in yet. + File noReseedFile = new I2PFile(new I2PFile(System.getProperty("user.home")), ".i2pnoreseed"); + File noReseedFileAlt1 = new I2PFile(new I2PFile(System.getProperty("user.home")), "noreseed.i2p"); + File noReseedFileAlt2 = new I2PFile(".i2pnoreseed"); + File noReseedFileAlt3 = new I2PFile("noreseed.i2p"); + if (!noReseedFile.exists() && !noReseedFileAlt1.exists() && !noReseedFileAlt2.exists() && !noReseedFileAlt3.exists()) { + File netDb = new I2PFile("netDb"); + // sure, some of them could be "my.info" or various leaseSet- files, but chances are, + // if someone has those files, they've already been seeded (at least enough to let them + // get i2p started - they can reseed later in the web console) + String names[] = (netDb.exists() ? netDb.list() : null); + if ( (names == null) || (names.length < 15) ) { + System.err.println("Yes, reseeding now"); + ReseedHandler reseedHandler = new ReseedHandler(); + reseedHandler.requestReseed(); + } + } + } + +} diff --git a/android/src/net/i2p/util/FileStreamFactory.java b/android/src/net/i2p/util/FileStreamFactory.java new file mode 100644 index 000000000..b7a65e4f2 --- /dev/null +++ b/android/src/net/i2p/util/FileStreamFactory.java @@ -0,0 +1,64 @@ +/* + * This is free software, do as you please. + */ + +package net.i2p.util; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; + +import net.i2p.router.I2PAndroid; + +/** + * Use android static file stream methods + * gaaah: + * 1) the CWD is / + * 2) we can only access /data/data/net.i2p.router/files/ + * 3) you can't change your CWD in Java + * so we have this lovely and the one in I2PFile. + * + * @author zzz + */ +public class FileStreamFactory { + private static final String DIR = "/data/data/net.i2p.router/files/"; + + /** hopefully no path separators in string */ + public static FileInputStream getFileInputStream(String f) throws FileNotFoundException { + System.err.println("Input file-s: " + I2PAndroid.getContext().getFileStreamPath(f).getAbsolutePath()); + return I2PAndroid.getContext().openFileInput(f); + } + + public static FileInputStream getFileInputStream(File f) throws FileNotFoundException { + System.err.println("Input file-f: " + getPath(f) + + ' ' + f.getAbsolutePath()); + //return I2PAndroid.getContext().openFileInput(f.getName()); + return new FileInputStream(getPath(f)); + } + + /** hopefully no path separators in string */ + public static FileOutputStream getFileOutputStream(String f) throws FileNotFoundException { + System.err.println("Output file-s: " + I2PAndroid.getContext().getFileStreamPath(f).getAbsolutePath()); + return I2PAndroid.getContext().openFileOutput(f, 0); + } + + public static FileOutputStream getFileOutputStream(File f) throws FileNotFoundException { + System.err.println("Output file-f: " + getPath(f) + + ' ' + f.getAbsolutePath()); + //return I2PAndroid.getContext().openFileOutput(f.getName(), 0); + return new FileOutputStream(getPath(f)); + } + + /** + * preserve path but convert /foo/blah to /data/data/net.i2p.router/files/foo/blah + * Although if the File arg was created with new I2PFile() then this isn't required + * + */ + private static String getPath(File f) { + String abs = f.getAbsolutePath(); + if (abs.startsWith(DIR)) + return abs; + return DIR + abs.substring(1); // strip extra '/' + } +} diff --git a/android/src/net/i2p/util/I2PFile.java b/android/src/net/i2p/util/I2PFile.java new file mode 100644 index 000000000..94bda029b --- /dev/null +++ b/android/src/net/i2p/util/I2PFile.java @@ -0,0 +1,29 @@ +/* + * This is free software, do as you please. + */ + +package net.i2p.util; + +import java.io.File; + +/** + * gaaah: + * 1) the CWD is / + * 2) we can only access /data/data/net.i2p.router/files/ + * 3) you can't change your CWD in Java + * so we have this lovely and the one in FileStreamFactory. + * + * @author zzz + */ +public class I2PFile extends File { + + public I2PFile (String f) { + super("/data/data/net.i2p.router/files/" + f); + } + + /** one level deep only */ + public I2PFile (File p, String f) { + super("/data/data/net.i2p.router/files/" + p.getName(), f); + } + +} diff --git a/android/src/net/i2p/util/LogWriter.java b/android/src/net/i2p/util/LogWriter.java index 847730d4f..03f5577ae 100644 --- a/android/src/net/i2p/util/LogWriter.java +++ b/android/src/net/i2p/util/LogWriter.java @@ -87,36 +87,44 @@ class LogWriter implements Runnable { private void writeRecord(LogRecord rec) { if (rec.getThrowable() == null) - log(rec.getPriority(), rec.getSourceName(), null, rec.getThreadName(), rec.getMessage()); + log(rec.getPriority(), rec.getSource(), rec.getSourceName(), rec.getThreadName(), rec.getMessage()); else - log(rec.getPriority(), rec.getSourceName(), null, rec.getThreadName(), rec.getMessage(), rec.getThrowable()); + log(rec.getPriority(), rec.getSource(), rec.getSourceName(), rec.getThreadName(), rec.getMessage(), rec.getThrowable()); } - public void log(int priority, String className, String name, String threadName, String msg) { - if (className != null) + public void log(int priority, Class src, String name, String threadName, String msg) { + if (src != null) { + String tag = src.getName(); + int dot = tag.lastIndexOf("."); + if (dot >= 0) + tag = tag.substring(dot + 1); android.util.Log.println(toAndroidLevel(priority), - className, - threadName + ' ' + msg); - else if (name != null) + tag, + '[' + threadName + "] " + msg); + } else if (name != null) android.util.Log.println(toAndroidLevel(priority), name, - threadName + ' ' + msg); + '[' + threadName + "] " + msg); else android.util.Log.println(toAndroidLevel(priority), threadName, msg); } - public void log(int priority, String className, String name, String threadName, String msg, Throwable t) { - if (className != null) + public void log(int priority, Class src, String name, String threadName, String msg, Throwable t) { + if (src != null) { + String tag = src.getName(); + int dot = tag.lastIndexOf("."); + if (dot >= 0) + tag = tag.substring(dot + 1); android.util.Log.println(toAndroidLevel(priority), - className, - threadName + ' ' + msg + - msg + ' ' + t.toString() + ' ' + android.util.Log.getStackTraceString(t)); - else if (name != null) + tag, + '[' + threadName + "] " + msg + + ' ' + t.toString() + ' ' + android.util.Log.getStackTraceString(t)); + } else if (name != null) android.util.Log.println(toAndroidLevel(priority), name, - threadName + ' ' + msg + - msg + ' ' + t.toString() + ' ' + android.util.Log.getStackTraceString(t)); + '[' + threadName + "] " + msg + + ' ' + t.toString() + ' ' + android.util.Log.getStackTraceString(t)); else android.util.Log.println(toAndroidLevel(priority), threadName, diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ReseedHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ReseedHandler.java index 066cb1144..3d3d603fa 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ReseedHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ReseedHandler.java @@ -15,6 +15,8 @@ import java.util.StringTokenizer; import net.i2p.I2PAppContext; import net.i2p.router.RouterContext; import net.i2p.util.EepGet; +import net.i2p.util.FileStreamFactory; +import net.i2p.util.I2PFile; import net.i2p.util.I2PThread; import net.i2p.util.Log; @@ -250,11 +252,11 @@ public class ReseedHandler { private void writeSeed(String name, byte data[]) throws Exception { String dirName = "netDb"; // _context.getProperty("router.networkDatabase.dbDir", "netDb"); - File netDbDir = new File(dirName); + File netDbDir = new I2PFile(dirName); if (!netDbDir.exists()) { boolean ok = netDbDir.mkdirs(); } - FileOutputStream fos = new FileOutputStream(new File(netDbDir, "routerInfo-" + name + ".dat")); + FileOutputStream fos = FileStreamFactory.getFileOutputStream(new I2PFile(netDbDir, "routerInfo-" + name + ".dat")); fos.write(data); fos.close(); } diff --git a/core/java/src/net/i2p/data/DataHelper.java b/core/java/src/net/i2p/data/DataHelper.java index 53e32a347..55b424562 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.TreeMap; import java.util.zip.Deflater; import net.i2p.util.ByteCache; +import net.i2p.util.FileStreamFactory; import net.i2p.util.OrderedProperties; import net.i2p.util.ReusableGZIPInputStream; import net.i2p.util.ReusableGZIPOutputStream; @@ -217,7 +218,7 @@ public class DataHelper { loadProps(props, file, false); } public static void loadProps(Properties props, File file, boolean forceLowerCase) throws IOException { - loadProps(props, new FileInputStream(file), forceLowerCase); + loadProps(props, FileStreamFactory.getFileInputStream(file), forceLowerCase); } public static void loadProps(Properties props, InputStream inStr) throws IOException { loadProps(props, inStr, false); diff --git a/core/java/src/net/i2p/util/FileStreamFactory.java b/core/java/src/net/i2p/util/FileStreamFactory.java new file mode 100644 index 000000000..01d505665 --- /dev/null +++ b/core/java/src/net/i2p/util/FileStreamFactory.java @@ -0,0 +1,36 @@ +/* + * public domain + */ + +package net.i2p.util; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; + + +/** + * This is pulled out and replaced in the android build. + * + * @author zzz + */ +public class FileStreamFactory { + + public static FileInputStream getFileInputStream(String f) throws FileNotFoundException { + return new FileInputStream(f); + } + + public static FileInputStream getFileInputStream(File f) throws FileNotFoundException { + return new FileInputStream(f); + } + + public static FileOutputStream getFileOutputStream(String f) throws FileNotFoundException { + return new FileOutputStream(f); + } + + public static FileOutputStream getFileOutputStream(File f) throws FileNotFoundException { + return new FileOutputStream(f); + } + +} diff --git a/core/java/src/net/i2p/util/I2PFile.java b/core/java/src/net/i2p/util/I2PFile.java new file mode 100644 index 000000000..107286edf --- /dev/null +++ b/core/java/src/net/i2p/util/I2PFile.java @@ -0,0 +1,24 @@ +/* + * public domain + */ + +package net.i2p.util; + +import java.io.File; + +/** + * This is pulled out and replaced in the android build. + * + * @author zzz + */ +public class I2PFile extends File { + + public I2PFile (String f) { + super(f); + } + + public I2PFile (File p, String f) { + super(p, f); + } + +} diff --git a/core/java/src/net/i2p/util/LogManager.java b/core/java/src/net/i2p/util/LogManager.java index 1f957515c..52b828af9 100644 --- a/core/java/src/net/i2p/util/LogManager.java +++ b/core/java/src/net/i2p/util/LogManager.java @@ -240,7 +240,7 @@ public class LogManager { // private void loadConfig() { - File cfgFile = new File(_location); + File cfgFile = new I2PFile(_location); if (!cfgFile.exists()) { if (!_alreadyNoticedMissingConfig) { if (_log.shouldLog(Log.WARN)) @@ -268,11 +268,11 @@ public class LogManager { Properties p = new Properties(); FileInputStream fis = null; try { - fis = new FileInputStream(cfgFile); + fis = FileStreamFactory.getFileInputStream(cfgFile); p.load(fis); _configLastRead = _context.clock().now(); } catch (IOException ioe) { - System.err.println("Error loading logger config from " + new File(_location).getAbsolutePath()); + System.err.println("Error loading logger config from " + new I2PFile(_location).getAbsolutePath()); } finally { if (fis != null) try { fis.close(); @@ -540,7 +540,7 @@ public class LogManager { String config = createConfig(); FileOutputStream fos = null; try { - fos = new FileOutputStream(_location); + fos = FileStreamFactory.getFileOutputStream(_location); fos.write(config.getBytes()); return true; } catch (IOException ioe) { diff --git a/router/java/src/net/i2p/router/KeyManager.java b/router/java/src/net/i2p/router/KeyManager.java index 4e2ed2c51..f2150b923 100644 --- a/router/java/src/net/i2p/router/KeyManager.java +++ b/router/java/src/net/i2p/router/KeyManager.java @@ -26,6 +26,7 @@ import net.i2p.data.PublicKey; import net.i2p.data.SigningPrivateKey; import net.i2p.data.SigningPublicKey; import net.i2p.util.Clock; +import net.i2p.util.FileStreamFactory; import net.i2p.util.Log; /** @@ -205,12 +206,12 @@ public class KeyManager { FileInputStream in = null; try { if (exists) { - out = new FileOutputStream(keyFile); + out = FileStreamFactory.getFileOutputStream(keyFile); structure.writeBytes(out); return structure; } else { if (keyFile.exists()) { - in = new FileInputStream(keyFile); + in = FileStreamFactory.getFileInputStream(keyFile); structure.readBytes(in); return structure; } else { diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java index 13e801458..c33dc3e63 100644 --- a/router/java/src/net/i2p/router/Router.java +++ b/router/java/src/net/i2p/router/Router.java @@ -40,7 +40,9 @@ import net.i2p.router.transport.FIFOBandwidthLimiter; import net.i2p.stat.Rate; import net.i2p.stat.RateStat; import net.i2p.stat.StatManager; +import net.i2p.util.FileStreamFactory; import net.i2p.util.FileUtil; +import net.i2p.util.I2PFile; import net.i2p.util.I2PThread; import net.i2p.util.Log; import net.i2p.util.SimpleScheduler; @@ -292,7 +294,7 @@ public class Router { } Properties props = new Properties(); try { - File f = new File(filename); + File f = new I2PFile(filename); if (f.canRead()) { DataHelper.loadProps(props, f); // dont be a wanker @@ -945,7 +947,7 @@ public class Router { public boolean saveConfig() { FileOutputStream fos = null; try { - fos = new FileOutputStream(_configFilename); + fos = FileStreamFactory.getFileOutputStream(_configFilename); StringBuffer buf = new StringBuffer(8*1024); synchronized (_config) { TreeSet ordered = new TreeSet(_config.keySet()); @@ -1331,7 +1333,7 @@ class MarkLiveliness implements Runnable { private void ping() { FileOutputStream fos = null; try { - fos = new FileOutputStream(_pingFile); + fos = FileStreamFactory.getFileOutputStream(_pingFile); fos.write(("" + System.currentTimeMillis()).getBytes()); } catch (IOException ioe) { System.err.println("Error writing to ping file"); @@ -1378,7 +1380,7 @@ class PersistRouterInfoJob extends JobImpl { FileOutputStream fos = null; try { - fos = new FileOutputStream(infoFilename); + fos = FileStreamFactory.getFileOutputStream(infoFilename); info.writeBytes(fos); } catch (DataFormatException dfe) { _log.error("Error rebuilding the router information", dfe); 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 5d0d219db..1d9490a33 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java @@ -26,6 +26,8 @@ import net.i2p.data.RouterInfo; import net.i2p.router.JobImpl; import net.i2p.router.Router; import net.i2p.router.RouterContext; +import net.i2p.util.FileStreamFactory; +import net.i2p.util.I2PFile; import net.i2p.util.I2PThread; import net.i2p.util.Log; @@ -171,11 +173,11 @@ class PersistentDataStore extends TransientDataStore { else throw new IOException("We don't know how to write objects of type " + data.getClass().getName()); - dbFile = new File(dbDir, filename); + dbFile = new I2PFile(dbDir, filename); long dataPublishDate = getPublishDate(data); if (dbFile.lastModified() < dataPublishDate) { // our filesystem is out of date, lets replace it - fos = new FileOutputStream(dbFile); + fos = FileStreamFactory.getFileOutputStream(dbFile); try { data.writeBytes(fos); fos.close(); @@ -278,7 +280,7 @@ class PersistentDataStore extends TransientDataStore { FileInputStream fis = null; boolean corrupt = false; try { - fis = new FileInputStream(_routerFile); + fis = FileStreamFactory.getFileInputStream(_routerFile); RouterInfo ri = new RouterInfo(); ri.readBytes(fis); if (ri.getNetworkId() != Router.NETWORK_ID) { @@ -312,7 +314,7 @@ class PersistentDataStore extends TransientDataStore { private File getDbDir() throws IOException { - File f = new File(_dbDir); + File f = new I2PFile(_dbDir); if (!f.exists()) { boolean created = f.mkdirs(); if (!created) @@ -362,7 +364,7 @@ class PersistentDataStore extends TransientDataStore { private void removeFile(Hash key, File dir) throws IOException { String riName = getRouterInfoName(key); - File f = new File(dir, riName); + File f = new I2PFile(dir, riName); if (f.exists()) { boolean removed = f.delete(); if (!removed) diff --git a/router/java/src/net/i2p/router/peermanager/ProfilePersistenceHelper.java b/router/java/src/net/i2p/router/peermanager/ProfilePersistenceHelper.java index fd88c406b..6b8e3105e 100644 --- a/router/java/src/net/i2p/router/peermanager/ProfilePersistenceHelper.java +++ b/router/java/src/net/i2p/router/peermanager/ProfilePersistenceHelper.java @@ -18,6 +18,8 @@ import net.i2p.data.DataFormatException; import net.i2p.data.DataHelper; import net.i2p.data.Hash; import net.i2p.router.RouterContext; +import net.i2p.util.FileStreamFactory; +import net.i2p.util.I2PFile; import net.i2p.util.Log; class ProfilePersistenceHelper { @@ -61,7 +63,7 @@ class ProfilePersistenceHelper { long before = _context.clock().now(); OutputStream fos = null; try { - fos = new BufferedOutputStream(new GZIPOutputStream(new FileOutputStream(f))); + fos = new BufferedOutputStream(new GZIPOutputStream(FileStreamFactory.getFileOutputStream(f))); writeProfile(profile, fos); } catch (IOException ioe) { _log.error("Error writing profile to " + f); @@ -264,10 +266,10 @@ class ProfilePersistenceHelper { private void loadProps(Properties props, File file) { try { - FileInputStream fin = new FileInputStream(file); + FileInputStream fin = FileStreamFactory.getFileInputStream(file); int c = fin.read(); fin.close(); - fin = new FileInputStream(file); // ghetto mark+reset + fin = FileStreamFactory.getFileInputStream(file); // ghetto mark+reset if (c == '#') { // uncompressed if (_log.shouldLog(Log.INFO)) @@ -299,7 +301,7 @@ class ProfilePersistenceHelper { } private File pickFile(PeerProfile profile) { - return new File(getProfileDir(), "profile-" + profile.getPeer().toBase64() + ".dat"); + return new I2PFile(getProfileDir(), "profile-" + profile.getPeer().toBase64() + ".dat"); } private File getProfileDir() { @@ -315,7 +317,7 @@ class ProfilePersistenceHelper { dir = DEFAULT_PEER_PROFILE_DIR; } } - _profileDir = new File(dir); + _profileDir = new I2PFile(dir); } return _profileDir; } diff --git a/router/java/src/net/i2p/router/startup/CreateRouterInfoJob.java b/router/java/src/net/i2p/router/startup/CreateRouterInfoJob.java index 92b176c30..12c6cee6a 100644 --- a/router/java/src/net/i2p/router/startup/CreateRouterInfoJob.java +++ b/router/java/src/net/i2p/router/startup/CreateRouterInfoJob.java @@ -25,6 +25,7 @@ import net.i2p.router.Job; import net.i2p.router.JobImpl; import net.i2p.router.Router; import net.i2p.router.RouterContext; +import net.i2p.util.FileStreamFactory; import net.i2p.util.Log; public class CreateRouterInfoJob extends JobImpl { @@ -79,13 +80,13 @@ public class CreateRouterInfoJob extends JobImpl { String infoFilename = getContext().router().getConfigSetting(Router.PROP_INFO_FILENAME); if (infoFilename == null) infoFilename = Router.PROP_INFO_FILENAME_DEFAULT; - fos1 = new FileOutputStream(infoFilename); + fos1 = FileStreamFactory.getFileOutputStream(infoFilename); info.writeBytes(fos1); String keyFilename = getContext().router().getConfigSetting(Router.PROP_KEYS_FILENAME); if (keyFilename == null) keyFilename = Router.PROP_KEYS_FILENAME_DEFAULT; - fos2 = new FileOutputStream(keyFilename); + fos2 = FileStreamFactory.getFileOutputStream(keyFilename); privkey.writeBytes(fos2); signingPrivKey.writeBytes(fos2); pubkey.writeBytes(fos2); diff --git a/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java b/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java index 0374922af..bdd3b9867 100644 --- a/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java +++ b/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java @@ -21,6 +21,8 @@ import net.i2p.data.SigningPublicKey; import net.i2p.router.JobImpl; import net.i2p.router.Router; import net.i2p.router.RouterContext; +import net.i2p.util.FileStreamFactory; +import net.i2p.util.I2PFile; import net.i2p.util.Log; public class LoadRouterInfoJob extends JobImpl { @@ -62,10 +64,10 @@ public class LoadRouterInfoJob extends JobImpl { if (keyFilename == null) keyFilename = Router.PROP_KEYS_FILENAME_DEFAULT; - File rif = new File(routerInfoFile); + File rif = new I2PFile(routerInfoFile); if (rif.exists()) _infoExists = true; - File rkf = new File(keyFilename); + File rkf = new I2PFile(keyFilename); if (rkf.exists()) _keysExist = true; @@ -73,14 +75,14 @@ public class LoadRouterInfoJob extends JobImpl { FileInputStream fis2 = null; try { if (_infoExists) { - fis1 = new FileInputStream(rif); + fis1 = FileStreamFactory.getFileInputStream(rif); info = new RouterInfo(); info.readBytes(fis1); _log.debug("Reading in routerInfo from " + rif.getAbsolutePath() + " and it has " + info.getAddresses().size() + " addresses"); } if (_keysExist) { - fis2 = new FileInputStream(rkf); + fis2 = FileStreamFactory.getFileInputStream(rkf); PrivateKey privkey = new PrivateKey(); privkey.readBytes(fis2); SigningPrivateKey signingPrivKey = new SigningPrivateKey(); diff --git a/router/java/src/net/i2p/router/startup/RebuildRouterInfoJob.java b/router/java/src/net/i2p/router/startup/RebuildRouterInfoJob.java index 967bc7a79..f3905f89f 100644 --- a/router/java/src/net/i2p/router/startup/RebuildRouterInfoJob.java +++ b/router/java/src/net/i2p/router/startup/RebuildRouterInfoJob.java @@ -25,6 +25,8 @@ import net.i2p.data.SigningPublicKey; import net.i2p.router.JobImpl; import net.i2p.router.Router; import net.i2p.router.RouterContext; +import net.i2p.util.FileStreamFactory; +import net.i2p.util.I2PFile; import net.i2p.util.Log; /** @@ -93,7 +95,7 @@ public class RebuildRouterInfoJob extends JobImpl { String keyFilename = getContext().router().getConfigSetting(Router.PROP_KEYS_FILENAME); if (keyFilename == null) keyFilename = Router.PROP_KEYS_FILENAME_DEFAULT; - File keyFile = new File(keyFilename); + File keyFile = new I2PFile(keyFilename); if (keyFile.exists()) { // ok, no need to rebuild a brand new identity, just update what we can @@ -102,7 +104,7 @@ public class RebuildRouterInfoJob extends JobImpl { info = new RouterInfo(); FileInputStream fis = null; try { - fis = new FileInputStream(keyFile); + fis = FileStreamFactory.getFileInputStream(keyFile); PrivateKey privkey = new PrivateKey(); privkey.readBytes(fis); SigningPrivateKey signingPrivKey = new SigningPrivateKey(); @@ -146,7 +148,7 @@ public class RebuildRouterInfoJob extends JobImpl { FileOutputStream fos = null; try { - fos = new FileOutputStream(infoFilename); + fos = FileStreamFactory.getFileOutputStream(infoFilename); info.writeBytes(fos); } catch (DataFormatException dfe) { _log.error("Error rebuilding the router information", dfe); 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 9c75f5328..b3901f07e 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/EventPumper.java +++ b/router/java/src/net/i2p/router/transport/ntcp/EventPumper.java @@ -81,7 +81,7 @@ public class EventPumper implements Runnable { public void stopPumping() { _alive = false; - if (_selector.isOpen()) + if (_selector != null &&_selector.isOpen()) _selector.wakeup(); } From 502257542928a7a3548a7b201928ca76781fbf99 Mon Sep 17 00:00:00 2001 From: zzz Date: Fri, 13 Mar 2009 21:49:27 +0000 Subject: [PATCH 06/12] - Deal with conflicting bouncycastle libs take #2 - Disable NTCP - Shuffle the startup/shutdown tasks some --- android/res/raw/router_config | 2 ++ android/src/net/i2p/router/I2PAndroid.java | 19 ++++++++++++++----- .../src/net/i2p/router/web/ReseedChecker.java | 2 ++ .../src/net/i2p/router/web/ContextHelper.java | 2 +- .../src/net/i2p/crypto/HMAC256Generator.java | 4 ++-- .../src/net/i2p/crypto/HMACGenerator.java | 6 +++--- 6 files changed, 24 insertions(+), 11 deletions(-) diff --git a/android/res/raw/router_config b/android/res/raw/router_config index 19c609542..0e7cd2ced 100644 --- a/android/res/raw/router_config +++ b/android/res/raw/router_config @@ -5,3 +5,5 @@ router.decayingBloomFilterM=20 stat.full=false # no I2CP i2p.dummyClientFacade=true +# for now +i2np.ntcp.enable=false diff --git a/android/src/net/i2p/router/I2PAndroid.java b/android/src/net/i2p/router/I2PAndroid.java index c08670e36..bb77d290b 100644 --- a/android/src/net/i2p/router/I2PAndroid.java +++ b/android/src/net/i2p/router/I2PAndroid.java @@ -12,6 +12,7 @@ import java.io.InputStream; import java.io.IOException; import net.i2p.router.Router; +import net.i2p.router.web.ContextHelper; import net.i2p.router.web.ReseedChecker; import net.i2p.util.I2PFile; @@ -29,11 +30,6 @@ public class I2PAndroid extends Activity _context = this; // Activity extends Context debugStuff(); initialize(); - - Router.main(null); - System.err.println("Router.main finished"); - - ReseedChecker.checkReseed(); } public void onRestart() @@ -42,6 +38,16 @@ public class I2PAndroid extends Activity super.onRestart(); } + public void onStart() + { + System.err.println("onStart called"); + super.onStart(); + Router.main(null); + System.err.println("Router.main finished"); + + ReseedChecker.checkReseed(); + } + public void onResume() { System.err.println("onResume called"); @@ -58,6 +64,9 @@ public class I2PAndroid extends Activity { System.err.println("onStop called"); super.onStop(); + // shutdown() doesn't return so use shutdownGracefully() + ContextHelper.getContext(null).router().shutdownGracefully(Router.EXIT_HARD); + System.err.println("shutdown complete"); } public void onDestroy() diff --git a/android/src/net/i2p/router/web/ReseedChecker.java b/android/src/net/i2p/router/web/ReseedChecker.java index 96eccce51..8c8ff7bf9 100644 --- a/android/src/net/i2p/router/web/ReseedChecker.java +++ b/android/src/net/i2p/router/web/ReseedChecker.java @@ -30,6 +30,8 @@ public class ReseedChecker { System.err.println("Yes, reseeding now"); ReseedHandler reseedHandler = new ReseedHandler(); reseedHandler.requestReseed(); + } else { + System.err.println("No, we have " + names.length + " routers in the netDb"); } } } diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ContextHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ContextHelper.java index 0aa250654..7d9b28e89 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ContextHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ContextHelper.java @@ -5,7 +5,7 @@ import java.util.List; import net.i2p.data.Hash; import net.i2p.router.RouterContext; -class ContextHelper { +public class ContextHelper { public static RouterContext getContext(String contextId) { List contexts = RouterContext.listContexts(); if ( (contexts == null) || (contexts.size() <= 0) ) diff --git a/core/java/src/net/i2p/crypto/HMAC256Generator.java b/core/java/src/net/i2p/crypto/HMAC256Generator.java index 7d6f67a76..0335d1e7e 100644 --- a/core/java/src/net/i2p/crypto/HMAC256Generator.java +++ b/core/java/src/net/i2p/crypto/HMAC256Generator.java @@ -20,10 +20,10 @@ public class HMAC256Generator extends HMACGenerator { public HMAC256Generator(I2PAppContext context) { super(context); } @Override - protected Mac acquire() { + protected I2PHMac acquire() { synchronized (_available) { if (_available.size() > 0) - return (Mac)_available.remove(0); + return (I2PHMac)_available.remove(0); } // the HMAC is hardcoded to use SHA256 digest size // for backwards compatability. next time we have a backwards diff --git a/core/java/src/net/i2p/crypto/HMACGenerator.java b/core/java/src/net/i2p/crypto/HMACGenerator.java index 52b29e19b..29d76cbd2 100644 --- a/core/java/src/net/i2p/crypto/HMACGenerator.java +++ b/core/java/src/net/i2p/crypto/HMACGenerator.java @@ -50,7 +50,7 @@ public class HMACGenerator { if ((key == null) || (key.getData() == null) || (data == null)) throw new NullPointerException("Null arguments for HMAC"); - Mac mac = acquire(); + I2PHMac mac = acquire(); mac.init(key.getData()); mac.update(data, offset, length); //byte rv[] = new byte[Hash.HASH_LENGTH]; @@ -87,10 +87,10 @@ public class HMACGenerator { return eq; } - protected Mac acquire() { + protected I2PHMac acquire() { synchronized (_available) { if (_available.size() > 0) - return (Mac)_available.remove(0); + return (I2PHMac)_available.remove(0); } // the HMAC is hardcoded to use SHA256 digest size // for backwards compatability. next time we have a backwards From db45e74fcc9d564d818271a707625f481d21c6b8 Mon Sep 17 00:00:00 2001 From: zzz Date: Mon, 29 Jun 2009 14:51:02 +0000 Subject: [PATCH 07/12] Cleanup after prop from i2p.i2p: - Remove I2PFile, FileStreamFactory hacks - Remove custom reseed stuff --- android/build.xml | 16 +---- android/src/net/i2p/router/I2PAndroid.java | 8 +-- .../src/net/i2p/router/web/ReseedChecker.java | 39 ----------- .../src/net/i2p/util/FileStreamFactory.java | 64 ------------------- android/src/net/i2p/util/I2PFile.java | 29 --------- core/java/src/net/i2p/data/DataHelper.java | 3 +- .../src/net/i2p/util/FileStreamFactory.java | 36 ----------- core/java/src/net/i2p/util/I2PFile.java | 24 ------- .../java/src/net/i2p/router/KeyManager.java | 5 +- .../i2p/router/startup/LoadRouterInfoJob.java | 2 +- 10 files changed, 10 insertions(+), 216 deletions(-) delete mode 100644 android/src/net/i2p/router/web/ReseedChecker.java delete mode 100644 android/src/net/i2p/util/FileStreamFactory.java delete mode 100644 android/src/net/i2p/util/I2PFile.java delete mode 100644 core/java/src/net/i2p/util/FileStreamFactory.java delete mode 100644 core/java/src/net/i2p/util/I2PFile.java diff --git a/android/build.xml b/android/build.xml index 5875c5fed..56cec083d 100644 --- a/android/build.xml +++ b/android/build.xml @@ -155,17 +155,7 @@ - - - - - - - - - - - + @@ -175,8 +165,6 @@ - - @@ -206,7 +194,7 @@ - + diff --git a/android/src/net/i2p/router/I2PAndroid.java b/android/src/net/i2p/router/I2PAndroid.java index bb77d290b..0d89bfb7b 100644 --- a/android/src/net/i2p/router/I2PAndroid.java +++ b/android/src/net/i2p/router/I2PAndroid.java @@ -13,8 +13,7 @@ import java.io.IOException; import net.i2p.router.Router; import net.i2p.router.web.ContextHelper; -import net.i2p.router.web.ReseedChecker; -import net.i2p.util.I2PFile; +// import net.i2p.util.NativeBigInteger; public class I2PAndroid extends Activity { @@ -30,6 +29,9 @@ public class I2PAndroid extends Activity _context = this; // Activity extends Context debugStuff(); initialize(); + // 300ms per run + // 5x slower than java on my server and 50x slower than native on my server + // NativeBigInteger.main(null); } public void onRestart() @@ -44,8 +46,6 @@ public class I2PAndroid extends Activity super.onStart(); Router.main(null); System.err.println("Router.main finished"); - - ReseedChecker.checkReseed(); } public void onResume() diff --git a/android/src/net/i2p/router/web/ReseedChecker.java b/android/src/net/i2p/router/web/ReseedChecker.java deleted file mode 100644 index 8c8ff7bf9..000000000 --- a/android/src/net/i2p/router/web/ReseedChecker.java +++ /dev/null @@ -1,39 +0,0 @@ -package net.i2p.router.web; - -import java.io.File; - -import net.i2p.router.web.ReseedHandler; -import net.i2p.util.I2PFile; - -/** - * Copied from RouterConsoleRunner.java - */ -public class ReseedChecker { - - public static void checkReseed() { - - System.err.println("Checking to see if we should reseed"); - // we check the i2p installation directory (.) for a flag telling us not to reseed, - // but also check the home directory for that flag too, since new users installing i2p - // don't have an installation directory that they can put the flag in yet. - File noReseedFile = new I2PFile(new I2PFile(System.getProperty("user.home")), ".i2pnoreseed"); - File noReseedFileAlt1 = new I2PFile(new I2PFile(System.getProperty("user.home")), "noreseed.i2p"); - File noReseedFileAlt2 = new I2PFile(".i2pnoreseed"); - File noReseedFileAlt3 = new I2PFile("noreseed.i2p"); - if (!noReseedFile.exists() && !noReseedFileAlt1.exists() && !noReseedFileAlt2.exists() && !noReseedFileAlt3.exists()) { - File netDb = new I2PFile("netDb"); - // sure, some of them could be "my.info" or various leaseSet- files, but chances are, - // if someone has those files, they've already been seeded (at least enough to let them - // get i2p started - they can reseed later in the web console) - String names[] = (netDb.exists() ? netDb.list() : null); - if ( (names == null) || (names.length < 15) ) { - System.err.println("Yes, reseeding now"); - ReseedHandler reseedHandler = new ReseedHandler(); - reseedHandler.requestReseed(); - } else { - System.err.println("No, we have " + names.length + " routers in the netDb"); - } - } - } - -} diff --git a/android/src/net/i2p/util/FileStreamFactory.java b/android/src/net/i2p/util/FileStreamFactory.java deleted file mode 100644 index b7a65e4f2..000000000 --- a/android/src/net/i2p/util/FileStreamFactory.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This is free software, do as you please. - */ - -package net.i2p.util; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; - -import net.i2p.router.I2PAndroid; - -/** - * Use android static file stream methods - * gaaah: - * 1) the CWD is / - * 2) we can only access /data/data/net.i2p.router/files/ - * 3) you can't change your CWD in Java - * so we have this lovely and the one in I2PFile. - * - * @author zzz - */ -public class FileStreamFactory { - private static final String DIR = "/data/data/net.i2p.router/files/"; - - /** hopefully no path separators in string */ - public static FileInputStream getFileInputStream(String f) throws FileNotFoundException { - System.err.println("Input file-s: " + I2PAndroid.getContext().getFileStreamPath(f).getAbsolutePath()); - return I2PAndroid.getContext().openFileInput(f); - } - - public static FileInputStream getFileInputStream(File f) throws FileNotFoundException { - System.err.println("Input file-f: " + getPath(f) + - ' ' + f.getAbsolutePath()); - //return I2PAndroid.getContext().openFileInput(f.getName()); - return new FileInputStream(getPath(f)); - } - - /** hopefully no path separators in string */ - public static FileOutputStream getFileOutputStream(String f) throws FileNotFoundException { - System.err.println("Output file-s: " + I2PAndroid.getContext().getFileStreamPath(f).getAbsolutePath()); - return I2PAndroid.getContext().openFileOutput(f, 0); - } - - public static FileOutputStream getFileOutputStream(File f) throws FileNotFoundException { - System.err.println("Output file-f: " + getPath(f) + - ' ' + f.getAbsolutePath()); - //return I2PAndroid.getContext().openFileOutput(f.getName(), 0); - return new FileOutputStream(getPath(f)); - } - - /** - * preserve path but convert /foo/blah to /data/data/net.i2p.router/files/foo/blah - * Although if the File arg was created with new I2PFile() then this isn't required - * - */ - private static String getPath(File f) { - String abs = f.getAbsolutePath(); - if (abs.startsWith(DIR)) - return abs; - return DIR + abs.substring(1); // strip extra '/' - } -} diff --git a/android/src/net/i2p/util/I2PFile.java b/android/src/net/i2p/util/I2PFile.java deleted file mode 100644 index 94bda029b..000000000 --- a/android/src/net/i2p/util/I2PFile.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This is free software, do as you please. - */ - -package net.i2p.util; - -import java.io.File; - -/** - * gaaah: - * 1) the CWD is / - * 2) we can only access /data/data/net.i2p.router/files/ - * 3) you can't change your CWD in Java - * so we have this lovely and the one in FileStreamFactory. - * - * @author zzz - */ -public class I2PFile extends File { - - public I2PFile (String f) { - super("/data/data/net.i2p.router/files/" + f); - } - - /** one level deep only */ - public I2PFile (File p, String f) { - super("/data/data/net.i2p.router/files/" + p.getName(), f); - } - -} diff --git a/core/java/src/net/i2p/data/DataHelper.java b/core/java/src/net/i2p/data/DataHelper.java index 55b424562..53e32a347 100644 --- a/core/java/src/net/i2p/data/DataHelper.java +++ b/core/java/src/net/i2p/data/DataHelper.java @@ -37,7 +37,6 @@ import java.util.TreeMap; import java.util.zip.Deflater; import net.i2p.util.ByteCache; -import net.i2p.util.FileStreamFactory; import net.i2p.util.OrderedProperties; import net.i2p.util.ReusableGZIPInputStream; import net.i2p.util.ReusableGZIPOutputStream; @@ -218,7 +217,7 @@ public class DataHelper { loadProps(props, file, false); } public static void loadProps(Properties props, File file, boolean forceLowerCase) throws IOException { - loadProps(props, FileStreamFactory.getFileInputStream(file), forceLowerCase); + loadProps(props, new FileInputStream(file), forceLowerCase); } public static void loadProps(Properties props, InputStream inStr) throws IOException { loadProps(props, inStr, false); diff --git a/core/java/src/net/i2p/util/FileStreamFactory.java b/core/java/src/net/i2p/util/FileStreamFactory.java deleted file mode 100644 index 01d505665..000000000 --- a/core/java/src/net/i2p/util/FileStreamFactory.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * public domain - */ - -package net.i2p.util; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; - - -/** - * This is pulled out and replaced in the android build. - * - * @author zzz - */ -public class FileStreamFactory { - - public static FileInputStream getFileInputStream(String f) throws FileNotFoundException { - return new FileInputStream(f); - } - - public static FileInputStream getFileInputStream(File f) throws FileNotFoundException { - return new FileInputStream(f); - } - - public static FileOutputStream getFileOutputStream(String f) throws FileNotFoundException { - return new FileOutputStream(f); - } - - public static FileOutputStream getFileOutputStream(File f) throws FileNotFoundException { - return new FileOutputStream(f); - } - -} diff --git a/core/java/src/net/i2p/util/I2PFile.java b/core/java/src/net/i2p/util/I2PFile.java deleted file mode 100644 index 107286edf..000000000 --- a/core/java/src/net/i2p/util/I2PFile.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * public domain - */ - -package net.i2p.util; - -import java.io.File; - -/** - * This is pulled out and replaced in the android build. - * - * @author zzz - */ -public class I2PFile extends File { - - public I2PFile (String f) { - super(f); - } - - public I2PFile (File p, String f) { - super(p, f); - } - -} diff --git a/router/java/src/net/i2p/router/KeyManager.java b/router/java/src/net/i2p/router/KeyManager.java index f82f9f824..711759a40 100644 --- a/router/java/src/net/i2p/router/KeyManager.java +++ b/router/java/src/net/i2p/router/KeyManager.java @@ -26,7 +26,6 @@ import net.i2p.data.PublicKey; import net.i2p.data.SigningPrivateKey; import net.i2p.data.SigningPublicKey; import net.i2p.util.Clock; -import net.i2p.util.FileStreamFactory; import net.i2p.util.Log; /** @@ -204,12 +203,12 @@ public class KeyManager { FileInputStream in = null; try { if (exists) { - out = FileStreamFactory.getFileOutputStream(keyFile); + out = new FileOutputStream(keyFile); structure.writeBytes(out); return structure; } else { if (keyFile.exists()) { - in = FileStreamFactory.getFileInputStream(keyFile); + in = new FileInputStream(keyFile); structure.readBytes(in); return structure; } else { diff --git a/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java b/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java index fea9c461e..f3428c447 100644 --- a/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java +++ b/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java @@ -76,7 +76,7 @@ public class LoadRouterInfoJob extends JobImpl { } if (_keysExist) { - fis2 = FileStreamFactory.getFileInputStream(rkf); + fis2 = new FileInputStream(rkf); PrivateKey privkey = new PrivateKey(); privkey.readBytes(fis2); SigningPrivateKey signingPrivKey = new SigningPrivateKey(); From 3fee5a378150b61da20275af0d336b04ad14f79a Mon Sep 17 00:00:00 2001 From: zzz Date: Mon, 29 Jun 2009 16:51:19 +0000 Subject: [PATCH 08/12] more cleanup, set dirs --- android/res/raw/router_config | 7 +++++++ android/src/net/i2p/router/I2PAndroid.java | 6 ++++++ android/src/net/i2p/util/LogWriter.java | 5 ++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/android/res/raw/router_config b/android/res/raw/router_config index 0e7cd2ced..cf63ed56a 100644 --- a/android/res/raw/router_config +++ b/android/res/raw/router_config @@ -1,9 +1,16 @@ # initial router.config +# temp directory +i2p.dir.temp=/data/data/net.i2p.router/files/tmp +i2p.dir.pid=/data/data/net.i2p.router/files/tmp # save memory router.prng.buffers=2 router.decayingBloomFilterM=20 stat.full=false +i2np.udp.maxConnections=30 # no I2CP i2p.dummyClientFacade=true # for now i2np.ntcp.enable=false +# not on android +i2np.upnp.enable=false +routerconsole.geoip.enable=false diff --git a/android/src/net/i2p/router/I2PAndroid.java b/android/src/net/i2p/router/I2PAndroid.java index 0d89bfb7b..69e0c8e3b 100644 --- a/android/src/net/i2p/router/I2PAndroid.java +++ b/android/src/net/i2p/router/I2PAndroid.java @@ -18,6 +18,7 @@ import net.i2p.router.web.ContextHelper; public class I2PAndroid extends Activity { static Context _context; + private static final String DIR = "/data/data/net.i2p.router/files"; /** Called when the activity is first created. */ @Override @@ -80,6 +81,7 @@ public class I2PAndroid extends Activity } private void debugStuff() { + System.err.println("java.io.tmpdir" + ": " + System.getProperty("java.io.tmpdir")); System.err.println("java.vendor" + ": " + System.getProperty("java.vendor")); System.err.println("java.version" + ": " + System.getProperty("java.version")); System.err.println("os.arch" + ": " + System.getProperty("os.arch")); @@ -99,6 +101,10 @@ public class I2PAndroid extends Activity copyResourceToFile(R.raw.logger_config, "logger.config"); copyResourceToFile(R.raw.blocklist_txt, "blocklist.txt"); // } + + // Set up the locations so Router and WorkingDir can find them + System.setProperty("i2p.dir.base", DIR); + System.setProperty("i2p.dir.config", DIR); } private void copyResourceToFile(int resID, String f) { diff --git a/android/src/net/i2p/util/LogWriter.java b/android/src/net/i2p/util/LogWriter.java index 03f5577ae..0babfab37 100644 --- a/android/src/net/i2p/util/LogWriter.java +++ b/android/src/net/i2p/util/LogWriter.java @@ -75,7 +75,10 @@ class LogWriter implements Runnable { } } } - + + public String currentFile() { + return _currentFile != null ? _currentFile.getAbsolutePath() : "uninitialized"; + } private void rereadConfig() { long now = Clock.getInstance().now(); From 7972c0c862c36d619414a4f4e7ea49ecf3aa308e Mon Sep 17 00:00:00 2001 From: zzz Date: Mon, 29 Jun 2009 17:42:13 +0000 Subject: [PATCH 09/12] - Fix another Mac class problem - Change to RouterLaunch main so we get a wrapper.log --- android/src/net/i2p/router/I2PAndroid.java | 4 +++- core/java/src/net/i2p/crypto/HMACGenerator.java | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/android/src/net/i2p/router/I2PAndroid.java b/android/src/net/i2p/router/I2PAndroid.java index 69e0c8e3b..18a6e149a 100644 --- a/android/src/net/i2p/router/I2PAndroid.java +++ b/android/src/net/i2p/router/I2PAndroid.java @@ -12,6 +12,7 @@ import java.io.InputStream; import java.io.IOException; import net.i2p.router.Router; +import net.i2p.router.RouterLaunch; import net.i2p.router.web.ContextHelper; // import net.i2p.util.NativeBigInteger; @@ -45,7 +46,7 @@ public class I2PAndroid extends Activity { System.err.println("onStart called"); super.onStart(); - Router.main(null); + RouterLaunch.main(null); System.err.println("Router.main finished"); } @@ -105,6 +106,7 @@ public class I2PAndroid extends Activity // Set up the locations so Router and WorkingDir can find them System.setProperty("i2p.dir.base", DIR); System.setProperty("i2p.dir.config", DIR); + System.setProperty("wrapper.logfile", DIR + "/wrapper.log"); } private void copyResourceToFile(int resID, String f) { diff --git a/core/java/src/net/i2p/crypto/HMACGenerator.java b/core/java/src/net/i2p/crypto/HMACGenerator.java index 29d76cbd2..b549c8855 100644 --- a/core/java/src/net/i2p/crypto/HMACGenerator.java +++ b/core/java/src/net/i2p/crypto/HMACGenerator.java @@ -74,7 +74,7 @@ public class HMACGenerator { if ((key == null) || (key.getData() == null) || (curData == null)) throw new NullPointerException("Null arguments for HMAC"); - Mac mac = acquire(); + I2PHMac mac = acquire(); mac.init(key.getData()); mac.update(curData, curOffset, curLength); byte rv[] = acquireTmp(); From 2e5caac8bf7db01098dccf846166dd44b8f4d4af Mon Sep 17 00:00:00 2001 From: zzz Date: Fri, 3 Jul 2009 22:13:18 +0000 Subject: [PATCH 10/12] - Update to Android 1.5 SDK - Fix RouterContext problem --- android/AndroidManifest.xml | 2 + android/README.txt | 15 +- android/build.xml | 491 +++++++++++---------- android/default.properties | 11 + android/src/net/i2p/router/I2PAndroid.java | 11 +- 5 files changed, 290 insertions(+), 240 deletions(-) create mode 100644 android/default.properties diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index cb63a80c1..de77168d0 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -4,6 +4,8 @@ android:versionCode="1" android:versionName="1.0.0"> + + - - - - - - - + + - - - - - - + + - + - - - - - - + application-package + the name of your application package as defined in the manifest. Used by the + 'uninstall' rule. + source-folder + the name of the source folder. Default is 'src'. + out-folder + the name of the output folder. Default is 'bin'. - - - - + Properties related to the SDK location or the project target should be updated + using the 'android' tool with the 'update' action. - - - - - + This file is an integral part of the build system for your application and + should be checked in in Version Control Systems. - - + --> + - - - - - - + + - - - - - + + + + + + + + - - - - + - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - Creating output directories if needed... - - - - - - - - - - - - - - - - - Generating R.java / Manifest.java from the resources... - - - - - - - - - - - - - - - - - Compiling aidl files into Java classes... - - - - - - - - - - - - - - - - - + - + @@ -168,7 +79,7 @@ - + @@ -190,7 +101,7 @@ --> - + @@ -199,104 +110,199 @@ - + - - - Converting compiled files and external libraries into ${outdir}/${dex-file}... - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Creating output directories if needed... + + + + + + + + + + Generating R.java / Manifest.java from the resources... + + + + + + + + + + + + + + + + + Compiling aidl files into Java classes... + + + + + + + - - - Packaging resources and assets... - - - - - - - - - - - - - - + + + + + + + + + + + - - - Packaging resources... - - - - - - - - - - - - - + + + + Converting compiled files and external libraries into ${out-folder}/${dex-file}... + + + + + + + + - - - - - - + + + Packaging resources + - - Packaging ${out-debug-package}, and signing it with a debug key... - - - - - - - - - - - + This is the default target when building. It is used for debug. --> + + + + + + + - - Packaging ${out-unsigned-package} for release... - - - - - - - - - - - - - It will need to be signed with jarsigner before being published. + This allows for the application to be signed later with an official publishing key. --> + + + + + + + + All generated packages need to be signed with jarsigner before they are published. @@ -304,7 +310,7 @@ Installing ${out-debug-package} onto default emulator... - + @@ -313,7 +319,7 @@ - + @@ -322,8 +328,25 @@ Uninstalling ${application-package} from the default emulator... - + - + + + + Android Ant Build. Available targets: + help: Displays this help. + debug: Builds the application and sign it with a debug key. + release: Builds the application. The generated apk file must be + signed before it is published. + install: Installs the debug package onto a running emulator or + device. This can only be used if the application has + not yet been installed. + reinstall: Installs the debug package on a running emulator or + device that already has the application. + The signatures must match. + uninstall: uninstall the application from a running emulator or + device. + diff --git a/android/default.properties b/android/default.properties new file mode 100644 index 000000000..eba5c59ff --- /dev/null +++ b/android/default.properties @@ -0,0 +1,11 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-2 diff --git a/android/src/net/i2p/router/I2PAndroid.java b/android/src/net/i2p/router/I2PAndroid.java index 18a6e149a..ed626639c 100644 --- a/android/src/net/i2p/router/I2PAndroid.java +++ b/android/src/net/i2p/router/I2PAndroid.java @@ -10,10 +10,10 @@ import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.IOException; +import java.util.List; import net.i2p.router.Router; import net.i2p.router.RouterLaunch; -import net.i2p.router.web.ContextHelper; // import net.i2p.util.NativeBigInteger; public class I2PAndroid extends Activity @@ -66,8 +66,15 @@ public class I2PAndroid extends Activity { System.err.println("onStop called"); super.onStop(); + + // from routerconsole ContextHelper + List contexts = RouterContext.listContexts(); + if ( (contexts == null) || (contexts.size() <= 0) ) + throw new IllegalStateException("No contexts. This is usually because the router is either starting up or shutting down."); + RouterContext ctx = (RouterContext)contexts.get(0); + // shutdown() doesn't return so use shutdownGracefully() - ContextHelper.getContext(null).router().shutdownGracefully(Router.EXIT_HARD); + ctx.router().shutdownGracefully(Router.EXIT_HARD); System.err.println("shutdown complete"); } From 4e844187f735aa04bfe249ade9cc8e34d3ded756 Mon Sep 17 00:00:00 2001 From: zzz Date: Sun, 9 Aug 2009 15:34:26 +0000 Subject: [PATCH 11/12] revert another change from when this branch had reseed changes --- .../java/src/net/i2p/router/web/ContextHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ContextHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ContextHelper.java index 7d9b28e89..0aa250654 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ContextHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ContextHelper.java @@ -5,7 +5,7 @@ import java.util.List; import net.i2p.data.Hash; import net.i2p.router.RouterContext; -public class ContextHelper { +class ContextHelper { public static RouterContext getContext(String contextId) { List contexts = RouterContext.listContexts(); if ( (contexts == null) || (contexts.size() <= 0) ) From d1114666defb0564b5e3248061bc6684373cfa16 Mon Sep 17 00:00:00 2001 From: zzz Date: Tue, 11 Aug 2009 15:37:12 +0000 Subject: [PATCH 12/12] fix comment --- core/java/src/net/i2p/util/DecayingBloomFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/java/src/net/i2p/util/DecayingBloomFilter.java b/core/java/src/net/i2p/util/DecayingBloomFilter.java index 8c375a66d..95da0a03b 100644 --- a/core/java/src/net/i2p/util/DecayingBloomFilter.java +++ b/core/java/src/net/i2p/util/DecayingBloomFilter.java @@ -47,7 +47,7 @@ public class DecayingBloomFilter { _entryBytes = entryBytes; // this is instantiated in four different places, they may have different // requirements, but for now use this as a gross method of memory reduction. - // m == 23 => 2MB each BloomSHA1 (8MB total) + // m == 23 => 1MB each BloomSHA1 (4 pairs = 8MB total) int m = context.getProperty("router.decayingBloomFilterM", DEFAULT_M); _current = new BloomSHA1(m, 11); //new BloomSHA1(23, 11); _previous = new BloomSHA1(m, 11); //new BloomSHA1(23, 11);