diff --git a/history.txt b/history.txt
index 1279ffe7da..afce958517 100644
--- a/history.txt
+++ b/history.txt
@@ -1,3 +1,15 @@
+2008-04-16 zzz
+ * SSU/Reachability:
+ - Extend shitlist time from 4-8m to 40-60m
+ - Add some shitlist logging
+ - Don't shitlist twice when unreachable on all transports
+ - Exclude netDb-listed unreachable peers from inbound tunnels;
+ this won't help much since there are very few of these now
+ - Remove 10s delay on inbound UDP connections used for the
+ 0.6.1.10 transition
+ - Track and display UDP connection direction on peers.jsp
+ - Show shitlist status in-line on profiles.jsp
+
2008-04-15 zzz
* SSU Reachability/PeerTestManager:
- Back out strict peer ordering until we fix SSU
diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java
index b4c410afba..1bdcecca63 100644
--- a/router/java/src/net/i2p/router/RouterVersion.java
+++ b/router/java/src/net/i2p/router/RouterVersion.java
@@ -17,7 +17,7 @@ import net.i2p.CoreVersion;
public class RouterVersion {
public final static String ID = "$Revision: 1.548 $ $Date: 2008-02-10 15:00:00 $";
public final static String VERSION = "0.6.1.32";
- public final static long BUILD = 17;
+ public final static long BUILD = 18;
public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
System.out.println("Router ID: " + RouterVersion.ID);
diff --git a/router/java/src/net/i2p/router/Shitlist.java b/router/java/src/net/i2p/router/Shitlist.java
index 80febdeea7..43c24a2e66 100644
--- a/router/java/src/net/i2p/router/Shitlist.java
+++ b/router/java/src/net/i2p/router/Shitlist.java
@@ -37,7 +37,7 @@ public class Shitlist {
Set transports;
}
- public final static long SHITLIST_DURATION_MS = 4*60*1000; // 4 minute shitlist
+ public final static long SHITLIST_DURATION_MS = 40*60*1000; // 40 minute shitlist
public Shitlist(RouterContext context) {
_context = context;
@@ -72,6 +72,8 @@ public class Shitlist {
if (prof != null)
prof.unshitlist();
_context.messageHistory().unshitlist(peer);
+ if (_log.shouldLog(Log.INFO))
+ _log.info("Unshitlisting router (expired) " + peer.toBase64());
}
requeue(30*1000);
@@ -152,12 +154,13 @@ public class Shitlist {
public void unshitlistRouter(Hash peer, String transport) { unshitlistRouter(peer, true, transport); }
private void unshitlistRouter(Hash peer, boolean realUnshitlist, String transport) {
if (peer == null) return;
- if (_log.shouldLog(Log.INFO))
- _log.info("Unshitlisting router " + peer.toBase64()
+ if (_log.shouldLog(Log.DEBUG))
+ _log.debug("Calling unshitlistRouter " + peer.toBase64()
+ (transport != null ? "/" + transport : ""));
boolean fully = false;
+ Entry e;
synchronized (_entries) {
- Entry e = (Entry)_entries.remove(peer);
+ e = (Entry)_entries.remove(peer);
if ( (e == null) || (e.transports == null) || (transport == null) || (e.transports.size() <= 1) ) {
// fully unshitlisted
fully = true;
@@ -176,6 +179,9 @@ public class Shitlist {
prof.unshitlist();
}
_context.messageHistory().unshitlist(peer);
+ if (_log.shouldLog(Log.INFO) && e != null)
+ _log.info("Unshitlisting router " + peer.toBase64()
+ + (transport != null ? "/" + transport : ""));
}
}
@@ -209,6 +215,8 @@ public class Shitlist {
if (prof != null)
prof.unshitlist();
_context.messageHistory().unshitlist(peer);
+ if (_log.shouldLog(Log.INFO))
+ _log.info("Unshitlisting router (expired) " + peer.toBase64());
}
return rv;
diff --git a/router/java/src/net/i2p/router/peermanager/ProfileOrganizerRenderer.java b/router/java/src/net/i2p/router/peermanager/ProfileOrganizerRenderer.java
index 5b1af57a7d..ebc87f0608 100644
--- a/router/java/src/net/i2p/router/peermanager/ProfileOrganizerRenderer.java
+++ b/router/java/src/net/i2p/router/peermanager/ProfileOrganizerRenderer.java
@@ -134,7 +134,10 @@ class ProfileOrganizerRenderer {
buf.append("");
buf.append("
").append(num(prof.getCapacityValue())).append(" | ");
buf.append("").append(num(prof.getIntegrationValue())).append(" | ");
- buf.append("").append(prof.getIsFailing()).append(" | ");
+ buf.append("");
+ if (_context.shitlist().isShitlisted(peer)) buf.append("Shitlist");
+ if (prof.getIsFailing()) buf.append(" Failing");
+ buf.append("  | ");
//buf.append("profile.txt ");
//buf.append(" netDb | ");
buf.append("netDb");
diff --git a/router/java/src/net/i2p/router/transport/TransportManager.java b/router/java/src/net/i2p/router/transport/TransportManager.java
index 0d29bb87bb..bc622db4c5 100644
--- a/router/java/src/net/i2p/router/transport/TransportManager.java
+++ b/router/java/src/net/i2p/router/transport/TransportManager.java
@@ -259,6 +259,9 @@ public class TransportManager implements TransportEventListener {
Transport t = (Transport)_transports.get(i);
if (t.isUnreachable(peer)) {
unreachableTransports++;
+ // this keeps GetBids() from shitlisting for "no common transports"
+ // right after we shitlisted for "unreachable on any transport" below...
+ msg.transportFailed(t.getStyle());
continue;
}
if (failedTransports.contains(t.getStyle())) {
diff --git a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java
index a6f9d13b75..5e46476e76 100644
--- a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java
+++ b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java
@@ -431,6 +431,7 @@ public class EstablishmentManager {
peer.setRemotePeer(remote.calculateHash());
peer.setWeRelayToThemAs(state.getSentRelayTag());
peer.setTheyRelayToUsAs(0);
+ peer.setInbound();
if (_log.shouldLog(Log.DEBUG))
_log.debug("Handle completely established (inbound): " + state.getRemoteHostId().toString()
@@ -451,9 +452,16 @@ public class EstablishmentManager {
* dont send our info immediately, just send a small data packet, and 5-10s later,
* if the peer isnt shitlisted, *then* send them our info. this will help kick off
* the oldnet
+ * The "oldnet" was < 0.6.1.10, it is long gone.
+ * The delay really slows down the network.
+ * The peer is unshitlisted and marked reachable by addRemotePeerState() which calls markReachable()
+ * so the check below is fairly pointless.
+ * If for some strange reason an oldnet router (NETWORK_ID == 1) does show up,
+ * it's handled in UDPTransport.messageReceived()
+ * (where it will get dropped, marked unreachable and shitlisted at that time).
*/
private void sendInboundComplete(PeerState peer) {
- SimpleTimer.getInstance().addEvent(new PublishToNewInbound(peer), 10*1000);
+ // SimpleTimer.getInstance().addEvent(new PublishToNewInbound(peer), 10*1000);
if (_log.shouldLog(Log.INFO))
_log.info("Completing to the peer after confirm: " + peer);
DeliveryStatusMessage dsm = new DeliveryStatusMessage(_context);
@@ -461,6 +469,7 @@ public class EstablishmentManager {
dsm.setMessageExpiration(_context.clock().now()+10*1000);
dsm.setMessageId(_context.random().nextLong(I2NPMessage.MAX_ID_VALUE));
_transport.send(dsm, peer);
+ SimpleTimer.getInstance().addEvent(new PublishToNewInbound(peer), 0);
}
private class PublishToNewInbound implements SimpleTimer.TimedEvent {
private PeerState _peer;
diff --git a/router/java/src/net/i2p/router/transport/udp/PeerState.java b/router/java/src/net/i2p/router/transport/udp/PeerState.java
index 53ab46e458..7aaff0ac99 100644
--- a/router/java/src/net/i2p/router/transport/udp/PeerState.java
+++ b/router/java/src/net/i2p/router/transport/udp/PeerState.java
@@ -190,7 +190,9 @@ public class PeerState {
private volatile int _concurrentMessagesActive = 0;
/** how many concurrency rejections have we had in a row */
private volatile int _consecutiveRejections = 0;
-
+ /** is it inbound? **/
+ private boolean _isInbound;
+
private static final int DEFAULT_SEND_WINDOW_BYTES = 8*1024;
private static final int MINIMUM_WINDOW_BYTES = DEFAULT_SEND_WINDOW_BYTES;
private static final int MAX_SEND_WINDOW_BYTES = 1024*1024;
@@ -268,6 +270,7 @@ public class PeerState {
_inboundMessages = new HashMap(8);
_outboundMessages = new ArrayList(32);
_dead = false;
+ _isInbound = false;
_context.statManager().createRateStat("udp.congestionOccurred", "How large the cwin was when congestion occurred (duration == sendBps)", "udp", new long[] { 60*1000, 10*60*1000, 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("udp.congestedRTO", "retransmission timeout after congestion (duration == rtt dev)", "udp", new long[] { 60*1000, 10*60*1000, 60*60*1000, 24*60*60*1000 });
_context.statManager().createRateStat("udp.sendACKPartial", "Number of partial ACKs sent (duration == number of full ACKs in that ack packet)", "udp", new long[] { 60*1000, 10*60*1000, 60*60*1000, 24*60*60*1000 });
@@ -553,6 +556,8 @@ public class PeerState {
public int getConcurrentSends() { return _concurrentMessagesActive; }
public int getConcurrentSendWindow() { return _concurrentMessagesAllowed; }
public int getConsecutiveSendRejections() { return _consecutiveRejections; }
+ public boolean isInbound() { return _isInbound; }
+ public void setInbound() { _isInbound = true; }
/** we received the message specified completely */
public void messageFullyReceived(Long messageId, int bytes) { messageFullyReceived(messageId, bytes, false); }
diff --git a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java
index 38f6ee7d30..77c1e3b7cd 100644
--- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java
+++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java
@@ -625,6 +625,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
}
}
markUnreachable(peerHash);
+ _context.shitlist().shitlistRouter(peerHash, "Part of the wrong network");
//_context.shitlist().shitlistRouter(peerHash, "Part of the wrong network", STYLE);
dropPeer(peerHash, false, "wrong network");
if (_log.shouldLog(Log.WARN))
@@ -1673,14 +1674,16 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
buf.append(port);
*/
buf.append(" ");
+ if (peer.isInbound())
+ buf.append("> ");
+ else
+ buf.append("< ");
if (peer.getWeRelayToThemAs() > 0)
- buf.append(">");
+ buf.append("^");
else
buf.append(" ");
if (peer.getTheyRelayToUsAs() > 0)
- buf.append("<");
- else
- buf.append(" ");
+ buf.append("v");
boolean appended = false;
if (_activeThrottle.isChoked(peer.getRemotePeer())) {
@@ -1872,7 +1875,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
}
private static final String KEY = " | " +
- "peer: the remote peer (< means they offer to introduce us, > means we offer to introduce them) \n" +
+ "peer: the remote peer (< inbound, > outbound, v means they offer to introduce us, ^ means we offer to introduce them) \n" +
"idle: the idle time is how long since a packet has been received or sent \n" +
"in/out: the rates show a smoothed inbound and outbound transfer rate (KBytes per second) \n" +
"up: the uptime is how long ago this session was established \n" +
diff --git a/router/java/src/net/i2p/router/tunnel/pool/TunnelPeerSelector.java b/router/java/src/net/i2p/router/tunnel/pool/TunnelPeerSelector.java
index 3d4a0b9a5c..97a1299785 100644
--- a/router/java/src/net/i2p/router/tunnel/pool/TunnelPeerSelector.java
+++ b/router/java/src/net/i2p/router/tunnel/pool/TunnelPeerSelector.java
@@ -152,16 +152,26 @@ public abstract class TunnelPeerSelector {
// isn't safe, since they may publish one set of routerInfo to us and another to
// other peers. the defaults for filterUnreachable has always been to return false,
// but might as well make it explicit with a "false &&"
-
- if (false && filterUnreachable(ctx, isInbound, isExploratory)) {
+ //
+ // Unreachable peers at the inbound gateway is a major cause of problems.
+ // Due to a bug in SSU peer testing in 0.6.1.32 and earlier, peers don't know
+ // if they are unreachable, so this won't help much. As of 0.6.1.33 we should have
+ // lots of unreachables, so enable this for now.
+ // We could just try and exclude them as the inbound gateway but that's harder
+ // (and even worse for anonymity?).
+ //
+ // Defaults changed to true for inbound only in filterUnreachable below.
+
+ Set peers = new HashSet(1);
+ // if (false && filterUnreachable(ctx, isInbound, isExploratory)) {
+ if (filterUnreachable(ctx, isInbound, isExploratory)) {
List caps = ctx.peerManager().getPeersByCapability(Router.CAPABILITY_UNREACHABLE);
- if (caps == null) return new HashSet(0);
- HashSet rv = new HashSet(caps);
- return rv;
- } else if (filterSlow(ctx, isInbound, isExploratory)) {
+ if (caps != null)
+ peers.addAll(caps);
+ }
+ if (filterSlow(ctx, isInbound, isExploratory)) {
Log log = ctx.logManager().getLog(TunnelPeerSelector.class);
char excl[] = getExcludeCaps(ctx);
- Set peers = new HashSet(1);
if (excl != null) {
FloodfillNetworkDatabaseFacade fac = (FloodfillNetworkDatabaseFacade)ctx.netDb();
List known = fac.getKnownRouterData();
@@ -268,10 +278,8 @@ public abstract class TunnelPeerSelector {
}
*/
}
- return peers;
- } else {
- return new HashSet(1);
}
+ return peers;
}
public static boolean shouldExclude(RouterContext ctx, RouterInfo peer) {
@@ -375,10 +383,11 @@ public abstract class TunnelPeerSelector {
private static final String PROP_INBOUND_EXPLORATORY_EXCLUDE_UNREACHABLE = "router.inboundExploratoryExcludeUnreachable";
private static final String PROP_INBOUND_CLIENT_EXCLUDE_UNREACHABLE = "router.inboundClientExcludeUnreachable";
- private static final boolean DEFAULT_OUTBOUND_EXPLORATORY_EXCLUDE_UNREACHABLE = false;
- private static final boolean DEFAULT_OUTBOUND_CLIENT_EXCLUDE_UNREACHABLE = false;
- private static final boolean DEFAULT_INBOUND_EXPLORATORY_EXCLUDE_UNREACHABLE = false;
- private static final boolean DEFAULT_INBOUND_CLIENT_EXCLUDE_UNREACHABLE = false;
+ private static final String DEFAULT_OUTBOUND_EXPLORATORY_EXCLUDE_UNREACHABLE = "false";
+ private static final String DEFAULT_OUTBOUND_CLIENT_EXCLUDE_UNREACHABLE = "false";
+ // see comments at getExclude() above
+ private static final String DEFAULT_INBOUND_EXPLORATORY_EXCLUDE_UNREACHABLE = "true";
+ private static final String DEFAULT_INBOUND_CLIENT_EXCLUDE_UNREACHABLE = "true";
protected boolean filterUnreachable(RouterContext ctx, boolean isInbound, boolean isExploratory) {
boolean def = false;
@@ -386,14 +395,14 @@ public abstract class TunnelPeerSelector {
if (isExploratory)
if (isInbound)
- val = ctx.getProperty(PROP_INBOUND_EXPLORATORY_EXCLUDE_UNREACHABLE);
+ val = ctx.getProperty(PROP_INBOUND_EXPLORATORY_EXCLUDE_UNREACHABLE, DEFAULT_INBOUND_EXPLORATORY_EXCLUDE_UNREACHABLE);
else
- val = ctx.getProperty(PROP_OUTBOUND_EXPLORATORY_EXCLUDE_UNREACHABLE);
+ val = ctx.getProperty(PROP_OUTBOUND_EXPLORATORY_EXCLUDE_UNREACHABLE, DEFAULT_OUTBOUND_EXPLORATORY_EXCLUDE_UNREACHABLE);
else
if (isInbound)
- val = ctx.getProperty(PROP_INBOUND_CLIENT_EXCLUDE_UNREACHABLE);
+ val = ctx.getProperty(PROP_INBOUND_CLIENT_EXCLUDE_UNREACHABLE, DEFAULT_INBOUND_CLIENT_EXCLUDE_UNREACHABLE);
else
- val = ctx.getProperty(PROP_OUTBOUND_CLIENT_EXCLUDE_UNREACHABLE);
+ val = ctx.getProperty(PROP_OUTBOUND_CLIENT_EXCLUDE_UNREACHABLE, DEFAULT_OUTBOUND_CLIENT_EXCLUDE_UNREACHABLE);
boolean rv = (val != null ? Boolean.valueOf(val).booleanValue() : def);
//System.err.println("Filter unreachable? " + rv + " (inbound? " + isInbound + ", exploratory? " + isExploratory);
|