* Reintroduce NTCP backlog pushback, with switch back to

previous tunnel when no longer backlogged
    * Catch an nio exception in an NTCP logging statement if loglevel is WARN
    * IRC Proxy: terminate all messages with \r\n (thanks TrivialPursuit!)
This commit is contained in:
zzz
2008-02-26 19:33:11 +00:00
parent bc7ab39131
commit bc7bd628db
5 changed files with 70 additions and 19 deletions

View File

@ -164,7 +164,7 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
if (_log.shouldLog(Log.INFO))
_log.info("inbound: "+outmsg);
}
outmsg=outmsg+"\n";
outmsg=outmsg+"\r\n"; // rfc1459 sec. 2.3
output.write(outmsg.getBytes("ISO-8859-1"));
} else {
if (_log.shouldLog(Log.WARN))
@ -238,7 +238,7 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
if (_log.shouldLog(Log.INFO))
_log.info("outbound: "+outmsg);
}
outmsg=outmsg+"\n";
outmsg=outmsg+"\r\n"; // rfc1459 sec. 2.3
output.write(outmsg.getBytes("ISO-8859-1"));
} else {
if (_log.shouldLog(Log.WARN))

View File

@ -1,3 +1,9 @@
2008-02-26 zzz
* Reintroduce NTCP backlog pushback, with switch back to
previous tunnel when no longer backlogged
* Catch an nio exception in an NTCP logging statement if loglevel is WARN
* IRC Proxy: terminate all messages with \r\n (thanks TrivialPursuit!)
2008-02-21 zzz
* Raise inbound default bandwidth to 32KBps
* Fix config.jsp that showed 0KBps share bandwidth by default

View File

@ -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.31";
public final static long BUILD = 6;
public final static long BUILD = 7;
public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
System.out.println("Router ID: " + RouterVersion.ID);

View File

@ -255,6 +255,9 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
return false;
}
// Right here is where we should use a persistent lease and caching like
// we do for outbound tunnel selection below???
// randomize the ordering (so leases with equal # of failures per next
// sort are randomly ordered)
Collections.shuffle(leases);
@ -435,39 +438,79 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
}
}
/**
* Clean out old tunnels from a set.
* Caller must synchronize on tc.
*/
private void cleanTunnelCache(HashMap tc) {
List deleteList = new ArrayList();
for (Iterator iter = tc.keySet().iterator(); iter.hasNext(); ) {
Destination dest = (Destination) iter.next();
TunnelInfo tunnel = (TunnelInfo) tc.get(dest);
if (!getContext().tunnelManager().isValidTunnel(_from.calculateHash(), tunnel))
deleteList.add(dest);
}
for (Iterator iter = deleteList.iterator(); iter.hasNext(); ) {
Destination dest = (Destination) iter.next();
tc.remove(dest);
}
}
/**
* Use the same outbound tunnel as we did for the same destination previously,
* if possible, to keep the streaming lib happy
* Use two caches - although a cache of a list of tunnels per dest might be
* more elegant.
* Key the caches just on the dest, not on source+dest, as different sources
* simultaneously talking to the same dest is probably rare enough
* to not bother separating out.
*
*/
private static HashMap _tunnelCache = new HashMap();
private static HashMap _backloggedTunnelCache = new HashMap();
private static long _cleanTime = 0;
private TunnelInfo selectOutboundTunnel(Destination to) {
TunnelInfo tunnel;
long now = getContext().clock().now();
synchronized (_tunnelCache) {
if (now - _cleanTime > 5*60*1000) { // clean out periodically
List deleteList = new ArrayList();
for (Iterator iter = _tunnelCache.keySet().iterator(); iter.hasNext(); ) {
Destination dest = (Destination) iter.next();
tunnel = (TunnelInfo) _tunnelCache.get(dest);
if (!getContext().tunnelManager().isValidTunnel(_from.calculateHash(), tunnel))
deleteList.add(dest);
}
for (Iterator iter = deleteList.iterator(); iter.hasNext(); ) {
Destination dest = (Destination) iter.next();
_tunnelCache.remove(dest);
}
cleanTunnelCache(_tunnelCache);
cleanTunnelCache(_backloggedTunnelCache);
_cleanTime = now;
}
/**
* If old tunnel is valid and no longer backlogged, use it.
* This prevents an active anonymity attack, where a peer could tell
* if you were the originator by backlogging the tunnel, then removing the
* backlog and seeing if traffic came back or not.
*/
tunnel = (TunnelInfo) _backloggedTunnelCache.get(to);
if (tunnel != null) {
if (getContext().tunnelManager().isValidTunnel(_from.calculateHash(), tunnel)) {
if (!getContext().commSystem().isBacklogged(tunnel.getPeer(1))) {
if (_log.shouldLog(Log.WARN))
_log.warn("Switching back to tunnel " + tunnel + " for dest " + to.calculateHash().toBase64());
_backloggedTunnelCache.remove(to);
_tunnelCache.put(to, tunnel);
return tunnel;
} // else still backlogged
} else // no longer valid
_backloggedTunnelCache.remove(to);
}
// Use the same tunnel unless backlogged
tunnel = (TunnelInfo) _tunnelCache.get(to);
if (tunnel != null) {
if (getContext().tunnelManager().isValidTunnel(_from.calculateHash(), tunnel))
return(tunnel);
else
_tunnelCache.remove(to);
if (getContext().tunnelManager().isValidTunnel(_from.calculateHash(), tunnel)) {
if (tunnel.getLength() <= 1 || !getContext().commSystem().isBacklogged(tunnel.getPeer(1)))
return tunnel;
// backlogged
if (_log.shouldLog(Log.WARN))
_log.warn("Switching from backlogged " + tunnel + " for dest " + to.calculateHash().toBase64());
_backloggedTunnelCache.put(to, tunnel);
} // else no longer valid
_tunnelCache.remove(to);
}
// Pick a new tunnel
tunnel = selectOutboundTunnel();
if (tunnel != null)
_tunnelCache.put(to, tunnel);

View File

@ -325,10 +325,12 @@ public class NTCPConnection implements FIFOBandwidthLimiter.CompleteListener {
int writeBufs = 0;
synchronized (_writeBufs) { writeBufs = _writeBufs.size(); }
if (_log.shouldLog(Log.WARN))
_log.warn("Too backlogged: queue time " + queueTime + " and the size is " + size
try {
_log.warn("Too backlogged: queue time " + queueTime + " and the size is " + size
+ ", wantsWrite? " + (0 != (_conKey.interestOps()&SelectionKey.OP_WRITE))
+ ", currentOut set? " + currentOutboundSet
+ ", writeBufs: " + writeBufs + " on " + toString());
} catch (Exception e) {} // java.nio.channels.CancelledKeyException
_context.statManager().addRateData("ntcp.sendBacklogTime", queueTime, size);
return true;
//} else if (size > 32) { // another arbitrary limit.