2005-05-01 jrandom

* Cleaned up the peers page a bit more.
more udp stuff:
* add new config option: i2np.udp.alwaysPreferred=true to adjust the bidding
  so that UDP is picked first, even if a TCP connection exists
* fixed the initial clock skew problem (duh)
* reduced the MTU to 576 (largest nearly-universally-safe, and allows a
  tunnel message in 2 fragments)
* handle some races @ connection establishment (thanks duck!)
* if there are more ACKs than we can send in a packet, reschedule another
  ACK immediately
This commit is contained in:
jrandom
2005-05-01 17:21:48 +00:00
committed by zzz
parent ea82f2a8cc
commit 3de23d4206
8 changed files with 59 additions and 20 deletions

View File

@ -1,4 +1,7 @@
$Id: history.txt,v 1.202 2005/04/30 18:26:19 jrandom Exp $
$Id: history.txt,v 1.203 2005/04/30 19:48:15 jrandom Exp $
2005-05-01 jrandom
* Cleaned up the peers page a bit more.
2005-04-30 jrandom
* Added a small new page to the web console (/peers.jsp) which contains

View File

@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
*
*/
public class RouterVersion {
public final static String ID = "$Revision: 1.193 $ $Date: 2005/04/30 18:26:19 $";
public final static String ID = "$Revision: 1.194 $ $Date: 2005/04/30 19:48:15 $";
public final static String VERSION = "0.5.0.7";
public final static long BUILD = 5;
public final static long BUILD = 6;
public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION);
System.out.println("Router ID: " + RouterVersion.ID);

View File

@ -102,6 +102,13 @@ public class ACKSender implements Runnable {
if (_log.shouldLog(Log.INFO))
_log.info("Sending ACK for " + acks);
_transport.send(ack);
if (wanted == peer.getWantedACKSendSince()) {
// still packets left to be ACKed, since wanted time
// is reset by retrieveACKs when all of the IDs are
// removed
ackPeer(peer);
}
}
}
}

View File

@ -129,11 +129,12 @@ public class OutboundMessageFragments {
synchronized (_activeMessages) {
for (int i = 0; i < _activeMessages.size(); i++) {
OutboundMessageState state = (OutboundMessageState)_activeMessages.get(i);
PeerState peer = state.getPeer();
if (state.isComplete()) {
_activeMessages.remove(i);
_transport.succeeded(state.getMessage());
if (state.getPeer().getSendWindowBytesRemaining() > 0)
_throttle.unchoke(state.getPeer().getRemotePeer());
if ( (peer != null) && (peer.getSendWindowBytesRemaining() > 0) )
_throttle.unchoke(peer.getRemotePeer());
state.releaseResources();
if (i < _nextPacketMessage) {
_nextPacketMessage--;
@ -153,8 +154,8 @@ public class OutboundMessageFragments {
if (_log.shouldLog(Log.WARN))
_log.warn("Unable to send an expired direct message: " + state);
}
if (state.getPeer().getSendWindowBytesRemaining() > 0)
_throttle.unchoke(state.getPeer().getRemotePeer());
if ( (peer != null) && (peer.getSendWindowBytesRemaining() > 0) )
_throttle.unchoke(peer.getRemotePeer());
state.releaseResources();
if (i < _nextPacketMessage) {
_nextPacketMessage--;
@ -176,8 +177,8 @@ public class OutboundMessageFragments {
if (_log.shouldLog(Log.WARN))
_log.warn("Unable to send a direct message after too many volleys: " + state);
}
if (state.getPeer().getSendWindowBytesRemaining() > 0)
_throttle.unchoke(state.getPeer().getRemotePeer());
if ( (peer != null) && (peer.getSendWindowBytesRemaining() > 0) )
_throttle.unchoke(peer.getRemotePeer());
state.releaseResources();
if (i < _nextPacketMessage) {
_nextPacketMessage--;
@ -226,8 +227,8 @@ public class OutboundMessageFragments {
_transport.failed(state);
if (_log.shouldLog(Log.WARN))
_log.warn("Peer disconnected for " + state);
if (state.getPeer().getSendWindowBytesRemaining() > 0)
_throttle.unchoke(state.getPeer().getRemotePeer());
if ( (peer != null) && (peer.getSendWindowBytesRemaining() > 0) )
_throttle.unchoke(peer.getRemotePeer());
state.releaseResources();
i--;
}

View File

@ -258,8 +258,8 @@ public class PacketHandler {
receivePacket(reader, packet);
}
/** let packets be up to 5s slow */
private static final long GRACE_PERIOD = Router.CLOCK_FUDGE_FACTOR + 5*1000;
/** let packets be up to 30s slow */
private static final long GRACE_PERIOD = Router.CLOCK_FUDGE_FACTOR + 30*1000;
/**
* Parse out the interesting bits and honor what it says
@ -279,8 +279,11 @@ public class PacketHandler {
return;
}
if (state != null)
if (state != null) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Received packet from " + state.getRemoteHostString() + " with skew " + skew);
state.adjustClockSkew((short)skew);
}
_context.statManager().addRateData("udp.receivePacketSkew", skew, packet.getLifetime());

View File

@ -39,7 +39,7 @@ public class PacketPusher implements Runnable {
if (packets != null) {
for (int i = 0; i < packets.length; i++) {
if (packets[i] != null) // null for ACKed fragments
_sender.add(packets[i], 1000); // blocks for up to a second
_sender.add(packets[i], 100); // blocks for up to 100ms
}
}
}

View File

@ -135,7 +135,12 @@ public class PeerState {
private static final int DEFAULT_SEND_WINDOW_BYTES = 8*1024;
private static final int MINIMUM_WINDOW_BYTES = DEFAULT_SEND_WINDOW_BYTES;
private static final int MAX_SEND_WINDOW_BYTES = 1024*1024;
private static final int DEFAULT_MTU = 1472;
/*
* 576 gives us 568 IP byes, 548 UDP bytes, and with an SSU data message,
* 502 fragment bytes, which is enough to send a tunnel data message in 2
* packets.
*/
private static final int DEFAULT_MTU = 576;
private static final int MIN_RTO = 600;
private static final int MAX_RTO = 5000;
@ -150,7 +155,7 @@ public class PeerState {
_nextKeyingMaterial = null;
_rekeyBeganLocally = false;
_keyEstablishedTime = -1;
_clockSkew = Short.MIN_VALUE;
_clockSkew = 0;
_currentReceiveSecond = -1;
_lastSendTime = -1;
_lastReceiveTime = -1;

View File

@ -70,6 +70,8 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
private TransportBid _fastBid;
/** shared slow bid for unconnected peers */
private TransportBid _slowBid;
/** shared slow bid for unconnected peers when we want to prefer UDP */
private TransportBid _slowPreferredBid;
public static final String STYLE = "SSUv1";
public static final String PROP_INTERNAL_PORT = "i2np.udp.internalPort";
@ -78,6 +80,13 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
public static final String PROP_EXTERNAL_HOST = "i2np.udp.host";
/** define this to explicitly set an external port */
public static final String PROP_EXTERNAL_PORT = "i2np.udp.port";
/**
* If i2np.udp.alwaysPreferred is set, the UDP bids will always be under
* the bid from the TCP transport - even if a TCP connection already
* exists. The default is to prefer UDP unless no UDP session exists and
* a TCP connection already exists.
*/
public static final String PROP_ALWAYS_PREFER_UDP = "i2np.udp.alwaysPreferred";
/** how many relays offered to us will we use at a time? */
@ -109,6 +118,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
_fastBid = new SharedBid(50);
_slowBid = new SharedBid(1000);
_slowPreferredBid = new SharedBid(75);
_fragments = new OutboundMessageFragments(_context, this, _activeThrottle);
_inboundFragments = new InboundMessageFragments(_context, _fragments, this);
@ -371,9 +381,17 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
if (_log.shouldLog(Log.DEBUG))
_log.debug("bidding on a message to an unestablished peer: " + to.toBase64());
return _slowBid;
if (alwaysPreferUDP())
return _slowPreferredBid;
else
return _slowBid;
}
}
private boolean alwaysPreferUDP() {
String pref = _context.getProperty(PROP_ALWAYS_PREFER_UDP);
return (pref != null) && "true".equals(pref);
}
public String getStyle() { return STYLE; }
public void send(OutNetMessage msg) {
@ -561,10 +579,12 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
buf.append("<tr>");
String name = peer.getRemotePeer().toBase64().substring(0,6);
buf.append("<td nowrap>");
buf.append("<a href=\"#");
buf.append(peer.getRemotePeer().toBase64().substring(0,6));
buf.append("<a href=\"netdb.jsp#");
buf.append(name);
buf.append("\">");
buf.append(name).append("@");
byte ip[] = peer.getRemoteIP();
for (int j = 0; j < ip.length; j++) {
buf.append(ip[j] & 0xFF);