diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelConnectClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelConnectClient.java
index 9e102aa98..13906807e 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelConnectClient.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelConnectClient.java
@@ -156,6 +156,12 @@ public class I2PTunnelConnectClient extends I2PTunnelClientBase implements Runna
defaultOpts.setProperty(I2PSocketOptions.PROP_READ_TIMEOUT, ""+DEFAULT_READ_TIMEOUT);
if (!defaultOpts.contains("i2p.streaming.inactivityTimeout"))
defaultOpts.setProperty("i2p.streaming.inactivityTimeout", ""+DEFAULT_READ_TIMEOUT);
+ // delayed start
+ if (sockMgr == null) {
+ synchronized(sockLock) {
+ sockMgr = getSocketManager();
+ }
+ }
I2PSocketOptions opts = sockMgr.buildOptions(defaultOpts);
if (!defaultOpts.containsKey(I2PSocketOptions.PROP_CONNECT_TIMEOUT))
opts.setConnectTimeout(DEFAULT_CONNECT_TIMEOUT);
diff --git a/apps/routerconsole/jsp/logs.jsp b/apps/routerconsole/jsp/logs.jsp
index dbaca0403..374a2ed8b 100644
--- a/apps/routerconsole/jsp/logs.jsp
+++ b/apps/routerconsole/jsp/logs.jsp
@@ -23,12 +23,12 @@ jbigi <%=net.i2p.util.NativeBigInteger.loadStatus()%>
" />
- Router logs:
-
-
Critical logs:
+ Router logs:
+
+
Service (Wrapper) logs:
diff --git a/history.txt b/history.txt
index 3f236597f..37533d996 100644
--- a/history.txt
+++ b/history.txt
@@ -1,5 +1,12 @@
+2009-05-11 zzz
+ * Connect client: Fix NPE when used with advanced i2ptunnel features
+ * Context: Don't instantiate unused AdminManager
+ * logs.jsp: Put critical log at the top
+ * NetDb: Don't accept stores of our own LeaseSets or RouterInfo
+
2009-05-11 mkvore
* SAM: fix: removed ERROR level logging when a client disconnects
+
2009-05-09 sponge
* merge
@@ -14,6 +21,7 @@
2009-05-07 mkvore
* SAM: version 3 added
* SAM: blocking case corrected on simultaneous client connection (v.1-3)
+
2009-05-07 zzz
* Add nibble.i2p to proxy list and hosts.txt
diff --git a/installer/resources/clients.config b/installer/resources/clients.config
index 170f4c8fe..88bba5f9a 100644
--- a/installer/resources/clients.config
+++ b/installer/resources/clients.config
@@ -1,32 +1,32 @@
# fire up the web console
clientApp.0.args=7657 ::1,127.0.0.1 ./webapps/
clientApp.0.main=net.i2p.router.web.RouterConsoleRunner
-clientApp.0.name=webConsole
+clientApp.0.name=Web console
clientApp.0.onBoot=true
clientApp.0.startOnLoad=true
# SAM bridge
clientApp.1.main=net.i2p.sam.SAMBridge
-clientApp.1.name=SAMBridge
+clientApp.1.name=SAM application bridge
clientApp.1.args=sam.keys 127.0.0.1 7656 i2cp.tcp.host=127.0.0.1 i2cp.tcp.port=7654
clientApp.1.startOnLoad=false
# poke the i2ptunnels defined in i2ptunnel.config
clientApp.2.main=net.i2p.i2ptunnel.TunnelControllerGroup
-clientApp.2.name=Tunnels
+clientApp.2.name=Application tunnels
clientApp.2.args=i2ptunnel.config
clientApp.2.startOnLoad=true
# run our own eepsite with a seperate jetty instance
clientApp.3.main=org.mortbay.jetty.Server
-clientApp.3.name=eepsite
+clientApp.3.name=My eepsite web server
clientApp.3.args=eepsite/jetty.xml
clientApp.3.delay=30
clientApp.3.startOnLoad=true
# load a browser pointing at the web console whenever we start up
clientApp.4.main=net.i2p.apps.systray.UrlLauncher
-clientApp.4.name=consoleBrowser
+clientApp.4.name=Browser launch at startup
clientApp.4.args=http://127.0.0.1:7657/index.jsp
clientApp.4.delay=15
clientApp.4.startOnLoad=true
@@ -35,5 +35,5 @@ clientApp.4.startOnLoad=true
clientApp.5.args=
clientApp.5.delay=10
clientApp.5.main=net.i2p.BOB.BOB
-clientApp.5.name=BOB
+clientApp.5.name=BOB application bridge
clientApp.5.startOnLoad=false
diff --git a/router/java/src/net/i2p/router/RouterContext.java b/router/java/src/net/i2p/router/RouterContext.java
index 782bc8a87..719224058 100644
--- a/router/java/src/net/i2p/router/RouterContext.java
+++ b/router/java/src/net/i2p/router/RouterContext.java
@@ -87,7 +87,7 @@ public class RouterContext extends I2PAppContext {
return envProps;
}
private void initAll() {
- _adminManager = new AdminManager(this);
+ //_adminManager = new AdminManager(this);
if ("false".equals(getProperty("i2p.dummyClientFacade", "false")))
_clientManagerFacade = new ClientManagerFacadeImpl(this);
else
diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java
index c0f2d3825..d06a930a7 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 = 12;
+ public final static long BUILD = 13;
/** for example "-test" */
public final static String EXTRA = "";
public final static String FULL_VERSION = VERSION + "-" + BUILD + EXTRA;
diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillVerifyStoreJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillVerifyStoreJob.java
index 0e5829b24..d541f781f 100644
--- a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillVerifyStoreJob.java
+++ b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillVerifyStoreJob.java
@@ -100,16 +100,10 @@ public class FloodfillVerifyStoreJob extends JobImpl {
public boolean isMatch(I2NPMessage message) {
if (message instanceof DatabaseStoreMessage) {
DatabaseStoreMessage dsm = (DatabaseStoreMessage)message;
- if (_key.equals(dsm.getKey()))
- return true;
- else
- return false;
+ return _key.equals(dsm.getKey());
} else if (message instanceof DatabaseSearchReplyMessage) {
DatabaseSearchReplyMessage dsrm = (DatabaseSearchReplyMessage)message;
- if (_key.equals(dsrm.getSearchKey()))
- return true;
- else
- return false;
+ return _key.equals(dsrm.getSearchKey());
}
return false;
}
diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/HandleFloodfillDatabaseStoreMessageJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/HandleFloodfillDatabaseStoreMessageJob.java
index 505638ecb..2c3cdbe4e 100644
--- a/router/java/src/net/i2p/router/networkdb/kademlia/HandleFloodfillDatabaseStoreMessageJob.java
+++ b/router/java/src/net/i2p/router/networkdb/kademlia/HandleFloodfillDatabaseStoreMessageJob.java
@@ -41,6 +41,8 @@ public class HandleFloodfillDatabaseStoreMessageJob extends JobImpl {
_log = ctx.logManager().getLog(getClass());
ctx.statManager().createRateStat("netDb.storeHandled", "How many netDb store messages have we handled?", "NetworkDatabase", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
ctx.statManager().createRateStat("netDb.storeLeaseSetHandled", "How many leaseSet store messages have we handled?", "NetworkDatabase", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
+ //ctx.statManager().createRateStat("netDb.storeLocalLeaseSetAttempt", "Peer tries to store our leaseset (multihome?)", "NetworkDatabase", new long[] { 60*60*1000l });
+ //ctx.statManager().createRateStat("netDb.storeLocalRouterInfoAttempt", "Peer tries to store our router info", "NetworkDatabase", new long[] { 60*60*1000l });
ctx.statManager().createRateStat("netDb.storeRouterInfoHandled", "How many routerInfo store messages have we handled?", "NetworkDatabase", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
ctx.statManager().createRateStat("netDb.storeRecvTime", "How long it takes to handle the local store part of a dbStore?", "NetworkDatabase", new long[] { 60*1000l, 10*60*1000l });
ctx.statManager().createRateStat("netDb.storeFloodNew", "How long it takes to flood out a newly received entry?", "NetworkDatabase", new long[] { 60*1000l, 10*60*1000l });
@@ -64,6 +66,18 @@ public class HandleFloodfillDatabaseStoreMessageJob extends JobImpl {
getContext().statManager().addRateData("netDb.storeLeaseSetHandled", 1, 0);
try {
+ // Never store a leaseSet for a local dest received from somebody else.
+ // This generally happens from a FloodfillVerifyStoreJob.
+ // If it is valid, it shouldn't be newer than what we have - unless
+ // somebody has our keys...
+ // This could happen with multihoming - where it's really important to prevent
+ // storing the other guy's leaseset, it will confuse us badly.
+ if (getContext().clientManager().isLocal(_message.getKey())) {
+ //getContext().statManager().addRateData("netDb.storeLocalLeaseSetAttempt", 1, 0);
+ // throw rather than return, so that we send the ack below (prevent easy attack)
+ throw new IllegalArgumentException("Peer attempted to store local leaseSet: " +
+ _message.getKey().toBase64().substring(0, 4));
+ }
LeaseSet ls = _message.getLeaseSet();
// mark it as something we received, so we'll answer queries
// for it. this flag does NOT get set on entries that we
@@ -86,6 +100,15 @@ public class HandleFloodfillDatabaseStoreMessageJob extends JobImpl {
_log.info("Handling dbStore of router " + key + " with publishDate of "
+ new Date(_message.getRouterInfo().getPublished()));
try {
+ // Never store our RouterInfo received from somebody else.
+ // This generally happens from a FloodfillVerifyStoreJob.
+ // If it is valid, it shouldn't be newer than what we have - unless
+ // somebody has our keys...
+ if (getContext().routerHash().equals(key)) {
+ //getContext().statManager().addRateData("netDb.storeLocalRouterInfoAttempt", 1, 0);
+ // throw rather than return, so that we send the ack below (prevent easy attack)
+ throw new IllegalArgumentException("Peer attempted to store our RouterInfo");
+ }
prevNetDb = getContext().netDb().store(key, _message.getRouterInfo());
wasNew = ((null == prevNetDb) || (prevNetDb.getPublished() < _message.getRouterInfo().getPublished()));
// Check new routerinfo address against blocklist
@@ -146,9 +169,13 @@ public class HandleFloodfillDatabaseStoreMessageJob extends JobImpl {
}
} else {
+ // Should we record in the profile?
if (_log.shouldLog(Log.WARN))
_log.warn("Peer " + _fromHash.toBase64() + " sent bad data: " + invalidMessage);
}
+ } else if (invalidMessage != null) {
+ if (_log.shouldLog(Log.WARN))
+ _log.warn("Unknown peer sent bad data: " + invalidMessage);
}
}