forked from I2P_Developers/i2p.i2p
* 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
This commit is contained in:
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
@@ -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);
|
||||||
|
@@ -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);
|
||||||
|
@@ -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);
|
||||||
|
@@ -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);
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
20
history.txt
20
history.txt
@@ -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
|
||||||
|
@@ -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);
|
||||||
|
|
||||||
|
@@ -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 = "";
|
||||||
|
@@ -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 "
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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!");
|
||||||
}
|
}
|
||||||
|
@@ -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"; }
|
||||||
|
@@ -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; }
|
||||||
|
@@ -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) {
|
||||||
|
@@ -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"; }
|
||||||
|
@@ -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);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user