From e78dd1fdc3ffc6f0000c3fd5cc6e089fbe66d830 Mon Sep 17 00:00:00 2001 From: zzz Date: Tue, 24 Nov 2009 20:08:58 +0000 Subject: [PATCH 001/127] remove unused Logs from DataStructures --- core/java/src/net/i2p/data/Address.java | 3 --- core/java/src/net/i2p/data/Certificate.java | 5 ++--- core/java/src/net/i2p/data/DataFormatException.java | 4 +--- core/java/src/net/i2p/data/DataHelper.java | 2 +- core/java/src/net/i2p/data/Destination.java | 3 --- core/java/src/net/i2p/data/Lease.java | 4 +--- core/java/src/net/i2p/data/PrivateKey.java | 2 -- core/java/src/net/i2p/data/PublicKey.java | 3 --- core/java/src/net/i2p/data/RouterAddress.java | 3 --- core/java/src/net/i2p/data/SessionKey.java | 3 --- core/java/src/net/i2p/data/Signature.java | 3 --- core/java/src/net/i2p/data/SigningPrivateKey.java | 2 -- core/java/src/net/i2p/data/SigningPublicKey.java | 3 --- core/java/src/net/i2p/data/TunnelId.java | 3 --- core/java/src/net/i2p/data/VerifiedDestination.java | 3 --- 15 files changed, 5 insertions(+), 41 deletions(-) diff --git a/core/java/src/net/i2p/data/Address.java b/core/java/src/net/i2p/data/Address.java index 3a69a232f..a34f773f3 100644 --- a/core/java/src/net/i2p/data/Address.java +++ b/core/java/src/net/i2p/data/Address.java @@ -4,10 +4,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import net.i2p.util.Log; - public class Address extends DataStructureImpl { - private final static Log _log = new Log(Address.class); private String _hostname; private Destination _destination; diff --git a/core/java/src/net/i2p/data/Certificate.java b/core/java/src/net/i2p/data/Certificate.java index 0fe61e5c0..f20f8322b 100644 --- a/core/java/src/net/i2p/data/Certificate.java +++ b/core/java/src/net/i2p/data/Certificate.java @@ -13,8 +13,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import net.i2p.util.Log; - /** * Defines a certificate that can be attached to various I2P structures, such * as RouterIdentity and Destination, allowing routers and clients to help @@ -23,10 +21,11 @@ import net.i2p.util.Log; * certificate authority, though that use probably isn't appropriate for an * anonymous network ;) * + * Todo: Properly support multiple certificates + * * @author jrandom */ public class Certificate extends DataStructureImpl { - private final static Log _log = new Log(Certificate.class); private int _type; private byte[] _payload; diff --git a/core/java/src/net/i2p/data/DataFormatException.java b/core/java/src/net/i2p/data/DataFormatException.java index 95e0d26c8..290afb5e9 100644 --- a/core/java/src/net/i2p/data/DataFormatException.java +++ b/core/java/src/net/i2p/data/DataFormatException.java @@ -10,7 +10,6 @@ package net.i2p.data; */ import net.i2p.I2PException; -import net.i2p.util.Log; /** * Thrown when the data was not available to read or write a DataStructure @@ -18,7 +17,6 @@ import net.i2p.util.Log; * @author jrandom */ public class DataFormatException extends I2PException { - private final static Log _log = new Log(DataFormatException.class); public DataFormatException(String msg, Throwable t) { super(msg, t); @@ -27,4 +25,4 @@ public class DataFormatException extends I2PException { public DataFormatException(String msg) { super(msg); } -} \ No newline at end of file +} diff --git a/core/java/src/net/i2p/data/DataHelper.java b/core/java/src/net/i2p/data/DataHelper.java index 96f9a0814..982241581 100644 --- a/core/java/src/net/i2p/data/DataHelper.java +++ b/core/java/src/net/i2p/data/DataHelper.java @@ -294,7 +294,7 @@ public class DataHelper { } /** - * Writes the props to the file, unsorted. + * Writes the props to the file, unsorted (unless props is an OrderedProperties) * Note that this does not escape the \r or \n that are unescaped in loadProps() above. */ public static void storeProps(Properties props, File file) throws IOException { diff --git a/core/java/src/net/i2p/data/Destination.java b/core/java/src/net/i2p/data/Destination.java index 7419e11ed..bebfde69e 100644 --- a/core/java/src/net/i2p/data/Destination.java +++ b/core/java/src/net/i2p/data/Destination.java @@ -14,8 +14,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import net.i2p.util.Log; - /** * Defines an end point in the I2P network. The Destination may move around * in the network, but messages sent to the Destination will find it @@ -23,7 +21,6 @@ import net.i2p.util.Log; * @author jrandom */ public class Destination extends DataStructureImpl { - protected final static Log _log = new Log(Destination.class); protected Certificate _certificate; protected SigningPublicKey _signingKey; protected PublicKey _publicKey; diff --git a/core/java/src/net/i2p/data/Lease.java b/core/java/src/net/i2p/data/Lease.java index eb22d64cf..7a5bde743 100644 --- a/core/java/src/net/i2p/data/Lease.java +++ b/core/java/src/net/i2p/data/Lease.java @@ -15,7 +15,6 @@ import java.io.OutputStream; import java.util.Date; import net.i2p.util.Clock; -import net.i2p.util.Log; /** * Defines the proof that a particular router / tunnel is allowed to receive @@ -24,7 +23,6 @@ import net.i2p.util.Log; * @author jrandom */ public class Lease extends DataStructureImpl { - private final static Log _log = new Log(Lease.class); private Hash _gateway; private TunnelId _tunnelId; private Date _end; @@ -155,4 +153,4 @@ public class Lease extends DataStructureImpl { buf.append("]"); return buf.toString(); } -} \ No newline at end of file +} diff --git a/core/java/src/net/i2p/data/PrivateKey.java b/core/java/src/net/i2p/data/PrivateKey.java index eed7f1eb7..c4c34b0e8 100644 --- a/core/java/src/net/i2p/data/PrivateKey.java +++ b/core/java/src/net/i2p/data/PrivateKey.java @@ -14,7 +14,6 @@ import java.io.InputStream; import java.io.OutputStream; import net.i2p.crypto.KeyGenerator; -import net.i2p.util.Log; /** * Defines the PrivateKey as defined by the I2P data structure spec. @@ -24,7 +23,6 @@ import net.i2p.util.Log; * @author jrandom */ public class PrivateKey extends DataStructureImpl { - private final static Log _log = new Log(PrivateKey.class); private byte[] _data; public final static int KEYSIZE_BYTES = 256; diff --git a/core/java/src/net/i2p/data/PublicKey.java b/core/java/src/net/i2p/data/PublicKey.java index 01bca46e5..3496f8d55 100644 --- a/core/java/src/net/i2p/data/PublicKey.java +++ b/core/java/src/net/i2p/data/PublicKey.java @@ -13,8 +13,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import net.i2p.util.Log; - /** * Defines the PublicKey as defined by the I2P data structure spec. * A public key is 256byte Integer. The public key represents only the @@ -23,7 +21,6 @@ import net.i2p.util.Log; * @author jrandom */ public class PublicKey extends DataStructureImpl { - private final static Log _log = new Log(PublicKey.class); private byte[] _data; public final static int KEYSIZE_BYTES = 256; diff --git a/core/java/src/net/i2p/data/RouterAddress.java b/core/java/src/net/i2p/data/RouterAddress.java index f353f7d73..0f03d9d34 100644 --- a/core/java/src/net/i2p/data/RouterAddress.java +++ b/core/java/src/net/i2p/data/RouterAddress.java @@ -16,15 +16,12 @@ import java.util.Date; import java.util.Iterator; import java.util.Properties; -import net.i2p.util.Log; - /** * Defines a method of communicating with a router * * @author jrandom */ public class RouterAddress extends DataStructureImpl { - private final static Log _log = new Log(RouterAddress.class); private int _cost; private Date _expiration; private String _transportStyle; diff --git a/core/java/src/net/i2p/data/SessionKey.java b/core/java/src/net/i2p/data/SessionKey.java index 17190ef3f..deaf292b5 100644 --- a/core/java/src/net/i2p/data/SessionKey.java +++ b/core/java/src/net/i2p/data/SessionKey.java @@ -13,8 +13,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import net.i2p.util.Log; - /** * Defines the SessionKey as defined by the I2P data structure spec. * A session key is 32byte Integer. @@ -22,7 +20,6 @@ import net.i2p.util.Log; * @author jrandom */ public class SessionKey extends DataStructureImpl { - private final static Log _log = new Log(SessionKey.class); private byte[] _data; private Object _preparedKey; diff --git a/core/java/src/net/i2p/data/Signature.java b/core/java/src/net/i2p/data/Signature.java index cb43741c5..2c35edebc 100644 --- a/core/java/src/net/i2p/data/Signature.java +++ b/core/java/src/net/i2p/data/Signature.java @@ -13,8 +13,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import net.i2p.util.Log; - /** * Defines the signature as defined by the I2P data structure spec. * A signature is a 40byte Integer verifying the authenticity of some data @@ -23,7 +21,6 @@ import net.i2p.util.Log; * @author jrandom */ public class Signature extends DataStructureImpl { - private final static Log _log = new Log(Signature.class); private byte[] _data; public final static int SIGNATURE_BYTES = 40; diff --git a/core/java/src/net/i2p/data/SigningPrivateKey.java b/core/java/src/net/i2p/data/SigningPrivateKey.java index 1d2e95cb0..3c1e71254 100644 --- a/core/java/src/net/i2p/data/SigningPrivateKey.java +++ b/core/java/src/net/i2p/data/SigningPrivateKey.java @@ -14,7 +14,6 @@ import java.io.InputStream; import java.io.OutputStream; import net.i2p.crypto.KeyGenerator; -import net.i2p.util.Log; /** * Defines the SigningPrivateKey as defined by the I2P data structure spec. @@ -25,7 +24,6 @@ import net.i2p.util.Log; * @author jrandom */ public class SigningPrivateKey extends DataStructureImpl { - private final static Log _log = new Log(SigningPrivateKey.class); private byte[] _data; public final static int KEYSIZE_BYTES = 20; diff --git a/core/java/src/net/i2p/data/SigningPublicKey.java b/core/java/src/net/i2p/data/SigningPublicKey.java index 44b8f3c13..2d2cf2f9b 100644 --- a/core/java/src/net/i2p/data/SigningPublicKey.java +++ b/core/java/src/net/i2p/data/SigningPublicKey.java @@ -13,8 +13,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import net.i2p.util.Log; - /** * Defines the SigningPublicKey as defined by the I2P data structure spec. * A public key is 256byte Integer. The public key represents only the @@ -24,7 +22,6 @@ import net.i2p.util.Log; * @author jrandom */ public class SigningPublicKey extends DataStructureImpl { - private final static Log _log = new Log(SigningPublicKey.class); private byte[] _data; public final static int KEYSIZE_BYTES = 128; diff --git a/core/java/src/net/i2p/data/TunnelId.java b/core/java/src/net/i2p/data/TunnelId.java index e9ed13cff..c692d70c8 100644 --- a/core/java/src/net/i2p/data/TunnelId.java +++ b/core/java/src/net/i2p/data/TunnelId.java @@ -12,8 +12,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import net.i2p.util.Log; - /** * Defines the tunnel ID that messages are passed through on a set of routers. * This is not globally unique, but must be unique on each router making up @@ -23,7 +21,6 @@ import net.i2p.util.Log; * @author jrandom */ public class TunnelId extends DataStructureImpl { - private final static Log _log = new Log(TunnelId.class); private long _tunnelId; private int _type; diff --git a/core/java/src/net/i2p/data/VerifiedDestination.java b/core/java/src/net/i2p/data/VerifiedDestination.java index 19fd1079e..dee86800d 100644 --- a/core/java/src/net/i2p/data/VerifiedDestination.java +++ b/core/java/src/net/i2p/data/VerifiedDestination.java @@ -13,8 +13,6 @@ import java.security.NoSuchAlgorithmException; import com.nettgryppa.security.HashCash; -import net.i2p.util.Log; - /** * Extend Destination with methods to verify its Certificate. * The router does not check Certificates, it doesn't care. @@ -26,7 +24,6 @@ import net.i2p.util.Log; * @author zzz */ public class VerifiedDestination extends Destination { - protected final static Log _log = new Log(Destination.class); public VerifiedDestination() { super(); From 94faf74aa477bc0602f9352e93d2b0c7b4d55d05 Mon Sep 17 00:00:00 2001 From: zzz Date: Tue, 24 Nov 2009 20:12:27 +0000 Subject: [PATCH 002/127] * Streaming: - When an "immediate" ack is requested, do it within 250 ms (was 2000) - Request immediate acks when < 1/3 of window remains, or when < 3 packets remain in window, and every 8 packets (was when < 2 packets in window remain) - Change requested delay to RTT/2 (was RTO/2) - Log cleanup and javadoc --- .../net/i2p/client/streaming/Connection.java | 68 +++++++++++++------ .../streaming/ConnectionDataReceiver.java | 8 +-- .../client/streaming/ConnectionOptions.java | 13 +++- .../streaming/ConnectionPacketHandler.java | 23 +++++-- .../src/net/i2p/client/streaming/Packet.java | 2 +- 5 files changed, 78 insertions(+), 36 deletions(-) diff --git a/apps/streaming/java/src/net/i2p/client/streaming/Connection.java b/apps/streaming/java/src/net/i2p/client/streaming/Connection.java index 9435727c4..aa826f799 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/Connection.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/Connection.java @@ -189,9 +189,9 @@ public class Connection { + _activeResends + "), waiting " + timeLeft); try { _outboundPackets.wait(Math.min(timeLeft,250l)); } catch (InterruptedException ie) { if (_log.shouldLog(Log.DEBUG)) _log.debug("InterruptedException while Outbound window is full (" + _outboundPackets.size() + "/" + _activeResends +")"); return false;} } else { - if (_log.shouldLog(Log.DEBUG)) - _log.debug("Outbound window is full (" + _outboundPackets.size() + "/" + _activeResends - + "), waiting indefinitely"); + //if (_log.shouldLog(Log.DEBUG)) + // _log.debug("Outbound window is full (" + _outboundPackets.size() + "/" + _activeResends + // + "), waiting indefinitely"); try { _outboundPackets.wait(250); } catch (InterruptedException ie) {if (_log.shouldLog(Log.DEBUG)) _log.debug("InterruptedException while Outbound window is full (" + _outboundPackets.size() + "/" + _activeResends + ")"); return false;} //10*1000 } } else { @@ -297,37 +297,48 @@ public class Connection { if ( (packet.getSequenceNum() == 0) && (!packet.isFlagSet(Packet.FLAG_SYNCHRONIZE)) ) { ackOnly = true; - if (_log.shouldLog(Log.DEBUG)) - _log.debug("No resend for " + packet); + //if (_log.shouldLog(Log.DEBUG)) + // _log.debug("No resend for " + packet); } else { - int remaining = 0; + int windowSize; + int remaining; synchronized (_outboundPackets) { _outboundPackets.put(new Long(packet.getSequenceNum()), packet); - remaining = _options.getWindowSize() - _outboundPackets.size() ; + windowSize = _options.getWindowSize(); + remaining = windowSize - _outboundPackets.size() ; _outboundPackets.notifyAll(); } - if (remaining < 0) - remaining = 0; - if (packet.isFlagSet(Packet.FLAG_CLOSE) || (remaining < 2)) { + // the other end has no idea what our window size is, so + // help him out by requesting acks below the 1/3 point, + // if remaining < 3, and every 8 minimum. + if (packet.isFlagSet(Packet.FLAG_CLOSE) || + (remaining < (windowSize + 2) / 3) || + (remaining < 3) || + (packet.getSequenceNum() % 8 == 0)) { packet.setOptionalDelay(0); packet.setFlag(Packet.FLAG_DELAY_REQUESTED); if (_log.shouldLog(Log.DEBUG)) _log.debug("Requesting no ack delay for packet " + packet); } else { - int delay = _options.getRTO() / 2; + // This is somewhat of a waste of time, unless the RTT < 4000, + // since the other end limits it to getSendAckDelay() + // which is always 2000, but it's good for diagnostics to see what the other end thinks + // the RTT is. + int delay = _options.getRTT() / 2; packet.setOptionalDelay(delay); if (delay > 0) packet.setFlag(Packet.FLAG_DELAY_REQUESTED); if (_log.shouldLog(Log.DEBUG)) _log.debug("Requesting ack delay of " + delay + "ms for packet " + packet); } + // WHY always set? packet.setFlag(Packet.FLAG_DELAY_REQUESTED); long timeout = _options.getRTO(); if (timeout > MAX_RESEND_DELAY) timeout = MAX_RESEND_DELAY; if (_log.shouldLog(Log.DEBUG)) - _log.debug("Resend in " + timeout + " for " + packet, new Exception("Sent by")); + _log.debug("Resend in " + timeout + " for " + packet); // schedules itself ResendPacketEvent rpe = new ResendPacketEvent(packet, timeout); @@ -370,6 +381,10 @@ public class Connection { } *********/ + /** + * Process the acks and nacks received in a packet + * @return List of packets acked or null + */ List ackPackets(long ackThrough, long nacks[]) { if (ackThrough < _highestAckedThrough) { // dupack which won't tell us anything @@ -685,6 +700,14 @@ public class Connection { * @return the next time the scheduler will want to send a packet, or -1 if never. */ public long getNextSendTime() { return _nextSendTime; } + + /** + * If the next send time is currently >= 0 (i.e. not "never"), + * this may make the next time sooner but will not make it later. + * If the next send time is currently < 0 (i.e. "never"), + * this will set it to the time specified, but not later than + * options.getSendAckDelay() from now (2000 ms) + */ public void setNextSendTime(long when) { if (_nextSendTime >= 0) { if (when < _nextSendTime) @@ -699,12 +722,12 @@ public class Connection { _nextSendTime = max; } - if (_log.shouldLog(Log.DEBUG) && false) { - if (_nextSendTime <= 0) - _log.debug("set next send time to an unknown time", new Exception(toString())); - else - _log.debug("set next send time to " + (_nextSendTime-_context.clock().now()) + "ms from now", new Exception(toString())); - } + //if (_log.shouldLog(Log.DEBUG) && false) { + // if (_nextSendTime <= 0) + // _log.debug("set next send time to an unknown time", new Exception(toString())); + // else + // _log.debug("set next send time to " + (_nextSendTime-_context.clock().now()) + "ms from now", new Exception(toString())); + //} } /** how many packets have we sent and the other side has ACKed? @@ -742,7 +765,9 @@ public class Connection { public long getCongestionWindowEnd() { return _congestionWindowEnd; } public void setCongestionWindowEnd(long endMsg) { _congestionWindowEnd = endMsg; } + /** @return the highest outbound packet we have recieved an ack for */ public long getHighestAckedThrough() { return _highestAckedThrough; } + /** @deprecated unused */ public void setHighestAckedThrough(long msgNum) { _highestAckedThrough = msgNum; } public long getLastActivityOn() { @@ -835,8 +860,8 @@ public class Connection { } long howLong = _options.getInactivityTimeout(); howLong += _randomWait; // randomize it a bit, so both sides don't do it at once - if (_log.shouldLog(Log.DEBUG)) - _log.debug("Resetting the inactivity timer to " + howLong, new Exception(toString())); + //if (_log.shouldLog(Log.DEBUG)) + // _log.debug("Resetting the inactivity timer to " + howLong); // this will get rescheduled, and rescheduled, and rescheduled... _activityTimer.reschedule(howLong, false); // use the later of current and previous timeout } @@ -1087,6 +1112,8 @@ public class Connection { // we want to resend this packet, but there are already active // resends in the air and we dont want to make a bad situation // worse. wait another second + // BUG? seq# = 0, activeResends = 0, loop forever - why? + // also seen with seq# > 0. Is the _activeResends count reliable? if (_log.shouldLog(Log.INFO)) _log.info("Delaying resend of " + _packet + " as there are " + _activeResends + " active resends already in play"); @@ -1104,6 +1131,7 @@ public class Connection { _packet.setOptionalDelay(choke); if (choke > 0) _packet.setFlag(Packet.FLAG_DELAY_REQUESTED); + // this seems unnecessary to send the MSS again: _packet.setOptionalMaxSize(getOptions().getMaxMessageSize()); // bugfix release 0.7.8, we weren't dividing by 1000 _packet.setResendDelay(getOptions().getResendDelay() / 1000); diff --git a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionDataReceiver.java b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionDataReceiver.java index 3b55160d3..acec982f6 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionDataReceiver.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionDataReceiver.java @@ -166,6 +166,7 @@ class ConnectionDataReceiver implements MessageOutputStream.DataReceiver { packet.setReceiveStreamId(con.getReceiveStreamId()); con.getInputStream().updateAcks(packet); + // note that the optional delay is usually rewritten in Connection.sendPacket() int choke = con.getOptions().getChoke(); packet.setOptionalDelay(choke); if (choke > 0) @@ -197,12 +198,9 @@ class ConnectionDataReceiver implements MessageOutputStream.DataReceiver { ( (size > 0) || (con.getUnackedPacketsSent() <= 0) || (packet.getSequenceNum() > 0) ) ) { packet.setFlag(Packet.FLAG_CLOSE); con.setCloseSentOn(_context.clock().now()); - if (_log.shouldLog(Log.DEBUG)) - _log.debug("Closed is set for a new packet on " + con + ": " + packet); - } else { - if (_log.shouldLog(Log.DEBUG)) - _log.debug("Closed is not set for a new packet on " + _connection + ": " + packet); } + if (_log.shouldLog(Log.DEBUG)) + _log.debug("New outbound packet on " + _connection + ": " + packet); return packet; } diff --git a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionOptions.java b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionOptions.java index bd32afbf7..d8f50fbcf 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionOptions.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionOptions.java @@ -46,6 +46,7 @@ public class ConnectionOptions extends I2PSocketOptionsImpl { public static final String PROP_INITIAL_RESEND_DELAY = "i2p.streaming.initialResendDelay"; public static final String PROP_INITIAL_ACK_DELAY = "i2p.streaming.initialAckDelay"; public static final String PROP_INITIAL_WINDOW_SIZE = "i2p.streaming.initialWindowSize"; + /** unused */ public static final String PROP_INITIAL_RECEIVE_WINDOW = "i2p.streaming.initialReceiveWindow"; public static final String PROP_INACTIVITY_TIMEOUT = "i2p.streaming.inactivityTimeout"; public static final String PROP_INACTIVITY_ACTION = "i2p.streaming.inactivityAction"; @@ -58,6 +59,7 @@ public class ConnectionOptions extends I2PSocketOptionsImpl { static final int INITIAL_WINDOW_SIZE = 6; static final int DEFAULT_MAX_SENDS = 8; public static final int DEFAULT_INITIAL_RTT = 8*1000; + public static final int DEFAULT_INITIAL_ACK_DELAY = 2*1000; static final int MIN_WINDOW_SIZE = 1; private static final boolean DEFAULT_ANSWER_PINGS = true; @@ -217,7 +219,7 @@ public class ConnectionOptions extends I2PSocketOptionsImpl { setRTT(getInt(opts, PROP_INITIAL_RTT, DEFAULT_INITIAL_RTT)); setReceiveWindow(getInt(opts, PROP_INITIAL_RECEIVE_WINDOW, 1)); setResendDelay(getInt(opts, PROP_INITIAL_RESEND_DELAY, 1000)); - setSendAckDelay(getInt(opts, PROP_INITIAL_ACK_DELAY, 2000)); + setSendAckDelay(getInt(opts, PROP_INITIAL_ACK_DELAY, DEFAULT_INITIAL_ACK_DELAY)); setWindowSize(getInt(opts, PROP_INITIAL_WINDOW_SIZE, INITIAL_WINDOW_SIZE)); setMaxResends(getInt(opts, PROP_MAX_RESENDS, DEFAULT_MAX_SENDS)); setWriteTimeout(getInt(opts, PROP_WRITE_TIMEOUT, -1)); @@ -249,7 +251,7 @@ public class ConnectionOptions extends I2PSocketOptionsImpl { if (opts.containsKey(PROP_INITIAL_RESEND_DELAY)) setResendDelay(getInt(opts, PROP_INITIAL_RESEND_DELAY, 1000)); if (opts.containsKey(PROP_INITIAL_ACK_DELAY)) - setSendAckDelay(getInt(opts, PROP_INITIAL_ACK_DELAY, 2000)); + setSendAckDelay(getInt(opts, PROP_INITIAL_ACK_DELAY, DEFAULT_INITIAL_ACK_DELAY)); if (opts.containsKey(PROP_INITIAL_WINDOW_SIZE)) setWindowSize(getInt(opts, PROP_INITIAL_WINDOW_SIZE, INITIAL_WINDOW_SIZE)); if (opts.containsKey(PROP_MAX_RESENDS)) @@ -295,6 +297,7 @@ public class ConnectionOptions extends I2PSocketOptionsImpl { * @return if we want signatures on all packets. */ public boolean getRequireFullySigned() { return _fullySigned; } + /** unused, see above */ public void setRequireFullySigned(boolean sign) { _fullySigned = sign; } /** @@ -325,7 +328,7 @@ public class ConnectionOptions extends I2PSocketOptionsImpl { } /** after how many consecutive messages should we ack? - * This doesn't appear to be used. + * @deprecated This doesn't appear to be used. * @return receive window size. */ public int getReceiveWindow() { return _receiveWindow; } @@ -405,6 +408,10 @@ public class ConnectionOptions extends I2PSocketOptionsImpl { * @return ACK delay in ms */ public int getSendAckDelay() { return _sendAckDelay; } + /** + * Unused except here, so expect the default initial delay of 2000 ms unless set by the user + * to remain constant. + */ public void setSendAckDelay(int delayMs) { _sendAckDelay = delayMs; } /** What is the largest message we want to send or receive? diff --git a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionPacketHandler.java b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionPacketHandler.java index 91a06e088..ba705b2d5 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/ConnectionPacketHandler.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/ConnectionPacketHandler.java @@ -131,11 +131,14 @@ public class ConnectionPacketHandler { isNew = false; } - if ( (packet.getSequenceNum() == 0) && (packet.getPayloadSize() > 0) ) { - if (_log.shouldLog(Log.DEBUG)) - _log.debug("seq=0 && size=" + packet.getPayloadSize() + ": isNew? " + isNew - + " packet: " + packet + " con: " + con); - } + //if ( (packet.getSequenceNum() == 0) && (packet.getPayloadSize() > 0) ) { + // if (_log.shouldLog(Log.DEBUG)) + // _log.debug("seq=0 && size=" + packet.getPayloadSize() + ": isNew? " + isNew + // + " packet: " + packet + " con: " + con); + //} + + if (_log.shouldLog(Log.DEBUG)) + _log.debug((isNew ? "New" : "Dup or ack-only") + " inbound packet on " + con + ": " + packet); // close *after* receiving the data, as well as after verifying the signatures / etc if (packet.isFlagSet(Packet.FLAG_CLOSE) && packet.isFlagSet(Packet.FLAG_SIGNATURE_INCLUDED)) @@ -151,7 +154,9 @@ public class ConnectionPacketHandler { if (packet.isFlagSet(Packet.FLAG_DELAY_REQUESTED) && (packet.getOptionalDelay() <= 0) ) { if (_log.shouldLog(Log.DEBUG)) _log.debug("Scheduling immediate ack for " + packet); - con.setNextSendTime(_context.clock().now() + con.getOptions().getSendAckDelay()); + //con.setNextSendTime(_context.clock().now() + con.getOptions().getSendAckDelay()); + // honor request "almost" immediately + con.setNextSendTime(_context.clock().now() + 250); } else { int delay = con.getOptions().getSendAckDelay(); if (packet.isFlagSet(Packet.FLAG_DELAY_REQUESTED)) // delayed ACK requested @@ -222,6 +227,10 @@ public class ConnectionPacketHandler { // con.fastRetransmit(); } + /** + * Process the acks in a received packet, and adjust our window and RTT + * @return are we congested? + */ private boolean ack(Connection con, long ackThrough, long nacks[], Packet packet, boolean isNew, boolean choke) { if (ackThrough < 0) return false; //if ( (nacks != null) && (nacks.length > 0) ) @@ -287,7 +296,7 @@ public class ConnectionPacketHandler { return adjustWindow(con, isNew, packet.getSequenceNum(), numResends, (acked != null ? acked.size() : 0), choke); } - + /** @return are we congested? */ private boolean adjustWindow(Connection con, boolean isNew, long sequenceNum, int numResends, int acked, boolean choke) { boolean congested = false; if ( (!isNew) && (sequenceNum > 0) ) { diff --git a/apps/streaming/java/src/net/i2p/client/streaming/Packet.java b/apps/streaming/java/src/net/i2p/client/streaming/Packet.java index 85981d9e6..14ebb61d5 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/Packet.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/Packet.java @@ -42,7 +42,7 @@ import net.i2p.util.Log; *
  • {@link #FLAG_MAX_PACKET_SIZE_INCLUDED}: 2 byte integer
  • *
  • {@link #FLAG_PROFILE_INTERACTIVE}: no option data
  • *
  • {@link #FLAG_ECHO}: no option data
  • - *
  • {@link #FLAG_NO_ACK}: no option data
  • + *
  • {@link #FLAG_NO_ACK}: no option data - this appears to be unused, we always ack, even for the first packet
  • * * *

    If the signature is included, it uses the Destination's DSA key From 234c084c2a1f7a5e4cb7dd080d498edc92ecb4f9 Mon Sep 17 00:00:00 2001 From: zzz Date: Tue, 24 Nov 2009 20:15:29 +0000 Subject: [PATCH 003/127] * OrderedProperties: Vastly implify, use in i2psnark --- .../src/org/klomp/snark/SnarkManager.java | 3 +- .../src/net/i2p/util/OrderedProperties.java | 353 +----------------- 2 files changed, 16 insertions(+), 340 deletions(-) diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java index d83b54060..2ad0107d6 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java +++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java @@ -20,6 +20,7 @@ import net.i2p.data.Base64; import net.i2p.data.DataHelper; import net.i2p.util.I2PAppThread; import net.i2p.util.Log; +import net.i2p.util.OrderedProperties; /** * Manage multiple snarks @@ -126,7 +127,7 @@ public class SnarkManager implements Snark.CompleteListener { /** null to set initial defaults */ public void loadConfig(String filename) { if (_config == null) - _config = new Properties(); + _config = new OrderedProperties(); if (filename != null) { File cfg = new File(filename); if (!cfg.isAbsolute()) diff --git a/core/java/src/net/i2p/util/OrderedProperties.java b/core/java/src/net/i2p/util/OrderedProperties.java index 3c10dcb92..731f27a85 100644 --- a/core/java/src/net/i2p/util/OrderedProperties.java +++ b/core/java/src/net/i2p/util/OrderedProperties.java @@ -9,371 +9,46 @@ package net.i2p.util; * */ -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PrintStream; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; +import java.util.Comparator; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.TreeSet; -import net.i2p.data.DataHelper; - /** * Properties map that has its keySet ordered consistently (via the key's lexicographical ordering). * This is useful in environments where maps must stay the same order (e.g. for signature verification) * This does NOT support remove against the iterators / etc. * + * @author zzz Rewritten + * + * Now unsorted until the keyset or entryset is requested. + * The class is unsynchronized. + * The keySet() and entrySet() methods return ordered sets. + * Others - such as the enumerations values(), keys(), propertyNames() - do not. */ public class OrderedProperties extends Properties { - private final static Log _log = new Log(OrderedProperties.class); - /** ordered set of keys (strings) stored in the properties */ - private TreeSet _order; - /** simple key=value mapping of the actual data */ - private Map _data; - - /** lock this before touching _order or _data */ - private final Object _lock = new Object(); public OrderedProperties() { super(); - _order = new TreeSet(); - _data = new HashMap(); - } - - @Override - public boolean contains(Object value) { - return containsValue(value); - } - - @Override - public boolean containsKey(Object key) { - synchronized (_lock) { - return _data.containsKey(key); - } - } - - @Override - public boolean containsValue(Object value) { - synchronized (_lock) { - return _data.containsValue(value); - } - } - - @Override - public boolean equals(Object obj) { - if ((obj != null) && (obj instanceof OrderedProperties)) { - synchronized (_lock) { - return _data.equals(obj); - } - } - - return false; - } - - @Override - public int hashCode() { - synchronized (_lock) { - return _data.hashCode(); - } - } - - @Override - public boolean isEmpty() { - return size() == 0; - } - - @Override - public String getProperty(String key) { - return getProperty((Object) key); - } - - @Override - public Object get(Object key) { - return getProperty(key); - } - - private String getProperty(Object key) { - if (key == null) return null; - synchronized (_lock) { - Object rv = _data.get(key); - if ((rv != null) && (rv instanceof String)) return (String) rv; - - return null; - } - } - - @Override - public Object setProperty(String key, String val) { - if ((key == null) || (val == null)) throw new IllegalArgumentException("Null values are not supported"); - synchronized (_lock) { - _order.add(key); - Object rv = _data.put(key, val); - return rv; - } - } - - @Override - public Object put(Object key, Object val) { - if ((key == null) || (val == null)) throw new NullPointerException("Null values or keys are not allowed"); - if (!(key instanceof String) || !(val instanceof String)) - throw new IllegalArgumentException("Key or value is not a string"); - return setProperty((String) key, (String) val); - } - - @Override - public void putAll(Map data) { - if (data == null) return; - for (Iterator iter = data.entrySet().iterator(); iter.hasNext();) { - Map.Entry entry = (Map.Entry)iter.next(); - Object key = entry.getKey(); - Object val = entry.getValue(); - put(key, val); - } - } - - @Override - public Object clone() { - synchronized (_lock) { - OrderedProperties rv = new OrderedProperties(); - rv.putAll(this); - return rv; - } - } - - @Override - public void clear() { - synchronized (_lock) { - _order.clear(); - _data.clear(); - } - } - - @Override - public int size() { - synchronized (_lock) { - return _order.size(); - } - } - - @Override - public Object remove(Object key) { - synchronized (_lock) { - _order.remove(key); - Object rv = _data.remove(key); - return rv; - } } @Override public Set keySet() { - synchronized (_lock) { - return Collections.unmodifiableSortedSet((TreeSet) _order.clone()); - } + return Collections.unmodifiableSortedSet(new TreeSet(super.keySet())); } @Override public Set entrySet() { - synchronized (_lock) { - return Collections.unmodifiableSet(buildEntrySet((TreeSet) _order.clone())); - } + TreeSet rv = new TreeSet(new EntryComparator()); + rv.addAll(super.entrySet()); + return Collections.unmodifiableSortedSet(rv); } - @Override - public Collection values() { - synchronized (_lock) { - Collection values = new ArrayList(_data.size()); - for (Iterator iter = _data.values().iterator(); iter.hasNext();) { - values.add(iter.next()); - } - return values; - } - } - - @Override - public Enumeration elements() { - return Collections.enumeration(values()); - } - - @Override - public Enumeration keys() { - return Collections.enumeration(keySet()); - } - - @Override - public Enumeration propertyNames() { - return Collections.enumeration(keySet()); - } - - @Override - public void list(PrintStream out) { // nop - } - - @Override - public void list(PrintWriter out) { // nop - } - - @Override - public void load(InputStream in) { // nop - } - - //public void save(OutputStream out, String header) {} - @Override - public void store(OutputStream out, String header) { // nop - } - - private Set buildEntrySet(Set data) { - TreeSet ts = new TreeSet(); - for (Iterator iter = data.iterator(); iter.hasNext();) { - String key = (String) iter.next(); - String val = getProperty(key); - ts.add(new StringMapEntry(key, val)); - } - return ts; - } - - private static class StringMapEntry implements Map.Entry, Comparable { - private Object _key; - private Object _value; - - public StringMapEntry(String key, String val) { - _key = key; - _value = val; - } - - public Object getKey() { - return _key; - } - - public Object getValue() { - return _value; - } - - public Object setValue(Object value) { - Object old = _value; - _value = value; - return old; - } - - public int compareTo(Object o) { - if (o == null) return -1; - if (o instanceof StringMapEntry) return ((String) getKey()).compareTo((String)((StringMapEntry) o).getKey()); - if (o instanceof String) return ((String) getKey()).compareTo((String)o); - return -2; - } - - /* FIXME missing hashCode() method FIXME */ - @Override - public boolean equals(Object o) { - if (o == null) return false; - if (!(o instanceof StringMapEntry)) return false; - StringMapEntry e = (StringMapEntry) o; - return DataHelper.eq(e.getKey(), getKey()) && DataHelper.eq(e.getValue(), getValue()); - } - } - - /// - /// tests - /// - - public static void main(String args[]) { - test(new OrderedProperties()); - _log.debug("After ordered"); - //test(new Properties()); - //System.out.println("After normal"); - test2(); - testThrash(); - } - - private static void test2() { - OrderedProperties p = new OrderedProperties(); - p.setProperty("a", "b"); - p.setProperty("c", "d"); - OrderedProperties p2 = new OrderedProperties(); - try { - p2.putAll(p); - } catch (Throwable t) { - t.printStackTrace(); - } - _log.debug("After test2"); - } - - private static void test(Properties p) { - for (int i = 0; i < 10; i++) - p.setProperty(i + "asdfasdfasdf", "qwerasdfqwer"); - for (Iterator iter = p.keySet().iterator(); iter.hasNext();) { - String key = (String) iter.next(); - String val = p.getProperty(key); - _log.debug("[" + key + "] = [" + val + "]"); - } - p.remove(4 + "asdfasdfasdf"); - _log.debug("After remove"); - for (Iterator iter = p.keySet().iterator(); iter.hasNext();) { - String key = (String) iter.next(); - String val = p.getProperty(key); - _log.debug("[" + key + "] = [" + val + "]"); - } - try { - p.put("nullVal", null); - _log.debug("Null put did NOT fail!"); - } catch (NullPointerException npe) { - _log.debug("Null put failed correctly"); - } - } - - /** - * Set 100 concurrent threads trying to do some operations against a single - * OrderedProperties object a thousand times. Hopefully this will help - * flesh out any synchronization issues. - * - */ - private static void testThrash() { - OrderedProperties prop = new OrderedProperties(); - for (int i = 0; i < 100; i++) - prop.setProperty(i + "", i + " value"); - _log.debug("Thrash properties built"); - for (int i = 0; i < 100; i++) - thrash(prop, i); - } - - private static void thrash(Properties props, int i) { - I2PThread t = new I2PThread(new Thrash(props)); - t.setName("Thrash" + i); - t.start(); - } - - private static class Thrash implements Runnable { - private Properties _props; - - public Thrash(Properties props) { - _props = props; - } - - public void run() { - int numRuns = 1000; - _log.debug("Begin thrashing " + numRuns + " times"); - for (int i = 0; i < numRuns; i++) { - Set keys = _props.keySet(); - //_log.debug("keySet fetched"); - int cur = 0; - for (Iterator iter = keys.iterator(); iter.hasNext();) { - Object o = iter.next(); - Object val = _props.get(o); - //_log.debug("Value " + cur + " fetched"); - cur++; - } - //_log.debug("Values fetched"); - int size = _props.size(); - _log.debug("Size calculated"); - } - _log.debug("Done thrashing " + numRuns + " times"); + private static class EntryComparator implements Comparator { + public int compare(Object l, Object r) { + return ((String)((Map.Entry)l).getKey()).compareTo(((String)((Map.Entry)r).getKey())); } } } From 95e0492b329e3e6aab030b53a94ed19524fca410 Mon Sep 17 00:00:00 2001 From: zzz Date: Tue, 24 Nov 2009 20:20:30 +0000 Subject: [PATCH 004/127] * Profiles: Record successes in the DB fail rate too, so we can calculate a percentage * profiles.jsp: - Change fail rate from count to percent - Hide standard profiles by default --- .../router/web/ProfileOrganizerRenderer.java | 30 ++++++++++++++----- .../net/i2p/router/web/ProfilesHelper.java | 8 ++++- apps/routerconsole/jsp/profiles.jsp | 1 + .../net/i2p/router/peermanager/DBHistory.java | 4 +++ 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ProfileOrganizerRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/ProfileOrganizerRenderer.java index 55939897a..5e7ef4b94 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ProfileOrganizerRenderer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ProfileOrganizerRenderer.java @@ -32,7 +32,7 @@ class ProfileOrganizerRenderer { _organizer = organizer; _comparator = new ProfileComparator(); } - public void renderStatusHTML(Writer out) throws IOException { + public void renderStatusHTML(Writer out, boolean full) throws IOException { Set peers = _organizer.selectAllPeers(); long now = _context.clock().now(); @@ -40,6 +40,8 @@ class ProfileOrganizerRenderer { TreeSet order = new TreeSet(_comparator); TreeSet integratedPeers = new TreeSet(_comparator); + int older = 0; + int standard = 0; for (Iterator iter = peers.iterator(); iter.hasNext();) { Hash peer = (Hash)iter.next(); if (_organizer.getUs().equals(peer)) continue; @@ -51,7 +53,14 @@ class ProfileOrganizerRenderer { if (info != null && info.getCapabilities().indexOf("f") >= 0) integratedPeers.add(prof); } - if (prof.getLastSendSuccessful() <= hideBefore) continue; + if (prof.getLastSendSuccessful() <= hideBefore) { + older++; + continue; + } + if ((!full) && !_organizer.isHighCapacity(peer)) { + standard++; + continue; + } order.add(prof); } @@ -62,7 +71,10 @@ class ProfileOrganizerRenderer { StringBuilder buf = new StringBuilder(16*1024); buf.append("

    ").append(_("Peer Profiles")).append("

    \n

    "); buf.append(_("Showing {0} recent profiles.", order.size())).append('\n'); - buf.append(_("Hiding {0} older profiles.", peers.size()-order.size())); + if (older > 0) + buf.append(_("Hiding {0} older profiles.", older)).append('\n'); + if (standard > 0) + buf.append("").append(_("Hiding {0} standard profiles.", standard)).append("\n"); buf.append("

    "); buf.append(""); buf.append(""); @@ -169,7 +181,7 @@ class ProfileOrganizerRenderer { } buf.append("
    "); - buf.append("

    ").append(_("Floodfill and Integrated Peers")).append("

    \n"); + buf.append("

    ").append(_("Floodfill and Integrated Peers")).append("

    \n"); buf.append(""); buf.append(""); buf.append(""); @@ -231,6 +243,7 @@ class ProfileOrganizerRenderer { for (int i = 0; i < 6; i++) buf.append("\n"); } buf.append("
    ").append(_("Peer")).append("").append(_(NA)); } + buf.append("
    "); @@ -324,12 +337,15 @@ class ProfileOrganizerRenderer { private String davg (DBHistory dbh, long rate) { RateStat rs = dbh.getFailedLookupRate(); if (rs == null) - return _(NA); + return "0%"; Rate r = rs.getRate(rate); if (r == null) - return _(NA); + return "0%"; long c = r.getCurrentEventCount() + r.getLastEventCount(); - return "" + c; + if (c <= 0) + return "0%"; + double avg = 0.5 + 100 * (r.getCurrentTotalValue() + r.getLastTotalValue()) / c; + return ((int) avg) + "%"; } /** translate a string */ diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ProfilesHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ProfilesHelper.java index ba7a6aa92..3e68c3169 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ProfilesHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ProfilesHelper.java @@ -4,13 +4,19 @@ import java.io.IOException; public class ProfilesHelper extends HelperBase { + private boolean _full; + public ProfilesHelper() {} + public void setFull(String f) { + _full = f != null; + } + /** @return empty string, writes directly to _out */ public String getProfileSummary() { try { ProfileOrganizerRenderer rend = new ProfileOrganizerRenderer(_context.profileOrganizer(), _context); - rend.renderStatusHTML(_out); + rend.renderStatusHTML(_out, _full); } catch (IOException ioe) { ioe.printStackTrace(); } diff --git a/apps/routerconsole/jsp/profiles.jsp b/apps/routerconsole/jsp/profiles.jsp index 035f50b5b..69100e349 100644 --- a/apps/routerconsole/jsp/profiles.jsp +++ b/apps/routerconsole/jsp/profiles.jsp @@ -11,6 +11,7 @@ " /> + " />

    <%=intl._("Banned Peers")%>

    diff --git a/router/java/src/net/i2p/router/peermanager/DBHistory.java b/router/java/src/net/i2p/router/peermanager/DBHistory.java index 38d06a890..a8e084e49 100644 --- a/router/java/src/net/i2p/router/peermanager/DBHistory.java +++ b/router/java/src/net/i2p/router/peermanager/DBHistory.java @@ -114,6 +114,7 @@ public class DBHistory { */ public void lookupSuccessful() { _successfulLookups++; + _failedLookupRate.addData(0, 0); _lastLookupSuccessful = _context.clock().now(); } @@ -132,6 +133,9 @@ public class DBHistory { * */ public void storeSuccessful() { + // Fixme, redefined this to include both lookup and store fails, + // need to fix the javadocs + _failedLookupRate.addData(0, 0); _lastStoreSuccessful = _context.clock().now(); } From 105524d9c07ce67cb9f8a43dc7995171df9e3467 Mon Sep 17 00:00:00 2001 From: zzz Date: Tue, 24 Nov 2009 20:22:31 +0000 Subject: [PATCH 005/127] remove another 8887 reference --- history.txt | 18 ++++++++++++++++++ .../resources/checklist.txt | 0 installer/resources/readme/readme.html | 2 +- .../java/src/net/i2p/router/RouterVersion.java | 2 +- 4 files changed, 20 insertions(+), 2 deletions(-) rename checklist.txt => installer/resources/checklist.txt (100%) diff --git a/history.txt b/history.txt index 66c39bf3d..c82497128 100644 --- a/history.txt +++ b/history.txt @@ -1,4 +1,22 @@ +2009-11-24 zzz + * DataStructures: Remove unused Logs + * OrderedProperties: Simplify, use in i2psnark + * Profiles: Record successes in the DB fail rate + too, so we can calculate a percentage + * profiles.jsp: + - Change fail rate from count to percent + - Hide standard profiles by default + * Streaming: + - When an "immediate" ack is requested, do it within + 250 ms (was 2000) + - Request immediate acks when < 1/3 of window remains, + or when < 3 packets remain in window, + and every 8 packets (was when < 2 packets in window remain) + - Change requested delay to RTT/2 (was RTO/2) + - Log cleanup and javadoc + 2009-11-21 zzz + * GeoIP: Update to Nov 17 2009 data * Netdb Floodfill rework part 4 of N: - Search closest-to-the-key - Put closest-to-the-key in explore don't-include-list diff --git a/checklist.txt b/installer/resources/checklist.txt similarity index 100% rename from checklist.txt rename to installer/resources/checklist.txt diff --git a/installer/resources/readme/readme.html b/installer/resources/readme/readme.html index fdb3682a9..79b7560ca 100644 --- a/installer/resources/readme/readme.html +++ b/installer/resources/readme/readme.html @@ -73,7 +73,7 @@ up, you can:

    Troubleshooting

    Be patient - I2P may be slow to start the first time as it searches for peers. If, after 30 minutes, your Active: connected/recent count has less than 10 connected - peers, you should open port 8887 on your firewall for better connectivity. If + peers, you should open I2P's port on your firewall for better connectivity. If you cannot see any eepsites at all (even www.i2p2.i2p), be sure your browser proxy is set to 127.0.0.1 port 4444. You may also want to review the information on the I2P website, diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 67b9de3fe..1ca622af5 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 20; + public final static long BUILD = 21; /** for example "-test" */ public final static String EXTRA = ""; public final static String FULL_VERSION = VERSION + "-" + BUILD + EXTRA; From 6371f66677d91b5ee1d1af1934613c1a734d35d2 Mon Sep 17 00:00:00 2001 From: z3d Date: Fri, 27 Nov 2009 12:03:56 +0000 Subject: [PATCH 006/127] Midnight console theme tweaks. --- .../themes/console/midnight/console.css | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/installer/resources/themes/console/midnight/console.css b/installer/resources/themes/console/midnight/console.css index 1c89b49e6..10ac6422b 100644 --- a/installer/resources/themes/console/midnight/console.css +++ b/installer/resources/themes/console/midnight/console.css @@ -47,7 +47,7 @@ div.logo hr { background: #99f; height: 1px; border: 0px solid #99f; - margin: 8px -3px; + margin: 8px -5px; } div.logo a:link, div.logo a:visited { @@ -103,7 +103,7 @@ div.warning hr { background: #fb7; height: 1px; border: 0px solid #fb7; - margin: 10px 0 5px 0; + margin: 10px 0; } div.warning h3 { @@ -114,6 +114,7 @@ div.warning h3 { font-variant: small-caps; text-transform: capitalize; font-size: 12.5pt; + background: none; } /* console error messages */ @@ -220,7 +221,7 @@ div.routersummary table { border: 0; text-align: center !important; margin: -5px 0px -5px 2px; - width: 185px !important; + width: 186px !important; overflow: hidden; font-size: 8pt; padding: 0 -12px; @@ -257,6 +258,7 @@ div.tunnels table{ width: 16px; text-align: right; margin-right: -2px; + padding-right: 0; } div.routersummary form { @@ -564,7 +566,7 @@ h2, h3 { .proxyfooter{ font-size: 7pt; - display: none !important; + display: none !important; } table { @@ -860,4 +862,12 @@ div.graphspanel h3 { table code { font-size: 8.5pt; +} + +table li:last-child{ + margin-bottom: 15px; +} + +table ul { + font-size: 8.5pt; } \ No newline at end of file From ab0a5a06af3c0cbce44efcaed6780357178cc64d Mon Sep 17 00:00:00 2001 From: zzz Date: Fri, 27 Nov 2009 13:26:38 +0000 Subject: [PATCH 007/127] add basic no-webapp handler --- .../i2p/router/web/RouterConsoleRunner.java | 22 ++++++++++++++++++- apps/routerconsole/jsp/nowebapp.jsp | 16 ++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 apps/routerconsole/jsp/nowebapp.jsp diff --git a/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java b/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java index ec2b10c24..bcd1f3cbd 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java @@ -1,5 +1,6 @@ package net.i2p.router.web; +import java.util.ArrayList; import java.io.File; import java.io.FilenameFilter; import java.io.IOException; @@ -20,6 +21,7 @@ import org.mortbay.http.SecurityConstraint; import org.mortbay.http.handler.SecurityHandler; import org.mortbay.jetty.Server; import org.mortbay.jetty.servlet.WebApplicationContext; +import org.mortbay.jetty.servlet.WebApplicationHandler; public class RouterConsoleRunner { private Server _server; @@ -87,6 +89,8 @@ public class RouterConsoleRunner { if (!_webAppsDir.endsWith("/")) _webAppsDir += '/'; + List notStarted = new ArrayList(); + WebApplicationHandler baseHandler = null; try { StringTokenizer tok = new StringTokenizer(_listenHost, " ,"); int boundAddresses = 0; @@ -111,7 +115,8 @@ public class RouterConsoleRunner { File tmpdir = new File(workDir, ROUTERCONSOLE + "-" + _listenPort); tmpdir.mkdir(); wac.setTempDirectory(tmpdir); - wac.addHandler(0, new LocaleWebAppHandler(I2PAppContext.getGlobalContext())); + baseHandler = new LocaleWebAppHandler(I2PAppContext.getGlobalContext()); + wac.addHandler(0, baseHandler); initialize(wac); File dir = new File(_webAppsDir); String fileNames[] = dir.list(WarFilenameFilter.instance()); @@ -132,6 +137,8 @@ public class RouterConsoleRunner { props.setProperty(PREFIX + appName + ENABLED, "true"); rewrite = true; } + } else { + notStarted.add(appName); } } catch (IOException ioe) { System.err.println("Error resolving '" + fileNames[i] + "' in '" + dir); @@ -154,6 +161,19 @@ public class RouterConsoleRunner { "\"::1,\" in the \"clientApp.0.args\" line of the clients.config file.\n" + "Exception: " + me); } + + if (baseHandler != null) { + // map each not-started webapp to the error page + for (int i = 0; i < notStarted.size(); i++) { + try { + baseHandler.mapPathToServlet('/' + notStarted.get(i) + "/*", + "net.i2p.router.web.jsp.nowebapp_jsp"); + } catch (Throwable me) { + System.err.println(me); + } + } + } + try { SysTray tray = SysTray.getInstance(); } catch (Throwable t) { diff --git a/apps/routerconsole/jsp/nowebapp.jsp b/apps/routerconsole/jsp/nowebapp.jsp new file mode 100644 index 000000000..f62ae6b16 --- /dev/null +++ b/apps/routerconsole/jsp/nowebapp.jsp @@ -0,0 +1,16 @@ +<%@page contentType="text/html"%> +<%@page pageEncoding="UTF-8"%> + +<% + response.setStatus(404, "Not Found"); +%> + +<%@include file="css.jsi" %> +<%=intl.title("WebApp Not Found")%> + +<%@include file="summary.jsi" %> +

    <%=intl._("Web Application Not Running")%>

    +
    +<%=intl._("The requested web application is not running.")%> +<%=intl._("Please visit the config clients page to start it.")%> +
    From ea0747171f69c1ccb0eef9aa328c2da16939f166 Mon Sep 17 00:00:00 2001 From: zzz Date: Fri, 27 Nov 2009 14:39:53 +0000 Subject: [PATCH 008/127] * NetDb: - Switch from ArrayList to ConcurrentHashSet in KBucketImpl to reduce chance of deadlock; remove periodic shuffling of the bucket, needs to be addressed elsewhere --- .../router/networkdb/kademlia/KBucket.java | 6 +- .../networkdb/kademlia/KBucketImpl.java | 82 +++++++++---------- .../router/networkdb/kademlia/KBucketSet.java | 7 +- .../networkdb/kademlia/PeerSelector.java | 5 +- 4 files changed, 48 insertions(+), 52 deletions(-) diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/KBucket.java b/router/java/src/net/i2p/router/networkdb/kademlia/KBucket.java index a329977b4..5c3c7b0e2 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/KBucket.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/KBucket.java @@ -56,19 +56,19 @@ interface KBucket { * Retrieve all routing table entries stored in the bucket * @return set of Hash structures */ - public Set getEntries(); + public Set getEntries(); /** * Retrieve hashes stored in the bucket, excluding the ones specified * @return set of Hash structures */ - public Set getEntries(Set toIgnoreHashes); + public Set getEntries(Set toIgnoreHashes); public void getEntries(SelectionCollector collector); /** * Fill the bucket with entries * @param entries set of Hash structures */ - public void setEntries(Set entries); + public void setEntries(Set entries); /** * Generate a random key that would go inside this bucket diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/KBucketImpl.java b/router/java/src/net/i2p/router/networkdb/kademlia/KBucketImpl.java index 58e6b16c4..2df76e40c 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/KBucketImpl.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/KBucketImpl.java @@ -9,24 +9,35 @@ package net.i2p.router.networkdb.kademlia; */ import java.math.BigInteger; -import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; -import java.util.List; import java.util.Set; import net.i2p.I2PAppContext; import net.i2p.data.DataHelper; import net.i2p.data.Hash; import net.i2p.router.RouterContext; +import net.i2p.util.ConcurrentHashSet; import net.i2p.util.Log; import net.i2p.util.RandomSource; class KBucketImpl implements KBucket { private Log _log; - /** set of Hash objects for the peers in the kbucket */ - private final List _entries; + /** + * set of Hash objects for the peers in the kbucketx + * + * jrandom switched from a HashSet to an ArrayList with this change: + * 2005-08-27 jrandom + * * Minor logging and optimization tweaks in the router and SDK + * + * Now we switch back to a ConcurrentHashSet and remove all the + * synchronization, which may or may not be faster than + * a synchronized ArrayList, with checks for existence before + * adding a Hash. But the other benefit is it removes one + * cause of profileMangager/netDb deadlock. + */ + private final Set _entries; /** we center the kbucket set on the given hash, and derive distances from this */ private Hash _local; /** include if any bits equal or higher to this bit (in big endian order) */ @@ -41,7 +52,7 @@ class KBucketImpl implements KBucket { public KBucketImpl(I2PAppContext context, Hash local) { _context = context; _log = context.logManager().getLog(KBucketImpl.class); - _entries = new ArrayList(0); //all but the last 1 or 2 buckets will be empty + _entries = new ConcurrentHashSet(2); //all but the last 1 or 2 buckets will be empty _lastShuffle = context.clock().now(); setLocal(local); } @@ -53,9 +64,7 @@ class KBucketImpl implements KBucket { _end = highOrderBitLimit; } public int getKeyCount() { - synchronized (_entries) { - return _entries.size(); - } + return _entries.size(); } public Hash getLocal() { return _local; } @@ -198,46 +207,35 @@ class KBucketImpl implements KBucket { return true; } - public Set getEntries() { - Set entries = new HashSet(64); - synchronized (_entries) { - for (int i = 0; i < _entries.size(); i++) - entries.add((Hash)_entries.get(i)); - } + public Set getEntries() { + Set entries = new HashSet(_entries); return entries; } - public Set getEntries(Set toIgnoreHashes) { - Set entries = new HashSet(64); - synchronized (_entries) { - for (int i = 0; i < _entries.size(); i++) - entries.add((Hash)_entries.get(i)); - entries.removeAll(toIgnoreHashes); - } + public Set getEntries(Set toIgnoreHashes) { + Set entries = new HashSet(_entries); + entries.removeAll(toIgnoreHashes); return entries; } public void getEntries(SelectionCollector collector) { - synchronized (_entries) { - for (int i = 0; i < _entries.size(); i++) - collector.add((Hash)_entries.get(i)); + Set entries = new HashSet(_entries); + for (Hash h : entries) { + collector.add(h); } } - public void setEntries(Set entries) { - synchronized (_entries) { - _entries.clear(); - for (Iterator iter = entries.iterator(); iter.hasNext(); ) { - Hash entry = (Hash)iter.next(); - if (!_entries.contains(entry)) - _entries.add(entry); - } - } + public void setEntries(Set entries) { + _entries.clear(); + _entries.addAll(entries); } + /** + * Todo: shuffling here is a hack and doesn't work since + * wwe witched back to a HashSet implementation + */ public int add(Hash peer) { - synchronized (_entries) { - if (!_entries.contains(peer)) - _entries.add(peer); + _entries.add(peer); +/********** // Randomize the bucket every once in a while if we are floodfill, so that // exploration will return better results. See FloodfillPeerSelector.add(Hash). if (_lastShuffle + SHUFFLE_DELAY < _context.clock().now() && @@ -245,14 +243,12 @@ class KBucketImpl implements KBucket { Collections.shuffle(_entries, _context.random()); _lastShuffle = _context.clock().now(); } - return _entries.size(); - } +***********/ + return _entries.size(); } public boolean remove(Hash peer) { - synchronized (_entries) { - return _entries.remove(peer); - } + return _entries.remove(peer); } /** @@ -332,9 +328,7 @@ class KBucketImpl implements KBucket { public String toString() { StringBuilder buf = new StringBuilder(1024); buf.append("KBucketImpl: "); - synchronized (_entries) { - buf.append(_entries.toString()).append("\n"); - } + buf.append(_entries.toString()).append("\n"); buf.append("Low bit: ").append(_begin).append(" high bit: ").append(_end).append('\n'); buf.append("Local key: \n"); if ( (_local != null) && (_local.getData() != null) ) diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/KBucketSet.java b/router/java/src/net/i2p/router/networkdb/kademlia/KBucketSet.java index c17292bdd..0b8fce229 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/KBucketSet.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/KBucketSet.java @@ -9,6 +9,7 @@ package net.i2p.router.networkdb.kademlia; */ import java.math.BigInteger; +import java.util.Collections; import java.util.HashSet; import java.util.Set; @@ -88,9 +89,9 @@ class KBucketSet { return removed; } - public Set getAll() { return getAll(new HashSet()); } - public Set getAll(Set toIgnore) { - HashSet all = new HashSet(1024); + public Set getAll() { return getAll(Collections.EMPTY_SET); }; + public Set getAll(Set toIgnore) { + Set all = new HashSet(1024); for (int i = 0; i < _buckets.length; i++) { all.addAll(_buckets[i].getEntries(toIgnore)); } diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/PeerSelector.java b/router/java/src/net/i2p/router/networkdb/kademlia/PeerSelector.java index 918465391..7ce9853ca 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/PeerSelector.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/PeerSelector.java @@ -121,8 +121,9 @@ public class PeerSelector { _matches = 0; } public void add(Hash entry) { - if (_context.profileOrganizer().isFailing(entry)) - return; + // deadlock seen here, and we don't mark profiles failing anymore + //if (_context.profileOrganizer().isFailing(entry)) + // return; if (_toIgnore.contains(entry)) return; RouterInfo info = _context.netDb().lookupRouterInfoLocally(entry); From 8682e7deb579dce4f0a4ebfab5deaaed212bbd10 Mon Sep 17 00:00:00 2001 From: zzz Date: Fri, 27 Nov 2009 16:29:15 +0000 Subject: [PATCH 009/127] cache the hash of the Hash --- core/java/src/net/i2p/data/Hash.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/java/src/net/i2p/data/Hash.java b/core/java/src/net/i2p/data/Hash.java index a99f5ceb5..10856d0c2 100644 --- a/core/java/src/net/i2p/data/Hash.java +++ b/core/java/src/net/i2p/data/Hash.java @@ -32,6 +32,7 @@ public class Hash extends DataStructureImpl { private volatile String _stringified; private volatile String _base64ed; private /* FIXME final FIXME */ Map _xorCache; + private int _cachedHashCode; public final static int HASH_LENGTH = 32; public final static Hash FAKE_HASH = new Hash(new byte[HASH_LENGTH]); @@ -54,6 +55,7 @@ public class Hash extends DataStructureImpl { _data = data; _stringified = null; _base64ed = null; + _cachedHashCode = calcHashCode(); } /** @@ -133,6 +135,7 @@ public class Hash extends DataStructureImpl { _base64ed = null; int read = read(in, _data); if (read != HASH_LENGTH) throw new DataFormatException("Not enough bytes to read the hash"); + _cachedHashCode = calcHashCode(); } public void writeBytes(OutputStream out) throws DataFormatException, IOException { @@ -150,6 +153,11 @@ public class Hash extends DataStructureImpl { /** a Hash is a hash, so just use the first 4 bytes for speed */ @Override public int hashCode() { + return _cachedHashCode; + } + + /** a Hash is a hash, so just use the first 4 bytes for speed */ + private int calcHashCode() { int rv = 0; if (_data != null) { for (int i = 0; i < 4; i++) From 2db7c2bdd8c4f97ce2fa63bc76df5ce44e381e7d Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 28 Nov 2009 13:38:35 +0000 Subject: [PATCH 010/127] new --- .../naming/EepGetAndAddNamingService.java | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 core/java/src/net/i2p/client/naming/EepGetAndAddNamingService.java diff --git a/core/java/src/net/i2p/client/naming/EepGetAndAddNamingService.java b/core/java/src/net/i2p/client/naming/EepGetAndAddNamingService.java new file mode 100644 index 000000000..cf282f719 --- /dev/null +++ b/core/java/src/net/i2p/client/naming/EepGetAndAddNamingService.java @@ -0,0 +1,69 @@ +/* + * public domain + * with no warranty of any kind, either expressed or implied. + */ +package net.i2p.client.naming; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; + +import net.i2p.I2PAppContext; +import net.i2p.data.Destination; + +/** + * Simple extension to EepGetNamingService to append what we find to hosts.txt, + * so we only have to do an EepGet query once. + * + * Note that there is little protection - there are a lot of validity checks in addressbook that are + * not included here. + * + * MUST be used from MetaNamingService, after HostsTxtNamingService. + * Cannot be used as the only NamingService! Be sure any naming service hosts + * are in hosts.txt. If this isn't after HostsTxtNamingService, you will + * clog up your hosts.txt with duplicate entries. + * + * Sample config to put in configadvanced.jsp (restart required): + * + * i2p.naming.impl=net.i2p.client.naming.MetaNamingService + * i2p.nameservicelist=net.i2p.client.naming.HostsTxtNamingService,net.i2p.client.naming.EepGetAndAddNamingService + * i2p.naming.eepget.list=http://stats.i2p/cgi-bin/hostquery.cgi?a=,http://i2host.i2p/cgi-bin/i2hostquery? + * + * @author zzz + */ +public class EepGetAndAddNamingService extends EepGetNamingService { + + /** default hosts.txt filename */ + private final static String DEFAULT_HOSTS_FILE = "hosts.txt"; + + public EepGetAndAddNamingService(I2PAppContext context) { + super(context); + } + + @Override + public Destination lookup(String hostname) { + Destination rv = super.lookup(hostname); + if (rv != null) { + hostname = hostname.toLowerCase(); + // If it's long, assume it's a key. + if (hostname.length() < 516 && hostname.endsWith(".i2p") && ! hostname.endsWith(".b32.i2p")) { + File f = new File(_context.getRouterDir(), DEFAULT_HOSTS_FILE); + if ( (f.exists()) && (f.canWrite()) ) { + synchronized(this) { + FileOutputStream fos = null; + try { + fos = new FileOutputStream(f, true); + String line = hostname + '=' + rv.toBase64() + System.getProperty("line.separator"); + fos.write(line.getBytes()); + } catch (IOException ioe) { + System.err.println("Error appending: " + ioe); + } finally { + if (fos != null) try { fos.close(); } catch (IOException cioe) {} + } + } + } + } + } + return rv; + } +} From 0642fa80939d9ca5c0972ef65f0defc645caf443 Mon Sep 17 00:00:00 2001 From: sponge Date: Sat, 28 Nov 2009 13:53:34 +0000 Subject: [PATCH 011/127] * Improvement to BOB's TCPio to hopefully lower load average. It seems to be helping a little when stress-tested with Robert. --- apps/BOB/nbproject/private/private.xml | 3 --- apps/BOB/src/net/i2p/BOB/DoCMDS.java | 2 +- apps/BOB/src/net/i2p/BOB/TCPio.java | 8 ++++++-- history.txt | 4 ++++ router/java/src/net/i2p/router/RouterVersion.java | 2 +- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/apps/BOB/nbproject/private/private.xml b/apps/BOB/nbproject/private/private.xml index 685ecc5a1..c1f155a78 100644 --- a/apps/BOB/nbproject/private/private.xml +++ b/apps/BOB/nbproject/private/private.xml @@ -1,7 +1,4 @@ - - file:/usblv/NetBeansProjects/wi2p.i2p/apps/BOB/src/net/i2p/BOB/BOB.java - diff --git a/apps/BOB/src/net/i2p/BOB/DoCMDS.java b/apps/BOB/src/net/i2p/BOB/DoCMDS.java index 8e4afb143..14c83c4ba 100644 --- a/apps/BOB/src/net/i2p/BOB/DoCMDS.java +++ b/apps/BOB/src/net/i2p/BOB/DoCMDS.java @@ -50,7 +50,7 @@ public class DoCMDS implements Runnable { // FIX ME // I need a better way to do versioning, but this will do for now. - public static final String BMAJ = "00", BMIN = "00", BREV = "08", BEXT = ""; + public static final String BMAJ = "00", BMIN = "00", BREV = "09", BEXT = ""; public static final String BOBversion = BMAJ + "." + BMIN + "." + BREV + BEXT; private Socket server; private Properties props; diff --git a/apps/BOB/src/net/i2p/BOB/TCPio.java b/apps/BOB/src/net/i2p/BOB/TCPio.java index d501759ef..5e99637dd 100644 --- a/apps/BOB/src/net/i2p/BOB/TCPio.java +++ b/apps/BOB/src/net/i2p/BOB/TCPio.java @@ -78,16 +78,20 @@ public class TCPio implements Runnable { * --Sponge * * Tested with 128 bytes, and there was no performance gain. + * 8192 bytes did lower load average across many connections. + * Should I raise it higer? The correct thing to do would be to + * override... perhaps use NTCP, but I2P's streaming lib lacks + * anything NTCP compatable. * * --Sponge */ int b; - byte a[] = new byte[1]; + byte a[] = new byte[8192]; try { try { while (lives.get()) { - b = Ain.read(a, 0, 1); + b = Ain.read(a, 0, 8192); if (b > 0) { Aout.write(a, 0, b); } else if (b == 0) { diff --git a/history.txt b/history.txt index c82497128..f70d505c5 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,7 @@ +2009-11-28 sponge + * Improvement to BOB's TCPio to hopefully lower load average. It seems + to be helping a little when stress-tested with Robert. + 2009-11-24 zzz * DataStructures: Remove unused Logs * OrderedProperties: Simplify, use in i2psnark diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 1ca622af5..b9d2a6b01 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 21; + public final static long BUILD = 22; /** for example "-test" */ public final static String EXTRA = ""; public final static String FULL_VERSION = VERSION + "-" + BUILD + EXTRA; From c10ea84adec0397b584b0fd6d3cea955fa9164bc Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 28 Nov 2009 14:37:07 +0000 Subject: [PATCH 012/127] * NamingServices - Move default reverseLookup to base class - Deprecate unused services --- core/java/src/net/i2p/I2PAppContext.java | 2 ++ core/java/src/net/i2p/client/naming/AddressDB.java | 3 +++ .../src/net/i2p/client/naming/AddressDBNamingService.java | 3 +++ core/java/src/net/i2p/client/naming/DummyAddressDB.java | 3 +++ .../java/src/net/i2p/client/naming/DummyNamingService.java | 7 +------ .../src/net/i2p/client/naming/EepGetNamingService.java | 5 ----- core/java/src/net/i2p/client/naming/ExecNamingService.java | 5 ----- .../src/net/i2p/client/naming/FilesystemAddressDB.java | 3 +++ .../src/net/i2p/client/naming/HostsTxtNamingService.java | 1 + core/java/src/net/i2p/client/naming/NamingService.java | 4 +++- core/java/src/net/i2p/client/naming/PetName.java | 2 +- core/java/src/net/i2p/client/naming/PetNameDB.java | 2 +- .../src/net/i2p/client/naming/PetNameNamingService.java | 3 +++ 13 files changed, 24 insertions(+), 19 deletions(-) diff --git a/core/java/src/net/i2p/I2PAppContext.java b/core/java/src/net/i2p/I2PAppContext.java index 86c1dc907..1cdb6b297 100644 --- a/core/java/src/net/i2p/I2PAppContext.java +++ b/core/java/src/net/i2p/I2PAppContext.java @@ -432,12 +432,14 @@ public class I2PAppContext { } } + /** @deprecated unused */ public PetNameDB petnameDb() { if (!_petnameDbInitialized) initializePetnameDb(); return _petnameDb; } + /** @deprecated unused */ private void initializePetnameDb() { synchronized (this) { if (_petnameDb == null) { diff --git a/core/java/src/net/i2p/client/naming/AddressDB.java b/core/java/src/net/i2p/client/naming/AddressDB.java index 29b8cf7cb..c43ada589 100644 --- a/core/java/src/net/i2p/client/naming/AddressDB.java +++ b/core/java/src/net/i2p/client/naming/AddressDB.java @@ -7,6 +7,9 @@ import net.i2p.I2PAppContext; import net.i2p.data.Address; import net.i2p.util.Log; +/** + * @deprecated unused + */ public abstract class AddressDB { private final static Log _log = new Log(NamingService.class); diff --git a/core/java/src/net/i2p/client/naming/AddressDBNamingService.java b/core/java/src/net/i2p/client/naming/AddressDBNamingService.java index 4dc65a10d..928212c89 100644 --- a/core/java/src/net/i2p/client/naming/AddressDBNamingService.java +++ b/core/java/src/net/i2p/client/naming/AddressDBNamingService.java @@ -6,6 +6,9 @@ import net.i2p.I2PAppContext; import net.i2p.data.Address; import net.i2p.data.Destination; +/** + * @deprecated unused + */ public class AddressDBNamingService extends NamingService { private AddressDB _addressdb; diff --git a/core/java/src/net/i2p/client/naming/DummyAddressDB.java b/core/java/src/net/i2p/client/naming/DummyAddressDB.java index d7ee9bac1..e18a2b7ad 100644 --- a/core/java/src/net/i2p/client/naming/DummyAddressDB.java +++ b/core/java/src/net/i2p/client/naming/DummyAddressDB.java @@ -5,6 +5,9 @@ import java.util.Collection; import net.i2p.I2PAppContext; import net.i2p.data.Address; +/** + * @deprecated unused + */ public class DummyAddressDB extends AddressDB { public DummyAddressDB(I2PAppContext context) { diff --git a/core/java/src/net/i2p/client/naming/DummyNamingService.java b/core/java/src/net/i2p/client/naming/DummyNamingService.java index dddd5915b..ff0855c27 100644 --- a/core/java/src/net/i2p/client/naming/DummyNamingService.java +++ b/core/java/src/net/i2p/client/naming/DummyNamingService.java @@ -27,9 +27,4 @@ class DummyNamingService extends NamingService { public Destination lookup(String hostname) { return lookupBase64(hostname); } - - @Override - public String reverseLookup(Destination dest) { - return null; - } -} \ No newline at end of file +} diff --git a/core/java/src/net/i2p/client/naming/EepGetNamingService.java b/core/java/src/net/i2p/client/naming/EepGetNamingService.java index 6ce7ca17b..8ddeaa248 100644 --- a/core/java/src/net/i2p/client/naming/EepGetNamingService.java +++ b/core/java/src/net/i2p/client/naming/EepGetNamingService.java @@ -136,9 +136,4 @@ public class EepGetNamingService extends NamingService { _log.error("Caught from: " + url + hostname); return null; } - - @Override - public String reverseLookup(Destination dest) { - return null; - } } diff --git a/core/java/src/net/i2p/client/naming/ExecNamingService.java b/core/java/src/net/i2p/client/naming/ExecNamingService.java index f014fa0d7..446e907c4 100644 --- a/core/java/src/net/i2p/client/naming/ExecNamingService.java +++ b/core/java/src/net/i2p/client/naming/ExecNamingService.java @@ -126,9 +126,4 @@ public class ExecNamingService extends NamingService { } return null; } - - @Override - public String reverseLookup(Destination dest) { - return null; - } } diff --git a/core/java/src/net/i2p/client/naming/FilesystemAddressDB.java b/core/java/src/net/i2p/client/naming/FilesystemAddressDB.java index cefbf5eea..806b9e90a 100644 --- a/core/java/src/net/i2p/client/naming/FilesystemAddressDB.java +++ b/core/java/src/net/i2p/client/naming/FilesystemAddressDB.java @@ -16,6 +16,9 @@ import net.i2p.data.DataFormatException; import net.i2p.data.DataHelper; import net.i2p.util.Log; +/** + * @deprecated unused + */ public class FilesystemAddressDB extends AddressDB { public final static String PROP_ADDRESS_DIR = "i2p.addressdir"; diff --git a/core/java/src/net/i2p/client/naming/HostsTxtNamingService.java b/core/java/src/net/i2p/client/naming/HostsTxtNamingService.java index f89d56d09..ff1b367fd 100644 --- a/core/java/src/net/i2p/client/naming/HostsTxtNamingService.java +++ b/core/java/src/net/i2p/client/naming/HostsTxtNamingService.java @@ -138,6 +138,7 @@ public class HostsTxtNamingService extends NamingService { return null; } + /** @deprecated unused */ @Override public String reverseLookup(Hash h) { List filenames = getFilenames(); diff --git a/core/java/src/net/i2p/client/naming/NamingService.java b/core/java/src/net/i2p/client/naming/NamingService.java index fd6277139..a7098d799 100644 --- a/core/java/src/net/i2p/client/naming/NamingService.java +++ b/core/java/src/net/i2p/client/naming/NamingService.java @@ -61,7 +61,9 @@ public abstract class NamingService { * if none is known. It is safe for subclasses to always return * null if no reverse lookup is possible. */ - public abstract String reverseLookup(Destination dest); + public String reverseLookup(Destination dest) { return null; }; + + /** @deprecated unused */ public String reverseLookup(Hash h) { return null; }; /** diff --git a/core/java/src/net/i2p/client/naming/PetName.java b/core/java/src/net/i2p/client/naming/PetName.java index 38d27b608..cb0df4ab9 100644 --- a/core/java/src/net/i2p/client/naming/PetName.java +++ b/core/java/src/net/i2p/client/naming/PetName.java @@ -7,7 +7,7 @@ import java.util.StringTokenizer; import net.i2p.data.DataHelper; /** - * + * deprecated unused but can be instantiated through I2PAppContext */ public class PetName { private String _name; diff --git a/core/java/src/net/i2p/client/naming/PetNameDB.java b/core/java/src/net/i2p/client/naming/PetNameDB.java index efa96e5d0..cff2ab56c 100644 --- a/core/java/src/net/i2p/client/naming/PetNameDB.java +++ b/core/java/src/net/i2p/client/naming/PetNameDB.java @@ -19,7 +19,7 @@ import java.util.Set; /** - * + * deprecated unused but can be instantiated through I2PAppContext */ public class PetNameDB { /** name (String) to PetName mapping */ diff --git a/core/java/src/net/i2p/client/naming/PetNameNamingService.java b/core/java/src/net/i2p/client/naming/PetNameNamingService.java index ec59249a7..a052315f3 100644 --- a/core/java/src/net/i2p/client/naming/PetNameNamingService.java +++ b/core/java/src/net/i2p/client/naming/PetNameNamingService.java @@ -5,6 +5,9 @@ import java.io.IOException; import net.i2p.I2PAppContext; import net.i2p.data.Destination; +/** + * @deprecated unused + */ public class PetNameNamingService extends NamingService { private PetNameDB _petnameDb; From 4b6989ef7bbbf8472d102a831c63e0d2fade6fd2 Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 28 Nov 2009 17:08:02 +0000 Subject: [PATCH 013/127] * Addressbook, susidns: Rework addressbook into a HttpServlet, so susidns can kick it when the subscription list changes --- .../java/src/net/i2p/addressbook/Servlet.java | 47 ++++++++++++++----- apps/addressbook/web.xml | 6 +++ .../src/i2p/susi/dns/SubscriptionsBean.java | 14 +++++- 3 files changed, 54 insertions(+), 13 deletions(-) diff --git a/apps/addressbook/java/src/net/i2p/addressbook/Servlet.java b/apps/addressbook/java/src/net/i2p/addressbook/Servlet.java index 8f26788e4..c5239609e 100644 --- a/apps/addressbook/java/src/net/i2p/addressbook/Servlet.java +++ b/apps/addressbook/java/src/net/i2p/addressbook/Servlet.java @@ -21,24 +21,43 @@ package net.i2p.addressbook; -import javax.servlet.GenericServlet; +import java.util.Random; + import javax.servlet.ServletConfig; import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; /** * A wrapper for addressbook to allow it to be started as a web application. * + * This was a GenericServlet, we make it an HttpServlet solely to provide a hook + * for SusiDNS to wake us up when the subscription list changes. + * * @author Ragnarok * */ -public class Servlet extends GenericServlet { +public class Servlet extends HttpServlet { + private Thread _thread; + private String _nonce; + private static final String PROP_NONCE = "addressbook.nonce"; - /* (non-Javadoc) - * @see javax.servlet.Servlet#service(javax.servlet.ServletRequest, javax.servlet.ServletResponse) + /** + * Hack to allow susidns to kick the daemon when the subscription list changes. + * URL must be /addressbook/ with wakeup param set, and nonce param set from system property. + * + * (non-Javadoc) + * see javax.servlet.Servlet#service(javax.servlet.ServletRequest, javax.servlet.ServletResponse) */ - public void service(ServletRequest request, ServletResponse response) { + public void service(HttpServletRequest request, HttpServletResponse response) { + //System.err.println("Got request nonce = " + request.getParameter("nonce")); + if (_thread != null && request.getParameter("wakeup") != null && + _nonce != null && _nonce.equals(request.getParameter("nonce"))) { + //System.err.println("Sending interrupt"); + _thread.interrupt(); + } + // no output } /* (non-Javadoc) @@ -49,15 +68,19 @@ public class Servlet extends GenericServlet { try { super.init(config); } catch (ServletException exp) { + System.err.println("Addressbook init exception: " + exp); } + _nonce = "" + Math.abs((new Random()).nextLong()); + // put the nonce where susidns can get it + System.setProperty(PROP_NONCE, _nonce); String[] args = new String[1]; args[0] = config.getInitParameter("home"); - DaemonThread thread = new DaemonThread(args); - thread.setDaemon(true); - thread.setName("Addressbook"); - thread.start(); + _thread = new DaemonThread(args); + _thread.setDaemon(true); + _thread.setName("Addressbook"); + _thread.start(); System.out.println("INFO: Starting Addressbook " + Daemon.VERSION); - System.out.println("INFO: config root under " + args[0]); + //System.out.println("INFO: config root under " + args[0]); } } diff --git a/apps/addressbook/web.xml b/apps/addressbook/web.xml index 0c3548c68..c5fe302a6 100644 --- a/apps/addressbook/web.xml +++ b/apps/addressbook/web.xml @@ -13,4 +13,10 @@ 1 + + + addressbook + / + + diff --git a/apps/susidns/src/java/src/i2p/susi/dns/SubscriptionsBean.java b/apps/susidns/src/java/src/i2p/susi/dns/SubscriptionsBean.java index 56a42208b..b860e2393 100644 --- a/apps/susidns/src/java/src/i2p/susi/dns/SubscriptionsBean.java +++ b/apps/susidns/src/java/src/i2p/susi/dns/SubscriptionsBean.java @@ -128,7 +128,19 @@ public class SubscriptionsBean if( lastSerial != null && serial != null && serial.compareTo( lastSerial ) == 0 ) { if( action.compareToIgnoreCase( "save") == 0 ) { save(); - message = "Subscriptions saved."; + String nonce = System.getProperty("addressbook.nonce"); + if (nonce != null) { + // Yes this is a hack. + // No it doesn't work on a text-mode browser. + // Fetching from the addressbook servlet + // with the correct parameters will kick off a + // config reload and fetch. + message = "Subscriptions saved, updating addressbook from subscription sources now." + + "\"\""; + } else { + message = "Subscriptions saved."; + } } else if( action.compareToIgnoreCase( "reload") == 0 ) { reload(); From 278b9174942349b4886e984023f7434c67e85854 Mon Sep 17 00:00:00 2001 From: sponge Date: Sun, 29 Nov 2009 15:02:50 +0000 Subject: [PATCH 014/127] net.i2p.router.transport.udp deadwood code cleanup. documented rare NPE in InboundEstablishState.java. --- apps/BOB/nbproject/private/private.xml | 3 +++ history.txt | 4 ++++ router/java/src/net/i2p/router/RouterVersion.java | 2 +- .../router/transport/udp/InboundEstablishState.java | 8 ++++---- .../router/transport/udp/IntroductionManager.java | 6 ++---- .../router/transport/udp/OutboundEstablishState.java | 3 +-- .../transport/udp/OutboundMessageFragments.java | 12 ++++++------ .../router/transport/udp/OutboundMessageState.java | 4 ++-- .../i2p/router/transport/udp/OutboundRefiller.java | 4 ++-- .../net/i2p/router/transport/udp/PacketBuilder.java | 6 ++---- .../net/i2p/router/transport/udp/PacketHandler.java | 3 +-- .../net/i2p/router/transport/udp/PacketPusher.java | 4 ++-- .../src/net/i2p/router/transport/udp/PeerState.java | 7 +++---- .../net/i2p/router/transport/udp/UDPEndpoint.java | 1 - .../src/net/i2p/router/transport/udp/UDPFlooder.java | 6 +++--- .../src/net/i2p/router/transport/udp/UDPPacket.java | 8 ++++---- .../net/i2p/router/transport/udp/UDPReceiver.java | 2 +- .../net/i2p/router/transport/udp/UDPTransport.java | 10 +++------- 18 files changed, 44 insertions(+), 49 deletions(-) diff --git a/apps/BOB/nbproject/private/private.xml b/apps/BOB/nbproject/private/private.xml index c1f155a78..653e554c3 100644 --- a/apps/BOB/nbproject/private/private.xml +++ b/apps/BOB/nbproject/private/private.xml @@ -1,4 +1,7 @@ + + file:/usblv/NetBeansProjects/i2p.i2p/apps/BOB/src/net/i2p/BOB/TCPio.java + diff --git a/history.txt b/history.txt index f70d505c5..79bb5b2a1 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,7 @@ +2009-11-29 sponge + * net.i2p.router.transport.udp deadwood code cleanup. + * documented rare NPE in InboundEstablishState.java. + 2009-11-28 sponge * Improvement to BOB's TCPio to hopefully lower load average. It seems to be helping a little when stress-tested with Robert. diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index b9d2a6b01..7de969bf4 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 22; + public final static long BUILD = 23; /** for example "-test" */ public final static String EXTRA = ""; public final static String FULL_VERSION = VERSION + "-" + BUILD + EXTRA; diff --git a/router/java/src/net/i2p/router/transport/udp/InboundEstablishState.java b/router/java/src/net/i2p/router/transport/udp/InboundEstablishState.java index fab4ce550..46085e3b4 100644 --- a/router/java/src/net/i2p/router/transport/udp/InboundEstablishState.java +++ b/router/java/src/net/i2p/router/transport/udp/InboundEstablishState.java @@ -46,7 +46,7 @@ public class InboundEstablishState { // general status private long _establishBegin; private long _lastReceive; - private long _lastSend; + // private long _lastSend; private long _nextSend; private RemoteHostId _remoteHostId; private int _currentState; @@ -129,6 +129,7 @@ public class InboundEstablishState { public synchronized byte[] getSentY() { if (_sentY == null) + // Rare NPE seen here... _sentY = _keyBuilder.getMyPublicValueBytes(); return _sentY; } @@ -198,7 +199,7 @@ public class InboundEstablishState { /** note that we just sent a SessionCreated packet */ public synchronized void createdPacketSent() { - _lastSend = _context.clock().now(); + // _lastSend = _context.clock().now(); if ( (_currentState == STATE_UNKNOWN) || (_currentState == STATE_REQUEST_RECEIVED) ) _currentState = STATE_CREATED_SENT; } @@ -210,8 +211,7 @@ public class InboundEstablishState { public synchronized void setNextSendTime(long when) { _nextSend = when; } /** RemoteHostId, uniquely identifies an attempt */ - // FIXME Exporting non-public type through public API FIXME - public RemoteHostId getRemoteHostId() { return _remoteHostId; } + RemoteHostId getRemoteHostId() { return _remoteHostId; } public synchronized void receiveSessionConfirmed(UDPPacketReader.SessionConfirmedReader conf) { if (_receivedIdentity == null) diff --git a/router/java/src/net/i2p/router/transport/udp/IntroductionManager.java b/router/java/src/net/i2p/router/transport/udp/IntroductionManager.java index 20db8a066..2e3329a8f 100644 --- a/router/java/src/net/i2p/router/transport/udp/IntroductionManager.java +++ b/router/java/src/net/i2p/router/transport/udp/IntroductionManager.java @@ -157,8 +157,7 @@ public class IntroductionManager { return found; } - /* FIXME Exporting non-public type through public API FIXME */ - public void receiveRelayIntro(RemoteHostId bob, UDPPacketReader reader) { + void receiveRelayIntro(RemoteHostId bob, UDPPacketReader reader) { if (_context.router().isHidden()) return; if (_log.shouldLog(Log.INFO)) @@ -167,8 +166,7 @@ public class IntroductionManager { _transport.send(_builder.buildHolePunch(reader)); } - /* FIXME Exporting non-public type through public API FIXME */ - public void receiveRelayRequest(RemoteHostId alice, UDPPacketReader reader) { + void receiveRelayRequest(RemoteHostId alice, UDPPacketReader reader) { if (_context.router().isHidden()) return; long tag = reader.getRelayRequestReader().readTag(); diff --git a/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java b/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java index 13a9b277f..ece42da7a 100644 --- a/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java +++ b/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java @@ -413,8 +413,7 @@ public class OutboundEstablishState { } /** uniquely identifies an attempt */ - /* FIXME Exporting non-public type through public API FIXME */ - public RemoteHostId getRemoteHostId() { return _remoteHostId; } + RemoteHostId getRemoteHostId() { return _remoteHostId; } /** we have received a real data packet, so we're done establishing */ public synchronized void dataReceived() { diff --git a/router/java/src/net/i2p/router/transport/udp/OutboundMessageFragments.java b/router/java/src/net/i2p/router/transport/udp/OutboundMessageFragments.java index 69f9f7554..f1d10e122 100644 --- a/router/java/src/net/i2p/router/transport/udp/OutboundMessageFragments.java +++ b/router/java/src/net/i2p/router/transport/udp/OutboundMessageFragments.java @@ -26,7 +26,7 @@ public class OutboundMessageFragments { private RouterContext _context; private Log _log; private UDPTransport _transport; - private ActiveThrottle _throttle; // LINT not used ?? + // private ActiveThrottle _throttle; // LINT not used ?? /** peers we are actively sending messages to */ private final List _activePeers; private boolean _alive; @@ -34,8 +34,8 @@ public class OutboundMessageFragments { private int _nextPeer; private PacketBuilder _builder; /** if we can handle more messages explicitly, set this to true */ - private boolean _allowExcess; // LINT not used?? - private volatile long _packetsRetransmitted; // LINT not used?? + // private boolean _allowExcess; // LINT not used?? + // private volatile long _packetsRetransmitted; // LINT not used?? // private static final int MAX_ACTIVE = 64; // not used. // don't send a packet more than 10 times @@ -45,12 +45,12 @@ public class OutboundMessageFragments { _context = ctx; _log = ctx.logManager().getLog(OutboundMessageFragments.class); _transport = transport; - _throttle = throttle; + // _throttle = throttle; _activePeers = new ArrayList(256); _nextPeer = 0; _builder = new PacketBuilder(ctx, transport); _alive = true; - _allowExcess = false; + // _allowExcess = false; _context.statManager().createRateStat("udp.sendVolleyTime", "Long it takes to send a full volley", "udp", UDPTransport.RATES); _context.statManager().createRateStat("udp.sendConfirmTime", "How long it takes to send a message and get the ACK", "udp", UDPTransport.RATES); _context.statManager().createRateStat("udp.sendConfirmFragments", "How many fragments are included in a fully ACKed message", "udp", UDPTransport.RATES); @@ -376,7 +376,7 @@ public class OutboundMessageFragments { if (state.getPushCount() > 1) { int toSend = fragments-sparseCount; peer.messageRetransmitted(toSend); - _packetsRetransmitted += toSend; // lifetime for the transport + // _packetsRetransmitted += toSend; // lifetime for the transport _context.statManager().addRateData("udp.peerPacketsRetransmitted", peer.getPacketsRetransmitted(), peer.getPacketsTransmitted()); _context.statManager().addRateData("udp.packetsRetransmitted", state.getLifetime(), peer.getPacketsTransmitted()); if (_log.shouldLog(Log.INFO)) diff --git a/router/java/src/net/i2p/router/transport/udp/OutboundMessageState.java b/router/java/src/net/i2p/router/transport/udp/OutboundMessageState.java index 650c17592..f4afa45c6 100644 --- a/router/java/src/net/i2p/router/transport/udp/OutboundMessageState.java +++ b/router/java/src/net/i2p/router/transport/udp/OutboundMessageState.java @@ -32,7 +32,7 @@ public class OutboundMessageState { private long _nextSendTime; private int _pushCount; private short _maxSends; - private int _nextSendFragment; + // private int _nextSendFragment; public static final int MAX_MSG_SIZE = 32 * 1024; /** is this enough for a high-bandwidth router? */ @@ -45,7 +45,7 @@ public class OutboundMessageState { _log = _context.logManager().getLog(OutboundMessageState.class); _pushCount = 0; _maxSends = 0; - _nextSendFragment = 0; + // _nextSendFragment = 0; } public boolean initialize(OutNetMessage msg) { diff --git a/router/java/src/net/i2p/router/transport/udp/OutboundRefiller.java b/router/java/src/net/i2p/router/transport/udp/OutboundRefiller.java index 457f7668e..1f61b896c 100644 --- a/router/java/src/net/i2p/router/transport/udp/OutboundRefiller.java +++ b/router/java/src/net/i2p/router/transport/udp/OutboundRefiller.java @@ -16,14 +16,14 @@ public class OutboundRefiller implements Runnable { private OutboundMessageFragments _fragments; private MessageQueue _messages; private boolean _alive; - private Object _refillLock; + // private Object _refillLock; public OutboundRefiller(RouterContext ctx, OutboundMessageFragments fragments, MessageQueue messages) { _context = ctx; _log = ctx.logManager().getLog(OutboundRefiller.class); _fragments = fragments; _messages = messages; - _refillLock = this; + // _refillLock = this; _context.statManager().createRateStat("udp.timeToActive", "Message lifetime until it reaches the outbound fragment queue", "udp", UDPTransport.RATES); } diff --git a/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java b/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java index 8b09dab41..5fe177764 100644 --- a/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java +++ b/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java @@ -879,8 +879,7 @@ public class PacketBuilder { */ private static final byte PEER_RELAY_INTRO_FLAG_BYTE = (UDPPacket.PAYLOAD_TYPE_RELAY_INTRO << 4); - /* FIXME Exporting non-public type through public API FIXME */ - public UDPPacket buildRelayIntro(RemoteHostId alice, PeerState charlie, UDPPacketReader.RelayRequestReader request) { + UDPPacket buildRelayIntro(RemoteHostId alice, PeerState charlie, UDPPacketReader.RelayRequestReader request) { UDPPacket packet = UDPPacket.acquire(_context, false); byte data[] = packet.getPacket().getData(); Arrays.fill(data, 0, data.length, (byte)0x0); @@ -930,8 +929,7 @@ public class PacketBuilder { */ private static final byte PEER_RELAY_RESPONSE_FLAG_BYTE = (UDPPacket.PAYLOAD_TYPE_RELAY_RESPONSE << 4); - /* FIXME Exporting non-public type through public API FIXME */ - public UDPPacket buildRelayResponse(RemoteHostId alice, PeerState charlie, long nonce, SessionKey aliceIntroKey) { + UDPPacket buildRelayResponse(RemoteHostId alice, PeerState charlie, long nonce, SessionKey aliceIntroKey) { InetAddress aliceAddr = null; try { aliceAddr = InetAddress.getByAddress(alice.getIP()); diff --git a/router/java/src/net/i2p/router/transport/udp/PacketHandler.java b/router/java/src/net/i2p/router/transport/udp/PacketHandler.java index 053bb14b0..8edcc5def 100644 --- a/router/java/src/net/i2p/router/transport/udp/PacketHandler.java +++ b/router/java/src/net/i2p/router/transport/udp/PacketHandler.java @@ -36,8 +36,7 @@ public class PacketHandler { /** let packets be up to 30s slow */ private static final long GRACE_PERIOD = Router.CLOCK_FUDGE_FACTOR + 30*1000; - /* FIXME Exporting non-public type through public API FIXME */ - public PacketHandler(RouterContext ctx, UDPTransport transport, UDPEndpoint endpoint, EstablishmentManager establisher, InboundMessageFragments inbound, PeerTestManager testManager, IntroductionManager introManager) {// LINT -- Exporting non-public type through public API + PacketHandler(RouterContext ctx, UDPTransport transport, UDPEndpoint endpoint, EstablishmentManager establisher, InboundMessageFragments inbound, PeerTestManager testManager, IntroductionManager introManager) {// LINT -- Exporting non-public type through public API _context = ctx; _log = ctx.logManager().getLog(PacketHandler.class); _transport = transport; diff --git a/router/java/src/net/i2p/router/transport/udp/PacketPusher.java b/router/java/src/net/i2p/router/transport/udp/PacketPusher.java index 8ec9cbb0d..cb31376b4 100644 --- a/router/java/src/net/i2p/router/transport/udp/PacketPusher.java +++ b/router/java/src/net/i2p/router/transport/udp/PacketPusher.java @@ -10,14 +10,14 @@ import net.i2p.util.Log; * */ public class PacketPusher implements Runnable { - private RouterContext _context; + // private RouterContext _context; private Log _log; private OutboundMessageFragments _fragments; private UDPSender _sender; private boolean _alive; public PacketPusher(RouterContext ctx, OutboundMessageFragments fragments, UDPSender sender) { - _context = ctx; + // _context = ctx; _log = ctx.logManager().getLog(PacketPusher.class); _fragments = fragments; _sender = sender; 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 275a68b00..050d87d4d 100644 --- a/router/java/src/net/i2p/router/transport/udp/PeerState.java +++ b/router/java/src/net/i2p/router/transport/udp/PeerState.java @@ -72,7 +72,7 @@ public class PeerState { /** how many consecutive messages have we sent and not received an ACK to */ private int _consecutiveFailedSends; /** when did we last have a failed send (beginning of period) */ - private long _lastFailedSendPeriod; + // private long _lastFailedSendPeriod; /** list of messageIds (Long) that we have received but not yet sent */ private final List _currentACKs; /** @@ -805,7 +805,7 @@ public class PeerState { _concurrentMessagesActive = 0; _consecutiveFailedSends = 0; - _lastFailedSendPeriod = -1; + // _lastFailedSendPeriod = -1; if (numSends < 2) { if (_context.random().nextInt(_concurrentMessagesAllowed) <= 0) _concurrentMessagesAllowed++; @@ -1003,8 +1003,7 @@ public class PeerState { return MAX_RTO; } - /* FIXME Exporting non-public type through public API FIXME */ - public RemoteHostId getRemoteHostId() { return _remoteHostId; } + RemoteHostId getRemoteHostId() { return _remoteHostId; } public int add(OutboundMessageState state) { if (_dead) { diff --git a/router/java/src/net/i2p/router/transport/udp/UDPEndpoint.java b/router/java/src/net/i2p/router/transport/udp/UDPEndpoint.java index 26563c210..ac9369d8e 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPEndpoint.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPEndpoint.java @@ -4,7 +4,6 @@ import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; -import net.i2p.router.CommSystemFacade; import net.i2p.router.RouterContext; import net.i2p.util.Log; diff --git a/router/java/src/net/i2p/router/transport/udp/UDPFlooder.java b/router/java/src/net/i2p/router/transport/udp/UDPFlooder.java index 633b92421..ef091ff53 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPFlooder.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPFlooder.java @@ -9,14 +9,14 @@ import net.i2p.data.i2np.I2NPMessage; import net.i2p.router.OutNetMessage; import net.i2p.router.RouterContext; import net.i2p.util.I2PThread; -import net.i2p.util.Log; +// import net.i2p.util.Log; /** * */ class UDPFlooder implements Runnable { private RouterContext _context; - private Log _log; + // private Log _log; private UDPTransport _transport; private final List _peers; private boolean _alive; @@ -24,7 +24,7 @@ class UDPFlooder implements Runnable { public UDPFlooder(RouterContext ctx, UDPTransport transport) { _context = ctx; - _log = ctx.logManager().getLog(UDPFlooder.class); + // _log = ctx.logManager().getLog(UDPFlooder.class); _transport = transport; _peers = new ArrayList(4); ctx.random().nextBytes(_floodData); diff --git a/router/java/src/net/i2p/router/transport/udp/UDPPacket.java b/router/java/src/net/i2p/router/transport/udp/UDPPacket.java index 11ffbc67e..97e112df3 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPPacket.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPPacket.java @@ -38,7 +38,7 @@ public class UDPPacket { private long _beforeReceiveFragments; private long _afterHandlingTime; private int _validateCount; - private boolean _isInbound; + // private boolean _isInbound; private static final List _packetCache; static { @@ -83,13 +83,14 @@ public class UDPPacket { _ivBuf = new byte[IV_SIZE]; init(ctx, inbound); } + // FIXME optimization, remove the inbound parameter, as it is unused. FIXME private void init(I2PAppContext ctx, boolean inbound) { _context = ctx; //_dataBuf = _dataCache.acquire(); Arrays.fill(_data, (byte)0); //_packet = new DatagramPacket(_data, MAX_PACKET_SIZE); _packet.setData(_data); - _isInbound = inbound; + // _isInbound = inbound; _initializeTime = _context.clock().now(); _markedType = -1; _validateCount = 0; @@ -125,8 +126,7 @@ public class UDPPacket { int getFragmentCount() { return _fragmentCount; } void setFragmentCount(int count) { _fragmentCount = count; } - // FIXME Exporting non-public type through public API FIXME - public RemoteHostId getRemoteHost() { + RemoteHostId getRemoteHost() { if (_remoteHost == null) { long before = System.currentTimeMillis(); InetAddress addr = _packet.getAddress(); diff --git a/router/java/src/net/i2p/router/transport/udp/UDPReceiver.java b/router/java/src/net/i2p/router/transport/udp/UDPReceiver.java index 2a03cb627..c1bd5133a 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPReceiver.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPReceiver.java @@ -28,7 +28,7 @@ public class UDPReceiver { private boolean _keepRunning; private Runner _runner; private UDPTransport _transport; - private static int __id; + // private static int __id; private int _id; public UDPReceiver(RouterContext ctx, UDPTransport transport, DatagramSocket socket, String name) { 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 a96a4d507..7bc5990b9 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java @@ -3,7 +3,6 @@ package net.i2p.router.transport.udp; import java.io.IOException; import java.io.Writer; import java.net.InetAddress; -import java.net.SocketException; import java.net.UnknownHostException; import java.text.DecimalFormat; import java.util.ArrayList; @@ -545,8 +544,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority * get the state for the peer at the given remote host/port, or null * if no state exists */ - /* FIXME Exporting non-public type through public API FIXME */ - public PeerState getPeerState(RemoteHostId hostInfo) { + PeerState getPeerState(RemoteHostId hostInfo) { synchronized (_peersByRemoteHost) { return (PeerState)_peersByRemoteHost.get(hostInfo); } @@ -783,8 +781,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority } } - /* FIXME Exporting non-public type through public API FIXME */ - public boolean isInDropList(RemoteHostId peer) { synchronized (_dropList) { return _dropList.contains(peer); } } + boolean isInDropList(RemoteHostId peer) { synchronized (_dropList) { return _dropList.contains(peer); } } void dropPeer(Hash peer, boolean shouldShitlist, String why) { PeerState state = getPeerState(peer); @@ -2235,8 +2232,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority _testEvent.runTest(); } - /* FIXME Exporting non-public type through public API FIXME */ - public PeerState pickTestPeer(RemoteHostId dontInclude) { + PeerState pickTestPeer(RemoteHostId dontInclude) { List peers = null; synchronized (_peersByIdent) { peers = new ArrayList(_peersByIdent.values()); From d7d058e772aa70230338b356d1407a2745459f06 Mon Sep 17 00:00:00 2001 From: zzz Date: Sun, 29 Nov 2009 17:58:24 +0000 Subject: [PATCH 015/127] addressbook servlet cleanup --- .../java/src/net/i2p/addressbook/Servlet.java | 31 +++++++++++-------- apps/addressbook/web.xml | 2 +- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/apps/addressbook/java/src/net/i2p/addressbook/Servlet.java b/apps/addressbook/java/src/net/i2p/addressbook/Servlet.java index c5239609e..fceecfe53 100644 --- a/apps/addressbook/java/src/net/i2p/addressbook/Servlet.java +++ b/apps/addressbook/java/src/net/i2p/addressbook/Servlet.java @@ -21,6 +21,8 @@ package net.i2p.addressbook; +import java.io.IOException; +import java.io.PrintWriter; import java.util.Random; import javax.servlet.ServletConfig; @@ -39,8 +41,8 @@ import javax.servlet.http.HttpServletResponse; * */ public class Servlet extends HttpServlet { - private Thread _thread; - private String _nonce; + private Thread thread; + private String nonce; private static final String PROP_NONCE = "addressbook.nonce"; /** @@ -50,14 +52,17 @@ public class Servlet extends HttpServlet { * (non-Javadoc) * see javax.servlet.Servlet#service(javax.servlet.ServletRequest, javax.servlet.ServletResponse) */ - public void service(HttpServletRequest request, HttpServletResponse response) { + public void service(HttpServletRequest request, HttpServletResponse response) throws IOException { //System.err.println("Got request nonce = " + request.getParameter("nonce")); - if (_thread != null && request.getParameter("wakeup") != null && - _nonce != null && _nonce.equals(request.getParameter("nonce"))) { + if (this.thread != null && request.getParameter("wakeup") != null && + this.nonce != null && this.nonce.equals(request.getParameter("nonce"))) { //System.err.println("Sending interrupt"); - _thread.interrupt(); + this.thread.interrupt(); + // no output + } else { + PrintWriter out = response.getWriter(); + out.write("I2P addressbook OK"); } - // no output } /* (non-Javadoc) @@ -70,15 +75,15 @@ public class Servlet extends HttpServlet { } catch (ServletException exp) { System.err.println("Addressbook init exception: " + exp); } - _nonce = "" + Math.abs((new Random()).nextLong()); + this.nonce = "" + Math.abs((new Random()).nextLong()); // put the nonce where susidns can get it - System.setProperty(PROP_NONCE, _nonce); + System.setProperty(PROP_NONCE, this.nonce); String[] args = new String[1]; args[0] = config.getInitParameter("home"); - _thread = new DaemonThread(args); - _thread.setDaemon(true); - _thread.setName("Addressbook"); - _thread.start(); + this.thread = new DaemonThread(args); + this.thread.setDaemon(true); + this.thread.setName("Addressbook"); + this.thread.start(); System.out.println("INFO: Starting Addressbook " + Daemon.VERSION); //System.out.println("INFO: config root under " + args[0]); } diff --git a/apps/addressbook/web.xml b/apps/addressbook/web.xml index c5fe302a6..6dd20ea1b 100644 --- a/apps/addressbook/web.xml +++ b/apps/addressbook/web.xml @@ -16,7 +16,7 @@ addressbook - / + * From 412d641eb6cd1d84c70853711f644cb77ce608c3 Mon Sep 17 00:00:00 2001 From: zzz Date: Sun, 29 Nov 2009 18:40:20 +0000 Subject: [PATCH 016/127] fix pathspec --- apps/addressbook/web.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/addressbook/web.xml b/apps/addressbook/web.xml index 6dd20ea1b..b791b4ea0 100644 --- a/apps/addressbook/web.xml +++ b/apps/addressbook/web.xml @@ -16,7 +16,7 @@ addressbook - * + /* From f3a88398f2828ce7aeec43c767d8140a3079e6cf Mon Sep 17 00:00:00 2001 From: zzz Date: Sun, 29 Nov 2009 18:46:48 +0000 Subject: [PATCH 017/127] Fix the default inbound burst --- .../src/net/i2p/router/transport/FIFOBandwidthRefiller.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/router/java/src/net/i2p/router/transport/FIFOBandwidthRefiller.java b/router/java/src/net/i2p/router/transport/FIFOBandwidthRefiller.java index b24d79a11..cd246bf2c 100644 --- a/router/java/src/net/i2p/router/transport/FIFOBandwidthRefiller.java +++ b/router/java/src/net/i2p/router/transport/FIFOBandwidthRefiller.java @@ -42,7 +42,7 @@ public class FIFOBandwidthRefiller implements Runnable { * adjusting bandwidth class boundaries. */ public static final int DEFAULT_OUTBOUND_BANDWIDTH = 40; - public static final int DEFAULT_INBOUND_BURST_BANDWIDTH = 80; + public static final int DEFAULT_INBOUND_BURST_BANDWIDTH = 96; public static final int DEFAULT_OUTBOUND_BURST_BANDWIDTH = 40; public static final int DEFAULT_BURST_SECONDS = 60; From 1ca651e803d9e494dc5e10e3c16038a88671e2b1 Mon Sep 17 00:00:00 2001 From: zzz Date: Sun, 29 Nov 2009 18:47:12 +0000 Subject: [PATCH 018/127] Fix an error message --- .../java/src/net/i2p/i2ptunnel/socks/I2PSOCKSTunnel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/I2PSOCKSTunnel.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/I2PSOCKSTunnel.java index be398f770..db37b9e59 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/I2PSOCKSTunnel.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/I2PSOCKSTunnel.java @@ -55,7 +55,7 @@ public class I2PSOCKSTunnel extends I2PTunnelClientBase { I2PSocket destSock = serv.getDestinationI2PSocket(this); new I2PTunnelRunner(clientSock, destSock, sockLock, null, mySockets); } catch (SOCKSException e) { - _log.error("Error from SOCKS connection: " + e.getMessage()); + _log.error("Error from SOCKS connection", e); closeSocket(s); } } From 64ee1b313be4748e1934a463ee3578c0bd073e40 Mon Sep 17 00:00:00 2001 From: zzz Date: Sun, 29 Nov 2009 18:47:34 +0000 Subject: [PATCH 019/127] Comment out unused stuff better --- apps/routerconsole/jsp/config.jsp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/apps/routerconsole/jsp/config.jsp b/apps/routerconsole/jsp/config.jsp index c422e1016..9a9942c79 100644 --- a/apps/routerconsole/jsp/config.jsp +++ b/apps/routerconsole/jsp/config.jsp @@ -32,15 +32,18 @@

    +<% /******** +*********/ %> +<% /******** +*********/ %> \n\t"); out.write(" - - + + - + @@ -162,15 +164,15 @@
    -

    The ${book.book} addressbook is empty.

    +

    <%=intl._("This addressbook is empty.")%>

    -

    Add new destination:

    -Hostname: -Destination:
    +

    <%=intl._("Add new destination")%>:

    +<%=intl._("Hostname")%>: +<%=intl._("Destination")%>:

    diff --git a/apps/susidns/src/jsp/config.jsp b/apps/susidns/src/jsp/config.jsp index 415bec755..4c3cefbdf 100644 --- a/apps/susidns/src/jsp/config.jsp +++ b/apps/susidns/src/jsp/config.jsp @@ -28,12 +28,13 @@ <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + -configuration - susidns v${version.version} +<%=intl._("configuration")%> - susidns v${version.version} @@ -43,14 +44,14 @@


    @@ -68,30 +69,58 @@ configuration *
    -

    Hints

    +

    <%=intl._("Hints")%>

      -
    1. All file or directory paths here are relative to the addressbook's working directory, which normally -is located at $I2P/addressbook/.
    2. -
    3. If you want to manually add lines to an addressbook, add them to the private or master addressbooks. The router -addressbook and the published addressbook are overwritten by the addressbook application.
    4. -
    5. Important:When you publish your addressbook, ALL destinations from the master and router addressbooks appear there. -Use the private addressbook for private destinations, these are not published. +
    6. +<%=intl._("File and directory paths here are relative to the addressbook's working directory, which is normally ~/.i2p/addressbook/ (Linux) or %APPDATA%\\I2P\\addressbook\\ (Windows).")%> +
    7. +
    8. +<%=intl._("If you want to manually add lines to an addressbook, add them to the private or master addressbooks.")%> +<%=intl._("The router addressbook and the published addressbook are updated by the addressbook application.")%> +
    9. +
    10. +<%=intl._("When you publish your addressbook, ALL destinations from the master and router addressbooks appear there.")%> +<%=intl._("Use the private addressbook for private destinations, these are not published.")%>
    -

    Options

    +

    <%=intl._("Options")%>

      -
    • subscriptions - file containing the list of subscriptions URLs (no need to change)
    • -
    • update_delay - update interval in hours (no need to change)
    • -
    • published_addressbook - your public hosts.txt file (choose a path within your webserver document root)
    • -
    • router_addressbook - your hosts.txt (don't change)
    • -
    • master_addressbook - your personal addressbook, it never gets overwritten by the addressbook (don't change)
    • -
    • private_addressbook - your private addressbook, it is never published (defaults to ../privatehosts.txt, don't change)
    • -
    • proxy_port - http port for your eepProxy (no need to change)
    • -
    • proxy_host - hostname for your eepProxy (no need to change)
    • -
    • should_publish - true/false whether to write the published addressbook
    • -
    • etags - file containing the etags header from the fetched subscription URLs (no need to change)
    • -
    • last_modified - file containing the modification timestamp for each fetched subscription URL (no need to change)
    • -
    • log - file to log activity to (change to /dev/null if you like)
    • +
    • subscriptions - +<%=intl._("File containing the list of subscriptions URLs (no need to change)")%> +
    • +
    • update_delay - +<%=intl._("Update interval in hours")%> +
    • +
    • published_addressbook - +<%=intl._("Your public hosts.txt file (choose a path within your webserver document root)")%> +
    • +
    • router_addressbook - +<%=intl._("Your hosts.txt (don't change)")%> +
    • +
    • master_addressbook - +<%=intl._("Your personal addressbook, these hosts will be published")%> +
    • +
    • private_addressbook - +<%=intl._("Your private addressbook, it is never published")%> +
    • +
    • proxy_port - +<%=intl._("Port for your eepProxy (no need to change)")%> +
    • +
    • proxy_host - +<%=intl._("Hostname for your eepProxy (no need to change)")%> +
    • +
    • should_publish - +<%=intl._("Whether to update the published addressbook")%> +
    • +
    • etags - +<%=intl._("File containing the etags header from the fetched subscription URLs (no need to change)")%> +
    • +
    • last_modified - +<%=intl._("File containing the modification timestamp for each fetched subscription URL (no need to change)")%> +
    • +
    • log - +<%=intl._("File to log activity to (change to /dev/null if you like)")%> +



    -

    Huh? what addressbook?

    +

    <%=intl._("What is the addressbook?")%>

    -The addressbook application is part of your i2p installation. It regularly updates your hosts.txt file -from distributed sources. It keeps your hosts.txt up to date, so it can automatically add -eepsites announced on other sites if you subscribe to those sites' addressbooks. +<%=intl._("The addressbook application is part of your i2p installation.")%> +<%=intl._("It regularly updates your hosts.txt file from distributed sources or \"subscriptions\".")%>

    -(To speak the truth: In its default configuration the addressbook does not poll -additional sites, but www.i2p2.i2p only. Subscribing to additional sites is an easy task, -just add them to your subscriptions file.) +<%=intl._("In the default configuration, the addressbook is only subscribed to www.i2p2.i2p.")%> +<%=intl._("Subscribing to additional sites is easy, just add them to your subscriptions file.")%>

    -

    If you have questions about naming in i2p, there is an excellent introduction -from duck in the forum and additional information on www.i2p2.i2p.

    -

    How does the addressbook work?

    -

    The addressbook application regularly (normally once per hour) polls your subscriptions and merges their content -into your so-called router addressbook (normally your plain hosts.txt). Then it merges your so-called master addressbook (normally -your userhosts.txt) into the router addressbook as well. If configured, the router addressbook is now written to the published addressbook, -which is a publicly available copy of your hosts.txt somewhere in your eepsite's document root. +

    +<%=intl._("For more information on naming in i2p, see the overview on www.i2p2.i2p.")%> +

    +

    <%=intl._("How does the addressbook work?")%>

    +

    +<%=intl._("The addressbook application regularly polls your subscriptions and merges their content into your \"router\" addressbook, stored in the hosts.txt file.")%> +<%=intl._("Then it merges your \"master\" addressbook (userhosts.txt) into the router addressbook as well.")%> +<%=intl._("If configured, the router addressbook is now written to the \"published\" addressbook, which will be publicly available if you are running an eepsite.")%>

    -The router also uses a private addressbook (privatehosts.txt, not shown in the picture), which is not merged or published. -Hosts in the private addressbook can be accessed by you but their addresses are never distributed to others. -The private addressbook can also be used for aliases of hosts in your other addressbooks. +<%=intl._("The router also uses a private addressbook (privatehosts.txt, not shown in the picture), which is not merged or published.")%> +<%=intl._("Hosts in the private addressbook can be accessed by you but their addresses are never distributed to others.")%> +<%=intl._("The private addressbook can also be used for aliases of hosts in your other addressbooks.")%>

    addressbook working scheme

    diff --git a/apps/susidns/src/jsp/subscriptions.jsp b/apps/susidns/src/jsp/subscriptions.jsp index a60710310..7485e10bc 100644 --- a/apps/susidns/src/jsp/subscriptions.jsp +++ b/apps/susidns/src/jsp/subscriptions.jsp @@ -28,12 +28,13 @@ <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> + -subscriptions - susidns v${version.version} +<%=intl._("subscriptions")%> - susidns v${version.version} @@ -42,14 +43,15 @@ susidns logo

    @@ -67,13 +69,13 @@ subscriptions *
    -

    Explanation

    -The subscription file contains a list of (i2p) URLs. The addressbook application -regularly (once per hour) checks this list for new eepsites. Those URLs simply contain the published hosts.txt -file of other people. The default subscription is the hosts.txt from www.i2p2.i2p, which is updated infrequently. -So it is a good idea to add additional subscriptions to sites that have the latest addresses. -See the FAQ for a list of subscription URLs. +<%=intl._("The subscription file contains a list of i2p URLs.")%> +<%=intl._("The addressbook application regularly checks this list for new eepsites.")%> +<%=intl._("Those URLs refer to published hosts.txt files.")%> +<%=intl._("The default subscription is the hosts.txt from www.i2p2.i2p, which is updated infrequently.")%> +<%=intl._("So it is a good idea to add additional subscriptions to sites that have the latest addresses.")%> +<%=intl._("See the FAQ for a list of subscription URLs.")%>


    " /> <%=intl._("KBps In")%> ()
    " /> <%=intl._("KBps Out")%> ()
    <%=intl._("Share")%> () @@ -121,6 +125,7 @@

    <%=intl._("UDP Configuration:")%>
    <%=intl._("UDP port:")%> " />
    +<% /******** +*********/ %>

    <%=intl._("TCP Configuration")%>:
    <%=intl._("Externally reachable hostname or IP address")%>:
    @@ -163,10 +169,12 @@ <%=intl._("Most of the options above are for special situations, for example where UPnP does not work correctly, or a firewall not under your control is doing harm.")%> <%=intl._("Certain firewalls such as symmetric NATs may not work well with I2P.")%>

    +<% /******** +*********/ %>

    <%=intl._("UPnP is used to communicate with Internet Gateway Devices (IGDs) to detect the external IP address and forward ports.")%> <%=intl._("UPnP support is beta, and may not work for any number of reasons")%>: From f95b5324e0fc57bf6c72d320b36be5fbf423f352 Mon Sep 17 00:00:00 2001 From: zzz Date: Sun, 29 Nov 2009 18:48:03 +0000 Subject: [PATCH 020/127] profiles.jsp: Hide non-ff from ff table --- .../src/net/i2p/router/web/ProfileOrganizerRenderer.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ProfileOrganizerRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/ProfileOrganizerRenderer.java index 5e7ef4b94..14863acf3 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ProfileOrganizerRenderer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ProfileOrganizerRenderer.java @@ -46,13 +46,13 @@ class ProfileOrganizerRenderer { Hash peer = (Hash)iter.next(); if (_organizer.getUs().equals(peer)) continue; PeerProfile prof = _organizer.getProfile(peer); - if (_organizer.isWellIntegrated(peer)) { - integratedPeers.add(prof); - } else { + //if (_organizer.isWellIntegrated(peer)) { + // integratedPeers.add(prof); + //} else { RouterInfo info = _context.netDb().lookupRouterInfoLocally(peer); if (info != null && info.getCapabilities().indexOf("f") >= 0) integratedPeers.add(prof); - } + //} if (prof.getLastSendSuccessful() <= hideBefore) { older++; continue; From 4c812c7bffd5c96662b3d2620bea005b1eec6ded Mon Sep 17 00:00:00 2001 From: zzz Date: Sun, 29 Nov 2009 18:49:28 +0000 Subject: [PATCH 021/127] * HTTP Proxy: Don't send proxy.i2p to the naming service, it was making the error pages load slowly --- .../i2p/i2ptunnel/I2PTunnelHTTPClient.java | 28 ++++++++++++------- history.txt | 8 ++++++ .../src/net/i2p/router/RouterVersion.java | 2 +- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java index b729b659b..ce62a23f0 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java @@ -245,6 +245,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable OutputStream out = null; String targetRequest = null; boolean usingWWWProxy = false; + boolean usingInternalServer = false; String currentProxy = null; long requestId = ++__requestId; try { @@ -271,6 +272,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable int pos = line.indexOf(" "); if (pos == -1) break; method = line.substring(0, pos); + // TODO use Java URL class to make all this simpler and more robust String request = line.substring(pos + 1); if (request.startsWith("/") && getTunnel().getClientOptions().getProperty("i2ptunnel.noproxy") != null) { request = "http://i2p" + request; @@ -316,8 +318,11 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable } } - // Quick hack for foo.bar.i2p - if (host.toLowerCase().endsWith(".i2p")) { + if (host.toLowerCase().equals("proxy.i2p")) { + // so we don't do any naming service lookups + destination = "proxy.i2p"; + usingInternalServer = true; + } else if (host.toLowerCase().endsWith(".i2p")) { // Destination gets the host name destination = host; // Host becomes the destination key @@ -454,15 +459,15 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable } destination = request.substring(0, pos); line = method + " " + request.substring(pos); - } + } // end host name processing - boolean isValid = usingWWWProxy || isSupportedAddress(host, protocol); + boolean isValid = usingWWWProxy || usingInternalServer || isSupportedAddress(host, protocol); if (!isValid) { if (_log.shouldLog(Log.INFO)) _log.info(getPrefix(requestId) + "notValid(" + host + ")"); method = null; destination = null; break; - } else if (!usingWWWProxy) { + } else if ((!usingWWWProxy) && (!usingInternalServer)) { if (_log.shouldLog(Log.INFO)) _log.info(getPrefix(requestId) + "host=getHostName(" + destination + ")"); host = getHostName(destination); // hide original host } @@ -473,7 +478,9 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable _log.debug(getPrefix(requestId) + "HOST :" + host + ":"); _log.debug(getPrefix(requestId) + "DEST :" + destination + ":"); } - + + // end first line processing + } else { if (lowercaseLine.startsWith("host: ") && !usingWWWProxy) { line = "Host: " + host; @@ -505,14 +512,14 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable continue; // completely strip the line } } - + if (line.length() == 0) { String ok = getTunnel().getClientOptions().getProperty("i2ptunnel.gzip"); boolean gzip = DEFAULT_GZIP; if (ok != null) gzip = Boolean.valueOf(ok).booleanValue(); - if (gzip) { + if (gzip && !usingInternalServer) { // according to rfc2616 s14.3, this *should* force identity, even if // an explicit q=0 for gzip doesn't. tested against orion.i2p, and it // seems to work. @@ -526,7 +533,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable } else { newRequest.append(line).append("\r\n"); // HTTP spec } - } + } // end header processing + if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix(requestId) + "NewRequest header: [" + newRequest.toString() + "]"); @@ -548,7 +556,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable // Serve local proxy files (images, css linked from error pages) // Ignore all the headers - if (destination.equals("proxy.i2p")) { + if (usingInternalServer) { serveLocalFile(out, method, targetRequest); s.close(); return; diff --git a/history.txt b/history.txt index 79bb5b2a1..62af66cba 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,11 @@ +2009-11-29 zzz + * config.jsp: Comment out unused stuff better + * profiles.jsp: Hide non-ff from ff table + * HTTP Proxy: Don't send proxy.i2p to the naming service, + it was making the error pages load slowly + * SOCKS Proxy: Fix an error message + * Transport: Fix the default inbound burst + 2009-11-29 sponge * net.i2p.router.transport.udp deadwood code cleanup. * documented rare NPE in InboundEstablishState.java. diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 7de969bf4..458d45df4 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 23; + public final static long BUILD = 24; /** for example "-test" */ public final static String EXTRA = ""; public final static String FULL_VERSION = VERSION + "-" + BUILD + EXTRA; From 454b2c8941f23fe7651c9a847f9412911a7f41c9 Mon Sep 17 00:00:00 2001 From: neutron Date: Mon, 30 Nov 2009 20:46:23 +0000 Subject: [PATCH 022/127] An updated (yet incomplete) version of messages_fr.po --- apps/routerconsole/locale/messages_fr.po | 477 ++++++++++++----------- 1 file changed, 239 insertions(+), 238 deletions(-) diff --git a/apps/routerconsole/locale/messages_fr.po b/apps/routerconsole/locale/messages_fr.po index 828345de9..30b2c3cac 100644 --- a/apps/routerconsole/locale/messages_fr.po +++ b/apps/routerconsole/locale/messages_fr.po @@ -9,17 +9,18 @@ msgstr "" "Project-Id-Version: I2P routerconsole\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2009-11-01 02:59+0000\n" -"PO-Revision-Date: 2009-11-16 22:31+0100\n" +"PO-Revision-Date: 2009-11-30 21:35+0100\n" "Last-Translator: \n" "Language-Team: foo \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: German\n" +"X-Poedit-Basepath: /home/lee/work/i2p/monotone/i2p.i2p/apps/routerconsole/java\n" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:106 msgid "config networking" -msgstr "" +msgstr "Interconnexion configuration" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:217 #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configadvanced_jsp.java:218 @@ -48,7 +49,7 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/summaryframe_jsp.java:236 #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/tunnels_jsp.java:216 msgid "Refresh (s)" -msgstr "" +msgstr "Actualiser (s)" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:221 #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configadvanced_jsp.java:222 @@ -77,15 +78,15 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/summaryframe_jsp.java:239 #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/tunnels_jsp.java:220 msgid "Enable" -msgstr "" +msgstr "Activer" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:241 msgid "I2P Network Configuration" -msgstr "" +msgstr "Configuration I2P réseau" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:297 msgid "Bandwidth limiter" -msgstr "" +msgstr "Limiteur de bande passante" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:299 msgid "I2P will work best if you configure your rates to match the speed of your internet connection." @@ -112,7 +113,7 @@ msgstr "NOTER" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:332 #, java-format msgid "You have configured I2P to share only {0} KBps." -msgstr "" +msgstr "Vous avez configuré I2P à partager que {0} KOps." #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:335 msgid "I2P requires at least 12KBps to enable sharing. " @@ -129,7 +130,7 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:340 #, java-format msgid "You have configured I2P to share {0} KBps." -msgstr "" +msgstr "Vous avez configuré I2P à partager {0} KOps." #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:343 msgid "The higher the share bandwidth the more you improve your anonymity and help the network." @@ -168,11 +169,11 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:357 msgid "There is help below." -msgstr "" +msgstr "Voir les explications ci-dessous." #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:359 msgid "UPnP Configuration" -msgstr "" +msgstr "Configuration UPnP" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:363 msgid "Enable UPnP to open firewall ports" @@ -180,11 +181,11 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:365 msgid "UPnP status" -msgstr "" +msgstr "Statut UPnP" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:367 msgid "IP Configuration" -msgstr "" +msgstr "Configuration IP" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:369 #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:425 @@ -210,11 +211,11 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:389 #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:443 msgid "Specify hostname or IP" -msgstr "" +msgstr "Stipuler l'adresse IP ou le nom de l'hôte" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:395 msgid "Select Interface" -msgstr "" +msgstr "Choisir l'interface" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:395 #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configservice_jsp.java:336 @@ -224,7 +225,7 @@ msgstr "ou" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:409 msgid "Hidden mode - do not publish IP" -msgstr "" +msgstr "Mode caché - ne pas publier l'adresse IP" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:411 msgid "(prevents participating traffic)" @@ -232,15 +233,15 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:413 msgid "UDP Configuration:" -msgstr "" +msgstr "Configuration UDP :" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:415 msgid "UDP port:" -msgstr "" +msgstr "Port UDP :" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:423 msgid "TCP Configuration" -msgstr "" +msgstr "Configuration TCP" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:429 msgid "Use auto-detected IP address" @@ -253,7 +254,7 @@ msgstr "actuellement" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:435 msgid "if we are not firewalled" -msgstr "" +msgstr "s'il n'y a pas de pare-feu" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:439 msgid "Always use auto-detected IP address (Not firewalled)" @@ -281,7 +282,7 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:469 msgid "Specify Port" -msgstr "" +msgstr "Stipuler le port" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:473 #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configservice_jsp.java:342 @@ -291,11 +292,11 @@ msgstr "Noter" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:476 msgid "Changing these settings will restart your router." -msgstr "" +msgstr "Un changement de cette configuration entraînera un redémarrage du routeur" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:482 msgid "Configuration Help" -msgstr "" +msgstr "Aide avec la configuration" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:484 #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:526 @@ -364,7 +365,7 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:516 msgid "They are not private." -msgstr "" +msgstr "Ils ne sont pas privés." #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:518 msgid "Also, do not enter a private IP address like 127.0.0.1 or 192.168.1.1." @@ -402,7 +403,7 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:538 #: src/net/i2p/router/web/SummaryHelper.java:114 msgid "Firewalled" -msgstr "" +msgstr "Bloqué par un pare-feu" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:540 msgid "Your UDP port appears to be firewalled." @@ -435,7 +436,7 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:554 #: src/net/i2p/router/web/SummaryHelper.java:127 msgid "Testing" -msgstr "" +msgstr "Test en cours" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:556 msgid "The router is currently testing whether your UDP port is firewalled." @@ -445,7 +446,7 @@ msgstr "" #: src/net/i2p/router/web/NetDbRenderer.java:234 #: src/net/i2p/router/web/SummaryHelper.java:96 msgid "Hidden" -msgstr "" +msgstr "Caché" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:560 msgid "The router is not configured to publish its address, therefore it does not expect incoming connections." @@ -509,7 +510,7 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:590 msgid "ERR - Clock Skew" -msgstr "" +msgstr "ERR - horloge décalé" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/config_jsp.java:592 msgid "Your system's clock is skewed, which will make it difficult to participate in the network." @@ -597,11 +598,11 @@ msgstr "configuration avancé" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configadvanced_jsp.java:242 msgid "I2P Advanced Configuration" -msgstr "" +msgstr "Configuration I2P avancé" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configadvanced_jsp.java:299 msgid "Advanced I2P Configuration" -msgstr "" +msgstr "Configuration I2P avancé" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configadvanced_jsp.java:303 #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configui_jsp.java:321 @@ -614,15 +615,15 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configclients_jsp.java:106 msgid "config clients" -msgstr "" +msgstr "Clients configuration" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configclients_jsp.java:241 msgid "I2P Client Configuration" -msgstr "" +msgstr "Client I2P configuration" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configclients_jsp.java:306 msgid "Client Configuration" -msgstr "" +msgstr "Configuration Client" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configclients_jsp.java:308 msgid "The Java clients listed below are started by the router and run in the same JVM." @@ -640,11 +641,11 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configclients_jsp.java:321 #: src/net/i2p/router/web/ConfigClientsHandler.java:32 msgid "Save Client Configuration" -msgstr "" +msgstr "Sauvegarder Configuration Client " #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configclients_jsp.java:323 msgid "WebApp Configuration" -msgstr "" +msgstr "Configuration WebApp" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configclients_jsp.java:325 msgid "The Java web applications listed below are started by the webConsole client and run in the same JVM as the router. They are usually web applications accessible through the router console. They may be complete applications (e.g. i2psnark),front-ends to another client or application which must be separately enabled (e.g. susidns, i2ptunnel), or have no web interface at all (e.g. addressbook)." @@ -661,16 +662,16 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configkeyring_jsp.java:106 msgid "config keyring" -msgstr "" +msgstr "Configuration porte-clés" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configkeyring_jsp.java:228 msgid "I2P Keyring Configuration" -msgstr "" +msgstr "Configuration du Porte-clés I2P" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configkeyring_jsp.java:292 #: src/net/i2p/router/web/ConfigNavHelper.java:19 msgid "Keyring" -msgstr "" +msgstr "Porte-clés" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configkeyring_jsp.java:294 msgid "The router keyring is used to decrypt encrypted leaseSets." @@ -698,11 +699,11 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configkeyring_jsp.java:316 msgid "Dest. name, hash, or full key" -msgstr "" +msgstr "Nom de destination, empreinte, ou clé complète" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configkeyring_jsp.java:318 msgid "Encryption Key" -msgstr "" +msgstr "Clé d'encryption" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configkeyring_jsp.java:320 #: src/net/i2p/router/web/ConfigKeyringHandler.java:18 @@ -716,7 +717,7 @@ msgstr "Supprimer une clé" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configlogging_jsp.java:107 msgid "config logging" -msgstr "" +msgstr "configuration enregistrements" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configlogging_jsp.java:242 msgid "I2P Logging Configuration" @@ -740,7 +741,7 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configlogging_jsp.java:311 msgid "(use 'd' = date, 'c' = class, 't' = thread, 'p' = priority, 'm' = message)" -msgstr "" +msgstr "(use 'd' = date, 'c' = classe, 't' = fil d'exécution, 'p' = priorité, 'm' = message)" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configlogging_jsp.java:313 msgid "Log date format" @@ -748,7 +749,7 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configlogging_jsp.java:317 msgid "('MM' = month, 'dd' = day, 'HH' = hour, 'mm' = minute, 'ss' = second, 'SSS' = millisecond)" -msgstr "" +msgstr "('MM' = mois, 'dd' = jour, 'HH' = heure, 'mm' = minute, 'ss' = seconde, 'SSS' = milliseconde)" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configlogging_jsp.java:319 msgid "Max log file size" @@ -768,11 +769,11 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configpeer_jsp.java:106 msgid "config peers" -msgstr "" +msgstr "Configuration des pairs" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configpeer_jsp.java:228 msgid "I2P Peer Configuration" -msgstr "" +msgstr "Configuration des pairs I2P" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configpeer_jsp.java:304 msgid "Manual Peer Controls" @@ -780,7 +781,7 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configpeer_jsp.java:306 msgid "Router Hash" -msgstr "" +msgstr "Routeur empreinte" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configpeer_jsp.java:310 msgid "Manually Ban / Unban a Peer" @@ -793,7 +794,7 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configpeer_jsp.java:314 #: src/net/i2p/router/web/ConfigPeerHandler.java:20 msgid "Ban peer until restart" -msgstr "" +msgstr "Interdire pair jusqu'au redémarrage" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configpeer_jsp.java:316 #: src/net/i2p/router/web/ConfigPeerHandler.java:28 @@ -811,7 +812,7 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configpeer_jsp.java:326 msgid "profiles page" -msgstr "" +msgstr "page des profiles" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configpeer_jsp.java:334 #: src/net/i2p/router/web/ProfileOrganizerRenderer.java:71 @@ -832,23 +833,23 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configpeer_jsp.java:344 #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/profiles_jsp.java:249 msgid "Banned Peers" -msgstr "" +msgstr "Pairs interdits" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configpeer_jsp.java:366 msgid "Banned IPs" -msgstr "" +msgstr "Adresses IP interdits" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configservice_jsp.java:106 msgid "config service" -msgstr "" +msgstr "Service Configuration " #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configservice_jsp.java:228 msgid "I2P Service Configuration" -msgstr "" +msgstr "Service I2P Configuration" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configservice_jsp.java:284 msgid "Shutdown the router" -msgstr "" +msgstr "Fermer le routeur" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configservice_jsp.java:286 msgid "Graceful shutdown lets the router satisfy the agreements it has already made before shutting down, but may take a few minutes." @@ -861,18 +862,18 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configservice_jsp.java:290 #: src/net/i2p/router/web/ConfigServiceHandler.java:53 msgid "Shutdown gracefully" -msgstr "" +msgstr "Fermer gracieusement" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configservice_jsp.java:292 #: src/net/i2p/router/web/ConfigRestartBean.java:32 #: src/net/i2p/router/web/ConfigServiceHandler.java:57 msgid "Shutdown immediately" -msgstr "" +msgstr "Fermer immédiatement" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configservice_jsp.java:294 #: src/net/i2p/router/web/ConfigServiceHandler.java:61 msgid "Cancel graceful shutdown" -msgstr "" +msgstr "Annuler fermeture gracieux" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configservice_jsp.java:298 msgid "If you want the router to restart itself after shutting down, you can choose one of the following." @@ -897,12 +898,12 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configservice_jsp.java:308 #: src/net/i2p/router/web/ConfigServiceHandler.java:64 msgid "Graceful restart" -msgstr "" +msgstr "Redémarrage gracieux" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configservice_jsp.java:310 #: src/net/i2p/router/web/ConfigServiceHandler.java:68 msgid "Hard restart" -msgstr "" +msgstr "Redémarrage immédiate" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configservice_jsp.java:316 msgid "Systray integration" @@ -932,7 +933,7 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configservice_jsp.java:328 msgid "Run on startup" -msgstr "" +msgstr "Lancer avec le démarrage du routeur" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configservice_jsp.java:330 msgid "You can control whether I2P is run on startup or not by selecting one of the following options" @@ -949,12 +950,12 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configservice_jsp.java:338 #: src/net/i2p/router/web/ConfigServiceHandler.java:80 msgid "Run I2P on startup" -msgstr "" +msgstr "Lancer I2P au démarrage" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configservice_jsp.java:340 #: src/net/i2p/router/web/ConfigServiceHandler.java:82 msgid "Don't run I2P on startup" -msgstr "" +msgstr "Ne pas lancer I2P au démarrage" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configservice_jsp.java:344 msgid "If you are running I2P as service right now, removing it will shut down your router immediately." @@ -966,16 +967,16 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configservice_jsp.java:354 msgid "Debugging" -msgstr "" +msgstr "Débogage" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configservice_jsp.java:356 #: src/net/i2p/router/web/ConfigServiceHandler.java:84 msgid "Dump threads" -msgstr "" +msgstr "Dump fils d'exécution" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configservice_jsp.java:360 msgid "Launch browser on router startup?" -msgstr "" +msgstr "Lancer explorateur internet pendant le démarrage du routeur ?" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configservice_jsp.java:362 msgid "I2P's main configuration interface is this web console, so for your convenience I2P can launch a web browser on startup pointing at" @@ -984,12 +985,12 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configservice_jsp.java:364 #: src/net/i2p/router/web/ConfigServiceHandler.java:115 msgid "View console on startup" -msgstr "" +msgstr "Montrer la console au démarrage" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configservice_jsp.java:366 #: src/net/i2p/router/web/ConfigServiceHandler.java:118 msgid "Do not view console on startup" -msgstr "" +msgstr "Ne pas montrer la console au démarrage" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configstats_jsp.java:107 msgid "config stats" @@ -997,7 +998,7 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configstats_jsp.java:229 msgid "I2P Stats Configuration" -msgstr "" +msgstr "Configuration I2P Statistiques" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configstats_jsp.java:300 msgid "Configure I2P Stat Collection" @@ -1022,15 +1023,15 @@ msgstr "Filtre" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configstats_jsp.java:317 #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configstats_jsp.java:326 msgid "toggle all" -msgstr "" +msgstr "basculer tous" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configstats_jsp.java:328 msgid "Log" -msgstr "" +msgstr "Enregistrement" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configstats_jsp.java:330 msgid "Graph" -msgstr "" +msgstr "Graphe" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configstats_jsp.java:369 msgid "Advanced filter" @@ -1046,7 +1047,7 @@ msgstr "Configuration des tunnels I2P" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configtunnels_jsp.java:305 msgid "The default settings work for most people." -msgstr "" +msgstr "La configuration défaut fonctionne pour le plupart des utilisateurs" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configtunnels_jsp.java:309 msgid "There is a fundamental tradeoff between anonymity and performance." @@ -1082,11 +1083,11 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configui_jsp.java:106 msgid "config UI" -msgstr "" +msgstr "configuration IHM" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configui_jsp.java:241 msgid "I2P UI Configuration" -msgstr "" +msgstr "Configuration de l'IHM I2P" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configui_jsp.java:291 msgid "Router Console Theme" @@ -1110,11 +1111,11 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configupdate_jsp.java:106 msgid "config update" -msgstr "" +msgstr "Mettre à jour la configuration" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configupdate_jsp.java:228 msgid "I2P Update Configuration" -msgstr "" +msgstr "Configuration du mise à jour I2P" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configupdate_jsp.java:300 msgid "Check for I2P and news updates" @@ -1122,36 +1123,36 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configupdate_jsp.java:302 msgid "News & I2P Updates" -msgstr "" +msgstr "Actualités et mises à jour I2P" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configupdate_jsp.java:306 msgid "Update In Progress" -msgstr "" +msgstr "Mise à jour en cours" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configupdate_jsp.java:310 #: src/net/i2p/router/web/ConfigUpdateHandler.java:56 msgid "Check for updates" -msgstr "" +msgstr "Chercher des mises à jour" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configupdate_jsp.java:314 msgid "News URL" -msgstr "" +msgstr "Actualités URL" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configupdate_jsp.java:318 msgid "Refresh frequency" -msgstr "" +msgstr "Fréquence d'actualisation" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configupdate_jsp.java:322 msgid "Update policy" -msgstr "" +msgstr "Méthode de mise à jour" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configupdate_jsp.java:326 msgid "Update through the eepProxy?" -msgstr "" +msgstr "Mettre à jour utilisant l'eeProxy ?" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configupdate_jsp.java:330 msgid "eepProxy host" -msgstr "" +msgstr "eeProxy hôte" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configupdate_jsp.java:334 msgid "eepProxy port" @@ -1159,19 +1160,19 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configupdate_jsp.java:338 msgid "Update URLs" -msgstr "" +msgstr "Mettre à jour à partir de ces URLs" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configupdate_jsp.java:342 msgid "Trusted keys" -msgstr "" +msgstr "Clés auxquelles on peut faire confiance" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configupdate_jsp.java:346 msgid "Update with unsigned development builds?" -msgstr "" +msgstr "Mettre à jour avec une version de développement d'i2p qui n'a pas été signée" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configupdate_jsp.java:350 msgid "Unsigned Build URL" -msgstr "" +msgstr "L'URL de la version d'i2p qui n'a pas été signée" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configupdate_jsp.java:354 msgid "Save" @@ -1195,7 +1196,7 @@ msgstr "pas trouvé" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/graphs_jsp.java:106 msgid "graphs" -msgstr "" +msgstr "graphes" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/graphs_jsp.java:228 msgid "I2P Performance Graphs" @@ -1210,11 +1211,11 @@ msgstr "" #: src/net/i2p/router/web/SummaryBarRenderer.java:26 #: src/net/i2p/router/web/SummaryBarRenderer.java:28 msgid "I2P Router Console" -msgstr "" +msgstr "Console du routeur I2P" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/jobs_jsp.java:105 msgid "job queue" -msgstr "" +msgstr "queue des tâches" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/jobs_jsp.java:227 msgid "I2P Router Job Queue" @@ -1222,11 +1223,11 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/logs_jsp.java:105 msgid "logs" -msgstr "" +msgstr "enregistrements" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/logs_jsp.java:227 msgid "I2P Router Logs" -msgstr "" +msgstr "Enregistrements du routeur I2P" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/logs_jsp.java:229 msgid "I2P Version & Running Environment" @@ -1246,15 +1247,15 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/oldstats_jsp.java:105 msgid "statistics" -msgstr "" +msgstr "statistiques" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/oldstats_jsp.java:242 msgid "I2P Router Statistics" -msgstr "" +msgstr "Statistiques du routeur I2P" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/peers_jsp.java:105 msgid "peer connections" -msgstr "" +msgstr "connexions pairs" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/peers_jsp.java:227 msgid "I2P Network Peers" @@ -1262,7 +1263,7 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/profiles_jsp.java:105 msgid "peer profiles" -msgstr "" +msgstr "profile des pairs" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/profiles_jsp.java:227 msgid "I2P Network Peer Profiles" @@ -1271,15 +1272,15 @@ msgstr "" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/summaryframe_jsp.java:245 #, java-format msgid "Disable {0}s Refresh" -msgstr "" +msgstr "Désactiver {0}s actualisation" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/tunnels_jsp.java:105 msgid "tunnel summary" -msgstr "" +msgstr "sommaire tunnel" #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/tunnels_jsp.java:227 msgid "I2P Tunnel Summary" -msgstr "" +msgstr "tunnel sommaire I2P" #: src/net/i2p/router/web/ConfigAdvancedHandler.java:57 msgid "Error updating the configuration - please see the error logs" @@ -1288,7 +1289,7 @@ msgstr "" #: src/net/i2p/router/web/ConfigAdvancedHandler.java:69 #: src/net/i2p/router/web/ConfigNetHandler.java:251 msgid "Configuration saved successfully" -msgstr "" +msgstr "Configuration sauvegardé avec succès" #: src/net/i2p/router/web/ConfigAdvancedHandler.java:71 #: src/net/i2p/router/web/ConfigNetHandler.java:253 @@ -1303,7 +1304,7 @@ msgstr "Démarrer" #: src/net/i2p/router/web/ConfigClientsHandler.java:68 #: src/net/i2p/router/web/ConfigKeyringHandler.java:49 msgid "Unsupported" -msgstr "" +msgstr "Non supportée" #: src/net/i2p/router/web/ConfigClientsHandler.java:83 msgid "Client configuration saved successfully - restart required to take effect." @@ -1323,7 +1324,7 @@ msgstr "Client" #: src/net/i2p/router/web/ConfigClientsHandler.java:94 #: src/net/i2p/router/web/ConfigClientsHandler.java:129 msgid "started" -msgstr "" +msgstr "démarré" #: src/net/i2p/router/web/ConfigClientsHandler.java:111 msgid "WebApp configuration saved successfully - restart required to take effect." @@ -1336,7 +1337,7 @@ msgstr "" #: src/net/i2p/router/web/ConfigClientsHandler.java:131 msgid "Failed to start" -msgstr "" +msgstr "Echec de démarrage" #: src/net/i2p/router/web/ConfigClientsHandler.java:137 msgid "Failed to find server." @@ -1349,12 +1350,12 @@ msgstr "" #: src/net/i2p/router/web/ConfigClientsHelper.java:17 #: src/net/i2p/router/web/ConfigClientsHelper.java:34 msgid "Run at Startup?" -msgstr "" +msgstr "Lancer au démarrage ?" #: src/net/i2p/router/web/ConfigClientsHelper.java:17 #: src/net/i2p/router/web/ConfigClientsHelper.java:34 msgid "Start Now" -msgstr "" +msgstr "Démarrer tout de suite" #: src/net/i2p/router/web/ConfigClientsHelper.java:34 msgid "Description" @@ -1362,37 +1363,37 @@ msgstr "" #: src/net/i2p/router/web/ConfigKeyringHandler.java:21 msgid "You must enter a destination" -msgstr "" +msgstr "Vous devez saisir une destination" #: src/net/i2p/router/web/ConfigKeyringHandler.java:23 msgid "You must enter a key" -msgstr "" +msgstr "Vous devez saisir une clé" #: src/net/i2p/router/web/ConfigKeyringHandler.java:34 #: src/net/i2p/router/web/ConfigKeyringHandler.java:41 #: src/net/i2p/router/web/ConfigKeyringHandler.java:43 msgid "Key for" -msgstr "" +msgstr "Clé pour" #: src/net/i2p/router/web/ConfigKeyringHandler.java:34 msgid "added to keyring" -msgstr "" +msgstr "ajouté au porte-clés " #: src/net/i2p/router/web/ConfigKeyringHandler.java:36 msgid "Invalid destination or key" -msgstr "" +msgstr "Destination ou clé pas valable" #: src/net/i2p/router/web/ConfigKeyringHandler.java:41 msgid "removed from keyring" -msgstr "" +msgstr "enlévé du porte-clés" #: src/net/i2p/router/web/ConfigKeyringHandler.java:43 msgid "not found in keyring" -msgstr "" +msgstr "pas trouvé sur le porte-clés" #: src/net/i2p/router/web/ConfigKeyringHandler.java:45 msgid "Invalid destination" -msgstr "" +msgstr "Destination pas valable" #: src/net/i2p/router/web/ConfigLoggingHelper.java:52 msgid "CRIT" @@ -1416,7 +1417,7 @@ msgstr "" #: src/net/i2p/router/web/ConfigNavHelper.java:18 msgid "Network" -msgstr "" +msgstr "Réseau" #: src/net/i2p/router/web/ConfigNavHelper.java:18 msgid "Service" @@ -1426,7 +1427,7 @@ msgstr "" #: src/net/i2p/router/web/SummaryBarRenderer.java:82 #: src/net/i2p/router/web/TunnelRenderer.java:253 msgid "Tunnels" -msgstr "Tunnels" +msgstr "" #: src/net/i2p/router/web/ConfigNavHelper.java:18 msgid "UI" @@ -1440,23 +1441,23 @@ msgstr "Mettre à jour" #: src/net/i2p/router/web/ConfigNavHelper.java:19 msgid "Clients" -msgstr "" +msgstr "Clients" #: src/net/i2p/router/web/ConfigNavHelper.java:19 msgid "Logging" -msgstr "" +msgstr "Enregistrements" #: src/net/i2p/router/web/ConfigNavHelper.java:19 #: src/net/i2p/router/web/SummaryBarRenderer.java:88 #: src/net/i2p/router/web/SummaryBarRenderer.java:223 msgid "Peers" -msgstr "" +msgstr "Pairs" #: src/net/i2p/router/web/ConfigNavHelper.java:19 #: src/net/i2p/router/web/NetDbRenderer.java:256 #: src/net/i2p/router/web/SummaryBarRenderer.java:124 msgid "Stats" -msgstr "" +msgstr "Statistiques" #: src/net/i2p/router/web/ConfigNavHelper.java:20 msgid "Advanced" @@ -1468,7 +1469,7 @@ msgstr "" #: src/net/i2p/router/web/ConfigNetHandler.java:148 msgid "Updating IP address" -msgstr "" +msgstr "Mise à jour d'adresse IP en cours" #: src/net/i2p/router/web/ConfigNetHandler.java:166 msgid "Disabling TCP completely" @@ -1532,7 +1533,7 @@ msgstr "" #: src/net/i2p/router/web/ConfigNetHandler.java:363 msgid "Updated bandwidth limits" -msgstr "" +msgstr "Limitations mises à jour de la bande passante " #: src/net/i2p/router/web/ConfigNetHelper.java:39 #: src/net/i2p/router/web/ConfigNetHelper.java:47 @@ -1552,7 +1553,7 @@ msgstr "bits par seconde" #: src/net/i2p/router/web/ProfileOrganizerRenderer.java:69 #: src/net/i2p/router/web/TunnelRenderer.java:235 msgid "Peer" -msgstr "" +msgstr "Pair" #: src/net/i2p/router/web/ConfigPeerHandler.java:24 msgid "banned until restart" @@ -1562,7 +1563,7 @@ msgstr "" #: src/net/i2p/router/web/ConfigPeerHandler.java:38 #: src/net/i2p/router/web/ConfigPeerHandler.java:59 msgid "Invalid peer" -msgstr "" +msgstr "Pair pas valable" #: src/net/i2p/router/web/ConfigPeerHandler.java:33 msgid "unbanned" @@ -1578,7 +1579,7 @@ msgstr "" #: src/net/i2p/router/web/ConfigPeerHandler.java:52 msgid "Bad capacity value" -msgstr "" +msgstr "Mauvaise valeur de capacité" #: src/net/i2p/router/web/ConfigRestartBean.java:36 msgid "Cancel shutdown" @@ -1594,21 +1595,21 @@ msgstr "Redémarrer" #: src/net/i2p/router/web/ConfigRestartBean.java:45 msgid "Shutdown" -msgstr "" +msgstr "Fermer" #: src/net/i2p/router/web/ConfigRestartBean.java:56 msgid "Shutdown imminent" -msgstr "" +msgstr "Fermature imminente" #: src/net/i2p/router/web/ConfigRestartBean.java:59 #, java-format msgid "Shutdown in {0}" -msgstr "" +msgstr "Fermature en {0}" #: src/net/i2p/router/web/ConfigRestartBean.java:64 #, java-format msgid "Restart in {0}" -msgstr "" +msgstr "Redémarrage en {0}" #: src/net/i2p/router/web/ConfigServiceHandler.java:56 msgid "Graceful shutdown initiated" @@ -1620,15 +1621,15 @@ msgstr "" #: src/net/i2p/router/web/ConfigServiceHandler.java:63 msgid "Graceful shutdown cancelled" -msgstr "" +msgstr "Fermeture gracieux annulée" #: src/net/i2p/router/web/ConfigServiceHandler.java:67 msgid "Graceful restart requested" -msgstr "" +msgstr "Redémarrage gracieux demandé" #: src/net/i2p/router/web/ConfigServiceHandler.java:71 msgid "Hard restart requested" -msgstr "" +msgstr "Redémarrage immédiate demandé" #: src/net/i2p/router/web/ConfigServiceHandler.java:72 msgid "Rekey and Restart" @@ -1674,7 +1675,7 @@ msgstr "" #: src/net/i2p/router/web/ConfigServiceHandler.java:129 msgid "Service installed" -msgstr "" +msgstr "Service installé" #: src/net/i2p/router/web/ConfigServiceHandler.java:131 msgid "Warning: unable to install the service" @@ -1682,7 +1683,7 @@ msgstr "" #: src/net/i2p/router/web/ConfigServiceHandler.java:137 msgid "Service removed" -msgstr "" +msgstr "Service enlévé" #: src/net/i2p/router/web/ConfigServiceHandler.java:139 msgid "Warning: unable to remove the service" @@ -1715,7 +1716,7 @@ msgstr "saut" #: src/net/i2p/router/web/ConfigTunnelsHelper.java:12 msgid "tunnel" -msgstr "tunnel" +msgstr "" #: src/net/i2p/router/web/ConfigTunnelsHelper.java:14 msgid "hops" @@ -1723,7 +1724,7 @@ msgstr "sauts" #: src/net/i2p/router/web/ConfigTunnelsHelper.java:15 msgid "tunnels" -msgstr "tunnels" +msgstr "" #: src/net/i2p/router/web/ConfigTunnelsHelper.java:26 #: src/net/i2p/router/web/TunnelRenderer.java:40 @@ -1765,27 +1766,27 @@ msgstr "Profondeur" #: src/net/i2p/router/web/ConfigTunnelsHelper.java:104 msgid "Randomization" -msgstr "" +msgstr "Randomisation" #: src/net/i2p/router/web/ConfigTunnelsHelper.java:128 msgid "Quantity" -msgstr "" +msgstr "Quantité" #: src/net/i2p/router/web/ConfigTunnelsHelper.java:145 msgid "Backup quantity" -msgstr "" +msgstr "'Backup' quantité" #: src/net/i2p/router/web/ConfigTunnelsHelper.java:167 msgid "Inbound options" -msgstr "" +msgstr "Options Entrants" #: src/net/i2p/router/web/ConfigTunnelsHelper.java:180 msgid "Outbound options" -msgstr "" +msgstr "Options Sortants" #: src/net/i2p/router/web/ConfigUIHandler.java:31 msgid "Theme change saved." -msgstr "" +msgstr "Changement de thème sauvegardé." #: src/net/i2p/router/web/ConfigUIHandler.java:33 msgid "Refresh the page to view." @@ -1801,19 +1802,19 @@ msgstr "Français" #: src/net/i2p/router/web/ConfigUIHelper.java:40 msgid "German" -msgstr "" +msgstr "Allemand" #: src/net/i2p/router/web/ConfigUIHelper.java:41 msgid "Chinese" -msgstr "" +msgstr "Chinois" #: src/net/i2p/router/web/ConfigUIHelper.java:41 msgid "Dutch" -msgstr "" +msgstr "Néerlandais" #: src/net/i2p/router/web/ConfigUIHelper.java:41 msgid "Swedish" -msgstr "" +msgstr "Suédois" #: src/net/i2p/router/web/ConfigUpdateHandler.java:63 msgid "Update available, attempting to download now" @@ -1871,7 +1872,7 @@ msgstr "Chaque" #: src/net/i2p/router/web/ConfigUpdateHelper.java:90 #: src/net/i2p/router/web/ConfigUpdateHelper.java:92 msgid "Notify only" -msgstr "" +msgstr "Notifier seulement" #: src/net/i2p/router/web/ConfigUpdateHelper.java:95 #: src/net/i2p/router/web/ConfigUpdateHelper.java:97 @@ -1881,11 +1882,11 @@ msgstr "Télécharger et vérifier seulement" #: src/net/i2p/router/web/ConfigUpdateHelper.java:101 #: src/net/i2p/router/web/ConfigUpdateHelper.java:103 msgid "Download, verify, and restart" -msgstr "" +msgstr "Télécharger, vérifier et redémarrer" #: src/net/i2p/router/web/GraphHelper.java:107 msgid "Configure Graph Display" -msgstr "" +msgstr "Graphe affichage configuration" #: src/net/i2p/router/web/GraphHelper.java:107 msgid "Select Stats" @@ -1893,27 +1894,27 @@ msgstr "" #: src/net/i2p/router/web/GraphHelper.java:109 msgid "Periods" -msgstr "" +msgstr "Périodes" #: src/net/i2p/router/web/GraphHelper.java:110 msgid "Plot averages" -msgstr "" +msgstr "Tracer les moyennes" #: src/net/i2p/router/web/GraphHelper.java:111 msgid "plot events" -msgstr "" +msgstr "tracer les événements" #: src/net/i2p/router/web/GraphHelper.java:112 msgid "Image sizes" -msgstr "" +msgstr "Taille des images" #: src/net/i2p/router/web/GraphHelper.java:112 msgid "width" -msgstr "" +msgstr "largeur" #: src/net/i2p/router/web/GraphHelper.java:113 msgid "height" -msgstr "" +msgstr "hauteur" #: src/net/i2p/router/web/GraphHelper.java:113 #: src/net/i2p/router/web/GraphHelper.java:114 @@ -1922,7 +1923,7 @@ msgstr "pixels" #: src/net/i2p/router/web/GraphHelper.java:115 msgid "Refresh delay" -msgstr "" +msgstr "Delai d'actualisation" #: src/net/i2p/router/web/GraphHelper.java:115 msgid "hour" @@ -1930,7 +1931,7 @@ msgstr "heure" #: src/net/i2p/router/web/GraphHelper.java:115 msgid "minute" -msgstr "minute" +msgstr "" #: src/net/i2p/router/web/GraphHelper.java:115 msgid "minutes" @@ -1968,22 +1969,22 @@ msgstr "Locale" #: src/net/i2p/router/web/NetDbRenderer.java:100 msgid "Unpublished" -msgstr "" +msgstr "Pas publié" #: src/net/i2p/router/web/NetDbRenderer.java:101 #: src/net/i2p/router/web/NetDbRenderer.java:108 msgid "Destination" -msgstr "Destination" +msgstr "" #: src/net/i2p/router/web/NetDbRenderer.java:118 #, java-format msgid "Expires in {0}" -msgstr "" +msgstr "Expirera en {0}" #: src/net/i2p/router/web/NetDbRenderer.java:120 #, java-format msgid "Expired {0} ago" -msgstr "" +msgstr "Périmé il y a {0}" #: src/net/i2p/router/web/NetDbRenderer.java:122 #: src/net/i2p/router/web/TunnelRenderer.java:156 @@ -1992,27 +1993,27 @@ msgstr "" #: src/net/i2p/router/web/NetDbRenderer.java:122 msgid "Lease" -msgstr "" +msgstr "Bail" #: src/net/i2p/router/web/NetDbRenderer.java:124 msgid "Tunnel" -msgstr "Tunnel" +msgstr "" #: src/net/i2p/router/web/NetDbRenderer.java:137 msgid "Not initialized" -msgstr "" +msgstr "Pas initialisé" #: src/net/i2p/router/web/NetDbRenderer.java:143 msgid "Routers" -msgstr "" +msgstr "Routeurs" #: src/net/i2p/router/web/NetDbRenderer.java:145 msgid "view without" -msgstr "" +msgstr "montrer sans" #: src/net/i2p/router/web/NetDbRenderer.java:147 msgid "view with" -msgstr "" +msgstr "montrer avec" #: src/net/i2p/router/web/NetDbRenderer.java:148 msgid "stats" @@ -2026,7 +2027,7 @@ msgstr "" #: src/net/i2p/router/web/NetDbRenderer.java:183 #: src/net/i2p/router/web/SummaryBarRenderer.java:150 msgid "Version" -msgstr "" +msgstr "Version" #: src/net/i2p/router/web/NetDbRenderer.java:199 msgid "Country" @@ -2038,7 +2039,7 @@ msgstr "Notre info" #: src/net/i2p/router/web/NetDbRenderer.java:224 msgid "Peer info for" -msgstr "" +msgstr "Mise à jour en cours" #: src/net/i2p/router/web/NetDbRenderer.java:228 msgid "Full entry" @@ -2046,46 +2047,46 @@ msgstr "" #: src/net/i2p/router/web/NetDbRenderer.java:234 msgid "Updated" -msgstr "" +msgstr "Mise à jour fini" #: src/net/i2p/router/web/NetDbRenderer.java:234 #: src/net/i2p/router/web/NetDbRenderer.java:236 #: src/net/i2p/router/web/SummaryHelper.java:385 msgid "ago" -msgstr "" +msgstr ":" #: src/net/i2p/router/web/NetDbRenderer.java:236 #: src/net/i2p/router/web/NetDbRenderer.java:238 msgid "Published" -msgstr "" +msgstr "Publié il y a" #: src/net/i2p/router/web/NetDbRenderer.java:239 msgid "Address(es)" -msgstr "" +msgstr "Adresse(s)" #: src/net/i2p/router/web/NewsFetcher.java:80 #, java-format msgid "News last updated {0} ago." -msgstr "" +msgstr "Actualités mises à jour il y a {0}" #: src/net/i2p/router/web/NewsFetcher.java:86 #, java-format msgid "News last checked {0} ago." -msgstr "" +msgstr "Actualités vérifiés il y a {0}" #: src/net/i2p/router/web/ProfileOrganizerRenderer.java:63 msgid "Peer Profiles" -msgstr "" +msgstr "Profils des pairs" #: src/net/i2p/router/web/ProfileOrganizerRenderer.java:64 #, java-format msgid "Showing {0} recent profiles." -msgstr "" +msgstr "Montrant {0} profiles récents" #: src/net/i2p/router/web/ProfileOrganizerRenderer.java:65 #, java-format msgid "Hiding {0} older profiles." -msgstr "" +msgstr "Cachant {0} profiles anciens" #: src/net/i2p/router/web/ProfileOrganizerRenderer.java:70 msgid "Groups (Caps)" @@ -2094,7 +2095,7 @@ msgstr "" #: src/net/i2p/router/web/ProfileOrganizerRenderer.java:73 #: src/net/i2p/router/web/ProfileOrganizerRenderer.java:233 msgid "Integration" -msgstr "" +msgstr "Intégration" #: src/net/i2p/router/web/ProfileOrganizerRenderer.java:74 msgid "Status" @@ -2115,7 +2116,7 @@ msgstr "" #: src/net/i2p/router/web/ProfileOrganizerRenderer.java:114 #: src/net/i2p/router/web/ProfileOrganizerRenderer.java:148 msgid "Failing" -msgstr "" +msgstr "Défaillant" #: src/net/i2p/router/web/ProfileOrganizerRenderer.java:116 #: src/net/i2p/router/web/SummaryBarRenderer.java:249 @@ -2128,23 +2129,23 @@ msgstr "Prohibé" #: src/net/i2p/router/web/ProfileOrganizerRenderer.java:149 msgid "Unreachable" -msgstr "" +msgstr "Inaccessible" #: src/net/i2p/router/web/ProfileOrganizerRenderer.java:156 msgid "Test Fails" -msgstr "" +msgstr "Test échec" #: src/net/i2p/router/web/ProfileOrganizerRenderer.java:168 msgid "Floodfill and Integrated Peers" -msgstr "" +msgstr "Floodfill et pairs intégrés" #: src/net/i2p/router/web/ProfileOrganizerRenderer.java:230 msgid "Thresholds:" -msgstr "" +msgstr "Seuils :" #: src/net/i2p/router/web/ProfileOrganizerRenderer.java:234 msgid "Definitions" -msgstr "" +msgstr "Définitions" #: src/net/i2p/router/web/ProfileOrganizerRenderer.java:235 msgid "as determined by the profile organizer" @@ -2152,7 +2153,7 @@ msgstr "" #: src/net/i2p/router/web/ProfileOrganizerRenderer.java:235 msgid "groups" -msgstr "" +msgstr "groupes" #: src/net/i2p/router/web/ProfileOrganizerRenderer.java:236 msgid "capabilities in the netDb, not used to determine profiles" @@ -2184,7 +2185,7 @@ msgstr "" #: src/net/i2p/router/web/ProfileOrganizerRenderer.java:239 msgid "integration" -msgstr "" +msgstr "intégration" #: src/net/i2p/router/web/ProfileOrganizerRenderer.java:240 msgid "is the peer banned, or unreachable, or failing tunnel tests?" @@ -2192,7 +2193,7 @@ msgstr "" #: src/net/i2p/router/web/ProfileOrganizerRenderer.java:240 msgid "status" -msgstr "" +msgstr "statut" #: src/net/i2p/router/web/StatsGenerator.java:58 msgid "Statistics gathered during this router's uptime" @@ -2208,7 +2209,7 @@ msgstr "" #: src/net/i2p/router/web/SummaryBarRenderer.java:42 msgid "I2P Services" -msgstr "" +msgstr "Services I2P" #: src/net/i2p/router/web/SummaryBarRenderer.java:48 msgid "Manage your I2P hosts file here (I2P domain name resolution)" @@ -2216,39 +2217,39 @@ msgstr "" #: src/net/i2p/router/web/SummaryBarRenderer.java:50 msgid "Addressbook" -msgstr "" +msgstr "Carnet d'adresses" #: src/net/i2p/router/web/SummaryBarRenderer.java:54 msgid "Built-in anonymous BitTorrent Client" -msgstr "" +msgstr "Client bittorrent anonyme" #: src/net/i2p/router/web/SummaryBarRenderer.java:56 msgid "Torrents" -msgstr "" +msgstr "Torrents" #: src/net/i2p/router/web/SummaryBarRenderer.java:60 msgid "Anonymous webmail client" -msgstr "" +msgstr "Client webmail anonyme" #: src/net/i2p/router/web/SummaryBarRenderer.java:62 msgid "Webmail" -msgstr "" +msgstr "messagerie Web" #: src/net/i2p/router/web/SummaryBarRenderer.java:66 msgid "Anonymous resident webserver" -msgstr "" +msgstr "Serveur web anonyme" #: src/net/i2p/router/web/SummaryBarRenderer.java:68 msgid "Webserver" -msgstr "" +msgstr "Serveur web" #: src/net/i2p/router/web/SummaryBarRenderer.java:72 msgid "Configure I2P Router" -msgstr "" +msgstr "I2P Routeur Configuration" #: src/net/i2p/router/web/SummaryBarRenderer.java:74 msgid "I2P Internals" -msgstr "" +msgstr "I2P Configuration Interne" #: src/net/i2p/router/web/SummaryBarRenderer.java:80 #: src/net/i2p/router/web/SummaryBarRenderer.java:344 @@ -2258,7 +2259,7 @@ msgstr "" #: src/net/i2p/router/web/SummaryBarRenderer.java:86 #: src/net/i2p/router/web/SummaryBarRenderer.java:221 msgid "Show all current peer connections" -msgstr "" +msgstr "Montrer toutes les connexions actuelles aux pairs" #: src/net/i2p/router/web/SummaryBarRenderer.java:92 msgid "Show recent peer performance profiles" @@ -2266,11 +2267,11 @@ msgstr "" #: src/net/i2p/router/web/SummaryBarRenderer.java:94 msgid "Profiles" -msgstr "" +msgstr "Profiles" #: src/net/i2p/router/web/SummaryBarRenderer.java:98 msgid "Show list of all known I2P routers" -msgstr "" +msgstr "Montrer une liste de touts le routeurs I2P connus" #: src/net/i2p/router/web/SummaryBarRenderer.java:100 msgid "NetDB" @@ -2282,7 +2283,7 @@ msgstr "" #: src/net/i2p/router/web/SummaryBarRenderer.java:106 msgid "Logs" -msgstr "" +msgstr "Enregistrements" #: src/net/i2p/router/web/SummaryBarRenderer.java:110 msgid "Show the router's workload, and how it's performing" @@ -2290,7 +2291,7 @@ msgstr "" #: src/net/i2p/router/web/SummaryBarRenderer.java:112 msgid "Jobs" -msgstr "" +msgstr "Tâches" #: src/net/i2p/router/web/SummaryBarRenderer.java:116 msgid "Graph router performance" @@ -2298,7 +2299,7 @@ msgstr "" #: src/net/i2p/router/web/SummaryBarRenderer.java:118 msgid "Graphs" -msgstr "" +msgstr "Graphes" #: src/net/i2p/router/web/SummaryBarRenderer.java:122 msgid "Textual router performance statistics" @@ -2306,19 +2307,19 @@ msgstr "" #: src/net/i2p/router/web/SummaryBarRenderer.java:134 msgid "I2P Router Help" -msgstr "" +msgstr "Aide routeur I2P" #: src/net/i2p/router/web/SummaryBarRenderer.java:136 msgid "General" -msgstr "" +msgstr "Général" #: src/net/i2p/router/web/SummaryBarRenderer.java:139 msgid "Your unique I2P router identity is" -msgstr "" +msgstr "L'identité unique de votre routeur est" #: src/net/i2p/router/web/SummaryBarRenderer.java:143 msgid "never reveal it to anyone" -msgstr "" +msgstr "révéler jamais à personne" #: src/net/i2p/router/web/SummaryBarRenderer.java:145 msgid "Local Identity" @@ -2330,19 +2331,19 @@ msgstr "" #: src/net/i2p/router/web/SummaryBarRenderer.java:160 msgid "Uptime" -msgstr "" +msgstr "Temps de service" #: src/net/i2p/router/web/SummaryBarRenderer.java:167 msgid "Help with configuring your firewall and router for optimal I2P performance" -msgstr "" +msgstr "Aide avec la configuration du pare-feu et du routeur afin d'optimiser la performance d'I2P" #: src/net/i2p/router/web/SummaryBarRenderer.java:194 msgid "Download" -msgstr "" +msgstr "Télécharger" #: src/net/i2p/router/web/SummaryBarRenderer.java:203 msgid "Download Unsigned" -msgstr "" +msgstr "Télécharger pas signé" #: src/net/i2p/router/web/SummaryBarRenderer.java:229 msgid "Active" @@ -2362,11 +2363,11 @@ msgstr "Connu" #: src/net/i2p/router/web/SummaryBarRenderer.java:270 msgid "Help with firewall configuration" -msgstr "" +msgstr "Aide avec la configuration du pare-feu" #: src/net/i2p/router/web/SummaryBarRenderer.java:272 msgid "Check NAT/firewall" -msgstr "" +msgstr "Vérifier NAT/pare-feu" #: src/net/i2p/router/web/SummaryBarRenderer.java:292 msgid "Reseed" @@ -2378,11 +2379,11 @@ msgstr "" #: src/net/i2p/router/web/SummaryBarRenderer.java:311 msgid "Bandwidth in/out" -msgstr "" +msgstr "Bande passante entrant/sortant" #: src/net/i2p/router/web/SummaryBarRenderer.java:328 msgid "Total" -msgstr "Total" +msgstr "" #: src/net/i2p/router/web/SummaryBarRenderer.java:336 msgid "Used" @@ -2406,23 +2407,23 @@ msgstr "" #: src/net/i2p/router/web/SummaryBarRenderer.java:375 msgid "Congestion" -msgstr "" +msgstr "Saturation réseau" #: src/net/i2p/router/web/SummaryBarRenderer.java:380 msgid "Job lag" -msgstr "" +msgstr "Tâche décalage" #: src/net/i2p/router/web/SummaryBarRenderer.java:386 msgid "Message delay" -msgstr "" +msgstr "Message retard" #: src/net/i2p/router/web/SummaryBarRenderer.java:392 msgid "Tunnel lag" -msgstr "" +msgstr "Tunnel décalage" #: src/net/i2p/router/web/SummaryBarRenderer.java:398 msgid "Backlog" -msgstr "" +msgstr "Retard accumulé" #: src/net/i2p/router/web/SummaryHelper.java:73 msgid "skew" @@ -2482,11 +2483,11 @@ msgstr "Serveur" #: src/net/i2p/router/web/SummaryHelper.java:373 msgid "Show tunnels" -msgstr "" +msgstr "Montrer les tunnels" #: src/net/i2p/router/web/SummaryHelper.java:384 msgid "Leases expired" -msgstr "" +msgstr "Bails périmés" #: src/net/i2p/router/web/SummaryHelper.java:384 #: src/net/i2p/router/web/SummaryHelper.java:385 @@ -2503,17 +2504,17 @@ msgstr "" #: src/net/i2p/router/web/SummaryHelper.java:392 msgid "Building tunnels" -msgstr "" +msgstr "Création des tunnels en cours" #: src/net/i2p/router/web/SummaryHelper.java:404 #: strings/Strings.java:33 msgid "shared clients" -msgstr "" +msgstr "clients partagés" #: src/net/i2p/router/web/TunnelRenderer.java:40 #: src/net/i2p/router/web/TunnelRenderer.java:62 msgid "config" -msgstr "" +msgstr "configuration" #: src/net/i2p/router/web/TunnelRenderer.java:70 msgid "Participating tunnels" @@ -2525,15 +2526,15 @@ msgstr "De" #: src/net/i2p/router/web/TunnelRenderer.java:71 msgid "Receive on" -msgstr "" +msgstr "Réception active" #: src/net/i2p/router/web/TunnelRenderer.java:72 msgid "Expiration" -msgstr "" +msgstr "Expiration" #: src/net/i2p/router/web/TunnelRenderer.java:72 msgid "Send on" -msgstr "" +msgstr "Envoyer activé" #: src/net/i2p/router/web/TunnelRenderer.java:72 msgid "To" @@ -2541,24 +2542,24 @@ msgstr "à" #: src/net/i2p/router/web/TunnelRenderer.java:73 msgid "Rate" -msgstr "" +msgstr "Taux" #: src/net/i2p/router/web/TunnelRenderer.java:73 msgid "Role" -msgstr "" +msgstr "Rôle" #: src/net/i2p/router/web/TunnelRenderer.java:73 #: src/net/i2p/router/web/TunnelRenderer.java:156 msgid "Usage" -msgstr "" +msgstr "Utilisation" #: src/net/i2p/router/web/TunnelRenderer.java:117 msgid "Outbound Endpoint" -msgstr "" +msgstr "Endpoint Sortant" #: src/net/i2p/router/web/TunnelRenderer.java:119 msgid "Inbound Gateway" -msgstr "" +msgstr "Gateway Entrant" #: src/net/i2p/router/web/TunnelRenderer.java:121 #: src/net/i2p/router/web/TunnelRenderer.java:162 @@ -2576,7 +2577,7 @@ msgstr "" #: src/net/i2p/router/web/TunnelRenderer.java:156 msgid "Expiry" -msgstr "" +msgstr "Echéance" #: src/net/i2p/router/web/TunnelRenderer.java:156 msgid "In/Out" @@ -2593,7 +2594,7 @@ msgstr "" #: src/net/i2p/router/web/TunnelRenderer.java:205 #: src/net/i2p/router/web/TunnelRenderer.java:211 msgid "Build in progress" -msgstr "" +msgstr "Création d'un tunnel en cours" #: src/net/i2p/router/web/TunnelRenderer.java:205 msgid "inbound" @@ -2605,7 +2606,7 @@ msgstr "sortant" #: src/net/i2p/router/web/TunnelRenderer.java:215 msgid "No tunnels; waiting for the grace period to end." -msgstr "" +msgstr "Pas de tunnel; attendant la fin du délai de grâce" #: src/net/i2p/router/web/TunnelRenderer.java:216 msgid "in" @@ -2617,7 +2618,7 @@ msgstr "sortir" #: src/net/i2p/router/web/TunnelRenderer.java:234 msgid "Tunnel Counts By Peer" -msgstr "" +msgstr "Nombre de tunnels par pair" #: src/net/i2p/router/web/TunnelRenderer.java:235 msgid "% of total" @@ -2653,11 +2654,11 @@ msgstr "susidns" #: strings/Strings.java:17 msgid "routerconsole" -msgstr "" +msgstr "routeurconsole" #: strings/Strings.java:22 msgid "Web console" -msgstr "" +msgstr "Console web" #: strings/Strings.java:23 msgid "SAM application bridge" From 9e4f04cc18d44bf2210b5b30709b65dd9bdbb249 Mon Sep 17 00:00:00 2001 From: zzz Date: Wed, 2 Dec 2009 16:50:15 +0000 Subject: [PATCH 023/127] fix exception text --- core/java/src/net/i2p/data/Hash.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/java/src/net/i2p/data/Hash.java b/core/java/src/net/i2p/data/Hash.java index 10856d0c2..ddf210c54 100644 --- a/core/java/src/net/i2p/data/Hash.java +++ b/core/java/src/net/i2p/data/Hash.java @@ -140,7 +140,7 @@ public class Hash extends DataStructureImpl { public void writeBytes(OutputStream out) throws DataFormatException, IOException { if (_data == null) throw new DataFormatException("No data in the hash to write out"); - if (_data.length != HASH_LENGTH) throw new DataFormatException("Invalid size of data in the private key"); + if (_data.length != HASH_LENGTH) throw new DataFormatException("Invalid size of data in the hash"); out.write(_data); } From 9f7bd99051da5fa83879968985719282bc313e85 Mon Sep 17 00:00:00 2001 From: zzz Date: Wed, 2 Dec 2009 16:50:42 +0000 Subject: [PATCH 024/127] fix popup based on torrent type --- .../java/src/org/klomp/snark/web/I2PSnarkServlet.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java index a4ac23b43..5beb0ae44 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java +++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java @@ -496,9 +496,14 @@ public class I2PSnarkServlet extends HttpServlet { out.write(statusString + "

    "); - if (remaining == 0) + if (remaining == 0) { out.write(""); + + "\" title=\""); + if (snark.meta.getFiles() != null) + out.write("View files\">"); + else + out.write("Open file\">"); + } out.write(filename); if (remaining == 0) out.write(""); From 7262c014c02fcc86c2706d267a6e7a1763c807b0 Mon Sep 17 00:00:00 2001 From: zzz Date: Fri, 4 Dec 2009 00:20:43 +0000 Subject: [PATCH 025/127] * I2CP: Implement an internal "socket" class that allows clients in the same JVM to connect to the router without going through the kernel --- .../src/net/i2p/client/I2PSessionImpl.java | 6 +- .../src/net/i2p/client/I2PSimpleClient.java | 4 +- .../src/net/i2p/client/I2PSimpleSession.java | 5 +- .../net/i2p/util/InternalServerSocket.java | 199 ++++++++++++++ .../java/src/net/i2p/util/InternalSocket.java | 259 ++++++++++++++++++ router/java/src/net/i2p/router/Router.java | 3 + .../router/client/ClientListenerRunner.java | 22 +- .../net/i2p/router/client/ClientManager.java | 18 +- .../client/InternalClientListenerRunner.java | 88 ++++++ 9 files changed, 584 insertions(+), 20 deletions(-) create mode 100644 core/java/src/net/i2p/util/InternalServerSocket.java create mode 100644 core/java/src/net/i2p/util/InternalSocket.java create mode 100644 router/java/src/net/i2p/router/client/InternalClientListenerRunner.java diff --git a/core/java/src/net/i2p/client/I2PSessionImpl.java b/core/java/src/net/i2p/client/I2PSessionImpl.java index 0cbde00ce..c11c71549 100644 --- a/core/java/src/net/i2p/client/I2PSessionImpl.java +++ b/core/java/src/net/i2p/client/I2PSessionImpl.java @@ -39,6 +39,7 @@ import net.i2p.data.i2cp.I2CPMessageReader; import net.i2p.data.i2cp.MessagePayloadMessage; import net.i2p.data.i2cp.SessionId; import net.i2p.util.I2PThread; +import net.i2p.util.InternalSocket; import net.i2p.util.Log; import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; @@ -268,12 +269,13 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa long startConnect = _context.clock().now(); try { - if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "connect begin to " + _hostname + ":" + _portNum); - _socket = new Socket(_hostname, _portNum); + // If we are in the router JVM, connect using the interal pseudo-socket + _socket = InternalSocket.getSocket(_hostname, _portNum); // _socket.setSoTimeout(1000000); // Uhmmm we could really-really use a real timeout, and handle it. _out = _socket.getOutputStream(); synchronized (_out) { _out.write(I2PClient.PROTOCOL_BYTE); + _out.flush(); } InputStream in = _socket.getInputStream(); _reader = new I2CPMessageReader(in, this); diff --git a/core/java/src/net/i2p/client/I2PSimpleClient.java b/core/java/src/net/i2p/client/I2PSimpleClient.java index 9ce4b8d6f..e91ae2f8b 100644 --- a/core/java/src/net/i2p/client/I2PSimpleClient.java +++ b/core/java/src/net/i2p/client/I2PSimpleClient.java @@ -20,12 +20,12 @@ import net.i2p.data.Destination; * just used to talk to the router. */ public class I2PSimpleClient implements I2PClient { - /** Don't do this */ + /** @deprecated Don't do this */ public Destination createDestination(OutputStream destKeyStream) throws I2PException, IOException { return null; } - /** or this */ + /** @deprecated or this */ public Destination createDestination(OutputStream destKeyStream, Certificate cert) throws I2PException, IOException { return null; } diff --git a/core/java/src/net/i2p/client/I2PSimpleSession.java b/core/java/src/net/i2p/client/I2PSimpleSession.java index bdc384b44..933a9578c 100644 --- a/core/java/src/net/i2p/client/I2PSimpleSession.java +++ b/core/java/src/net/i2p/client/I2PSimpleSession.java @@ -20,6 +20,7 @@ import net.i2p.data.i2cp.DestReplyMessage; import net.i2p.data.i2cp.GetBandwidthLimitsMessage; import net.i2p.data.i2cp.I2CPMessageReader; import net.i2p.util.I2PThread; +import net.i2p.util.InternalSocket; /** * Create a new session for doing naming and bandwidth queries only. Do not create a Destination. @@ -71,10 +72,12 @@ class I2PSimpleSession extends I2PSessionImpl2 { notifier.start(); try { - _socket = new Socket(_hostname, _portNum); + // If we are in the router JVM, connect using the interal pseudo-socket + _socket = InternalSocket.getSocket(_hostname, _portNum); _out = _socket.getOutputStream(); synchronized (_out) { _out.write(I2PClient.PROTOCOL_BYTE); + _out.flush(); } InputStream in = _socket.getInputStream(); _reader = new I2CPMessageReader(in, this); diff --git a/core/java/src/net/i2p/util/InternalServerSocket.java b/core/java/src/net/i2p/util/InternalServerSocket.java new file mode 100644 index 000000000..00d8352ee --- /dev/null +++ b/core/java/src/net/i2p/util/InternalServerSocket.java @@ -0,0 +1,199 @@ +package net.i2p.util; + +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketAddress; +import java.nio.channels.ServerSocketChannel; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.LinkedBlockingQueue; + +import net.i2p.I2PAppContext; + +/** + * A simple in-JVM ServerSocket using Piped Streams. + * We use port numbers just like regular sockets. + * Can only be connected by InternalSocket. + */ +public class InternalServerSocket extends ServerSocket { + private static final ConcurrentHashMap _sockets = new ConcurrentHashMap(4); + private BlockingQueue _acceptQueue; + private Integer _port; + private boolean _running; + private static Log _log = I2PAppContext.getGlobalContext().logManager().getLog(InternalServerSocket.class); + + public InternalServerSocket(int port) throws IOException { + if (port <= 0) + throw new IOException("Bad port: " + port); + _port = Integer.valueOf(port); + InternalServerSocket previous = _sockets.putIfAbsent(_port, this); + if (previous != null) + throw new IOException("Internal port in use: " + port); + _running = true; + _acceptQueue = new LinkedBlockingQueue(); + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Registered " + _port); + } + + @Override + public void close() { + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Closing " + _port); + _running = false; + _sockets.remove(_port); + _acceptQueue.clear(); + try { + // use null streams as a poison + _acceptQueue.put(new InternalSocket(null, null)); + } catch (InterruptedException ie) {} + } + + @Override + public Socket accept() throws IOException { + InternalSocket serverSock = null; + while (_running) { + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Accepting " + _port); + try { + serverSock = _acceptQueue.take(); + } catch (InterruptedException ie) { + continue; + } + if (serverSock.getInputStream() == null) // poison + throw new IOException("closed"); + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Accepted " + _port); + break; + } + return serverSock; + } + + @Override + public String toString() { + return ("Internal server socket on port " + _port); + } + + /** + * This is how the client connects. + * + * Todo: Java 1.5 PipedInputStream buffers are only 1024 bytes; our I2CP messages are typically 1730 bytes, + * thus causing thread blockage before the whole message is transferred. + * We can specify buffer size in 1.6 but not in 1.5. + * Does wrapping the PipedOutputStreams in BufferedOutputStreams gain capacity? + * No? + */ + static void internalConnect(int port, InternalSocket clientSock) throws IOException { + InternalServerSocket iss = _sockets.get(Integer.valueOf(port)); + if (iss == null) + throw new IOException("No server for port: " + port); + PipedInputStream cis = new BigPipedInputStream(); + PipedInputStream sis = new BigPipedInputStream(); + PipedOutputStream cos = new PipedOutputStream(sis); + PipedOutputStream sos = new PipedOutputStream(cis); + clientSock.setInputStream(cis); + clientSock.setOutputStream(cos); + iss.queueConnection(new InternalSocket(sis, sos)); + } + + /** + * Until we switch to Java 1.6 + * http://javatechniques.com/blog/low-memory-deep-copy-technique-for-java-objects/ + */ + private static class BigPipedInputStream extends PipedInputStream { + protected static int PIPE_SIZE = 64*1024; + public BigPipedInputStream() { + super(); + buffer = new byte[PIPE_SIZE]; + } + } + + private void queueConnection(InternalSocket sock) throws IOException { + if (!_running) + throw new IOException("Server closed for port: " + _port); + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Queueing " + _port); + try { + _acceptQueue.put(sock); + } catch (InterruptedException ie) {} + } + + @Override + public int getLocalPort() { + return _port.intValue(); + } + + // ignored stuff + + /** warning - unsupported */ + @Override + public void setSoTimeout(int timeout) {} + + @Override + public int getSoTimeout () { + return 0; + } + + // everything below here unsupported + /** @deprecated unsupported */ + @Override + public void bind(SocketAddress endpoint) { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public void bind(SocketAddress endpoint, int backlog) { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public ServerSocketChannel getChannel() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public InetAddress getInetAddress() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public SocketAddress getLocalSocketAddress() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public int getReceiveBufferSize() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public boolean getReuseAddress() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public boolean isBound() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public boolean isClosed() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public void setReceiveBufferSize(int size) { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public void setReuseAddress(boolean on) { + throw new IllegalArgumentException("unsupported"); + } +} diff --git a/core/java/src/net/i2p/util/InternalSocket.java b/core/java/src/net/i2p/util/InternalSocket.java new file mode 100644 index 000000000..b1feb847f --- /dev/null +++ b/core/java/src/net/i2p/util/InternalSocket.java @@ -0,0 +1,259 @@ +package net.i2p.util; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.Socket; +import java.net.SocketAddress; +import java.nio.channels.SocketChannel; + +/** + * A simple in-JVM Socket using Piped Streams. + * We use port numbers just like regular sockets. + * Can only connect to InternalServerSocket. + */ +public class InternalSocket extends Socket { + private InputStream _is; + private OutputStream _os; + + /** server side */ + InternalSocket(InputStream is, OutputStream os) { + _is = is; + _os = os; + } + + /** client side */ + public InternalSocket(int port) throws IOException { + if (port <= 0) + throw new IOException("bad port number"); + InternalServerSocket.internalConnect(port, this); + } + + /** + * Convenience method to return either a Socket or an InternalSocket + */ + public static Socket getSocket(String host, int port) throws IOException { + if (System.getProperty("router.version") != null && + (host.equals("127.0.0.1") || host.equals("localhost"))) { + return new InternalSocket(port); + } else { + return new Socket(host, port); + } + } + + @Override + public InputStream getInputStream() { + return _is; + } + + @Override + public OutputStream getOutputStream() { + return _os; + } + + void setInputStream(InputStream is) { + _is = is; + } + + void setOutputStream(OutputStream os) { + _os = os; + } + + @Override + public void close() { + try { + if (_is != null) _is.close(); + } catch (IOException ie) {} + try { + if (_os != null) _os.close(); + } catch (IOException ie) {} + } + + @Override + public String toString() { + return ("Internal socket"); + } + + // ignored stuff + /** warning - unsupported */ + @Override + public void setSoTimeout(int timeout) {} + + @Override + public int getSoTimeout () { + return 0; + } + + // everything below here unsupported + /** @deprecated unsupported */ + @Override + public void bind(SocketAddress endpoint) { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public void connect(SocketAddress endpoint) { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public void connect(SocketAddress endpoint, int timeout) { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public SocketChannel getChannel() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public InetAddress getInetAddress() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public boolean getKeepAlive() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public InetAddress getLocalAddress() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public int getLocalPort() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public SocketAddress getLocalSocketAddress() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public boolean getOOBInline() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public int getPort() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public int getReceiveBufferSize() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public SocketAddress getRemoteSocketAddress() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public boolean getReuseAddress() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public int getSendBufferSize() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public int getSoLinger() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public boolean getTcpNoDelay() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public int getTrafficClass() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public boolean isBound() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public boolean isClosed() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public boolean isConnected() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public boolean isInputShutdown() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public boolean isOutputShutdown() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public void sendUrgentData(int data) { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public void setKeepAlive(boolean on) { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public void setOOBInline(boolean on) { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public void setReceiveBufferSize(int size) { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public void setReuseAddress(boolean on) { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public void setSendBufferSize(int size) { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public void setSoLinger(boolean on, int linger) { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public void setTcpNoDelay(boolean on) { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public void setTrafficClass(int cize) { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public void shutdownInput() { + throw new IllegalArgumentException("unsupported"); + } + /** @deprecated unsupported */ + @Override + public void shutdownOutput() { + throw new IllegalArgumentException("unsupported"); + } +} diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java index 3e9a6cc66..7e231097b 100644 --- a/router/java/src/net/i2p/router/Router.java +++ b/router/java/src/net/i2p/router/Router.java @@ -200,6 +200,9 @@ public class Router { // overwrite an existing running router's jar files. Other than ours. installUpdates(); + // Apps may use this as an easy way to determine if they are in the router JVM + System.setProperty("router.version", RouterVersion.VERSION); + // NOW we start all the activity _context.initAll(); diff --git a/router/java/src/net/i2p/router/client/ClientListenerRunner.java b/router/java/src/net/i2p/router/client/ClientListenerRunner.java index 0f26b8d00..e5e6d8443 100644 --- a/router/java/src/net/i2p/router/client/ClientListenerRunner.java +++ b/router/java/src/net/i2p/router/client/ClientListenerRunner.java @@ -24,14 +24,14 @@ import net.i2p.util.Log; * @author jrandom */ public class ClientListenerRunner implements Runnable { - private Log _log; - private RouterContext _context; - private ClientManager _manager; - private ServerSocket _socket; - private int _port; + protected Log _log; + protected RouterContext _context; + protected ClientManager _manager; + protected ServerSocket _socket; + protected int _port; private boolean _bindAllInterfaces; - private boolean _running; - private boolean _listening; + protected boolean _running; + protected boolean _listening; public static final String BIND_ALL_INTERFACES = "i2cp.tcp.bindAllInterfaces"; @@ -91,7 +91,9 @@ public class ClientListenerRunner implements Runnable { } else { if (_log.shouldLog(Log.WARN)) _log.warn("Refused connection from " + socket.getInetAddress()); - socket.close(); + try { + socket.close(); + } catch (IOException ioe) {} } } catch (IOException ioe) { if (_context.router().isAlive()) @@ -132,7 +134,7 @@ public class ClientListenerRunner implements Runnable { /** give the i2cp client 5 seconds to show that they're really i2cp clients */ private final static int CONNECT_TIMEOUT = 5*1000; - private boolean validate(Socket socket) { + protected boolean validate(Socket socket) { try { socket.setSoTimeout(CONNECT_TIMEOUT); int read = socket.getInputStream().read(); @@ -150,7 +152,7 @@ public class ClientListenerRunner implements Runnable { * Handle the connection by passing it off to a {@link ClientConnectionRunner ClientConnectionRunner} * */ - protected void runConnection(Socket socket) throws IOException { + protected void runConnection(Socket socket) { ClientConnectionRunner runner = new ClientConnectionRunner(_context, _manager, socket); _manager.registerConnection(runner); } diff --git a/router/java/src/net/i2p/router/client/ClientManager.java b/router/java/src/net/i2p/router/client/ClientManager.java index cbc5d778b..4e77bbf9f 100644 --- a/router/java/src/net/i2p/router/client/ClientManager.java +++ b/router/java/src/net/i2p/router/client/ClientManager.java @@ -42,6 +42,7 @@ import net.i2p.util.Log; public class ClientManager { private Log _log; private ClientListenerRunner _listener; + private ClientListenerRunner _internalListener; private final HashMap _runners; // Destination --> ClientConnectionRunner private final Set _pendingRunners; // ClientConnectionRunner for clients w/out a Dest yet private RouterContext _ctx; @@ -58,11 +59,21 @@ public class ClientManager { new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l }); _runners = new HashMap(); _pendingRunners = new HashSet(); + startListeners(port); + } + + /** Todo: Start a 3rd listener for IPV6? */ + private void startListeners(int port) { _listener = new ClientListenerRunner(_ctx, this, port); Thread t = new I2PThread(_listener); t.setName("ClientListener:" + port); t.setDaemon(true); t.start(); + _internalListener = new InternalClientListenerRunner(_ctx, this, port); + t = new I2PThread(_internalListener); + t.setName("ClientListener:" + port + "-i"); + t.setDaemon(true); + t.start(); } public void restart() { @@ -80,16 +91,13 @@ public class ClientManager { _log.error("Error setting the port: " + portStr + " is not valid", nfe); } } - _listener = new ClientListenerRunner(_ctx, this, port); - Thread t = new I2PThread(_listener); - t.setName("ClientListener:" + port); - t.setDaemon(true); - t.start(); + startListeners(port); } public void shutdown() { _log.info("Shutting down the ClientManager"); _listener.stopListening(); + _internalListener.stopListening(); Set runners = new HashSet(); synchronized (_runners) { for (Iterator iter = _runners.values().iterator(); iter.hasNext();) { diff --git a/router/java/src/net/i2p/router/client/InternalClientListenerRunner.java b/router/java/src/net/i2p/router/client/InternalClientListenerRunner.java new file mode 100644 index 000000000..2105f7691 --- /dev/null +++ b/router/java/src/net/i2p/router/client/InternalClientListenerRunner.java @@ -0,0 +1,88 @@ +package net.i2p.router.client; +/* + * free (adj.): unencumbered; not under the control of others + * Written by jrandom in 2003 and released into the public domain + * with no warranty of any kind, either expressed or implied. + * It probably won't make your computer catch on fire, or eat + * your children, but it might. Use at your own risk. + * + */ + +import java.io.IOException; +import java.net.Socket; + +import net.i2p.router.RouterContext; +import net.i2p.util.Log; +import net.i2p.util.InternalServerSocket; + +/** + * Listen for in-JVM connections on the internal "socket" + * + * @author zzz + */ +public class InternalClientListenerRunner extends ClientListenerRunner { + + public InternalClientListenerRunner(RouterContext context, ClientManager manager, int port) { + super(context, manager, port); + _log = _context.logManager().getLog(InternalClientListenerRunner.class); + } + + /** + * Start up the socket listener, listens for connections, and + * fires those connections off via {@link #runConnection runConnection}. + * This only returns if the socket cannot be opened or there is a catastrophic + * failure. + * + */ + public void runServer() { + try { + if (_log.shouldLog(Log.INFO)) + _log.info("Listening on internal port " + _port); + _socket = new InternalServerSocket(_port); + + if (_log.shouldLog(Log.DEBUG)) + _log.debug("InternalServerSocket created, before accept: " + _socket); + + _listening = true; + _running = true; + while (_running) { + try { + Socket socket = _socket.accept(); + if (validate(socket)) { + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Internal connection received"); + runConnection(socket); + } else { + if (_log.shouldLog(Log.WARN)) + _log.warn("Refused connection from " + socket.getInetAddress()); + try { + socket.close(); + } catch (IOException ioe) {} + } + } catch (IOException ioe) { + if (_context.router().isAlive()) + _log.error("Server error accepting", ioe); + } catch (Throwable t) { + if (_context.router().isAlive()) + _log.error("Fatal error running client listener - killing the thread!", t); + _listening = false; + return; + } + } + } catch (IOException ioe) { + if (_context.router().isAlive()) + _log.error("Error listening on internal port " + _port, ioe); + } + + _listening = false; + if (_socket != null) { + try { _socket.close(); } catch (IOException ioe) {} + _socket = null; + } + + + if (_context.router().isAlive()) + _log.error("CANCELING I2CP LISTEN", new Exception("I2CP Listen cancelled!!!")); + _running = false; + } +} From 43029de2f368262256e2bd4e800cb5fb27617470 Mon Sep 17 00:00:00 2001 From: zzz Date: Fri, 4 Dec 2009 00:22:12 +0000 Subject: [PATCH 026/127] point to translated pages on www.i2p2.i2p --- installer/resources/readme/readme_fr.html | 6 +++--- installer/resources/readme/readme_zh.html | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/installer/resources/readme/readme_fr.html b/installer/resources/readme/readme_fr.html index a95ffe266..a3d38072c 100644 --- a/installer/resources/readme/readme_fr.html +++ b/installer/resources/readme/readme_fr.html @@ -9,8 +9,8 @@
  • inproxy.tino.i2p et perv.i2p: listent les eepsites actifs
  • forum.i2p: une connection sécurisée et anonyme vers forum.i2p2.de
  • -
  • www.i2p2.i2p et le miroir i2p-projekt.i2p: - connections sécurisées et anonyme vers www.i2p2.de
  • +
  • www.i2p2.i2p et le miroir i2p-projekt.i2p: + connections sécurisées et anonyme vers www.i2p2.de
  • eepsites.i2p: un moteur de recherche d'eepsites
  • ugha.i2p: l'eepsite d'ugha, un wiki que chaucun peut éditer ainsi que
  • fproxy.tino.i2p: un proxy Freenet 0.5
  • @@ -38,4 +38,4 @@

    Dépannage

    -

    Soyez patient - i2p peut s'avérer lent à démarrer la première fois car il recherche des pairs. Si, après 30 minutes, votre Actives: connecté/récent compte moins de 10 pairs connectés, vous devez ouvrir le port 8887 sur votre pare-feu pour avoir une meilleure connection. Si vous ne pouvez accéder à aucun eepsite (même www.i2p2.i2p), soyez sûr que votre navigateur utilise bien le proxy 127.0.0.1 sur le port 4444. Vous pouvez aussi faire part de votre démarche sur le site web I2P, poster des message sur le forum de discussion, ou passer par #i2p ou #i2p-chat sur IRC sur le serveur irc.freenode.net, irc.postman.i2p ou irc.freshcoffee.i2p (ils sont liés).


    +

    Soyez patient - i2p peut s'avérer lent à démarrer la première fois car il recherche des pairs. Si, après 30 minutes, votre Actives: connecté/récent compte moins de 10 pairs connectés, vous devez ouvrir le port 8887 sur votre pare-feu pour avoir une meilleure connection. Si vous ne pouvez accéder à aucun eepsite (même www.i2p2.i2p), soyez sûr que votre navigateur utilise bien le proxy 127.0.0.1 sur le port 4444. Vous pouvez aussi faire part de votre démarche sur le site web I2P, poster des message sur le forum de discussion, ou passer par #i2p ou #i2p-chat sur IRC sur le serveur irc.freenode.net, irc.postman.i2p ou irc.freshcoffee.i2p (ils sont liés).


    diff --git a/installer/resources/readme/readme_zh.html b/installer/resources/readme/readme_zh.html index d3cf05a77..2ebf15bde 100644 --- a/installer/resources/readme/readme_zh.html +++ b/installer/resources/readme/readme_zh.html @@ -12,7 +12,7 @@
  • 浏览 I2P 站点 "eepsites" - I2P 网络内匿名运行的小站 - 您要首先设置浏览器的 HTTP 代理 为 127.0.0.1:4444, 然后才能浏览 I2P 站点 -
  •   NameDestination<%=intl._("Name")%><%=intl._("Destination")%>
    "> ${addr.name} - -(addrhlpr) +(<%=intl._("address helper link")%>)
    - +

    @@ -155,7 +155,7 @@
    -

    +

    " >

    @@ -174,7 +174,7 @@ <%=intl._("Hostname")%>: <%=intl._("Destination")%>:

    - +" >

    diff --git a/apps/susidns/src/jsp/config.jsp b/apps/susidns/src/jsp/config.jsp index 4c3cefbdf..9f407ced9 100644 --- a/apps/susidns/src/jsp/config.jsp +++ b/apps/susidns/src/jsp/config.jsp @@ -34,7 +34,7 @@ -<%=intl._("configuration")%> - susidns v${version.version} +<%=intl._("configuration")%> - susidns @@ -64,8 +64,8 @@
    - - +" > +" >
    diff --git a/apps/susidns/src/jsp/index.jsp b/apps/susidns/src/jsp/index.jsp index 0f56bdf18..51e0517e9 100644 --- a/apps/susidns/src/jsp/index.jsp +++ b/apps/susidns/src/jsp/index.jsp @@ -32,7 +32,7 @@ -<%=intl._("Introduction")%> - SusiDNS v${version.version} +<%=intl._("Introduction")%> - SusiDNS diff --git a/apps/susidns/src/jsp/subscriptions.jsp b/apps/susidns/src/jsp/subscriptions.jsp index 7485e10bc..4edd704ae 100644 --- a/apps/susidns/src/jsp/subscriptions.jsp +++ b/apps/susidns/src/jsp/subscriptions.jsp @@ -34,7 +34,7 @@ -<%=intl._("subscriptions")%> - susidns v${version.version} +<%=intl._("subscriptions")%> - susidns @@ -64,8 +64,8 @@
    - - +" > +" >
    From b53031685063a034d612a58d0affed481b438be9 Mon Sep 17 00:00:00 2001 From: zzz Date: Thu, 17 Dec 2009 01:05:29 +0000 Subject: [PATCH 088/127] * I2CP: - Move client-side writes to their own thread - Reenable InternalSockets --- .../net/i2p/client/ClientWriterRunner.java | 97 +++++++++++++++++++ .../src/net/i2p/client/I2PSessionImpl.java | 42 +++----- .../src/net/i2p/client/I2PSimpleSession.java | 1 + .../net/i2p/util/InternalServerSocket.java | 5 + .../java/src/net/i2p/util/InternalSocket.java | 10 +- 5 files changed, 123 insertions(+), 32 deletions(-) create mode 100644 core/java/src/net/i2p/client/ClientWriterRunner.java diff --git a/core/java/src/net/i2p/client/ClientWriterRunner.java b/core/java/src/net/i2p/client/ClientWriterRunner.java new file mode 100644 index 000000000..056208fb5 --- /dev/null +++ b/core/java/src/net/i2p/client/ClientWriterRunner.java @@ -0,0 +1,97 @@ +package net.i2p.client; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +import net.i2p.data.i2cp.I2CPMessage; +import net.i2p.data.i2cp.I2CPMessageImpl; +import net.i2p.data.i2cp.I2CPMessageException; +import net.i2p.util.I2PAppThread; + +/** + * Copied from net.i2p.router.client + * We need a single thread that writes so we don't have issues with + * the Piped Streams used in InternalSocket. + * + * @author zzz from net.i2p.router.client.ClientWriterRunner + */ +class ClientWriterRunner implements Runnable { + private OutputStream _out; + private I2PSessionImpl _session; + private BlockingQueue _messagesToWrite; + private static volatile long __Id = 0; + + /** starts the thread too */ + public ClientWriterRunner(OutputStream out, I2PSessionImpl session) { + _out = out; + _session = session; + _messagesToWrite = new LinkedBlockingQueue(); + Thread t = new I2PAppThread(this, "I2CP Client Writer " + (++__Id), true); + t.start(); + } + + /** + * Add this message to the writer's queue + * + */ + public void addMessage(I2CPMessage msg) { + try { + _messagesToWrite.put(msg); + } catch (InterruptedException ie) {} + } + + /** + * No more messages - dont even try to send what we have + * + */ + public void stopWriting() { + _messagesToWrite.clear(); + try { + _messagesToWrite.put(new PoisonMessage()); + } catch (InterruptedException ie) {} + } + + public void run() { + I2CPMessage msg; + while (!_session.isClosed()) { + try { + msg = _messagesToWrite.take(); + } catch (InterruptedException ie) { + continue; + } + if (msg.getType() == PoisonMessage.MESSAGE_TYPE) + break; + // only thread, we don't need synchronized + try { + msg.writeMessage(_out); + _out.flush(); + } catch (I2CPMessageException ime) { + _session.propogateError("Error writing out the message", ime); + _session.disconnect(); + break; + } catch (IOException ioe) { + _session.propogateError("Error writing out the message", ioe); + _session.disconnect(); + break; + } + } + _messagesToWrite.clear(); + } + + /** + * End-of-stream msg used to stop the concurrent queue + * See http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html + * + */ + private static class PoisonMessage extends I2CPMessageImpl { + public static final int MESSAGE_TYPE = 999999; + public int getType() { + return MESSAGE_TYPE; + } + public void doReadMessage(InputStream buf, int size) throws I2CPMessageException, IOException {} + public byte[] doWriteMessage() throws I2CPMessageException, IOException { return null; } + } +} diff --git a/core/java/src/net/i2p/client/I2PSessionImpl.java b/core/java/src/net/i2p/client/I2PSessionImpl.java index c11c71549..b1fc2b226 100644 --- a/core/java/src/net/i2p/client/I2PSessionImpl.java +++ b/core/java/src/net/i2p/client/I2PSessionImpl.java @@ -73,6 +73,8 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa protected Socket _socket; /** reader that always searches for messages */ protected I2CPMessageReader _reader; + /** writer message queue */ + protected ClientWriterRunner _writer; /** where we pipe our messages */ protected /* FIXME final FIXME */OutputStream _out; @@ -277,11 +279,11 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa _out.write(I2PClient.PROTOCOL_BYTE); _out.flush(); } + _writer = new ClientWriterRunner(_out, this); InputStream in = _socket.getInputStream(); _reader = new I2CPMessageReader(in, this); if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "before startReading"); _reader.startReading(); - if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "Before getDate"); sendMessage(new GetDateMessage()); if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "After getDate / begin waiting for a response"); @@ -543,34 +545,14 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa * @throws I2PSessionException if the message is malformed or there is an error writing it out */ void sendMessage(I2CPMessage message) throws I2PSessionException { - if (isClosed()) throw new I2PSessionException("Already closed"); - - long beforeSync = _context.clock().now(); - long inSync = 0; - if (_log.shouldLog(Log.DEBUG)) _log.debug("before sync to write"); - try { - synchronized (_out) { - inSync = _context.clock().now(); - if (_log.shouldLog(Log.DEBUG)) _log.debug("before writeMessage"); - message.writeMessage(_out); - if (_log.shouldLog(Log.DEBUG)) _log.debug("after writeMessage"); - _out.flush(); - if (_log.shouldLog(Log.DEBUG)) _log.debug("after flush"); - } - } catch (I2CPMessageException ime) { - throw new I2PSessionException(getPrefix() + "Error writing out the message", ime); - } catch (IOException ioe) { - throw new I2PSessionException(getPrefix() + "Error writing out the message", ioe); - } - long afterSync = _context.clock().now(); - if (_log.shouldLog(Log.DEBUG)) - _log.debug(getPrefix() + "Message written out and flushed w/ " - + (inSync-beforeSync) + "ms to sync and " - + (afterSync-inSync) + "ms to send"); + if (isClosed() || _writer == null) + throw new I2PSessionException("Already closed"); + _writer.addMessage(message); } /** * Pass off the error to the listener + * Misspelled, oh well. */ void propogateError(String msg, Throwable error) { if (_log.shouldLog(Log.ERROR)) @@ -629,8 +611,14 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa private void closeSocket() { if (_log.shouldLog(Log.INFO)) _log.info(getPrefix() + "Closing the socket", new Exception("closeSocket")); _closed = true; - if (_reader != null) _reader.stopReading(); - _reader = null; + if (_reader != null) { + _reader.stopReading(); + _reader = null; + } + if (_writer != null) { + _writer.stopWriting(); + _writer = null; + } if (_socket != null) { try { diff --git a/core/java/src/net/i2p/client/I2PSimpleSession.java b/core/java/src/net/i2p/client/I2PSimpleSession.java index 933a9578c..af5ab9a75 100644 --- a/core/java/src/net/i2p/client/I2PSimpleSession.java +++ b/core/java/src/net/i2p/client/I2PSimpleSession.java @@ -79,6 +79,7 @@ class I2PSimpleSession extends I2PSessionImpl2 { _out.write(I2PClient.PROTOCOL_BYTE); _out.flush(); } + _writer = new ClientWriterRunner(_out, this); InputStream in = _socket.getInputStream(); _reader = new I2CPMessageReader(in, this); _reader.startReading(); diff --git a/core/java/src/net/i2p/util/InternalServerSocket.java b/core/java/src/net/i2p/util/InternalServerSocket.java index 00d8352ee..bc9a19ff7 100644 --- a/core/java/src/net/i2p/util/InternalServerSocket.java +++ b/core/java/src/net/i2p/util/InternalServerSocket.java @@ -21,6 +21,11 @@ import net.i2p.I2PAppContext; * A simple in-JVM ServerSocket using Piped Streams. * We use port numbers just like regular sockets. * Can only be connected by InternalSocket. + * + * Warning - this uses Piped Streams, which don't like multiple writers from threads + * that may vanish. If you do use multipe writers, + * you may get intermittent 'write end dead' or 'pipe broken' IOExceptions on the reader side. + * See http://techtavern.wordpress.com/2008/07/16/whats-this-ioexception-write-end-dead/ */ public class InternalServerSocket extends ServerSocket { private static final ConcurrentHashMap _sockets = new ConcurrentHashMap(4); diff --git a/core/java/src/net/i2p/util/InternalSocket.java b/core/java/src/net/i2p/util/InternalSocket.java index 52b028c11..26280f254 100644 --- a/core/java/src/net/i2p/util/InternalSocket.java +++ b/core/java/src/net/i2p/util/InternalSocket.java @@ -34,12 +34,12 @@ public class InternalSocket extends Socket { * Convenience method to return either a Socket or an InternalSocket */ public static Socket getSocket(String host, int port) throws IOException { - //if (System.getProperty("router.version") != null && - // (host.equals("127.0.0.1") || host.equals("localhost"))) { - // return new InternalSocket(port); - //} else { + if (System.getProperty("router.version") != null && + (host.equals("127.0.0.1") || host.equals("localhost"))) { + return new InternalSocket(port); + } else { return new Socket(host, port); - //} + } } @Override From 7ca8e0c3a125f0677d992c102ad2a44cc6f0b15d Mon Sep 17 00:00:00 2001 From: zzz Date: Thu, 17 Dec 2009 14:02:02 +0000 Subject: [PATCH 089/127] fix spacing in update section --- .../java/src/net/i2p/router/web/SummaryBarRenderer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/routerconsole/java/src/net/i2p/router/web/SummaryBarRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/SummaryBarRenderer.java index 8643a9c0c..23f297031 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/SummaryBarRenderer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/SummaryBarRenderer.java @@ -176,7 +176,7 @@ public class SummaryBarRenderer { if (_helper.updateAvailable() || _helper.unsignedUpdateAvailable()) { // display all the time so we display the final failure message - buf.append("
    ").append(UpdateHandler.getStatus()); + buf.append(UpdateHandler.getStatus()); if ("true".equals(System.getProperty("net.i2p.router.web.UpdateHandler.updateInProgress"))) { // nothing } else if( @@ -191,7 +191,7 @@ public class SummaryBarRenderer { System.setProperty("net.i2p.router.web.UpdateHandler.noncePrev", prev); System.setProperty("net.i2p.router.web.UpdateHandler.nonce", nonce+""); String uri = _helper.getRequestURI(); - buf.append("
    \n"); + buf.append("

    \n"); buf.append("\n"); if (_helper.updateAvailable()) { buf.append("

    \n"); } From 8e656427d8de41be361407a919ecd429d3ad36c6 Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 19 Dec 2009 16:47:18 +0000 Subject: [PATCH 099/127] * Console: - Fix status to show a disconnected network error rather than clock skew or UDP error when disconnected - Use peer clock skew rather than clock offset for determining whether to display clock skew error, i.e. display what matters * Transport: Rework peer clock skew method to always return a value by falling back to router clock offset; Fix possible AIOOBE and divide by zero; remove logging; reduce min number of peers --- .../src/net/i2p/router/web/SummaryHelper.java | 19 +++++++++++--- .../transport/CommSystemFacadeImpl.java | 26 +++++++------------ 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java index 1fc6c31b7..516855e2d 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java @@ -62,6 +62,9 @@ public class SummaryHelper extends HelperBase { return DataHelper.formatDuration(router.getUptime()); } +/** + this displayed offset, not skew - now handled in reachability() + private String timeSkew() { if (_context == null) return ""; //if (!_context.clock().getUpdatedSuccessfully()) @@ -72,6 +75,7 @@ public class SummaryHelper extends HelperBase { return ""; return " (" + DataHelper.formatDuration(diff) + " " + _("skew") + ")"; } +**/ public boolean allowReseed() { return _context.netDb().isInitialized() && @@ -83,15 +87,20 @@ public class SummaryHelper extends HelperBase { public int getAllPeers() { return Math.max(_context.netDb().getKnownRouters() - 1, 0); } public String getReachability() { - return reachability() + timeSkew(); + return reachability(); // + timeSkew(); } private String reachability() { if (_context.router().getUptime() > 60*1000 && (!_context.router().gracefulShutdownInProgress()) && !_context.clientManager().isAlive()) return _("ERR-Client Manager I2CP Error - check logs"); // not a router problem but the user should know - if (!_context.clock().getUpdatedSuccessfully()) - return _("ERR-ClockSkew"); + // Warn based on actual skew from peers, not update status, so if we successfully offset + // the clock, we don't complain. + //if (!_context.clock().getUpdatedSuccessfully()) + Long skew = _context.commSystem().getFramedAveragePeerClockSkew(33); + // Display the actual skew, not the offset + if (skew != null && Math.abs(skew.longValue()) > 45) + return _("ERR-Clock Skew of {0}", DataHelper.formatDuration(Math.abs(skew.longValue()) * 1000)); if (_context.router().isHidden()) return _("Hidden"); @@ -118,7 +127,9 @@ public class SummaryHelper extends HelperBase { default: ra = _context.router().getRouterInfo().getTargetAddress("SSU"); if (ra == null && _context.router().getUptime() > 5*60*1000) { - if (_context.getProperty(ConfigNetHelper.PROP_I2NP_NTCP_HOSTNAME) == null || + if (getActivePeers() <= 0) + return _("ERR-No Active Peers, Check Network Connection and Firewall"); + else if (_context.getProperty(ConfigNetHelper.PROP_I2NP_NTCP_HOSTNAME) == null || _context.getProperty(ConfigNetHelper.PROP_I2NP_NTCP_PORT) == null) return _("ERR-UDP Disabled and Inbound TCP host/port not set"); else diff --git a/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java b/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java index 6a7eaca84..f1460b9f7 100644 --- a/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java +++ b/router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java @@ -77,31 +77,26 @@ public class CommSystemFacadeImpl extends CommSystemFacade { public boolean haveHighOutboundCapacity() { return (_manager == null ? false : _manager.haveHighOutboundCapacity()); } /** - * Framed average clock skew of connected peers in seconds, or null if we cannot answer. + * Framed average clock skew of connected peers in seconds, or the clock offset if we cannot answer. * Average is calculated over the middle "percentToInclude" peers. */ @Override public Long getFramedAveragePeerClockSkew(int percentToInclude) { if (_manager == null) { - if (_log.shouldLog(Log.INFO)) - _log.info("Returning null for framed averege peer clock skew (no transport manager)!"); - return null; + // round toward zero + return Long.valueOf(_context.clock().getOffset() / 1000); } Vector skews = _manager.getClockSkews(); if (skews == null) { - if (_log.shouldLog(Log.ERROR)) - _log.error("Returning null for framed average peer clock skew (no data)!"); - return null; + return Long.valueOf(_context.clock().getOffset() / 1000); } - if (skews.size() < 20) { - if (_log.shouldLog(Log.WARN)) - _log.warn("Returning null for framed average peer clock skew (only " + skews.size() + " peers)!"); - return null; + if (skews.size() < 5) { + return Long.valueOf(_context.clock().getOffset() / 1000); } // Going to calculate, sort them Collections.sort(skews); // Calculate frame size - int frameSize = (skews.size() * percentToInclude / 100); + int frameSize = Math.min((skews.size() * percentToInclude / 100), 2); int first = (skews.size() / 2) - (frameSize / 2); int last = (skews.size() / 2) + (frameSize / 2); // Sum skew values @@ -112,11 +107,8 @@ public class CommSystemFacadeImpl extends CommSystemFacade { _log.debug("Adding clock skew " + i + " valued " + value + " s."); sum = sum + value; } - // Calculate average - Long framedAverageClockSkew = new Long(sum / frameSize); - if (_log.shouldLog(Log.INFO)) - _log.info("Our framed average peer clock skew is " + framedAverageClockSkew + " s."); - return framedAverageClockSkew; + // Calculate average (round toward zero) + return Long.valueOf(sum / frameSize); } public List getBids(OutNetMessage msg) { From 4baff9fbab70965e7cdb397e1d09cb0fcafed2d4 Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 19 Dec 2009 16:49:55 +0000 Subject: [PATCH 100/127] * Router: Move some more threads to I2PAppThread so an OOM won't crash the router --- router/java/src/net/i2p/router/Router.java | 13 ++++++------- .../net/i2p/router/networkdb/reseed/Reseeder.java | 6 ++++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java index 7e231097b..4ed70a772 100644 --- a/router/java/src/net/i2p/router/Router.java +++ b/router/java/src/net/i2p/router/Router.java @@ -41,6 +41,7 @@ import net.i2p.stat.Rate; import net.i2p.stat.RateStat; import net.i2p.stat.StatManager; import net.i2p.util.FileUtil; +import net.i2p.util.I2PAppThread; import net.i2p.util.I2PThread; import net.i2p.util.Log; import net.i2p.util.SimpleScheduler; @@ -201,6 +202,8 @@ public class Router { installUpdates(); // Apps may use this as an easy way to determine if they are in the router JVM + // But context.isRouterContext() is even easier... + // Both of these as of 0.7.9 System.setProperty("router.version", RouterVersion.VERSION); // NOW we start all the activity @@ -228,14 +231,10 @@ public class Router { } }; _shutdownHook = new ShutdownHook(_context); - _gracefulShutdownDetector = new I2PThread(new GracefulShutdown()); - _gracefulShutdownDetector.setDaemon(true); - _gracefulShutdownDetector.setName("Graceful shutdown hook"); + _gracefulShutdownDetector = new I2PAppThread(new GracefulShutdown(), "Graceful shutdown hook", true); _gracefulShutdownDetector.start(); - I2PThread watchdog = new I2PThread(new RouterWatchdog(_context)); - watchdog.setName("RouterWatchdog"); - watchdog.setDaemon(true); + Thread watchdog = new I2PAppThread(new RouterWatchdog(_context), "RouterWatchdog", true); watchdog.start(); } @@ -339,7 +338,7 @@ public class Router { long waited = System.currentTimeMillis() - before; if (_log.shouldLog(Log.INFO)) _log.info("Waited " + waited + "ms to initialize"); - + _context.jobQueue().addJob(new StartupJob(_context)); } diff --git a/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java b/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java index f37f01aa2..2e93cb3e0 100644 --- a/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java +++ b/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java @@ -15,7 +15,7 @@ import java.util.StringTokenizer; import net.i2p.I2PAppContext; import net.i2p.router.RouterContext; import net.i2p.util.EepGet; -import net.i2p.util.I2PThread; +import net.i2p.util.I2PAppThread; import net.i2p.util.Log; /** @@ -52,13 +52,15 @@ public class Reseeder { return; } else { System.setProperty(PROP_INPROGRESS, "true"); - I2PThread reseed = new I2PThread(_reseedRunner, "Reseed"); + // set to daemon so it doesn't hang a shutdown + Thread reseed = new I2PAppThread(_reseedRunner, "Reseed", true); reseed.start(); } } } + /** Todo: translate the messages sent via PROP_STATUS */ public class ReseedRunner implements Runnable, EepGet.StatusListener { private boolean _isRunning; From f0d444b32eea1ef45ce9d0dab4791834091281fa Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 19 Dec 2009 16:52:18 +0000 Subject: [PATCH 101/127] add to javadoc and adjust logging --- .../i2p/router/tunnel/FragmentHandler.java | 73 +++++++++++++++++-- 1 file changed, 65 insertions(+), 8 deletions(-) diff --git a/router/java/src/net/i2p/router/tunnel/FragmentHandler.java b/router/java/src/net/i2p/router/tunnel/FragmentHandler.java index 43e1d1314..57e44203e 100644 --- a/router/java/src/net/i2p/router/tunnel/FragmentHandler.java +++ b/router/java/src/net/i2p/router/tunnel/FragmentHandler.java @@ -21,6 +21,65 @@ import net.i2p.util.SimpleTimer; * Handle fragments at the endpoint of a tunnel, peeling off fully completed * I2NPMessages when they arrive, and dropping fragments if they take too long * to arrive. + * + * From tunnel-alt.html: + +

    When the gateway wants to deliver data through the tunnel, it first +gathers zero or more I2NP messages, selects how much padding will be used, +fragments it across the necessary number of 1KB tunnel messages, and decides how +each I2NP message should be handled by the tunnel endpoint, encoding that +data into the raw tunnel payload:

    +
      +
    • the first 4 bytes of the SHA256 of the remaining preprocessed data concatenated + with the IV, using the IV as will be seen on the tunnel endpoint (for + outbound tunnels) or the IV as was seen on the tunnel gateway (for inbound + tunnels) (see below for IV processing).
    • +
    • 0 or more bytes containing random nonzero integers
    • +
    • 1 byte containing 0x00
    • +
    • a series of zero or more { instructions, message } pairs
    • +
    + +

    The instructions are encoded with a single control byte, followed by any +necessary additional information. The first bit in that control byte determines +how the remainder of the header is interpreted - if it is not set, the message +is either not fragmented or this is the first fragment in the message. If it is +set, this is a follow on fragment.

    + +

    With the first bit being 0, the instructions are:

    +
      +
    • 1 byte control byte:
      +      bit 0: is follow on fragment?  (1 = true, 0 = false, must be 0)
      +   bits 1-2: delivery type
      +             (0x0 = LOCAL, 0x01 = TUNNEL, 0x02 = ROUTER)
      +      bit 3: delay included?  (1 = true, 0 = false)
      +      bit 4: fragmented?  (1 = true, 0 = false)
      +      bit 5: extended options?  (1 = true, 0 = false)
      +   bits 6-7: reserved
    • +
    • if the delivery type was TUNNEL, a 4 byte tunnel ID
    • +
    • if the delivery type was TUNNEL or ROUTER, a 32 byte router hash
    • +
    • if the delay included flag is true, a 1 byte value:
      +      bit 0: type (0 = strict, 1 = randomized)
      +   bits 1-7: delay exponent (2^value minutes)
    • +
    • if the fragmented flag is true, a 4 byte message ID
    • +
    • if the extended options flag is true:
      +   = a 1 byte option size (in bytes)
      +   = that many bytes
    • +
    • 2 byte size of the I2NP message or this fragment
    • +
    + +

    If the first bit being 1, the instructions are:

    +
      +
    • 1 byte control byte:
      +      bit 0: is follow on fragment?  (1 = true, 0 = false, must be 1)
      +   bits 1-6: fragment number
      +      bit 7: is last? (1 = true, 0 = false)
    • +
    • 4 byte message ID (same one defined in the first fragment)
    • +
    • 2 byte size of this fragment
    • +
    + +

    The I2NP message is encoded in its standard form, and the +preprocessed payload must be padded to a multiple of 16 bytes.

    + * */ public class FragmentHandler { @@ -165,21 +224,19 @@ public class FragmentHandler { _log.debug("endpoint IV: " + Base64.encode(preV, validLength - HopProcessor.IV_LENGTH, HopProcessor.IV_LENGTH)); Hash v = _context.sha().calculateHash(preV, 0, validLength); + _validateCache.release(ba); - //Hash v = _context.sha().calculateHash(preV, 0, validLength); boolean eq = DataHelper.eq(v.getData(), 0, preprocessed, offset + HopProcessor.IV_LENGTH, 4); if (!eq) { - if (_log.shouldLog(Log.WARN)) - _log.warn("Corrupt tunnel message - verification fails: \n" + Base64.encode(preprocessed, offset+HopProcessor.IV_LENGTH, 4) - + "\n" + Base64.encode(v.getData(), 0, 4)); - if (_log.shouldLog(Log.WARN)) - _log.warn("nomatching endpoint: # pad bytes: " + (paddingEnd-(HopProcessor.IV_LENGTH+4)-1) + "\n" + if (_log.shouldLog(Log.WARN)) { + _log.warn("Corrupt tunnel message - verification fails: " + Base64.encode(preprocessed, offset+HopProcessor.IV_LENGTH, 4) + + " != " + Base64.encode(v.getData(), 0, 4)); + _log.warn("No matching endpoint: # pad bytes: " + (paddingEnd-(HopProcessor.IV_LENGTH+4)-1) + " offset=" + offset + " length=" + length + " paddingEnd=" + paddingEnd + Base64.encode(preprocessed, offset, length)); + } } - _validateCache.release(ba); - if (eq) { int excessPadding = paddingEnd - (HopProcessor.IV_LENGTH + 4 + 1); if (excessPadding > 0) // suboptimal fragmentation From 2cd5c209f5f5c190ddce31d71c2278b6deab7553 Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 19 Dec 2009 16:52:49 +0000 Subject: [PATCH 102/127] unused cleanup --- router/java/src/net/i2p/router/tunnel/TunnelParticipant.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/router/java/src/net/i2p/router/tunnel/TunnelParticipant.java b/router/java/src/net/i2p/router/tunnel/TunnelParticipant.java index a73208e3b..6263f8ec7 100644 --- a/router/java/src/net/i2p/router/tunnel/TunnelParticipant.java +++ b/router/java/src/net/i2p/router/tunnel/TunnelParticipant.java @@ -101,8 +101,11 @@ public class TunnelParticipant { } } +/**** private int _periodMessagesTransferred; private long _lastCoallesced = System.currentTimeMillis(); +****/ + /** * take note that the peers specified were able to push us data. hmm, is this safe? * this could be easily gamed to get us to rank some peer of their choosing as quite From f226392c9d74b0e3cc7089e2a7944a73a2bdbffe Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 19 Dec 2009 16:53:49 +0000 Subject: [PATCH 103/127] static access fix --- router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java b/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java index e1cec3607..5e4456490 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java +++ b/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java @@ -54,9 +54,7 @@ class BuildExecutor implements Runnable { // Get stat manager, get recognized bandwidth tiers StatManager statMgr = _context.statManager(); - @SuppressWarnings("static-access") - /* FIXME Accessing static field "BW_CAPABILITY_CHARS" FIXME */ - String bwTiers = _context.router().getRouterInfo().BW_CAPABILITY_CHARS; + String bwTiers = RouterInfo.BW_CAPABILITY_CHARS; // For each bandwidth tier, create tunnel build agree/reject/expire stats for (int i = 0; i < bwTiers.length(); i++) { String bwTier = String.valueOf(bwTiers.charAt(i)); From 72eafe0920d5b0a48663a4dffbf27701428fa9f6 Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 19 Dec 2009 16:54:59 +0000 Subject: [PATCH 104/127] * Tunnels: Reduce the drop probability for TunnelBuildMessages at the OBEP --- .../src/net/i2p/router/tunnel/TunnelDispatcher.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java b/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java index 681dadec1..6b5457719 100644 --- a/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java +++ b/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java @@ -605,12 +605,17 @@ public class TunnelDispatcher implements Service { if (pctDrop <= 0) return false; // increase the drop probability for OBEP, + // (except lower it for tunnel build messages (type 21)), // and lower it for IBGW, for network efficiency double len = length; - if (type.startsWith("OBEP")) - len *= 1.5; - else if (type.startsWith("IBGW")) + if (type.startsWith("OBEP")) { + if (type.equals("OBEP 21")) + len /= 1.5; + else + len *= 1.5; + } else if (type.startsWith("IBGW")) { len /= 1.5; + } // drop in proportion to size w.r.t. a standard 1024-byte message // this is a little expensive but we want to adjust the curve between 0 and 1 // Most messages are 1024, only at the OBEP do we see other sizes From 579b450029cba2068154e724ac383c2a35360867 Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 19 Dec 2009 16:56:38 +0000 Subject: [PATCH 105/127] clean up context usage --- .../router/tunnel/InboundEndpointProcessor.java | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/router/java/src/net/i2p/router/tunnel/InboundEndpointProcessor.java b/router/java/src/net/i2p/router/tunnel/InboundEndpointProcessor.java index 6c572cb42..7376a5046 100644 --- a/router/java/src/net/i2p/router/tunnel/InboundEndpointProcessor.java +++ b/router/java/src/net/i2p/router/tunnel/InboundEndpointProcessor.java @@ -1,6 +1,5 @@ package net.i2p.router.tunnel; -import net.i2p.I2PAppContext; import net.i2p.data.ByteArray; import net.i2p.data.Hash; import net.i2p.router.RouterContext; @@ -16,7 +15,7 @@ import net.i2p.util.Log; * */ public class InboundEndpointProcessor { - private I2PAppContext _context; + private RouterContext _context; private Log _log; private TunnelCreatorConfig _config; private IVValidator _validator; @@ -24,10 +23,10 @@ public class InboundEndpointProcessor { static final boolean USE_ENCRYPTION = HopProcessor.USE_ENCRYPTION; private static final ByteCache _cache = ByteCache.getInstance(128, HopProcessor.IV_LENGTH); - public InboundEndpointProcessor(I2PAppContext ctx, TunnelCreatorConfig cfg) { + public InboundEndpointProcessor(RouterContext ctx, TunnelCreatorConfig cfg) { this(ctx, cfg, DummyValidator.getInstance()); } - public InboundEndpointProcessor(I2PAppContext ctx, TunnelCreatorConfig cfg, IVValidator validator) { + public InboundEndpointProcessor(RouterContext ctx, TunnelCreatorConfig cfg, IVValidator validator) { _context = ctx; _log = ctx.logManager().getLog(InboundEndpointProcessor.class); _config = cfg; @@ -73,23 +72,19 @@ public class InboundEndpointProcessor { _cache.release(ba); - // now for a little bookkeeping - RouterContext ctx = null; - if (_context instanceof RouterContext) - ctx = (RouterContext)_context; - if ( (ctx != null) && (_config.getLength() > 0) ) { + if (_config.getLength() > 0) { int rtt = 0; // dunno... may not be related to an rtt if (_log.shouldLog(Log.DEBUG)) _log.debug("Received a " + length + "byte message through tunnel " + _config); for (int i = 0; i < _config.getLength(); i++) - ctx.profileManager().tunnelDataPushed(_config.getPeer(i), rtt, length); + _context.profileManager().tunnelDataPushed(_config.getPeer(i), rtt, length); _config.incrementVerifiedBytesTransferred(length); } return true; } - private void decrypt(I2PAppContext ctx, TunnelCreatorConfig cfg, byte iv[], byte orig[], int offset, int length) { + private void decrypt(RouterContext ctx, TunnelCreatorConfig cfg, byte iv[], byte orig[], int offset, int length) { Log log = ctx.logManager().getLog(OutboundGatewayProcessor.class); ByteArray ba = _cache.acquire(); byte cur[] = ba.getData(); // new byte[HopProcessor.IV_LENGTH]; // so we dont malloc From 2a1d358141e7341c8c88e97a7d42f5e32469ce0c Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 19 Dec 2009 17:10:39 +0000 Subject: [PATCH 106/127] * Profile, DBHistory: - Tweak the rate periods - Add a global fail rate stat - Increase the HashMap sizes --- router/java/src/net/i2p/router/peermanager/DBHistory.java | 8 ++++++-- .../src/net/i2p/router/peermanager/ProfileOrganizer.java | 8 +++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/router/java/src/net/i2p/router/peermanager/DBHistory.java b/router/java/src/net/i2p/router/peermanager/DBHistory.java index a8e084e49..36b9bc9a3 100644 --- a/router/java/src/net/i2p/router/peermanager/DBHistory.java +++ b/router/java/src/net/i2p/router/peermanager/DBHistory.java @@ -105,6 +105,7 @@ public class DBHistory { */ public RateStat getFailedLookupRate() { return _failedLookupRate; } + /** not sure how much this is used, to be investigated */ public RateStat getInvalidReplyRate() { return _invalidReplyRate; } /** @@ -115,6 +116,7 @@ public class DBHistory { public void lookupSuccessful() { _successfulLookups++; _failedLookupRate.addData(0, 0); + _context.statManager().addRateData("peer.failedLookupRate", 0, 0); _lastLookupSuccessful = _context.clock().now(); } @@ -124,6 +126,7 @@ public class DBHistory { public void lookupFailed() { _failedLookups++; _failedLookupRate.addData(1, 0); + _context.statManager().addRateData("peer.failedLookupRate", 1, 0); _lastLookupFailed = _context.clock().now(); } @@ -136,6 +139,7 @@ public class DBHistory { // Fixme, redefined this to include both lookup and store fails, // need to fix the javadocs _failedLookupRate.addData(0, 0); + _context.statManager().addRateData("peer.failedLookupRate", 0, 0); _lastStoreSuccessful = _context.clock().now(); } @@ -275,9 +279,9 @@ public class DBHistory { private void createRates(String statGroup) { if (_failedLookupRate == null) - _failedLookupRate = new RateStat("dbHistory.failedLookupRate", "How often does this peer to respond to a lookup?", statGroup, new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l }); + _failedLookupRate = new RateStat("dbHistory.failedLookupRate", "How often does this peer to respond to a lookup?", statGroup, new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l }); if (_invalidReplyRate == null) - _invalidReplyRate = new RateStat("dbHistory.invalidReplyRate", "How often does this peer give us a bad (nonexistant, forged, etc) peer?", statGroup, new long[] { 30*60*1000l, 60*60*1000l, 24*60*60*1000l }); + _invalidReplyRate = new RateStat("dbHistory.invalidReplyRate", "How often does this peer give us a bad (nonexistant, forged, etc) peer?", statGroup, new long[] { 30*60*1000l }); _failedLookupRate.setStatLog(_context.statManager().getStatLog()); _invalidReplyRate.setStatLog(_context.statManager().getStatLog()); } diff --git a/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java b/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java index 20f0fba3d..d249dc968 100644 --- a/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java +++ b/router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java @@ -97,10 +97,10 @@ public class ProfileOrganizer { _log = context.logManager().getLog(ProfileOrganizer.class); _comp = new InverseCapacityComparator(); _fastPeers = new HashMap(16); - _highCapacityPeers = new HashMap(16); + _highCapacityPeers = new HashMap(32); _wellIntegratedPeers = new HashMap(16); - _notFailingPeers = new HashMap(64); - _notFailingPeersList = new ArrayList(64); + _notFailingPeers = new HashMap(256); + _notFailingPeersList = new ArrayList(256); _failingPeers = new HashMap(16); _strictCapacityOrder = new TreeSet(_comp); _thresholdSpeedValue = 0.0d; @@ -113,6 +113,8 @@ public class ProfileOrganizer { _context.statManager().createRateStat("peer.profileThresholdTime", "How long the reorg takes determining the tier thresholds", "Peers", new long[] { 10*60*1000 }); _context.statManager().createRateStat("peer.profilePlaceTime", "How long the reorg takes placing peers in the tiers", "Peers", new long[] { 10*60*1000 }); _context.statManager().createRateStat("peer.profileReorgTime", "How long the reorg takes overall", "Peers", new long[] { 10*60*1000 }); + // used in DBHistory + _context.statManager().createRateStat("peer.failedLookupRate", "DB Lookup fail rate", "Peers", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l }); } private void getReadLock() { From 9bf22fb0d336b47dd66d40545eeb0a2356f8a33e Mon Sep 17 00:00:00 2001 From: zzz Date: Sat, 19 Dec 2009 17:41:47 +0000 Subject: [PATCH 107/127] stats.jsp tagging --- .../net/i2p/router/web/StatsGenerator.java | 29 +++++++++++-------- apps/routerconsole/java/strings/Strings.java | 19 ++++++++++++ 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/apps/routerconsole/java/src/net/i2p/router/web/StatsGenerator.java b/apps/routerconsole/java/src/net/i2p/router/web/StatsGenerator.java index 9ac1ae542..4ddc6e6f4 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/StatsGenerator.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/StatsGenerator.java @@ -40,7 +40,7 @@ public class StatsGenerator { String group = (String)entry.getKey(); Set stats = (Set)entry.getValue(); buf.append("\n"); + buf.append(_(group)).append("\n"); for (Iterator statIter = stats.iterator(); statIter.hasNext(); ) { String stat = (String)statIter.next(); buf.append("