- Prep for delivery of detailed failure codes to the client (ticket #788)
   - Store session ID as an int instead of a long
   - Clean up some duplicate createRateStat calls (ticket #787 comment 2)
   - Other optimizations, cleanups, final
This commit is contained in:
zzz
2012-12-26 14:29:49 +00:00
parent f4740d2639
commit 38214cf5be
18 changed files with 259 additions and 66 deletions

View File

@@ -6,6 +6,7 @@ import java.io.OutputStream;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import net.i2p.data.i2cp.I2CPMessage; import net.i2p.data.i2cp.I2CPMessage;
import net.i2p.data.i2cp.I2CPMessageException; import net.i2p.data.i2cp.I2CPMessageException;
@@ -20,10 +21,10 @@ import net.i2p.util.I2PAppThread;
* @author zzz from net.i2p.router.client.ClientWriterRunner * @author zzz from net.i2p.router.client.ClientWriterRunner
*/ */
class ClientWriterRunner implements Runnable { class ClientWriterRunner implements Runnable {
private OutputStream _out; private final OutputStream _out;
private I2PSessionImpl _session; private final I2PSessionImpl _session;
private BlockingQueue<I2CPMessage> _messagesToWrite; private final BlockingQueue<I2CPMessage> _messagesToWrite;
private static volatile long __Id = 0; private static final AtomicLong __Id = new AtomicLong();
private static final int MAX_QUEUE_SIZE = 32; private static final int MAX_QUEUE_SIZE = 32;
private static final long MAX_SEND_WAIT = 10*1000; private static final long MAX_SEND_WAIT = 10*1000;
@@ -33,7 +34,7 @@ class ClientWriterRunner implements Runnable {
_out = new BufferedOutputStream(out); _out = new BufferedOutputStream(out);
_session = session; _session = session;
_messagesToWrite = new LinkedBlockingQueue(MAX_QUEUE_SIZE); _messagesToWrite = new LinkedBlockingQueue(MAX_QUEUE_SIZE);
Thread t = new I2PAppThread(this, "I2CP Client Writer " + (++__Id), true); Thread t = new I2PAppThread(this, "I2CP Client Writer " + __Id.incrementAndGet(), true);
t.start(); t.start();
} }

View File

@@ -218,10 +218,7 @@ class I2PSessionMuxedImpl extends I2PSessionImpl2 {
/** /**
* See SendMessageOptions for option details. * See SendMessageOptions for option details.
* *
* Always uses sendNoEffort for now. These are presumed to be datagrams. * Always uses sendNoEffort for now.
* SendMessageOptions 16-bit flag field is currently undefined, so
* serialization won't work; therefore this only makes sense in RouterContext,
* for now.
* *
* @param proto 1-254 or 0 for unset; recommended: * @param proto 1-254 or 0 for unset; recommended:
* I2PSession.PROTO_UNSPECIFIED * I2PSession.PROTO_UNSPECIFIED
@@ -294,7 +291,7 @@ class I2PSessionMuxedImpl extends I2PSessionImpl2 {
} }
protected class MuxedAvailabilityNotifier extends AvailabilityNotifier { protected class MuxedAvailabilityNotifier extends AvailabilityNotifier {
private LinkedBlockingQueue<MsgData> _msgs; private final LinkedBlockingQueue<MsgData> _msgs;
private volatile boolean _alive = false; private volatile boolean _alive = false;
private static final int POISON_SIZE = -99999; private static final int POISON_SIZE = -99999;
private final AtomicBoolean stopping = new AtomicBoolean(false); private final AtomicBoolean stopping = new AtomicBoolean(false);
@@ -364,7 +361,7 @@ class I2PSessionMuxedImpl extends I2PSessionImpl2 {
/** let's keep this simple */ /** let's keep this simple */
private static class MsgData { private static class MsgData {
public int id, size, proto, fromPort, toPort; public final int id, size, proto, fromPort, toPort;
public MsgData(int i, int s, int p, int f, int t) { public MsgData(int i, int s, int p, int f, int t) {
id = i; id = i;
size = s; size = s;

View File

@@ -24,7 +24,7 @@ import net.i2p.data.Payload;
*/ */
public class MessagePayloadMessage extends I2CPMessageImpl { public class MessagePayloadMessage extends I2CPMessageImpl {
public final static int MESSAGE_TYPE = 31; public final static int MESSAGE_TYPE = 31;
private long _sessionId; private int _sessionId;
private long _messageId; private long _messageId;
private Payload _payload; private Payload _payload;
@@ -37,8 +37,9 @@ public class MessagePayloadMessage extends I2CPMessageImpl {
return _sessionId; return _sessionId;
} }
/** @param id 0-65535 */
public void setSessionId(long id) { public void setSessionId(long id) {
_sessionId = id; _sessionId = (int) id;
} }
public long getMessageId() { public long getMessageId() {
@@ -60,7 +61,7 @@ public class MessagePayloadMessage extends I2CPMessageImpl {
@Override @Override
protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException { protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException {
try { try {
_sessionId = DataHelper.readLong(in, 2); _sessionId = (int) DataHelper.readLong(in, 2);
_messageId = DataHelper.readLong(in, 4); _messageId = DataHelper.readLong(in, 4);
_payload = new Payload(); _payload = new Payload();
_payload.readBytes(in); _payload.readBytes(in);

View File

@@ -17,28 +17,166 @@ import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper; import net.i2p.data.DataHelper;
/** /**
* Defines the message a client sends to a router when destroying * Defines the message a router sends to a client about a single message.
* existing session. * For incoming messages, it tells the client that a new message is available.
* For outgoing messages, it tells the client whether the message was delivered.
* *
* @author jrandom * @author jrandom
*/ */
public class MessageStatusMessage extends I2CPMessageImpl { public class MessageStatusMessage extends I2CPMessageImpl {
public final static int MESSAGE_TYPE = 22; public final static int MESSAGE_TYPE = 22;
private long _sessionId; private int _sessionId;
private long _messageId; private long _messageId;
private long _nonce; private long _nonce;
private long _size; private long _size;
private int _status; private int _status;
/**
* For incoming messages. All the rest are for outgoing.
*/
public final static int STATUS_AVAILABLE = 0; public final static int STATUS_AVAILABLE = 0;
public final static int STATUS_SEND_ACCEPTED = 1; public final static int STATUS_SEND_ACCEPTED = 1;
/** unused */ /** unused */
public final static int STATUS_SEND_BEST_EFFORT_SUCCESS = 2; public final static int STATUS_SEND_BEST_EFFORT_SUCCESS = 2;
/** unused */ /** unused */
public final static int STATUS_SEND_BEST_EFFORT_FAILURE = 3; public final static int STATUS_SEND_BEST_EFFORT_FAILURE = 3;
/**
* Generic success.
* May not really be guaranteed, as the best-effort
* success code is unused.
*/
public final static int STATUS_SEND_GUARANTEED_SUCCESS = 4; public final static int STATUS_SEND_GUARANTEED_SUCCESS = 4;
/**
* Generic failure, specific cause unknown.
* May not really be a guaranteed failure, as the best-effort
* failure code is unused.
*/
public final static int STATUS_SEND_GUARANTEED_FAILURE = 5; public final static int STATUS_SEND_GUARANTEED_FAILURE = 5;
/**
* The far-end destination is local and we are pretty darn sure
* the delivery succeeded.
* @since 0.9.5
*/
public final static int STATUS_SEND_SUCCESS_LOCAL = 6;
/**
* The far-end destination is local but delivery failed for some reason.
* This is a guaranteed failure.
* @since 0.9.5
*/
public final static int STATUS_SEND_FAILURE_LOCAL = 7;
/**
* The router is not ready, has shut down, or has major problems.
* This is a guaranteed failure.
* @since 0.9.5
*/
public final static int STATUS_SEND_FAILURE_ROUTER = 8;
/**
* The PC apparently has no network connectivity at all.
* This is a guaranteed failure.
* @since 0.9.5
*/
public final static int STATUS_SEND_FAILURE_NETWORK = 9;
/**
* The session is invalid or closed.
* This is a guaranteed failure.
* @since 0.9.5
*/
public final static int STATUS_SEND_FAILURE_BAD_SESSION = 10;
/**
* The message payload is invalid or zero-length or too big.
* This is a guaranteed failure.
* @since 0.9.5
*/
public final static int STATUS_SEND_FAILURE_BAD_MESSAGE = 11;
/**
* Something is invalid in the message options, or the expiration
* is too far in the future.
* This is a guaranteed failure.
* @since 0.9.5
*/
public final static int STATUS_SEND_FAILURE_BAD_OPTIONS = 12;
/**
* Some queue or buffer in the router is full and the message was dropped.
* This is a guaranteed failure.
* @since 0.9.5
*/
public final static int STATUS_SEND_FAILURE_OVERFLOW = 13;
/**
* Message expired before it could be sent.
* This is a guaranteed failure.
* @since 0.9.5
*/
public final static int STATUS_SEND_FAILURE_EXPIRED = 14;
/**
* Local leaseset problems. The client has not yet signed
* a leaseset, or the local keys are invalid, or it has expired,
* or it does not have any tunnels in it.
* This is a guaranteed failure.
* @since 0.9.5
*/
public final static int STATUS_SEND_FAILURE_LOCAL_LEASESET = 15;
/**
* Local problems - no outbound tunnel to send through,
* or no inbound tunnel if a reply is required.
* This is a guaranteed failure.
* @since 0.9.5
*/
public final static int STATUS_SEND_FAILURE_NO_TUNNELS = 16;
/**
* The certs or options in the destination or leaseset indicate that
* it uses an encryption format that we don't support, so we can't talk to it.
* This is a guaranteed failure.
* @since 0.9.5
*/
public final static int STATUS_SEND_FAILURE_UNSUPPORTED_ENCRYPTION = 17;
/**
* Something strange is wrong with the far-end destination.
* Bad format, unsupported options, certificates, etc.
* This is a guaranteed failure.
* @since 0.9.5
*/
public final static int STATUS_SEND_FAILURE_DESTINATION = 18;
/**
* We got the far-end leaseset but something strange is wrong with it.
* Unsupported options or certificates, no tunnels, etc.
* This is a guaranteed failure.
* @since 0.9.5
*/
public final static int STATUS_SEND_FAILURE_BAD_LEASESET = 19;
/**
* We got the far-end leaseset but it's expired and can't get a new one.
* This is a guaranteed failure.
* @since 0.9.5
*/
public final static int STATUS_SEND_FAILURE_EXPIRED_LEASESET = 20;
/**
* Could not find the far-end destination's lease set.
* This is a common failure, equivalent to a DNS lookup fail.
* This is a guaranteed failure.
* @since 0.9.5
*/
public final static int STATUS_SEND_FAILURE_NO_LEASESET = 21;
public MessageStatusMessage() { public MessageStatusMessage() {
_sessionId = -1; _sessionId = -1;
_status = -1; _status = -1;
@@ -51,18 +189,40 @@ public class MessageStatusMessage extends I2CPMessageImpl {
return _sessionId; return _sessionId;
} }
/** @param id 0-65535 */
public void setSessionId(long id) { public void setSessionId(long id) {
_sessionId = id; _sessionId = (int) id;
} }
public int getStatus() { public int getStatus() {
return _status; return _status;
} }
/** @param status 0-255 */
public void setStatus(int status) { public void setStatus(int status) {
_status = status; _status = status;
} }
/**
* Is the status code a success status code?
* @since 0.9.5
*/
public boolean isSuccessful() {
return isSuccessful(_status);
}
/**
* Is the status code a success status code?
* @since 0.9.5
*/
public static boolean isSuccessful(int status) {
return status == STATUS_SEND_GUARANTEED_SUCCESS ||
status == STATUS_SEND_BEST_EFFORT_SUCCESS ||
status == STATUS_SEND_SUCCESS_LOCAL ||
status == STATUS_SEND_ACCEPTED ||
status == STATUS_AVAILABLE;
}
public long getMessageId() { public long getMessageId() {
return _messageId; return _messageId;
} }
@@ -95,21 +255,19 @@ public class MessageStatusMessage extends I2CPMessageImpl {
return "SEND ACCEPTED "; return "SEND ACCEPTED ";
case STATUS_SEND_BEST_EFFORT_SUCCESS: case STATUS_SEND_BEST_EFFORT_SUCCESS:
return "BEST EFFORT SUCCESS"; return "BEST EFFORT SUCCESS";
case STATUS_SEND_BEST_EFFORT_FAILURE:
return "BEST EFFORT FAILURE";
case STATUS_SEND_GUARANTEED_SUCCESS: case STATUS_SEND_GUARANTEED_SUCCESS:
return "GUARANTEED SUCCESS "; return "GUARANTEED SUCCESS ";
case STATUS_SEND_GUARANTEED_FAILURE: case STATUS_SEND_SUCCESS_LOCAL:
return "GUARANTEED FAILURE "; return "LOCAL SUCCESS ";
default: default:
return "***INVALID STATUS: " + status; return "SEND FAILURE CODE: " + status;
} }
} }
@Override @Override
protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException { protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException {
try { try {
_sessionId = DataHelper.readLong(in, 2); _sessionId = (int) DataHelper.readLong(in, 2);
_messageId = DataHelper.readLong(in, 4); _messageId = DataHelper.readLong(in, 4);
_status = (int) DataHelper.readLong(in, 1); _status = (int) DataHelper.readLong(in, 1);
_size = DataHelper.readLong(in, 4); _size = DataHelper.readLong(in, 4);

View File

@@ -24,7 +24,7 @@ import net.i2p.data.DataHelper;
*/ */
public class ReceiveMessageBeginMessage extends I2CPMessageImpl { public class ReceiveMessageBeginMessage extends I2CPMessageImpl {
public final static int MESSAGE_TYPE = 6; public final static int MESSAGE_TYPE = 6;
private long _sessionId; private int _sessionId;
private long _messageId; private long _messageId;
public ReceiveMessageBeginMessage() { public ReceiveMessageBeginMessage() {
@@ -36,8 +36,9 @@ public class ReceiveMessageBeginMessage extends I2CPMessageImpl {
return _sessionId; return _sessionId;
} }
/** @param id 0-65535 */
public void setSessionId(long id) { public void setSessionId(long id) {
_sessionId = id; _sessionId = (int) id;
} }
public long getMessageId() { public long getMessageId() {
@@ -51,7 +52,7 @@ public class ReceiveMessageBeginMessage extends I2CPMessageImpl {
@Override @Override
protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException { protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException {
try { try {
_sessionId = DataHelper.readLong(in, 2); _sessionId = (int) DataHelper.readLong(in, 2);
_messageId = DataHelper.readLong(in, 4); _messageId = DataHelper.readLong(in, 4);
} catch (DataFormatException dfe) { } catch (DataFormatException dfe) {
throw new I2CPMessageException("Unable to load the message data", dfe); throw new I2CPMessageException("Unable to load the message data", dfe);

View File

@@ -23,7 +23,7 @@ import net.i2p.data.DataHelper;
*/ */
public class ReceiveMessageEndMessage extends I2CPMessageImpl { public class ReceiveMessageEndMessage extends I2CPMessageImpl {
public final static int MESSAGE_TYPE = 7; public final static int MESSAGE_TYPE = 7;
private long _sessionId; private int _sessionId;
private long _messageId; private long _messageId;
public ReceiveMessageEndMessage() { public ReceiveMessageEndMessage() {
@@ -35,8 +35,9 @@ public class ReceiveMessageEndMessage extends I2CPMessageImpl {
return _sessionId; return _sessionId;
} }
/** @param id 0-65535 */
public void setSessionId(long id) { public void setSessionId(long id) {
_sessionId = id; _sessionId = (int) id;
} }
public long getMessageId() { public long getMessageId() {
@@ -50,7 +51,7 @@ public class ReceiveMessageEndMessage extends I2CPMessageImpl {
@Override @Override
protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException { protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException {
try { try {
_sessionId = DataHelper.readLong(in, 2); _sessionId = (int) DataHelper.readLong(in, 2);
_messageId = DataHelper.readLong(in, 4); _messageId = DataHelper.readLong(in, 4);
} catch (DataFormatException dfe) { } catch (DataFormatException dfe) {
throw new I2CPMessageException("Unable to load the message data", dfe); throw new I2CPMessageException("Unable to load the message data", dfe);

View File

@@ -33,6 +33,7 @@ public class SessionId extends DataStructureImpl {
return _sessionId; return _sessionId;
} }
/** @param id 0-65535 */
public void setSessionId(int id) { public void setSessionId(int id) {
_sessionId = id; _sessionId = id;
} }

View File

@@ -1,15 +1,25 @@
2012-12-26 zzz
* I2CP:
- Prep for delivery of detailed failure codes to the client (ticket #788)
- Minor optimizations and cleanups
* i2psnark: Create torrent form tweaks
* NetDB: Split routerInfo files into subdirectories, disabled for now,
enable with router.networkDatabase.flat=false
* Stats: Clean up some duplicate createRateStat calls (ticket #787 comment 2)
* Tunnels: Catch rare BuildExecutor IAE only in Java 7 (ticket #811)
2012-12-24 kytv 2012-12-24 kytv
* Javadocs: Fix javadoc errors in the cybergarage package. Upstream bug #3598391 has been * Javadocs: Fix javadoc errors in the cybergarage package. Upstream bug #3598391 has been
filed for this issue. If these javadoc fixes need to be reverted in the future, filed for this issue. If these javadoc fixes need to be reverted in the future,
MTN rev 5bdb7fc27e35f174001bd6105a502fd5094842e5 covers it. MTN rev 5bdb7fc27e35f174001bd6105a502fd5094842e5 covers it.
2012-12-22 zzz 2012-12-22 zzz
- i2psnark: Add announce list support (BEP 12) (ticket #778) * i2psnark: Add announce list support (BEP 12) (ticket #778)
- i2ptunnel: Add more tunnel quantity options for servers * i2ptunnel: Add more tunnel quantity options for servers
- Jetty: Update to Apache Tomcat 0.6.36 * Jetty: Update to Apache Tomcat 6.0.36
2012-12-22 kytv 2012-12-22 kytv
* French language translation update from Transifex * French language translation update from Transifex
2012-12-19 zzz 2012-12-19 zzz
* Update: Hide the update buttons when router.updateDisabled=true, as is the case * Update: Hide the update buttons when router.updateDisabled=true, as is the case

View File

@@ -68,7 +68,11 @@ public abstract class ClientManagerFacade implements Service {
* @param destHash Hash of Destination to be checked * @param destHash Hash of Destination to be checked
*/ */
public abstract boolean isLocal(Hash destHash); public abstract boolean isLocal(Hash destHash);
public abstract void messageDeliveryStatusUpdate(Destination fromDest, MessageId id, boolean delivered);
/**
* @param status see I2CP MessageStatusMessage for success/failure codes
*/
public abstract void messageDeliveryStatusUpdate(Destination fromDest, MessageId id, int status);
public abstract void messageReceived(ClientMessage msg); public abstract void messageReceived(ClientMessage msg);

View File

@@ -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 = 1; public final static long BUILD = 2;
/** for example "-test" */ /** for example "-test" */
public final static String EXTRA = ""; public final static String EXTRA = "";

View File

@@ -269,11 +269,13 @@ class ClientConnectionRunner {
* delivered (or failed delivery) * delivered (or failed delivery)
* Note that this sends the Guaranteed status codes, even though we only support best effort. * Note that this sends the Guaranteed status codes, even though we only support best effort.
* Doesn't do anything if i2cp.messageReliability = "none" * Doesn't do anything if i2cp.messageReliability = "none"
*
* @param status see I2CP MessageStatusMessage for success/failure codes
*/ */
void updateMessageDeliveryStatus(MessageId id, boolean delivered) { void updateMessageDeliveryStatus(MessageId id, int status) {
if (_dead || _dontSendMSM) if (_dead || _dontSendMSM)
return; return;
_context.jobQueue().addJob(new MessageDeliveryStatusUpdate(id, delivered)); _context.jobQueue().addJob(new MessageDeliveryStatusUpdate(id, status));
} }
/** /**
@@ -624,13 +626,16 @@ class ClientConnectionRunner {
private class MessageDeliveryStatusUpdate extends JobImpl { private class MessageDeliveryStatusUpdate extends JobImpl {
private final MessageId _messageId; private final MessageId _messageId;
private final boolean _success; private final int _status;
private long _lastTried; private long _lastTried;
public MessageDeliveryStatusUpdate(MessageId id, boolean success) { /**
* @param status see I2CP MessageStatusMessage for success/failure codes
*/
public MessageDeliveryStatusUpdate(MessageId id, int status) {
super(ClientConnectionRunner.this._context); super(ClientConnectionRunner.this._context);
_messageId = id; _messageId = id;
_success = success; _status = status;
} }
public String getName() { return "Update Delivery Status"; } public String getName() { return "Update Delivery Status"; }
@@ -647,10 +652,7 @@ class ClientConnectionRunner {
// has to be >= 0, it is initialized to -1 // has to be >= 0, it is initialized to -1
msg.setNonce(2); msg.setNonce(2);
msg.setSize(0); msg.setSize(0);
if (_success) msg.setStatus(_status);
msg.setStatus(MessageStatusMessage.STATUS_SEND_GUARANTEED_SUCCESS);
else
msg.setStatus(MessageStatusMessage.STATUS_SEND_GUARANTEED_FAILURE);
if (!alreadyAccepted(_messageId)) { if (!alreadyAccepted(_messageId)) {
_log.warn("Almost send an update for message " + _messageId + " to " _log.warn("Almost send an update for message " + _messageId + " to "

View File

@@ -26,6 +26,7 @@ import net.i2p.data.LeaseSet;
import net.i2p.data.Payload; import net.i2p.data.Payload;
import net.i2p.data.i2cp.I2CPMessage; import net.i2p.data.i2cp.I2CPMessage;
import net.i2p.data.i2cp.MessageId; import net.i2p.data.i2cp.MessageId;
import net.i2p.data.i2cp.MessageStatusMessage;
import net.i2p.data.i2cp.SessionConfig; import net.i2p.data.i2cp.SessionConfig;
import net.i2p.internal.I2CPMessageQueue; import net.i2p.internal.I2CPMessageQueue;
import net.i2p.router.ClientManagerFacade; import net.i2p.router.ClientManagerFacade;
@@ -75,6 +76,10 @@ class ClientManager {
_runnersByHash = new ConcurrentHashMap(); _runnersByHash = new ConcurrentHashMap();
_pendingRunners = new HashSet(); _pendingRunners = new HashSet();
startListeners(port); startListeners(port);
// following are for RequestLeaseSetJob
_ctx.statManager().createRateStat("client.requestLeaseSetSuccess", "How frequently the router requests successfully a new leaseSet?", "ClientMessages", new long[] { 60*60*1000 });
_ctx.statManager().createRateStat("client.requestLeaseSetTimeout", "How frequently the router requests a new leaseSet but gets no reply?", "ClientMessages", new long[] { 60*60*1000 });
_ctx.statManager().createRateStat("client.requestLeaseSetDropped", "How frequently the router requests a new leaseSet but the client drops?", "ClientMessages", new long[] { 60*60*1000 });
} }
/** Todo: Start a 3rd listener for IPV6? */ /** Todo: Start a 3rd listener for IPV6? */
@@ -265,7 +270,7 @@ class ClientManager {
public void runJob() { public void runJob() {
_to.receiveMessage(_toDest, _fromDest, _payload); _to.receiveMessage(_toDest, _fromDest, _payload);
if (_from != null) { if (_from != null) {
_from.updateMessageDeliveryStatus(_msgId, true); _from.updateMessageDeliveryStatus(_msgId, MessageStatusMessage.STATUS_SEND_SUCCESS_LOCAL);
} }
} }
} }
@@ -382,17 +387,20 @@ class ClientManager {
return _runnersByHash.get(destHash); return _runnersByHash.get(destHash);
} }
public void messageDeliveryStatusUpdate(Destination fromDest, MessageId id, boolean delivered) { /**
* @param status see I2CP MessageStatusMessage for success/failure codes
*/
public void messageDeliveryStatusUpdate(Destination fromDest, MessageId id, int status) {
ClientConnectionRunner runner = getRunner(fromDest); ClientConnectionRunner runner = getRunner(fromDest);
if (runner != null) { if (runner != null) {
if (_log.shouldLog(Log.DEBUG)) if (_log.shouldLog(Log.DEBUG))
_log.debug("Delivering status [" + (delivered?"success":"failure") + "] to " _log.debug("Delivering status " + status + " to "
+ fromDest.calculateHash().toBase64() + " for message " + id); + fromDest.calculateHash() + " for message " + id);
runner.updateMessageDeliveryStatus(id, delivered); runner.updateMessageDeliveryStatus(id, status);
} else { } else {
if (_log.shouldLog(Log.WARN)) if (_log.shouldLog(Log.WARN))
_log.warn("Cannot deliver status [" + (delivered?"success":"failure") + "] to " _log.warn("Cannot deliver status " + status + " to "
+ fromDest.calculateHash().toBase64() + " for message " + id); + fromDest.calculateHash() + " for message " + id);
} }
} }

View File

@@ -178,9 +178,12 @@ public class ClientManagerFacadeImpl extends ClientManagerFacade implements Inte
@Override @Override
public boolean shouldPublishLeaseSet(Hash destinationHash) { return _manager.shouldPublishLeaseSet(destinationHash); } public boolean shouldPublishLeaseSet(Hash destinationHash) { return _manager.shouldPublishLeaseSet(destinationHash); }
public void messageDeliveryStatusUpdate(Destination fromDest, MessageId id, boolean delivered) { /**
* @param status see I2CP MessageStatusMessage for success/failure codes
*/
public void messageDeliveryStatusUpdate(Destination fromDest, MessageId id, int status) {
if (_manager != null) if (_manager != null)
_manager.messageDeliveryStatusUpdate(fromDest, id, delivered); _manager.messageDeliveryStatusUpdate(fromDest, id, status);
else else
_log.error("Null manager on messageDeliveryStatusUpdate!"); _log.error("Null manager on messageDeliveryStatusUpdate!");
} }

View File

@@ -36,9 +36,7 @@ class RequestLeaseSetJob extends JobImpl {
_log = ctx.logManager().getLog(RequestLeaseSetJob.class); _log = ctx.logManager().getLog(RequestLeaseSetJob.class);
_runner = runner; _runner = runner;
_requestState = state; _requestState = state;
ctx.statManager().createRateStat("client.requestLeaseSetSuccess", "How frequently the router requests successfully a new leaseSet?", "ClientMessages", new long[] { 60*60*1000 }); // all createRateStat in ClientManager
ctx.statManager().createRateStat("client.requestLeaseSetTimeout", "How frequently the router requests a new leaseSet but gets no reply?", "ClientMessages", new long[] { 60*60*1000 });
ctx.statManager().createRateStat("client.requestLeaseSetDropped", "How frequently the router requests a new leaseSet but the client drops?", "ClientMessages", new long[] { 60*60*1000 });
} }
public String getName() { return "Request Lease Set"; } public String getName() { return "Request Lease Set"; }

View File

@@ -43,7 +43,7 @@ public class DummyClientManagerFacade extends ClientManagerFacade {
public void shutdown(String msg) {} public void shutdown(String msg) {}
public void restart() {} public void restart() {}
public void messageDeliveryStatusUpdate(Destination fromDest, MessageId id, boolean delivered) {} public void messageDeliveryStatusUpdate(Destination fromDest, MessageId id, int status) {}
public SessionConfig getClientSessionConfig(Destination _dest) { return null; } public SessionConfig getClientSessionConfig(Destination _dest) { return null; }
public SessionKeyManager getClientSessionKeyManager(Hash _dest) { return null; } public SessionKeyManager getClientSessionKeyManager(Hash _dest) { return null; }

View File

@@ -49,11 +49,11 @@ public class GarlicMessageReceiver {
public GarlicMessageReceiver(RouterContext context, CloveReceiver receiver, Hash clientDestination) { public GarlicMessageReceiver(RouterContext context, CloveReceiver receiver, Hash clientDestination) {
_context = context; _context = context;
_log = context.logManager().getLog(GarlicMessageReceiver.class); _log = context.logManager().getLog(GarlicMessageReceiver.class);
_context.statManager().createRateStat("crypto.garlic.decryptFail", "How often garlic messages are undecryptable", "Encryption", new long[] { 60*60*1000, 24*60*60*1000 });
_clientDestination = clientDestination; _clientDestination = clientDestination;
_parser = new GarlicMessageParser(context); _parser = new GarlicMessageParser(context);
_receiver = receiver; _receiver = receiver;
//_log.error("New GMR dest = " + clientDestination); //_log.error("New GMR dest = " + clientDestination);
// all createRateStat in OCMOSJ.init()
} }
public void receive(GarlicMessage message) { public void receive(GarlicMessage message) {

View File

@@ -50,7 +50,6 @@ class HandleGarlicMessageJob extends JobImpl implements GarlicMessageReceiver.Cl
public HandleGarlicMessageJob(RouterContext context, GarlicMessage msg, RouterIdentity from, Hash fromHash) { public HandleGarlicMessageJob(RouterContext context, GarlicMessage msg, RouterIdentity from, Hash fromHash) {
super(context); super(context);
_log = context.logManager().getLog(HandleGarlicMessageJob.class); _log = context.logManager().getLog(HandleGarlicMessageJob.class);
getContext().statManager().createRateStat("crypto.garlic.decryptFail", "How often garlic messages are undecryptable", "Encryption", new long[] { 5*60*1000, 60*60*1000, 24*60*60*1000 });
if (_log.shouldLog(Log.DEBUG)) if (_log.shouldLog(Log.DEBUG))
_log.debug("Garlic Message not down a tunnel from [" + from + "]"); _log.debug("Garlic Message not down a tunnel from [" + from + "]");
_message = msg; _message = msg;
@@ -59,6 +58,7 @@ class HandleGarlicMessageJob extends JobImpl implements GarlicMessageReceiver.Cl
//_cloves = new HashMap(); //_cloves = new HashMap();
//_handler = new MessageHandler(context); //_handler = new MessageHandler(context);
//_parser = new GarlicMessageParser(context); //_parser = new GarlicMessageParser(context);
// all createRateStat in OCMOSJ.init()
} }
public String getName() { return "Handle Inbound Garlic Message"; } public String getName() { return "Handle Inbound Garlic Message"; }

View File

@@ -21,6 +21,7 @@ import net.i2p.data.RouterInfo;
import net.i2p.data.SessionKey; import net.i2p.data.SessionKey;
import net.i2p.data.SessionTag; import net.i2p.data.SessionTag;
import net.i2p.data.i2cp.MessageId; import net.i2p.data.i2cp.MessageId;
import net.i2p.data.i2cp.MessageStatusMessage;
import net.i2p.data.i2np.DataMessage; import net.i2p.data.i2np.DataMessage;
import net.i2p.data.i2np.DeliveryInstructions; import net.i2p.data.i2np.DeliveryInstructions;
import net.i2p.data.i2np.DeliveryStatusMessage; import net.i2p.data.i2np.DeliveryStatusMessage;
@@ -189,6 +190,8 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
ctx.statManager().createRateStat("client.dispatchSendTime", "How long the actual dispatching takes?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); ctx.statManager().createRateStat("client.dispatchSendTime", "How long the actual dispatching takes?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
ctx.statManager().createRateStat("client.dispatchNoTunnels", "How long after start do we run out of tunnels to send/receive with?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l }); ctx.statManager().createRateStat("client.dispatchNoTunnels", "How long after start do we run out of tunnels to send/receive with?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
ctx.statManager().createRateStat("client.dispatchNoACK", "Repeated message sends to a peer (no ack required)", "ClientMessages", new long[] { 60*1000l, 5*60*1000l, 60*60*1000l }); ctx.statManager().createRateStat("client.dispatchNoACK", "Repeated message sends to a peer (no ack required)", "ClientMessages", new long[] { 60*1000l, 5*60*1000l, 60*60*1000l });
// for HandleGarlicMessageJob / GarlicMessageReceiver
ctx.statManager().createRateStat("crypto.garlic.decryptFail", "How often garlic messages are undecryptable", "Encryption", new long[] { 5*60*1000, 60*60*1000, 24*60*60*1000 });
} }
public String getName() { return "Outbound client message"; } public String getName() { return "Outbound client message"; }
@@ -674,6 +677,10 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
* this is safe to call multiple times (only tells the client once) * this is safe to call multiple times (only tells the client once)
*/ */
private void dieFatal() { private void dieFatal() {
dieFatal(MessageStatusMessage.STATUS_SEND_GUARANTEED_FAILURE);
}
private void dieFatal(int status) {
if (_finished) return; if (_finished) return;
_finished = true; _finished = true;
@@ -693,7 +700,7 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
clearCaches(); clearCaches();
getContext().messageHistory().sendPayloadMessage(_clientMessageId.getMessageId(), false, sendTime); getContext().messageHistory().sendPayloadMessage(_clientMessageId.getMessageId(), false, sendTime);
getContext().clientManager().messageDeliveryStatusUpdate(_from, _clientMessageId, false); getContext().clientManager().messageDeliveryStatusUpdate(_from, _clientMessageId, status);
getContext().statManager().updateFrequency("client.sendMessageFailFrequency"); getContext().statManager().updateFrequency("client.sendMessageFailFrequency");
_clove = null; _clove = null;
} }
@@ -820,7 +827,8 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
long dataMsgId = _cloveId; long dataMsgId = _cloveId;
getContext().messageHistory().sendPayloadMessage(dataMsgId, true, sendTime); getContext().messageHistory().sendPayloadMessage(dataMsgId, true, sendTime);
getContext().clientManager().messageDeliveryStatusUpdate(_from, _clientMessageId, true); getContext().clientManager().messageDeliveryStatusUpdate(_from, _clientMessageId,
MessageStatusMessage.STATUS_SEND_GUARANTEED_SUCCESS);
// unused // unused
//_lease.setNumSuccess(_lease.getNumSuccess()+1); //_lease.setNumSuccess(_lease.getNumSuccess()+1);