forked from I2P_Developers/i2p.i2p
NetDB: Improve routing of DatabaseStoreMessage acks
Send our own RI unsolicited in reply if we aren't floodfill Don't ack or flood a store of an unknown type PeerTestJob: Don't generate zero reply token Tunnels: More checks of messages received down exploratory tunnels javadocs and comments
This commit is contained in:
18
history.txt
18
history.txt
@ -1,3 +1,12 @@
|
|||||||
|
2015-06-13 zzz
|
||||||
|
* i2psnark: Fix NPE (ticket #1602)
|
||||||
|
* NetDB:
|
||||||
|
- Improve routing of DatabaseStoreMessage acks
|
||||||
|
- Send our own RI unsolicited in reply if we aren't floodfill
|
||||||
|
- Don't ack or flood a store of an unknown type
|
||||||
|
* PeerTestJob: Don't generate zero reply token
|
||||||
|
* Tunnels: More checks of messages received down exploratory tunnels
|
||||||
|
|
||||||
2015-06-08 dg
|
2015-06-08 dg
|
||||||
* Language fixes
|
* Language fixes
|
||||||
* Make netDb.storeFloodNew graphable for testing (#1195)
|
* Make netDb.storeFloodNew graphable for testing (#1195)
|
||||||
@ -6,6 +15,15 @@
|
|||||||
* Silence Irc{Inbound,Outbound}Filter warnings about 'no streams'
|
* Silence Irc{Inbound,Outbound}Filter warnings about 'no streams'
|
||||||
when we can't connect to an IRC server. Change to WARN.
|
when we can't connect to an IRC server. Change to WARN.
|
||||||
|
|
||||||
|
2015-06-07 zzz
|
||||||
|
* Logs: Correct wrapper.config location when running as a service
|
||||||
|
* NetDB: Fix early NPE
|
||||||
|
* SSU: Possible fix for NPE in establisher
|
||||||
|
|
||||||
|
2015-06-06 zzz
|
||||||
|
* Console: Add indication of current ff status on /configadvanced,
|
||||||
|
change immediately when config changes, force republish
|
||||||
|
|
||||||
2015-06-06 str4d
|
2015-06-06 str4d
|
||||||
* newsxml: Don't use XXX for parsing dates on Android
|
* newsxml: Don't use XXX for parsing dates on Android
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ public class RouterVersion {
|
|||||||
/** deprecated */
|
/** deprecated */
|
||||||
public final static String ID = "Monotone";
|
public final static String ID = "Monotone";
|
||||||
public final static String VERSION = CoreVersion.VERSION;
|
public final static String VERSION = CoreVersion.VERSION;
|
||||||
public final static long BUILD = 4;
|
public final static long BUILD = 5;
|
||||||
|
|
||||||
/** for example "-test" */
|
/** for example "-test" */
|
||||||
public final static String EXTRA = "";
|
public final static String EXTRA = "";
|
||||||
|
@ -43,15 +43,33 @@ public class SendMessageDirectJob extends JobImpl {
|
|||||||
private boolean _sent;
|
private boolean _sent;
|
||||||
private long _searchOn;
|
private long _searchOn;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param toPeer may be ourselves
|
||||||
|
*/
|
||||||
public SendMessageDirectJob(RouterContext ctx, I2NPMessage message, Hash toPeer, int timeoutMs, int priority) {
|
public SendMessageDirectJob(RouterContext ctx, I2NPMessage message, Hash toPeer, int timeoutMs, int priority) {
|
||||||
this(ctx, message, toPeer, null, null, null, null, timeoutMs, priority);
|
this(ctx, message, toPeer, null, null, null, null, timeoutMs, priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SendMessageDirectJob(RouterContext ctx, I2NPMessage message, Hash toPeer, ReplyJob onSuccess, Job onFail, MessageSelector selector, int timeoutMs, int priority) {
|
/**
|
||||||
|
* @param toPeer may be ourselves
|
||||||
|
* @param onSuccess may be null
|
||||||
|
* @param onFail may be null
|
||||||
|
* @param selector be null
|
||||||
|
*/
|
||||||
|
public SendMessageDirectJob(RouterContext ctx, I2NPMessage message, Hash toPeer, ReplyJob onSuccess,
|
||||||
|
Job onFail, MessageSelector selector, int timeoutMs, int priority) {
|
||||||
this(ctx, message, toPeer, null, onSuccess, onFail, selector, timeoutMs, priority);
|
this(ctx, message, toPeer, null, onSuccess, onFail, selector, timeoutMs, priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SendMessageDirectJob(RouterContext ctx, I2NPMessage message, Hash toPeer, Job onSend, ReplyJob onSuccess, Job onFail, MessageSelector selector, int timeoutMs, int priority) {
|
/**
|
||||||
|
* @param toPeer may be ourselves
|
||||||
|
* @param onSend may be null
|
||||||
|
* @param onSuccess may be null
|
||||||
|
* @param onFail may be null
|
||||||
|
* @param selector be null
|
||||||
|
*/
|
||||||
|
public SendMessageDirectJob(RouterContext ctx, I2NPMessage message, Hash toPeer, Job onSend, ReplyJob onSuccess,
|
||||||
|
Job onFail, MessageSelector selector, int timeoutMs, int priority) {
|
||||||
super(ctx);
|
super(ctx);
|
||||||
_log = getContext().logManager().getLog(SendMessageDirectJob.class);
|
_log = getContext().logManager().getLog(SendMessageDirectJob.class);
|
||||||
_message = message;
|
_message = message;
|
||||||
|
@ -14,14 +14,19 @@ import java.util.Date;
|
|||||||
import net.i2p.data.DatabaseEntry;
|
import net.i2p.data.DatabaseEntry;
|
||||||
import net.i2p.data.Hash;
|
import net.i2p.data.Hash;
|
||||||
import net.i2p.data.LeaseSet;
|
import net.i2p.data.LeaseSet;
|
||||||
|
import net.i2p.data.TunnelId;
|
||||||
import net.i2p.data.router.RouterAddress;
|
import net.i2p.data.router.RouterAddress;
|
||||||
import net.i2p.data.router.RouterIdentity;
|
import net.i2p.data.router.RouterIdentity;
|
||||||
import net.i2p.data.router.RouterInfo;
|
import net.i2p.data.router.RouterInfo;
|
||||||
import net.i2p.data.i2np.DatabaseStoreMessage;
|
import net.i2p.data.i2np.DatabaseStoreMessage;
|
||||||
import net.i2p.data.i2np.DeliveryStatusMessage;
|
import net.i2p.data.i2np.DeliveryStatusMessage;
|
||||||
|
import net.i2p.data.i2np.TunnelGatewayMessage;
|
||||||
|
import net.i2p.router.Job;
|
||||||
import net.i2p.router.JobImpl;
|
import net.i2p.router.JobImpl;
|
||||||
|
import net.i2p.router.OutNetMessage;
|
||||||
import net.i2p.router.RouterContext;
|
import net.i2p.router.RouterContext;
|
||||||
import net.i2p.router.TunnelInfo;
|
import net.i2p.router.TunnelInfo;
|
||||||
|
import net.i2p.router.message.SendMessageDirectJob;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -34,8 +39,15 @@ public class HandleFloodfillDatabaseStoreMessageJob extends JobImpl {
|
|||||||
private final RouterIdentity _from;
|
private final RouterIdentity _from;
|
||||||
private Hash _fromHash;
|
private Hash _fromHash;
|
||||||
private final FloodfillNetworkDatabaseFacade _facade;
|
private final FloodfillNetworkDatabaseFacade _facade;
|
||||||
|
private final static int REPLY_TIMEOUT = 60*1000;
|
||||||
|
private final static int MESSAGE_PRIORITY = OutNetMessage.PRIORITY_NETDB_REPLY;
|
||||||
|
|
||||||
public HandleFloodfillDatabaseStoreMessageJob(RouterContext ctx, DatabaseStoreMessage receivedMessage, RouterIdentity from, Hash fromHash, FloodfillNetworkDatabaseFacade facade) {
|
/**
|
||||||
|
* @param receivedMessage must never have reply token set if it came down a tunnel
|
||||||
|
*/
|
||||||
|
public HandleFloodfillDatabaseStoreMessageJob(RouterContext ctx, DatabaseStoreMessage receivedMessage,
|
||||||
|
RouterIdentity from, Hash fromHash,
|
||||||
|
FloodfillNetworkDatabaseFacade facade) {
|
||||||
super(ctx);
|
super(ctx);
|
||||||
_log = ctx.logManager().getLog(getClass());
|
_log = ctx.logManager().getLog(getClass());
|
||||||
_message = receivedMessage;
|
_message = receivedMessage;
|
||||||
@ -136,6 +148,7 @@ public class HandleFloodfillDatabaseStoreMessageJob extends JobImpl {
|
|||||||
// somebody has our keys...
|
// somebody has our keys...
|
||||||
if (getContext().routerHash().equals(key)) {
|
if (getContext().routerHash().equals(key)) {
|
||||||
//getContext().statManager().addRateData("netDb.storeLocalRouterInfoAttempt", 1, 0);
|
//getContext().statManager().addRateData("netDb.storeLocalRouterInfoAttempt", 1, 0);
|
||||||
|
// This is initiated by PeerTestJob from another peer
|
||||||
// throw rather than return, so that we send the ack below (prevent easy attack)
|
// throw rather than return, so that we send the ack below (prevent easy attack)
|
||||||
dontBlamePeer = true;
|
dontBlamePeer = true;
|
||||||
throw new IllegalArgumentException("Peer attempted to store our RouterInfo");
|
throw new IllegalArgumentException("Peer attempted to store our RouterInfo");
|
||||||
@ -170,15 +183,18 @@ public class HandleFloodfillDatabaseStoreMessageJob extends JobImpl {
|
|||||||
if (_log.shouldLog(Log.ERROR))
|
if (_log.shouldLog(Log.ERROR))
|
||||||
_log.error("Invalid DatabaseStoreMessage data type - " + entry.getType()
|
_log.error("Invalid DatabaseStoreMessage data type - " + entry.getType()
|
||||||
+ ": " + _message);
|
+ ": " + _message);
|
||||||
|
// don't ack or flood
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
long recvEnd = System.currentTimeMillis();
|
long recvEnd = System.currentTimeMillis();
|
||||||
getContext().statManager().addRateData("netDb.storeRecvTime", recvEnd-recvBegin);
|
getContext().statManager().addRateData("netDb.storeRecvTime", recvEnd-recvBegin);
|
||||||
|
|
||||||
// ack even if invalid or unsupported
|
// ack even if invalid
|
||||||
|
// in particular, ack our own RI (from PeerTestJob)
|
||||||
// TODO any cases where we shouldn't?
|
// TODO any cases where we shouldn't?
|
||||||
if (_message.getReplyToken() > 0)
|
if (_message.getReplyToken() > 0)
|
||||||
sendAck();
|
sendAck(key);
|
||||||
long ackEnd = System.currentTimeMillis();
|
long ackEnd = System.currentTimeMillis();
|
||||||
|
|
||||||
if (_from != null)
|
if (_from != null)
|
||||||
@ -223,7 +239,7 @@ public class HandleFloodfillDatabaseStoreMessageJob extends JobImpl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendAck() {
|
private void sendAck(Hash storedKey) {
|
||||||
DeliveryStatusMessage msg = new DeliveryStatusMessage(getContext());
|
DeliveryStatusMessage msg = new DeliveryStatusMessage(getContext());
|
||||||
msg.setMessageId(_message.getReplyToken());
|
msg.setMessageId(_message.getReplyToken());
|
||||||
// Randomize for a little protection against clock-skew fingerprinting.
|
// Randomize for a little protection against clock-skew fingerprinting.
|
||||||
@ -231,31 +247,62 @@ public class HandleFloodfillDatabaseStoreMessageJob extends JobImpl {
|
|||||||
// TODO just set to 0?
|
// TODO just set to 0?
|
||||||
// TODO we have no session to garlic wrap this with, needs new message
|
// TODO we have no session to garlic wrap this with, needs new message
|
||||||
msg.setArrival(getContext().clock().now() - getContext().random().nextInt(3*1000));
|
msg.setArrival(getContext().clock().now() - getContext().random().nextInt(3*1000));
|
||||||
/*
|
// may be null
|
||||||
if (FloodfillNetworkDatabaseFacade.floodfillEnabled(getContext())) {
|
TunnelId replyTunnel = _message.getReplyTunnel();
|
||||||
// no need to do anything but send it where they ask
|
// A store of our own RI, only if we are not FF
|
||||||
|
DatabaseStoreMessage msg2;
|
||||||
|
if (getContext().netDb().floodfillEnabled() ||
|
||||||
|
storedKey.equals(getContext().routerHash())) {
|
||||||
|
// don't send our RI if the store was our RI (from PeerTestJob)
|
||||||
|
msg2 = null;
|
||||||
|
} else {
|
||||||
|
// we aren't ff, send a go-away message
|
||||||
|
msg2 = new DatabaseStoreMessage(getContext());
|
||||||
|
RouterInfo me = getContext().router().getRouterInfo();
|
||||||
|
msg2.setEntry(me);
|
||||||
|
if (_log.shouldWarn())
|
||||||
|
_log.warn("Got a store w/ reply token, but we aren't ff: from: " + _from +
|
||||||
|
" fromHash: " + _fromHash + " msg: " + _message, new Exception());
|
||||||
|
}
|
||||||
|
Hash toPeer = _message.getReplyGateway();
|
||||||
|
boolean toUs = getContext().routerHash().equals(toPeer);
|
||||||
|
// to reduce connection congestion, send directly if connected already,
|
||||||
|
// else through an exploratory tunnel.
|
||||||
|
if (toUs && replyTunnel != null) {
|
||||||
|
// if we are the gateway, act as if we received it
|
||||||
TunnelGatewayMessage tgm = new TunnelGatewayMessage(getContext());
|
TunnelGatewayMessage tgm = new TunnelGatewayMessage(getContext());
|
||||||
tgm.setMessage(msg);
|
tgm.setMessage(msg);
|
||||||
tgm.setTunnelId(_message.getReplyTunnel());
|
tgm.setTunnelId(replyTunnel);
|
||||||
tgm.setMessageExpiration(msg.getMessageExpiration());
|
tgm.setMessageExpiration(msg.getMessageExpiration());
|
||||||
|
getContext().tunnelDispatcher().dispatch(tgm);
|
||||||
getContext().jobQueue().addJob(new SendMessageDirectJob(getContext(), tgm, _message.getReplyGateway(), 10*1000, 200));
|
if (msg2 != null) {
|
||||||
|
TunnelGatewayMessage tgm2 = new TunnelGatewayMessage(getContext());
|
||||||
|
tgm2.setMessage(msg2);
|
||||||
|
tgm2.setTunnelId(replyTunnel);
|
||||||
|
tgm2.setMessageExpiration(msg.getMessageExpiration());
|
||||||
|
getContext().tunnelDispatcher().dispatch(tgm2);
|
||||||
|
}
|
||||||
|
} else if (toUs || getContext().commSystem().isEstablished(toPeer)) {
|
||||||
|
Job send = new SendMessageDirectJob(getContext(), msg, toPeer, REPLY_TIMEOUT, MESSAGE_PRIORITY);
|
||||||
|
send.runJob();
|
||||||
|
if (msg2 != null) {
|
||||||
|
Job send2 = new SendMessageDirectJob(getContext(), msg2, toPeer, REPLY_TIMEOUT, MESSAGE_PRIORITY);
|
||||||
|
send2.runJob();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
*/
|
// pick tunnel with endpoint closest to toPeer
|
||||||
TunnelInfo outTunnel = selectOutboundTunnel();
|
TunnelInfo outTunnel = getContext().tunnelManager().selectOutboundExploratoryTunnel(toPeer);
|
||||||
if (outTunnel == null) {
|
if (outTunnel == null) {
|
||||||
if (_log.shouldLog(Log.WARN))
|
if (_log.shouldLog(Log.WARN))
|
||||||
_log.warn("No outbound tunnel could be found");
|
_log.warn("No outbound tunnel could be found");
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
getContext().tunnelDispatcher().dispatchOutbound(msg, outTunnel.getSendTunnelId(0),
|
|
||||||
_message.getReplyTunnel(), _message.getReplyGateway());
|
|
||||||
}
|
}
|
||||||
//}
|
getContext().tunnelDispatcher().dispatchOutbound(msg, outTunnel.getSendTunnelId(0),
|
||||||
}
|
replyTunnel, toPeer);
|
||||||
|
if (msg2 != null)
|
||||||
private TunnelInfo selectOutboundTunnel() {
|
getContext().tunnelDispatcher().dispatchOutbound(msg2, outTunnel.getSendTunnelId(0),
|
||||||
return getContext().tunnelManager().selectOutboundTunnel();
|
replyTunnel, toPeer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() { return "Handle Database Store Message"; }
|
public String getName() { return "Handle Database Store Message"; }
|
||||||
|
@ -24,7 +24,8 @@ import net.i2p.util.Log;
|
|||||||
* selection to the peer manager and tests the peer by sending it a useless
|
* selection to the peer manager and tests the peer by sending it a useless
|
||||||
* database store message
|
* database store message
|
||||||
*
|
*
|
||||||
* TODO - What's the point? Disable this? See also notes in PeerManager.selectPeers()
|
* TODO - What's the point? Disable this? See also notes in PeerManager.selectPeers().
|
||||||
|
* TODO - Use something besides sending the peer's RI to itself?
|
||||||
*/
|
*/
|
||||||
public class PeerTestJob extends JobImpl {
|
public class PeerTestJob extends JobImpl {
|
||||||
private final Log _log;
|
private final Log _log;
|
||||||
@ -82,6 +83,7 @@ public class PeerTestJob extends JobImpl {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a group of 0 or more peers that we want to test.
|
* Retrieve a group of 0 or more peers that we want to test.
|
||||||
|
* Returned list will not include ourselves.
|
||||||
*
|
*
|
||||||
* @return set of RouterInfo structures
|
* @return set of RouterInfo structures
|
||||||
*/
|
*/
|
||||||
@ -110,7 +112,8 @@ public class PeerTestJob extends JobImpl {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Fire off the necessary jobs and messages to test the given peer
|
* Fire off the necessary jobs and messages to test the given peer
|
||||||
*
|
* The message is a store of the peer's RI to itself,
|
||||||
|
* with a reply token.
|
||||||
*/
|
*/
|
||||||
private void testPeer(RouterInfo peer) {
|
private void testPeer(RouterInfo peer) {
|
||||||
TunnelInfo inTunnel = getInboundTunnelId();
|
TunnelInfo inTunnel = getInboundTunnelId();
|
||||||
@ -130,7 +133,7 @@ public class PeerTestJob extends JobImpl {
|
|||||||
int timeoutMs = getTestTimeout();
|
int timeoutMs = getTestTimeout();
|
||||||
long expiration = getContext().clock().now() + timeoutMs;
|
long expiration = getContext().clock().now() + timeoutMs;
|
||||||
|
|
||||||
long nonce = getContext().random().nextLong(I2NPMessage.MAX_ID_VALUE);
|
long nonce = 1 + getContext().random().nextLong(I2NPMessage.MAX_ID_VALUE - 1);
|
||||||
DatabaseStoreMessage msg = buildMessage(peer, inTunnelId, inGateway.getIdentity().getHash(), nonce, expiration);
|
DatabaseStoreMessage msg = buildMessage(peer, inTunnelId, inGateway.getIdentity().getHash(), nonce, expiration);
|
||||||
|
|
||||||
TunnelInfo outTunnel = getOutboundTunnelId();
|
TunnelInfo outTunnel = getOutboundTunnelId();
|
||||||
@ -172,7 +175,9 @@ public class PeerTestJob extends JobImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build a message to test the peer with
|
* Build a message to test the peer with.
|
||||||
|
* The message is a store of the peer's RI to itself,
|
||||||
|
* with a reply token.
|
||||||
*/
|
*/
|
||||||
private DatabaseStoreMessage buildMessage(RouterInfo peer, TunnelId replyTunnel, Hash replyGateway, long nonce, long expiration) {
|
private DatabaseStoreMessage buildMessage(RouterInfo peer, TunnelId replyTunnel, Hash replyGateway, long nonce, long expiration) {
|
||||||
DatabaseStoreMessage msg = new DatabaseStoreMessage(getContext());
|
DatabaseStoreMessage msg = new DatabaseStoreMessage(getContext());
|
||||||
|
@ -117,8 +117,8 @@ class InboundMessageDistributor implements GarlicMessageReceiver.CloveReceiver {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else if (dsm.getReplyToken() != 0) {
|
} else if (dsm.getReplyToken() != 0) {
|
||||||
if (_log.shouldLog(Log.WARN))
|
_context.statManager().addRateData("tunnel.dropDangerousClientTunnelMessage", 1, type);
|
||||||
_log.warn("Dropping LS DSM w/ reply token down a tunnel for " + _client + ": " + msg);
|
_log.error("Dropping LS DSM w/ reply token down a tunnel for " + _client + ": " + msg);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// allow DSM of our own key (used by FloodfillVerifyStoreJob)
|
// allow DSM of our own key (used by FloodfillVerifyStoreJob)
|
||||||
@ -143,6 +143,33 @@ class InboundMessageDistributor implements GarlicMessageReceiver.CloveReceiver {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
} // switch
|
} // switch
|
||||||
|
} else {
|
||||||
|
// expl. tunnel
|
||||||
|
switch (type) {
|
||||||
|
case DatabaseStoreMessage.MESSAGE_TYPE:
|
||||||
|
DatabaseStoreMessage dsm = (DatabaseStoreMessage) msg;
|
||||||
|
if (dsm.getReplyToken() != 0) {
|
||||||
|
_context.statManager().addRateData("tunnel.dropDangerousExplTunnelMessage", 1, type);
|
||||||
|
_log.error("Dropping DSM w/ reply token down a expl. tunnel: " + msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (dsm.getEntry().getType() == DatabaseEntry.KEY_TYPE_LEASESET)
|
||||||
|
((LeaseSet)dsm.getEntry()).setReceivedAsReply();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DatabaseSearchReplyMessage.MESSAGE_TYPE:
|
||||||
|
case DeliveryStatusMessage.MESSAGE_TYPE:
|
||||||
|
case GarlicMessage.MESSAGE_TYPE:
|
||||||
|
case TunnelBuildReplyMessage.MESSAGE_TYPE:
|
||||||
|
case VariableTunnelBuildReplyMessage.MESSAGE_TYPE:
|
||||||
|
// these are safe, handled below
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
_context.statManager().addRateData("tunnel.dropDangerousExplTunnelMessage", 1, type);
|
||||||
|
_log.error("Dropped dangerous message down expl tunnel: " + msg, new Exception("cause"));
|
||||||
|
return;
|
||||||
|
} // switch
|
||||||
} // client != null
|
} // client != null
|
||||||
|
|
||||||
if ( (target == null) || ( (tunnel == null) && (_context.routerHash().equals(target) ) ) ) {
|
if ( (target == null) || ( (tunnel == null) && (_context.routerHash().equals(target) ) ) ) {
|
||||||
|
@ -211,7 +211,8 @@ public class TunnelDispatcher implements Service {
|
|||||||
ctx.statManager().createRequiredRateStat("tunnel.corruptMessage", "Corrupt messages received",
|
ctx.statManager().createRequiredRateStat("tunnel.corruptMessage", "Corrupt messages received",
|
||||||
"Tunnels", RATES);
|
"Tunnels", RATES);
|
||||||
// following are for InboundMessageDistributor
|
// following are for InboundMessageDistributor
|
||||||
ctx.statManager().createRateStat("tunnel.dropDangerousClientTunnelMessage", "How many tunnel messages come down a client tunnel that we shouldn't expect (lifetime is the 'I2NP type')", "Tunnels", new long[] { 60*60*1000 });
|
ctx.statManager().createRateStat("tunnel.dropDangerousClientTunnelMessage", "(lifetime is the I2NP type)", "Tunnels", new long[] { 60*60*1000 });
|
||||||
|
ctx.statManager().createRateStat("tunnel.dropDangerousExplTunnelMessage", "(lifetime is the I2NP type)", "Tunnels", new long[] { 60*60*1000 });
|
||||||
ctx.statManager().createRateStat("tunnel.handleLoadClove", "When do we receive load test cloves", "Tunnels", new long[] { 60*60*1000 });
|
ctx.statManager().createRateStat("tunnel.handleLoadClove", "When do we receive load test cloves", "Tunnels", new long[] { 60*60*1000 });
|
||||||
// following is for PumpedTunnelGateway
|
// following is for PumpedTunnelGateway
|
||||||
ctx.statManager().createRateStat("tunnel.dropGatewayOverflow", "Dropped message at GW, queue full", "Tunnels", new long[] { 60*60*1000 });
|
ctx.statManager().createRateStat("tunnel.dropGatewayOverflow", "Dropped message at GW, queue full", "Tunnels", new long[] { 60*60*1000 });
|
||||||
|
Reference in New Issue
Block a user