* 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:
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
Reference in New Issue
Block a user