From 38214cf5be5725386d69e4395896265d728a2efd Mon Sep 17 00:00:00 2001 From: zzz Date: Wed, 26 Dec 2012 14:29:49 +0000 Subject: [PATCH] * I2CP: - 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 --- .../net/i2p/client/ClientWriterRunner.java | 11 +- .../net/i2p/client/I2PSessionMuxedImpl.java | 9 +- .../i2p/data/i2cp/MessagePayloadMessage.java | 7 +- .../i2p/data/i2cp/MessageStatusMessage.java | 178 +++++++++++++++++- .../data/i2cp/ReceiveMessageBeginMessage.java | 7 +- .../data/i2cp/ReceiveMessageEndMessage.java | 7 +- .../java/src/net/i2p/data/i2cp/SessionId.java | 1 + history.txt | 26 ++- .../net/i2p/router/ClientManagerFacade.java | 6 +- .../src/net/i2p/router/RouterVersion.java | 2 +- .../router/client/ClientConnectionRunner.java | 20 +- .../net/i2p/router/client/ClientManager.java | 22 ++- .../client/ClientManagerFacadeImpl.java | 7 +- .../i2p/router/client/RequestLeaseSetJob.java | 4 +- .../dummy/DummyClientManagerFacade.java | 2 +- .../router/message/GarlicMessageReceiver.java | 2 +- .../message/HandleGarlicMessageJob.java | 2 +- .../OutboundClientMessageOneShotJob.java | 12 +- 18 files changed, 259 insertions(+), 66 deletions(-) diff --git a/core/java/src/net/i2p/client/ClientWriterRunner.java b/core/java/src/net/i2p/client/ClientWriterRunner.java index a1d55ca5c..9edf52f54 100644 --- a/core/java/src/net/i2p/client/ClientWriterRunner.java +++ b/core/java/src/net/i2p/client/ClientWriterRunner.java @@ -6,6 +6,7 @@ import java.io.OutputStream; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; import net.i2p.data.i2cp.I2CPMessage; import net.i2p.data.i2cp.I2CPMessageException; @@ -20,10 +21,10 @@ import net.i2p.util.I2PAppThread; * @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; + private final OutputStream _out; + private final I2PSessionImpl _session; + private final BlockingQueue _messagesToWrite; + private static final AtomicLong __Id = new AtomicLong(); private static final int MAX_QUEUE_SIZE = 32; private static final long MAX_SEND_WAIT = 10*1000; @@ -33,7 +34,7 @@ class ClientWriterRunner implements Runnable { _out = new BufferedOutputStream(out); _session = session; _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(); } diff --git a/core/java/src/net/i2p/client/I2PSessionMuxedImpl.java b/core/java/src/net/i2p/client/I2PSessionMuxedImpl.java index e1f208e55..383a59b81 100644 --- a/core/java/src/net/i2p/client/I2PSessionMuxedImpl.java +++ b/core/java/src/net/i2p/client/I2PSessionMuxedImpl.java @@ -218,10 +218,7 @@ class I2PSessionMuxedImpl extends I2PSessionImpl2 { /** * See SendMessageOptions for option details. * - * Always uses sendNoEffort for now. These are presumed to be datagrams. - * SendMessageOptions 16-bit flag field is currently undefined, so - * serialization won't work; therefore this only makes sense in RouterContext, - * for now. + * Always uses sendNoEffort for now. * * @param proto 1-254 or 0 for unset; recommended: * I2PSession.PROTO_UNSPECIFIED @@ -294,7 +291,7 @@ class I2PSessionMuxedImpl extends I2PSessionImpl2 { } protected class MuxedAvailabilityNotifier extends AvailabilityNotifier { - private LinkedBlockingQueue _msgs; + private final LinkedBlockingQueue _msgs; private volatile boolean _alive = false; private static final int POISON_SIZE = -99999; private final AtomicBoolean stopping = new AtomicBoolean(false); @@ -364,7 +361,7 @@ class I2PSessionMuxedImpl extends I2PSessionImpl2 { /** let's keep this simple */ 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) { id = i; size = s; diff --git a/core/java/src/net/i2p/data/i2cp/MessagePayloadMessage.java b/core/java/src/net/i2p/data/i2cp/MessagePayloadMessage.java index d9739ee58..5b339c265 100644 --- a/core/java/src/net/i2p/data/i2cp/MessagePayloadMessage.java +++ b/core/java/src/net/i2p/data/i2cp/MessagePayloadMessage.java @@ -24,7 +24,7 @@ import net.i2p.data.Payload; */ public class MessagePayloadMessage extends I2CPMessageImpl { public final static int MESSAGE_TYPE = 31; - private long _sessionId; + private int _sessionId; private long _messageId; private Payload _payload; @@ -37,8 +37,9 @@ public class MessagePayloadMessage extends I2CPMessageImpl { return _sessionId; } + /** @param id 0-65535 */ public void setSessionId(long id) { - _sessionId = id; + _sessionId = (int) id; } public long getMessageId() { @@ -60,7 +61,7 @@ public class MessagePayloadMessage extends I2CPMessageImpl { @Override protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException { try { - _sessionId = DataHelper.readLong(in, 2); + _sessionId = (int) DataHelper.readLong(in, 2); _messageId = DataHelper.readLong(in, 4); _payload = new Payload(); _payload.readBytes(in); diff --git a/core/java/src/net/i2p/data/i2cp/MessageStatusMessage.java b/core/java/src/net/i2p/data/i2cp/MessageStatusMessage.java index 933a80785..b3c138b4a 100644 --- a/core/java/src/net/i2p/data/i2cp/MessageStatusMessage.java +++ b/core/java/src/net/i2p/data/i2cp/MessageStatusMessage.java @@ -17,28 +17,166 @@ import net.i2p.data.DataFormatException; import net.i2p.data.DataHelper; /** - * Defines the message a client sends to a router when destroying - * existing session. + * Defines the message a router sends to a client about a single message. + * 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 */ public class MessageStatusMessage extends I2CPMessageImpl { public final static int MESSAGE_TYPE = 22; - private long _sessionId; + private int _sessionId; private long _messageId; private long _nonce; private long _size; private int _status; + /** + * For incoming messages. All the rest are for outgoing. + */ public final static int STATUS_AVAILABLE = 0; public final static int STATUS_SEND_ACCEPTED = 1; /** unused */ public final static int STATUS_SEND_BEST_EFFORT_SUCCESS = 2; /** unused */ 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; + + /** + * 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; + /** + * 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() { _sessionId = -1; _status = -1; @@ -51,18 +189,40 @@ public class MessageStatusMessage extends I2CPMessageImpl { return _sessionId; } + /** @param id 0-65535 */ public void setSessionId(long id) { - _sessionId = id; + _sessionId = (int) id; } public int getStatus() { return _status; } + /** @param status 0-255 */ public void setStatus(int 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() { return _messageId; } @@ -95,21 +255,19 @@ public class MessageStatusMessage extends I2CPMessageImpl { return "SEND ACCEPTED "; case STATUS_SEND_BEST_EFFORT_SUCCESS: return "BEST EFFORT SUCCESS"; - case STATUS_SEND_BEST_EFFORT_FAILURE: - return "BEST EFFORT FAILURE"; case STATUS_SEND_GUARANTEED_SUCCESS: return "GUARANTEED SUCCESS "; - case STATUS_SEND_GUARANTEED_FAILURE: - return "GUARANTEED FAILURE "; + case STATUS_SEND_SUCCESS_LOCAL: + return "LOCAL SUCCESS "; default: - return "***INVALID STATUS: " + status; + return "SEND FAILURE CODE: " + status; } } @Override protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException { try { - _sessionId = DataHelper.readLong(in, 2); + _sessionId = (int) DataHelper.readLong(in, 2); _messageId = DataHelper.readLong(in, 4); _status = (int) DataHelper.readLong(in, 1); _size = DataHelper.readLong(in, 4); diff --git a/core/java/src/net/i2p/data/i2cp/ReceiveMessageBeginMessage.java b/core/java/src/net/i2p/data/i2cp/ReceiveMessageBeginMessage.java index 15bd6779d..04cd20470 100644 --- a/core/java/src/net/i2p/data/i2cp/ReceiveMessageBeginMessage.java +++ b/core/java/src/net/i2p/data/i2cp/ReceiveMessageBeginMessage.java @@ -24,7 +24,7 @@ import net.i2p.data.DataHelper; */ public class ReceiveMessageBeginMessage extends I2CPMessageImpl { public final static int MESSAGE_TYPE = 6; - private long _sessionId; + private int _sessionId; private long _messageId; public ReceiveMessageBeginMessage() { @@ -36,8 +36,9 @@ public class ReceiveMessageBeginMessage extends I2CPMessageImpl { return _sessionId; } + /** @param id 0-65535 */ public void setSessionId(long id) { - _sessionId = id; + _sessionId = (int) id; } public long getMessageId() { @@ -51,7 +52,7 @@ public class ReceiveMessageBeginMessage extends I2CPMessageImpl { @Override protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException { try { - _sessionId = DataHelper.readLong(in, 2); + _sessionId = (int) DataHelper.readLong(in, 2); _messageId = DataHelper.readLong(in, 4); } catch (DataFormatException dfe) { throw new I2CPMessageException("Unable to load the message data", dfe); diff --git a/core/java/src/net/i2p/data/i2cp/ReceiveMessageEndMessage.java b/core/java/src/net/i2p/data/i2cp/ReceiveMessageEndMessage.java index 718fd8b73..028c028b9 100644 --- a/core/java/src/net/i2p/data/i2cp/ReceiveMessageEndMessage.java +++ b/core/java/src/net/i2p/data/i2cp/ReceiveMessageEndMessage.java @@ -23,7 +23,7 @@ import net.i2p.data.DataHelper; */ public class ReceiveMessageEndMessage extends I2CPMessageImpl { public final static int MESSAGE_TYPE = 7; - private long _sessionId; + private int _sessionId; private long _messageId; public ReceiveMessageEndMessage() { @@ -35,8 +35,9 @@ public class ReceiveMessageEndMessage extends I2CPMessageImpl { return _sessionId; } + /** @param id 0-65535 */ public void setSessionId(long id) { - _sessionId = id; + _sessionId = (int) id; } public long getMessageId() { @@ -50,7 +51,7 @@ public class ReceiveMessageEndMessage extends I2CPMessageImpl { @Override protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException { try { - _sessionId = DataHelper.readLong(in, 2); + _sessionId = (int) DataHelper.readLong(in, 2); _messageId = DataHelper.readLong(in, 4); } catch (DataFormatException dfe) { throw new I2CPMessageException("Unable to load the message data", dfe); diff --git a/core/java/src/net/i2p/data/i2cp/SessionId.java b/core/java/src/net/i2p/data/i2cp/SessionId.java index 708ba9c46..68f8c1a29 100644 --- a/core/java/src/net/i2p/data/i2cp/SessionId.java +++ b/core/java/src/net/i2p/data/i2cp/SessionId.java @@ -33,6 +33,7 @@ public class SessionId extends DataStructureImpl { return _sessionId; } + /** @param id 0-65535 */ public void setSessionId(int id) { _sessionId = id; } diff --git a/history.txt b/history.txt index b6f5c7bf1..dd7fb3398 100644 --- a/history.txt +++ b/history.txt @@ -1,19 +1,29 @@ +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 -* 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, - MTN rev 5bdb7fc27e35f174001bd6105a502fd5094842e5 covers it. + * 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, + MTN rev 5bdb7fc27e35f174001bd6105a502fd5094842e5 covers it. 2012-12-22 zzz - - i2psnark: Add announce list support (BEP 12) (ticket #778) - - i2ptunnel: Add more tunnel quantity options for servers - - Jetty: Update to Apache Tomcat 0.6.36 + * i2psnark: Add announce list support (BEP 12) (ticket #778) + * i2ptunnel: Add more tunnel quantity options for servers + * Jetty: Update to Apache Tomcat 6.0.36 2012-12-22 kytv -* French language translation update from Transifex + * French language translation update from Transifex 2012-12-19 zzz * Update: Hide the update buttons when router.updateDisabled=true, as is the case - for Debian packages. Broken in 0.9.4. (Ticket #817) + for Debian packages. Broken in 0.9.4. (Ticket #817) * 2012-12-17 0.9.4 released diff --git a/router/java/src/net/i2p/router/ClientManagerFacade.java b/router/java/src/net/i2p/router/ClientManagerFacade.java index dca7f5b30..204a3f591 100644 --- a/router/java/src/net/i2p/router/ClientManagerFacade.java +++ b/router/java/src/net/i2p/router/ClientManagerFacade.java @@ -68,7 +68,11 @@ public abstract class ClientManagerFacade implements Service { * @param destHash Hash of Destination to be checked */ 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); diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 87e5bffca..282c18b42 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 = 1; + public final static long BUILD = 2; /** for example "-test" */ public final static String EXTRA = ""; diff --git a/router/java/src/net/i2p/router/client/ClientConnectionRunner.java b/router/java/src/net/i2p/router/client/ClientConnectionRunner.java index bdb60ccf2..10bd79d4b 100644 --- a/router/java/src/net/i2p/router/client/ClientConnectionRunner.java +++ b/router/java/src/net/i2p/router/client/ClientConnectionRunner.java @@ -269,11 +269,13 @@ class ClientConnectionRunner { * delivered (or failed delivery) * Note that this sends the Guaranteed status codes, even though we only support best effort. * 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) 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 final MessageId _messageId; - private final boolean _success; + private final int _status; 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); _messageId = id; - _success = success; + _status = status; } public String getName() { return "Update Delivery Status"; } @@ -647,10 +652,7 @@ class ClientConnectionRunner { // has to be >= 0, it is initialized to -1 msg.setNonce(2); msg.setSize(0); - if (_success) - msg.setStatus(MessageStatusMessage.STATUS_SEND_GUARANTEED_SUCCESS); - else - msg.setStatus(MessageStatusMessage.STATUS_SEND_GUARANTEED_FAILURE); + msg.setStatus(_status); if (!alreadyAccepted(_messageId)) { _log.warn("Almost send an update for message " + _messageId + " to " diff --git a/router/java/src/net/i2p/router/client/ClientManager.java b/router/java/src/net/i2p/router/client/ClientManager.java index 1a07da10e..e82ef49d9 100644 --- a/router/java/src/net/i2p/router/client/ClientManager.java +++ b/router/java/src/net/i2p/router/client/ClientManager.java @@ -26,6 +26,7 @@ import net.i2p.data.LeaseSet; import net.i2p.data.Payload; import net.i2p.data.i2cp.I2CPMessage; import net.i2p.data.i2cp.MessageId; +import net.i2p.data.i2cp.MessageStatusMessage; import net.i2p.data.i2cp.SessionConfig; import net.i2p.internal.I2CPMessageQueue; import net.i2p.router.ClientManagerFacade; @@ -75,6 +76,10 @@ class ClientManager { _runnersByHash = new ConcurrentHashMap(); _pendingRunners = new HashSet(); 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? */ @@ -265,7 +270,7 @@ class ClientManager { public void runJob() { _to.receiveMessage(_toDest, _fromDest, _payload); 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); } - 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); if (runner != null) { if (_log.shouldLog(Log.DEBUG)) - _log.debug("Delivering status [" + (delivered?"success":"failure") + "] to " - + fromDest.calculateHash().toBase64() + " for message " + id); - runner.updateMessageDeliveryStatus(id, delivered); + _log.debug("Delivering status " + status + " to " + + fromDest.calculateHash() + " for message " + id); + runner.updateMessageDeliveryStatus(id, status); } else { if (_log.shouldLog(Log.WARN)) - _log.warn("Cannot deliver status [" + (delivered?"success":"failure") + "] to " - + fromDest.calculateHash().toBase64() + " for message " + id); + _log.warn("Cannot deliver status " + status + " to " + + fromDest.calculateHash() + " for message " + id); } } diff --git a/router/java/src/net/i2p/router/client/ClientManagerFacadeImpl.java b/router/java/src/net/i2p/router/client/ClientManagerFacadeImpl.java index ff40c2115..a9133182d 100644 --- a/router/java/src/net/i2p/router/client/ClientManagerFacadeImpl.java +++ b/router/java/src/net/i2p/router/client/ClientManagerFacadeImpl.java @@ -178,9 +178,12 @@ public class ClientManagerFacadeImpl extends ClientManagerFacade implements Inte @Override 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) - _manager.messageDeliveryStatusUpdate(fromDest, id, delivered); + _manager.messageDeliveryStatusUpdate(fromDest, id, status); else _log.error("Null manager on messageDeliveryStatusUpdate!"); } diff --git a/router/java/src/net/i2p/router/client/RequestLeaseSetJob.java b/router/java/src/net/i2p/router/client/RequestLeaseSetJob.java index 72147c060..96592e7f3 100644 --- a/router/java/src/net/i2p/router/client/RequestLeaseSetJob.java +++ b/router/java/src/net/i2p/router/client/RequestLeaseSetJob.java @@ -36,9 +36,7 @@ class RequestLeaseSetJob extends JobImpl { _log = ctx.logManager().getLog(RequestLeaseSetJob.class); _runner = runner; _requestState = state; - 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 }); + // all createRateStat in ClientManager } public String getName() { return "Request Lease Set"; } diff --git a/router/java/src/net/i2p/router/dummy/DummyClientManagerFacade.java b/router/java/src/net/i2p/router/dummy/DummyClientManagerFacade.java index 3f98e7577..c0b476333 100644 --- a/router/java/src/net/i2p/router/dummy/DummyClientManagerFacade.java +++ b/router/java/src/net/i2p/router/dummy/DummyClientManagerFacade.java @@ -43,7 +43,7 @@ public class DummyClientManagerFacade extends ClientManagerFacade { public void shutdown(String msg) {} 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 SessionKeyManager getClientSessionKeyManager(Hash _dest) { return null; } diff --git a/router/java/src/net/i2p/router/message/GarlicMessageReceiver.java b/router/java/src/net/i2p/router/message/GarlicMessageReceiver.java index 3666276cb..75105c902 100644 --- a/router/java/src/net/i2p/router/message/GarlicMessageReceiver.java +++ b/router/java/src/net/i2p/router/message/GarlicMessageReceiver.java @@ -49,11 +49,11 @@ public class GarlicMessageReceiver { public GarlicMessageReceiver(RouterContext context, CloveReceiver receiver, Hash clientDestination) { _context = context; _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; _parser = new GarlicMessageParser(context); _receiver = receiver; //_log.error("New GMR dest = " + clientDestination); + // all createRateStat in OCMOSJ.init() } public void receive(GarlicMessage message) { diff --git a/router/java/src/net/i2p/router/message/HandleGarlicMessageJob.java b/router/java/src/net/i2p/router/message/HandleGarlicMessageJob.java index 6dbff9678..9392526b3 100644 --- a/router/java/src/net/i2p/router/message/HandleGarlicMessageJob.java +++ b/router/java/src/net/i2p/router/message/HandleGarlicMessageJob.java @@ -50,7 +50,6 @@ class HandleGarlicMessageJob extends JobImpl implements GarlicMessageReceiver.Cl public HandleGarlicMessageJob(RouterContext context, GarlicMessage msg, RouterIdentity from, Hash fromHash) { super(context); _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)) _log.debug("Garlic Message not down a tunnel from [" + from + "]"); _message = msg; @@ -59,6 +58,7 @@ class HandleGarlicMessageJob extends JobImpl implements GarlicMessageReceiver.Cl //_cloves = new HashMap(); //_handler = new MessageHandler(context); //_parser = new GarlicMessageParser(context); + // all createRateStat in OCMOSJ.init() } public String getName() { return "Handle Inbound Garlic Message"; } diff --git a/router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java b/router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java index f7090eb7e..18b7daca0 100644 --- a/router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java +++ b/router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java @@ -21,6 +21,7 @@ import net.i2p.data.RouterInfo; import net.i2p.data.SessionKey; import net.i2p.data.SessionTag; import net.i2p.data.i2cp.MessageId; +import net.i2p.data.i2cp.MessageStatusMessage; import net.i2p.data.i2np.DataMessage; import net.i2p.data.i2np.DeliveryInstructions; 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.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 }); + // 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"; } @@ -674,6 +677,10 @@ public class OutboundClientMessageOneShotJob extends JobImpl { * this is safe to call multiple times (only tells the client once) */ private void dieFatal() { + dieFatal(MessageStatusMessage.STATUS_SEND_GUARANTEED_FAILURE); + } + + private void dieFatal(int status) { if (_finished) return; _finished = true; @@ -693,7 +700,7 @@ public class OutboundClientMessageOneShotJob extends JobImpl { clearCaches(); getContext().messageHistory().sendPayloadMessage(_clientMessageId.getMessageId(), false, sendTime); - getContext().clientManager().messageDeliveryStatusUpdate(_from, _clientMessageId, false); + getContext().clientManager().messageDeliveryStatusUpdate(_from, _clientMessageId, status); getContext().statManager().updateFrequency("client.sendMessageFailFrequency"); _clove = null; } @@ -820,7 +827,8 @@ public class OutboundClientMessageOneShotJob extends JobImpl { long dataMsgId = _cloveId; getContext().messageHistory().sendPayloadMessage(dataMsgId, true, sendTime); - getContext().clientManager().messageDeliveryStatusUpdate(_from, _clientMessageId, true); + getContext().clientManager().messageDeliveryStatusUpdate(_from, _clientMessageId, + MessageStatusMessage.STATUS_SEND_GUARANTEED_SUCCESS); // unused //_lease.setNumSuccess(_lease.getNumSuccess()+1);