diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java
index 338070af7c..13fad5ee91 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java
@@ -2574,6 +2574,9 @@ public void run() {
try { Thread.sleep(delay); } catch (InterruptedException ie) {}
// Remove that first message
_messages.clearThrough(id);
+ } else if (_context.isRouterContext()) {
+ // to wait for client manager to be up so we can get bandwidth limits
+ try { Thread.sleep(3000); } catch (InterruptedException ie) {}
}
// here because we need to delay until I2CP is up
diff --git a/apps/i2psnark/java/src/org/klomp/snark/dht/KRPC.java b/apps/i2psnark/java/src/org/klomp/snark/dht/KRPC.java
index 1cd378822f..ae3763994d 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/dht/KRPC.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/dht/KRPC.java
@@ -688,7 +688,7 @@ public void clear() {
public String renderStatusHTML() {
long uptime = Math.max(1000, _context.clock().now() - _started);
StringBuilder buf = new StringBuilder(256);
- buf.append("
DHT DEBUG
TX: ").append(_txPkts.get()).append(" pkts / ")
+ buf.append("
TX: ").append(_txPkts.get()).append(" pkts / ")
.append(DataHelper.formatSize2(_txBytes.get())).append("B / ")
.append(DataHelper.formatSize2Decimal(_txBytes.get() * 1000 / uptime)).append("Bps
" +
"RX: ").append(_rxPkts.get()).append(" pkts / ")
diff --git a/apps/i2psnark/resources/themes/dark/snark.css b/apps/i2psnark/resources/themes/dark/snark.css
index 7a2522332f..7491a0db5f 100644
--- a/apps/i2psnark/resources/themes/dark/snark.css
+++ b/apps/i2psnark/resources/themes/dark/snark.css
@@ -2177,10 +2177,6 @@ input#toggle_addtorrent:checked + label + hr + table, input#toggle_createtorrent
margin: -23px 0 -12px;
}
-.dhtDebug th b:first-of-type, .dhtDebug th b:first-of-type + br + hr.debug {
- display: none;
-}
-
input#toggle_debug:not(checked) + label {
padding-bottom: 2px;
}
diff --git a/apps/i2psnark/resources/themes/light/snark.css b/apps/i2psnark/resources/themes/light/snark.css
index 1bd4e4b2ff..fe70e7a213 100644
--- a/apps/i2psnark/resources/themes/light/snark.css
+++ b/apps/i2psnark/resources/themes/light/snark.css
@@ -1837,10 +1837,6 @@ input#toggle_addtorrent:checked + label + hr + table, input#toggle_createtorrent
margin: -19px 0 -12px;
}
-.dhtDebug th b:first-of-type, .dhtDebug th b:first-of-type + br + hr.debug {
- display: none;
-}
-
input#toggle_debug:not(checked) + label {
padding-bottom: 2px;
}
diff --git a/apps/i2psnark/resources/themes/ubergine/snark.css b/apps/i2psnark/resources/themes/ubergine/snark.css
index 8789cce143..a28bc97ea7 100644
--- a/apps/i2psnark/resources/themes/ubergine/snark.css
+++ b/apps/i2psnark/resources/themes/ubergine/snark.css
@@ -2304,10 +2304,6 @@ input#toggle_debug:not(checked) + label {
}
}
-.dhtDebug th b:first-of-type, .dhtDebug th b:first-of-type + br + hr.debug {
- display: none;
-}
-
input#toggle_debug:not(checked) + label {
padding-bottom: 2px;
}
diff --git a/apps/i2psnark/resources/themes/vanilla/snark.css b/apps/i2psnark/resources/themes/vanilla/snark.css
index 88bc14d54d..1d612a33bd 100644
--- a/apps/i2psnark/resources/themes/vanilla/snark.css
+++ b/apps/i2psnark/resources/themes/vanilla/snark.css
@@ -2152,10 +2152,6 @@ hr.debug:last-child {
border-radius: 0 0 2px 2px;
}
-.dhtDebug th b:first-of-type, .dhtDebug th b:first-of-type + br + hr.debug {
- display: none;
-}
-
/* toggle debug view */
input#toggle_debug:not(checked) + label {
diff --git a/installer/resources/checklist.md b/installer/resources/checklist.md
index 777ee7b84c..667ea79b53 100644
--- a/installer/resources/checklist.md
+++ b/installer/resources/checklist.md
@@ -124,7 +124,7 @@
- `core/java/src/net/i2p/CoreVersion.java`
- (both VERSION and PUBLISHED_VERSION)
- `router/java/src/net/i2p/router/RouterVersion.java`
- - (change to BUILD = 0 and EXTRA = "")
+ - (change to BUILD = 0 and EXTRA = "" and QUALIFIER = "")
8. `git commit`
diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java
index dbc7575100..ef2c125062 100644
--- a/router/java/src/net/i2p/router/RouterVersion.java
+++ b/router/java/src/net/i2p/router/RouterVersion.java
@@ -20,7 +20,7 @@ public class RouterVersion {
public final static String VERSION = CoreVersion.VERSION;
/** for example: "beta", "alpha", "rc" */
public final static String QUALIFIER = "-rc";
- public final static long BUILD = 14;
+ public final static long BUILD = 15;
/** for example "-test" */
public final static String EXTRA = "";
public final static String FULL_VERSION = VERSION + "-" + BUILD + QUALIFIER + EXTRA;
diff --git a/router/java/src/net/i2p/router/tunnel/InboundMessageDistributor.java b/router/java/src/net/i2p/router/tunnel/InboundMessageDistributor.java
index f015a9a324..ca4c317620 100644
--- a/router/java/src/net/i2p/router/tunnel/InboundMessageDistributor.java
+++ b/router/java/src/net/i2p/router/tunnel/InboundMessageDistributor.java
@@ -198,12 +198,9 @@ public void distribute(I2NPMessage msg, Hash target, TunnelId tunnel) {
} // switch
} // client != null
- if ( (target == null) && (tunnel == null) ) {
- // Since the InboundMessageDistributor handles messages for the endpoint,
- // most messages that arrive here have both target==null and tunnel==null.
- // Messages with targeting instructions need careful handling, and will
- // typically be dropped because we're the endpoint. Especially when they
- // specifically target this router (_context.routerHash().equals(target)).
+ if ( (target == null) || ( (tunnel == null) && (_context.routerHash().equals(target) ) ) ) {
+ // targetting us either implicitly (no target) or explicitly (no tunnel)
+ // make sure we don't honor any remote requests directly (garlic instructions, etc)
if (type == GarlicMessage.MESSAGE_TYPE) {
// in case we're looking for replies to a garlic message (cough load tests cough)
_context.inNetMessagePool().handleReplies(msg);
@@ -212,40 +209,47 @@ public void distribute(I2NPMessage msg, Hash target, TunnelId tunnel) {
_receiver.receive((GarlicMessage)msg);
} else {
if (_log.shouldLog(Log.INFO))
- _log.info("distributing inbound tunnel message into our inNetMessagePool"
- + " (for client " + _clientNickname + " ("
- + ((_client != null) ? _client.toBase32() : "null")
- + ") to target=NULL/tunnel=NULL " + msg);
- _context.inNetMessagePool().add(msg, null, null, _msgIDBloomXor);
+ _log.info("distributing inbound tunnel message into our inNetMessagePool: " + msg);
+ _context.inNetMessagePool().add(msg, null, null);
}
+/****** latency measuring attack?
} else if (_context.routerHash().equals(target)) {
- if (type == GarlicMessage.MESSAGE_TYPE)
- if (_log.shouldLog(Log.WARN))
- _log.warn("Dropping inbound garlic message TARGETED TO OUR ROUTER for client "
- + _clientNickname + " ("
- + ((_client != null) ? _client.toBase32() : "null")
- + ") to " + target + " / " + tunnel);
- else
- if (_log.shouldLog(Log.WARN))
- _log.warn("Dropping inbound message TARGETED TO OUR ROUTER for client "
- + _clientNickname + " (" + ((_client != null) ? _client.toBase32() : "null")
- + ") to " + target + " / " + tunnel + " : " + msg);
- return;
+ // the want to send it to a tunnel, except we are also that tunnel's gateway
+ // dispatch it directly
+ if (_log.shouldLog(Log.INFO))
+ _log.info("distributing inbound tunnel message back out, except we are the gateway");
+ TunnelGatewayMessage gw = new TunnelGatewayMessage(_context);
+ gw.setMessage(msg);
+ gw.setTunnelId(tunnel);
+ gw.setMessageExpiration(_context.clock().now()+10*1000);
+ gw.setUniqueId(_context.random().nextLong(I2NPMessage.MAX_ID_VALUE));
+ _context.tunnelDispatcher().dispatch(gw);
+******/
} else {
- if (type == GarlicMessage.MESSAGE_TYPE)
+ // ok, they want us to send it remotely, but that'd bust our anonymity,
+ // so we send it out a tunnel first
+ // TODO use the OCMOSJ cache to pick OB tunnel we are already using?
+ TunnelInfo out = _context.tunnelManager().selectOutboundTunnel(_client, target);
+ if (out == null) {
if (_log.shouldLog(Log.WARN))
- _log.warn("Dropping targeted inbound garlic message for client "
- + _clientNickname + " ("
- + ((_client != null) ? _client.toBase32() : "null")
- + ") to " + target + " / " + tunnel);
- else
- if (_log.shouldLog(Log.WARN))
- _log.warn("Dropping targeted inbound message for client " + _clientNickname
- + " (" + ((_client != null) ? _client.toBase32() : "null")
- + " to " + target + " / " + tunnel + " : " + msg);
- return;
+ _log.warn("no outbound tunnel to send the client message for " + _client + ": " + msg);
+ return;
+ }
+ if (_log.shouldLog(Log.DEBUG))
+ _log.debug("distributing IB tunnel msg type " + type + " back out " + out
+ + " targetting " + target);
+ TunnelId outId = out.getSendTunnelId(0);
+ if (outId == null) {
+ if (_log.shouldLog(Log.ERROR))
+ _log.error("strange? outbound tunnel has no outboundId? " + out
+ + " failing to distribute " + msg);
+ return;
+ }
+ long exp = _context.clock().now() + 20*1000;
+ if (msg.getMessageExpiration() < exp)
+ msg.setMessageExpiration(exp);
+ _context.tunnelDispatcher().dispatchOutbound(msg, outId, tunnel, target);
}
-
}
/**