2004-12-14 jrandom
* Periodically send a message along all I2NP connections with the router's current time, allowing the receiving peer to determine that the clock has skewed too much, and hence, disconnect. For backwards compatability reasons, this is being kludged into a DeliveryStatusMessage (ewww). The next time we have a backwards compatability break, we can put in a proper message setup for it.
This commit is contained in:
10
history.txt
10
history.txt
@ -1,4 +1,12 @@
|
||||
$Id: history.txt,v 1.105 2004/12/13 08:45:52 jrandom Exp $
|
||||
$Id: history.txt,v 1.106 2004/12/14 06:54:39 jrandom Exp $
|
||||
|
||||
2004-12-14 jrandom
|
||||
* Periodically send a message along all I2NP connections with the router's
|
||||
current time, allowing the receiving peer to determine that the clock
|
||||
has skewed too much, and hence, disconnect. For backwards compatability
|
||||
reasons, this is being kludged into a DeliveryStatusMessage (ewww). The
|
||||
next time we have a backwards compatability break, we can put in a proper
|
||||
message setup for it.
|
||||
|
||||
2004-12-14 jrandom
|
||||
* Reenable the probabalistic drop on the TCP queues to deal with good old
|
||||
|
@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
|
||||
*
|
||||
*/
|
||||
public class RouterVersion {
|
||||
public final static String ID = "$Revision: 1.110 $ $Date: 2004/12/13 08:45:52 $";
|
||||
public final static String ID = "$Revision: 1.111 $ $Date: 2004/12/14 06:54:39 $";
|
||||
public final static String VERSION = "0.4.2.3";
|
||||
public final static long BUILD = 4;
|
||||
public final static long BUILD = 5;
|
||||
public static void main(String args[]) {
|
||||
System.out.println("I2P Router version: " + VERSION);
|
||||
System.out.println("Router ID: " + RouterVersion.ID);
|
||||
|
@ -2,9 +2,11 @@ package net.i2p.router.transport.tcp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Date;
|
||||
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.i2np.I2NPMessage;
|
||||
import net.i2p.data.i2np.DeliveryStatusMessage;
|
||||
import net.i2p.router.OutNetMessage;
|
||||
import net.i2p.router.Router;
|
||||
import net.i2p.router.RouterContext;
|
||||
@ -21,6 +23,9 @@ class ConnectionRunner implements Runnable {
|
||||
private TCPConnection _con;
|
||||
private boolean _keepRunning;
|
||||
private byte _writeBuffer[];
|
||||
private long _lastTimeSend;
|
||||
|
||||
private static final long TIME_SEND_FREQUENCY = 60*1000;
|
||||
|
||||
public ConnectionRunner(RouterContext ctx, TCPConnection con) {
|
||||
_context = ctx;
|
||||
@ -32,6 +37,7 @@ class ConnectionRunner implements Runnable {
|
||||
public void startRunning() {
|
||||
_keepRunning = true;
|
||||
_writeBuffer = new byte[38*1024]; // expansion factor
|
||||
_lastTimeSend = -1;
|
||||
|
||||
String name = "TCP " + _context.routerHash().toBase64().substring(0,6)
|
||||
+ " to "
|
||||
@ -39,6 +45,7 @@ class ConnectionRunner implements Runnable {
|
||||
I2PThread t = new I2PThread(this, name);
|
||||
t.start();
|
||||
}
|
||||
|
||||
public void stopRunning() {
|
||||
_keepRunning = false;
|
||||
}
|
||||
@ -85,6 +92,12 @@ class ConnectionRunner implements Runnable {
|
||||
|
||||
msg.timestamp("ConnectionRunner.sendMessage data");
|
||||
|
||||
I2NPMessage timeMessage = null;
|
||||
if (_lastTimeSend < _context.clock().now() - TIME_SEND_FREQUENCY) {
|
||||
timeMessage = buildTimeMessage();
|
||||
_lastTimeSend = _context.clock().now();
|
||||
}
|
||||
|
||||
OutputStream out = _con.getOutputStream();
|
||||
boolean ok = false;
|
||||
long before = -1;
|
||||
@ -93,6 +106,8 @@ class ConnectionRunner implements Runnable {
|
||||
synchronized (out) {
|
||||
before = _context.clock().now();
|
||||
out.write(buf, 0, written);
|
||||
if (timeMessage != null)
|
||||
out.write(timeMessage.toByteArray());
|
||||
out.flush();
|
||||
after = _context.clock().now();
|
||||
}
|
||||
@ -110,4 +125,18 @@ class ConnectionRunner implements Runnable {
|
||||
}
|
||||
_con.sent(msg, ok, after - before);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build up a new message to be sent with the current router's time
|
||||
*
|
||||
*/
|
||||
private I2NPMessage buildTimeMessage() {
|
||||
// holy crap this is a kludge - strapping ourselves into a
|
||||
// deliveryStatusMessage
|
||||
DeliveryStatusMessage tm = new DeliveryStatusMessage(_context);
|
||||
tm.setArrival(new Date(_context.clock().now()));
|
||||
tm.setMessageId(0);
|
||||
tm.setUniqueId(0);
|
||||
return tm;
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,12 @@
|
||||
package net.i2p.router.transport.tcp;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.RouterIdentity;
|
||||
import net.i2p.data.i2np.I2NPMessageReader;
|
||||
import net.i2p.data.i2np.I2NPMessage;
|
||||
import net.i2p.data.i2np.DeliveryStatusMessage;
|
||||
import net.i2p.router.Router;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
@ -35,9 +38,32 @@ public class MessageHandler implements I2NPMessageReader.I2NPMessageEventListene
|
||||
_log.debug("Just received message " + message.getUniqueId() + " from "
|
||||
+ _identHash.toBase64().substring(0,6)
|
||||
+ " readTime = " + msToRead + "ms type = " + message.getClass().getName());
|
||||
if (message instanceof DeliveryStatusMessage) {
|
||||
DeliveryStatusMessage msg = (DeliveryStatusMessage)message;
|
||||
if ( (msg.getMessageId() == 0) && (msg.getUniqueId() == 0) ) {
|
||||
timeMessageReceived(msg.getArrival().getTime());
|
||||
// dont propogate the message, its just a fake
|
||||
return;
|
||||
}
|
||||
}
|
||||
_transport.messageReceived(message, _ident, _identHash, msToRead, size);
|
||||
}
|
||||
|
||||
private void timeMessageReceived(long remoteTime) {
|
||||
long delta = _con.getRouterContext().clock().now() - remoteTime;
|
||||
if ( (delta > Router.CLOCK_FUDGE_FACTOR) || (delta < 0 - Router.CLOCK_FUDGE_FACTOR) ) {
|
||||
_log.error("Peer " + _identHash.toBase64().substring(0,6) + " is too far skewed ("
|
||||
+ DataHelper.formatDuration(delta) + ") after uptime of "
|
||||
+ DataHelper.formatDuration(_con.getLifetime()) );
|
||||
_con.closeConnection();
|
||||
} else {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Peer " + _identHash.toBase64().substring(0,6) + " is only skewed by ("
|
||||
+ DataHelper.formatDuration(delta) + ") after uptime of "
|
||||
+ DataHelper.formatDuration(_con.getLifetime()) );
|
||||
}
|
||||
}
|
||||
|
||||
public void readError(I2NPMessageReader reader, Exception error) {
|
||||
_con.closeConnection();
|
||||
}
|
||||
|
Reference in New Issue
Block a user