2005-02-19 jrandom

* Only build new extra tunnels on failure if we don't have enough
    * Fix a fencepost in the tunnel building so that e.g. a variance of
      2 means +/- 2, not +/- 1 (thanks dm!)
    * Avoid an NPE on client disconnect
    * Never select a shitlisted peer to participate in a tunnel
    * Have netDb store messages timeout after 10s, not the full 60s (duh)
    * Keep session tags around for a little longer, just in case (grr)
    * Cleaned up some closing event issues on the streaming lib
    * Stop bundling the jetty 5.1.2 and updated wrapper.config in the update
      so that 0.4.* users will need to do a clean install, but we don't need
      to shove an additional 2MB in each update to those already on 0.5.
    * Imported the susimail css (oops, thanks susi!)
This commit is contained in:
jrandom
2005-02-19 23:20:56 +00:00
committed by zzz
parent d27feabcb3
commit 7d4e093b58
16 changed files with 184 additions and 40 deletions

View File

@@ -57,7 +57,7 @@ public class Connection {
private I2PSocketFull _socket; private I2PSocketFull _socket;
/** set to an error cause if the connection could not be established */ /** set to an error cause if the connection could not be established */
private String _connectionError; private String _connectionError;
private boolean _disconnectScheduled; private long _disconnectScheduledOn;
private long _lastReceivedOn; private long _lastReceivedOn;
private ActivityTimer _activityTimer; private ActivityTimer _activityTimer;
/** window size when we last saw congestion */ /** window size when we last saw congestion */
@@ -113,7 +113,7 @@ public class Connection {
_connectionManager = manager; _connectionManager = manager;
_resetReceived = false; _resetReceived = false;
_connected = true; _connected = true;
_disconnectScheduled = false; _disconnectScheduledOn = -1;
_lastReceivedOn = -1; _lastReceivedOn = -1;
_activityTimer = new ActivityTimer(); _activityTimer = new ActivityTimer();
_ackSinceCongestion = true; _ackSinceCongestion = true;
@@ -191,6 +191,10 @@ public class Connection {
* *
*/ */
void sendReset() { void sendReset() {
if (_disconnectScheduledOn < 0) {
_disconnectScheduledOn = _context.clock().now();
SimpleTimer.getInstance().addEvent(new DisconnectEvent(), DISCONNECT_TIMEOUT);
}
_resetSent = true; _resetSent = true;
if (_resetSentOn <= 0) if (_resetSentOn <= 0)
_resetSentOn = _context.clock().now(); _resetSentOn = _context.clock().now();
@@ -382,6 +386,10 @@ public class Connection {
} }
void resetReceived() { void resetReceived() {
if (_disconnectScheduledOn < 0) {
_disconnectScheduledOn = _context.clock().now();
SimpleTimer.getInstance().addEvent(new DisconnectEvent(), DISCONNECT_TIMEOUT);
}
_resetReceived = true; _resetReceived = true;
MessageOutputStream mos = _outputStream; MessageOutputStream mos = _outputStream;
MessageInputStream mis = _inputStream; MessageInputStream mis = _inputStream;
@@ -398,6 +406,7 @@ public class Connection {
public boolean getHardDisconnected() { return _hardDisconnected; } public boolean getHardDisconnected() { return _hardDisconnected; }
public boolean getResetSent() { return _resetSent; } public boolean getResetSent() { return _resetSent; }
public long getResetSentOn() { return _resetSentOn; } public long getResetSentOn() { return _resetSentOn; }
public long getDisconnectScheduledOn() { return _disconnectScheduledOn; }
void disconnect(boolean cleanDisconnect) { void disconnect(boolean cleanDisconnect) {
disconnect(cleanDisconnect, true); disconnect(cleanDisconnect, true);
@@ -424,8 +433,8 @@ public class Connection {
killOutstandingPackets(); killOutstandingPackets();
} }
if (removeFromConMgr) { if (removeFromConMgr) {
if (!_disconnectScheduled) { if (_disconnectScheduledOn < 0) {
_disconnectScheduled = true; _disconnectScheduledOn = _context.clock().now();
SimpleTimer.getInstance().addEvent(new DisconnectEvent(), DISCONNECT_TIMEOUT); SimpleTimer.getInstance().addEvent(new DisconnectEvent(), DISCONNECT_TIMEOUT);
} }
} }
@@ -445,8 +454,8 @@ public class Connection {
SimpleTimer.getInstance().removeEvent(_activityTimer); SimpleTimer.getInstance().removeEvent(_activityTimer);
_activityTimer = null; _activityTimer = null;
if (!_disconnectScheduled) { if (_disconnectScheduledOn < 0) {
_disconnectScheduled = true; _disconnectScheduledOn = _context.clock().now();
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
_log.info("Connection disconnect complete from dead, drop the con " _log.info("Connection disconnect complete from dead, drop the con "
@@ -576,7 +585,13 @@ public class Connection {
public long getAckedPackets() { return _ackedPackets; } public long getAckedPackets() { return _ackedPackets; }
public long getCreatedOn() { return _createdOn; } public long getCreatedOn() { return _createdOn; }
public long getCloseSentOn() { return _closeSentOn; } public long getCloseSentOn() { return _closeSentOn; }
public void setCloseSentOn(long when) { _closeSentOn = when; } public void setCloseSentOn(long when) {
_closeSentOn = when;
if (_disconnectScheduledOn < 0) {
_disconnectScheduledOn = _context.clock().now();
SimpleTimer.getInstance().addEvent(new DisconnectEvent(), DISCONNECT_TIMEOUT);
}
}
public long getCloseReceivedOn() { return _closeReceivedOn; } public long getCloseReceivedOn() { return _closeReceivedOn; }
public void setCloseReceivedOn(long when) { _closeReceivedOn = when; } public void setCloseReceivedOn(long when) { _closeReceivedOn = when; }

View File

@@ -156,12 +156,14 @@ public class PacketHandler {
sendReset(packet); sendReset(packet);
} }
} else { } else {
if (!con.getResetSent()) {
// someone is sending us a packet on the wrong stream // someone is sending us a packet on the wrong stream
if (_log.shouldLog(Log.WARN)) if (_log.shouldLog(Log.WARN))
_log.warn("Received a packet on the wrong stream: " + packet + " connection: " + con); _log.warn("Received a packet on the wrong stream: " + packet + " connection: " + con);
} }
} }
} }
}
private void sendReset(Packet packet) { private void sendReset(Packet packet) {
PacketLocal reply = new PacketLocal(_context, packet.getOptionalFrom()); PacketLocal reply = new PacketLocal(_context, packet.getOptionalFrom());

View File

@@ -32,19 +32,13 @@ class SchedulerDead extends SchedulerImpl {
public boolean accept(Connection con) { public boolean accept(Connection con) {
if (con == null) return false; if (con == null) return false;
long timeSinceClose = _context.clock().now() - con.getCloseSentOn(); long timeSinceClose = _context.clock().now() - con.getDisconnectScheduledOn();
if (con.getResetSent()) boolean nothingLeftToDo = (con.getDisconnectScheduledOn() > 0) &&
timeSinceClose = _context.clock().now() - con.getResetSentOn();
boolean nothingLeftToDo = (con.getCloseSentOn() > 0) &&
(con.getCloseReceivedOn() > 0) &&
(con.getUnackedPacketsReceived() <= 0) &&
(con.getUnackedPacketsSent() <= 0) &&
(con.getResetSent()) &&
(timeSinceClose >= Connection.DISCONNECT_TIMEOUT); (timeSinceClose >= Connection.DISCONNECT_TIMEOUT);
boolean timedOut = (con.getOptions().getConnectTimeout() < con.getLifetime()) && boolean timedOut = (con.getOptions().getConnectTimeout() < con.getLifetime()) &&
con.getSendStreamId() == null && con.getSendStreamId() == null &&
con.getLifetime() >= Connection.DISCONNECT_TIMEOUT; con.getLifetime() >= Connection.DISCONNECT_TIMEOUT;
return con.getResetReceived() || nothingLeftToDo || timedOut; return nothingLeftToDo || timedOut;
} }
public void eventOccurred(Connection con) { public void eventOccurred(Connection con) {

View File

@@ -36,7 +36,7 @@ class SchedulerHardDisconnected extends SchedulerImpl {
long timeSinceClose = _context.clock().now() - con.getCloseSentOn(); long timeSinceClose = _context.clock().now() - con.getCloseSentOn();
if (con.getResetSent()) if (con.getResetSent())
timeSinceClose = _context.clock().now() - con.getResetSentOn(); timeSinceClose = _context.clock().now() - con.getResetSentOn();
boolean ok = (con.getHardDisconnected() || con.getResetSent()) && boolean ok = (con.getHardDisconnected() || con.getResetSent() || con.getResetReceived()) &&
(timeSinceClose < Connection.DISCONNECT_TIMEOUT); (timeSinceClose < Connection.DISCONNECT_TIMEOUT);
return ok; return ok;
} }

96
apps/susimail/src/css.css Normal file
View File

@@ -0,0 +1,96 @@
body {
background-color:white;
}
li {
font-family:Verdana,Tahoma,Arial,Helvetica;
color:black;
line-height:12pt;
font-size:10pt;
margin-left:5mm;
margin-right:5mm;
}
p {
font-family:Verdana,Tahoma,Arial,Helvetica;
color:black;
line-height:12pt;
margin-left:5mm;
margin-right:5mm;
font-size:10pt;
}
p.hl {
font-size:12pt;
letter-spacing:2pt;
line-height:18pt;
font-weight:bold;
}
p.text {
margin-left:10mm;
margin-right:10mm;
}
p.error {
color:#ff0000;
}
p.info {
color:#327BBF;
}
span.coloured {
color:#327BBF;
}
p.footer {
margin-left:10mm;
margin-right:10mm;
font-size:8pt;
line-height:10pt;
}
p.mailbody {
font-family:Courier-Fixed;
margin-left:1cm;
margin-right:1cm;
}
a {
color:#327BBF;
text-decoration:none;
}
a:hover {
text-decoration:underline;
}
td {
font-family:Verdana,Tahoma,Arial,Helvetica;
color:black;
line-height:12pt;
margin-left:5mm;
margin-right:5mm;
font-size:10pt;
}
tr.list0 {
background-color:#e0e0e0;
}
tr.list1 {
background-color:#ffffff;
}
table.noborder {
margin-left:0mm;
margin-top:0mm;
margin-right:0mm;
}
pre {
font-family:Courier-Fixed;
margin-left:1cm;
margin-right:1cm;
}

View File

@@ -250,15 +250,19 @@
<copy file="build/routerconsole.jar" todir="pkg-temp/lib/" /> <copy file="build/routerconsole.jar" todir="pkg-temp/lib/" />
<!-- for the i2p 0.5 release, push jetty 5.2.1 --> <!-- for the i2p 0.5 release, push jetty 5.2.1 -->
<!--
<copy file="build/jasper-compiler.jar" todir="pkg-temp/lib/" /> <copy file="build/jasper-compiler.jar" todir="pkg-temp/lib/" />
<copy file="build/jasper-runtime.jar" todir="pkg-temp/lib/" /> <copy file="build/jasper-runtime.jar" todir="pkg-temp/lib/" />
<copy file="build/commons-logging.jar" todir="pkg-temp/lib/" /> <copy file="build/commons-logging.jar" todir="pkg-temp/lib/" />
<copy file="build/commons-el.jar" todir="pkg-temp/lib/" /> <copy file="build/commons-el.jar" todir="pkg-temp/lib/" />
<copy file="build/org.mortbay.jetty.jar" todir="pkg-temp/lib/" /> <copy file="build/org.mortbay.jetty.jar" todir="pkg-temp/lib/" />
<copy file="build/javax.servlet.jar" todir="pkg-temp/lib/" /> <copy file="build/javax.servlet.jar" todir="pkg-temp/lib/" />
-->
<!-- requires commons-* to be added to the classpath (boo, hiss) --> <!-- requires commons-* to be added to the classpath (boo, hiss) -->
<!--
<copy file="installer/resources/wrapper.config" todir="pkg-temp/" /> <copy file="installer/resources/wrapper.config" todir="pkg-temp/" />
<touch file="pkg-temp/wrapper.config.updated" /> <touch file="pkg-temp/wrapper.config.updated" />
-->
<copy file="build/i2ptunnel.war" todir="pkg-temp/webapps/" /> <copy file="build/i2ptunnel.war" todir="pkg-temp/webapps/" />
<copy file="build/routerconsole.war" todir="pkg-temp/webapps/" /> <copy file="build/routerconsole.war" todir="pkg-temp/webapps/" />

View File

@@ -53,7 +53,7 @@ class TransientSessionKeyManager extends SessionKeyManager {
* can cause failed decrypts) * can cause failed decrypts)
* *
*/ */
public final static long SESSION_LIFETIME_MAX_MS = SESSION_TAG_DURATION_MS + 2 * 60 * 1000; public final static long SESSION_LIFETIME_MAX_MS = SESSION_TAG_DURATION_MS + 5 * 60 * 1000;
public final static int MAX_INBOUND_SESSION_TAGS = 500 * 1000; // this will consume at most a few MB public final static int MAX_INBOUND_SESSION_TAGS = 500 * 1000; // this will consume at most a few MB
/** /**

View File

@@ -99,7 +99,7 @@ public class BufferedStatLog implements StatLog {
if (_out != null) try { _out.close(); } catch (IOException ioe) {} if (_out != null) try { _out.close(); } catch (IOException ioe) {}
_outFile = filename; _outFile = filename;
try { try {
_out = new BufferedWriter(new FileWriter(_outFile, true)); _out = new BufferedWriter(new FileWriter(_outFile, true), 32*1024);
} catch (IOException ioe) { ioe.printStackTrace(); } } catch (IOException ioe) { ioe.printStackTrace(); }
} }
} }
@@ -147,12 +147,16 @@ public class BufferedStatLog implements StatLog {
_out.write(when); _out.write(when);
_out.write(" "); _out.write(" ");
if (_events[cur].getScope() == null) if (_events[cur].getScope() == null)
_out.write("noScope "); _out.write("noScope");
else else
_out.write(_events[cur].getScope() + " "); _out.write(_events[cur].getScope());
_out.write(_events[cur].getStat()+" "); _out.write(" ");
_out.write(_events[cur].getValue()+" "); _out.write(_events[cur].getStat());
_out.write(_events[cur].getDuration()+"\n"); _out.write(" ");
_out.write(Long.toString(_events[cur].getValue()));
_out.write(" ");
_out.write(Long.toString(_events[cur].getDuration()));
_out.write("\n");
} }
cur = (cur + 1) % _events.length; cur = (cur + 1) % _events.length;
} }

View File

@@ -1,4 +1,18 @@
$Id: history.txt,v 1.146 2005/02/17 17:57:53 jrandom Exp $ $Id: history.txt,v 1.147 2005/02/18 10:58:20 jrandom Exp $
2005-02-19 jrandom
* Only build new extra tunnels on failure if we don't have enough
* Fix a fencepost in the tunnel building so that e.g. a variance of
2 means +/- 2, not +/- 1 (thanks dm!)
* Avoid an NPE on client disconnect
* Never select a shitlisted peer to participate in a tunnel
* Have netDb store messages timeout after 10s, not the full 60s (duh)
* Keep session tags around for a little longer, just in case (grr)
* Cleaned up some closing event issues on the streaming lib
* Stop bundling the jetty 5.1.2 and updated wrapper.config in the update
so that 0.4.* users will need to do a clean install, but we don't need
to shove an additional 2MB in each update to those already on 0.5.
* Imported the susimail css (oops, thanks susi!)
* 2005-02-18 0.5 released * 2005-02-18 0.5 released

View File

@@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
* *
*/ */
public class RouterVersion { public class RouterVersion {
public final static String ID = "$Revision: 1.141 $ $Date: 2005/02/17 12:59:28 $"; public final static String ID = "$Revision: 1.142 $ $Date: 2005/02/17 17:57:53 $";
public final static String VERSION = "0.5"; public final static String VERSION = "0.5";
public final static long BUILD = 0; public final static long BUILD = 1;
public static void main(String args[]) { public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION); System.out.println("I2P Router version: " + VERSION);
System.out.println("Router ID: " + RouterVersion.ID); System.out.println("Router ID: " + RouterVersion.ID);

View File

@@ -22,7 +22,8 @@ import net.i2p.util.Log;
*/ */
public class RepublishLeaseSetJob extends JobImpl { public class RepublishLeaseSetJob extends JobImpl {
private Log _log; private Log _log;
private final static long REPUBLISH_LEASESET_DELAY = 60*1000; // 5 mins private final static long REPUBLISH_LEASESET_DELAY = 5*60*1000; // 5 mins
private final static long REPUBLISH_LEASESET_TIMEOUT = 60*1000;
private Hash _dest; private Hash _dest;
private KademliaNetworkDatabaseFacade _facade; private KademliaNetworkDatabaseFacade _facade;
@@ -43,7 +44,7 @@ public class RepublishLeaseSetJob extends JobImpl {
if (!ls.isCurrent(Router.CLOCK_FUDGE_FACTOR)) { if (!ls.isCurrent(Router.CLOCK_FUDGE_FACTOR)) {
_log.warn("Not publishing a LOCAL lease that isn't current - " + _dest, new Exception("Publish expired LOCAL lease?")); _log.warn("Not publishing a LOCAL lease that isn't current - " + _dest, new Exception("Publish expired LOCAL lease?"));
} else { } else {
getContext().jobQueue().addJob(new StoreJob(getContext(), _facade, _dest, ls, new OnSuccess(getContext()), new OnFailure(getContext()), REPUBLISH_LEASESET_DELAY)); getContext().jobQueue().addJob(new StoreJob(getContext(), _facade, _dest, ls, new OnSuccess(getContext()), new OnFailure(getContext()), REPUBLISH_LEASESET_TIMEOUT));
} }
} else { } else {
_log.warn("Client " + _dest + " is local, but we can't find a valid LeaseSet? perhaps its being rebuilt?"); _log.warn("Client " + _dest + " is local, but we can't find a valid LeaseSet? perhaps its being rebuilt?");

View File

@@ -199,7 +199,7 @@ class StoreJob extends JobImpl {
// _log.debug(getJobId() + ": Send store to " + router.getIdentity().getHash().toBase64()); // _log.debug(getJobId() + ": Send store to " + router.getIdentity().getHash().toBase64());
} }
sendStore(msg, router, _expiration); sendStore(msg, router, getContext().clock().now() + STORE_TIMEOUT_MS);
} }
private void sendStore(DatabaseStoreMessage msg, RouterInfo peer, long expiration) { private void sendStore(DatabaseStoreMessage msg, RouterInfo peer, long expiration) {
@@ -315,7 +315,7 @@ class StoreJob extends JobImpl {
sendNext(); sendNext();
} }
public String getName() { return "Kademlia Store Failed"; } public String getName() { return "Kademlia Store Peer Failed"; }
} }
/** /**

View File

@@ -690,6 +690,9 @@ public class ProfileOrganizer {
// the CLI shouldn't depend upon the netDb // the CLI shouldn't depend upon the netDb
if (netDb == null) return true; if (netDb == null) return true;
if (_context.router() == null) return true; if (_context.router() == null) return true;
if ( (_context.shitlist() != null) && (_context.shitlist().isShitlisted(peer)) )
return false; // never select a shitlisted peer
if (null != netDb.lookupRouterInfoLocally(peer)) { if (null != netDb.lookupRouterInfoLocally(peer)) {
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
_log.info("Peer " + peer.toBase64() + " is locally known, allowing its use"); _log.info("Peer " + peer.toBase64() + " is locally known, allowing its use");

View File

@@ -80,6 +80,11 @@ public class InboundMessageDistributor implements GarlicMessageReceiver.CloveRec
// ok, they want us to send it remotely, but that'd bust our anonymity, // ok, they want us to send it remotely, but that'd bust our anonymity,
// so we send it out a tunnel first // so we send it out a tunnel first
TunnelInfo out = _context.tunnelManager().selectOutboundTunnel(_client); TunnelInfo out = _context.tunnelManager().selectOutboundTunnel(_client);
if (out == null) {
if (_log.shouldLog(Log.ERROR))
_log.error("no outbound tunnel to send the client message for " + _client + ": " + msg);
return;
}
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
_log.info("distributing inbound tunnel message back out " + out _log.info("distributing inbound tunnel message back out " + out
+ " targetting " + target.toBase64().substring(0,4)); + " targetting " + target.toBase64().substring(0,4));

View File

@@ -26,10 +26,14 @@ abstract class TunnelPeerSelector {
if (settings.getLengthVariance() != 0) { if (settings.getLengthVariance() != 0) {
int skew = settings.getLengthVariance(); int skew = settings.getLengthVariance();
if (skew > 0) if (skew > 0)
length += ctx.random().nextInt(skew); length += ctx.random().nextInt(skew+1);
else { else {
skew = 0 - skew; skew = 1 - skew;
length += ctx.random().nextInt(2*skew) - skew; int off = ctx.random().nextInt(skew);
if (ctx.random().nextBoolean())
length += off;
else
length -= off;
} }
if (length < 0) if (length < 0)
length = 0; length = 0;

View File

@@ -298,6 +298,7 @@ public class TunnelPool {
if (_log.shouldLog(Log.WARN)) if (_log.shouldLog(Log.WARN))
_log.warn(toString() + ": unable to build a new leaseSet on failure (" + remaining _log.warn(toString() + ": unable to build a new leaseSet on failure (" + remaining
+ " remaining), request a new tunnel"); + " remaining), request a new tunnel");
if (remaining < _settings.getBackupQuantity() + _settings.getQuantity())
buildFake(false); buildFake(false);
} }
} }
@@ -320,7 +321,8 @@ public class TunnelPool {
if (_log.shouldLog(Log.WARN)) if (_log.shouldLog(Log.WARN))
_log.warn(toString() + ": unable to build a new leaseSet on expire (" + remaining _log.warn(toString() + ": unable to build a new leaseSet on expire (" + remaining
+ " remaining), request a new tunnel"); + " remaining), request a new tunnel");
if (_settings.getAllowZeroHop()) if ( (remaining < _settings.getBackupQuantity() + _settings.getQuantity())
&& (_settings.getAllowZeroHop()) )
buildFake(); buildFake();
} }
} }