From ca00b3431491ac2b88cfa65d1b49662fb07db767 Mon Sep 17 00:00:00 2001 From: zzz Date: Wed, 5 Dec 2012 00:03:27 +0000 Subject: [PATCH] * I2CP: Fix external I2CP apps, including i2ping, caused by 0 nonce value, broken in 0.9.2 (tickets #799, #801). Allow nonces == 0. Javadocs and cleanups. --- .../net/i2p/client/I2CPMessageProducer.java | 5 +++ .../src/net/i2p/client/I2PSessionImpl2.java | 2 +- .../data/i2cp/SendMessageExpiresMessage.java | 32 +++++++++++-------- .../net/i2p/data/i2cp/SendMessageMessage.java | 24 ++++++++++---- history.txt | 12 +++++-- .../src/net/i2p/router/RouterVersion.java | 2 +- .../router/client/ClientConnectionRunner.java | 3 +- 7 files changed, 56 insertions(+), 24 deletions(-) diff --git a/core/java/src/net/i2p/client/I2CPMessageProducer.java b/core/java/src/net/i2p/client/I2CPMessageProducer.java index bcf3876ae..47c8bd53f 100644 --- a/core/java/src/net/i2p/client/I2CPMessageProducer.java +++ b/core/java/src/net/i2p/client/I2CPMessageProducer.java @@ -122,6 +122,7 @@ class I2CPMessageProducer { /** * Package up and send the payload to the router for delivery * + * @param nonce 0 to 0xffffffff; if 0, the router will not reply with a MessageStatusMessage * @param tag unused - no end-to-end crypto * @param tags unused - no end-to-end crypto * @param key unused - no end-to-end crypto @@ -134,6 +135,8 @@ class I2CPMessageProducer { /** * Package up and send the payload to the router for delivery + * + * @param nonce 0 to 0xffffffff; if 0, the router will not reply with a MessageStatusMessage * @since 0.8.4 */ public void sendMessage(I2PSessionImpl session, Destination dest, long nonce, byte[] payload, @@ -160,6 +163,8 @@ class I2CPMessageProducer { /** * Package up and send the payload to the router for delivery + * + * @param nonce 0 to 0xffffffff; if 0, the router will not reply with a MessageStatusMessage * @since 0.9.2 */ public void sendMessage(I2PSessionImpl session, Destination dest, long nonce, byte[] payload, diff --git a/core/java/src/net/i2p/client/I2PSessionImpl2.java b/core/java/src/net/i2p/client/I2PSessionImpl2.java index a71d7f099..c369f3a62 100644 --- a/core/java/src/net/i2p/client/I2PSessionImpl2.java +++ b/core/java/src/net/i2p/client/I2PSessionImpl2.java @@ -309,7 +309,7 @@ class I2PSessionImpl2 extends I2PSessionImpl { //if (_log.shouldLog(Log.DEBUG)) _log.debug("before creating nonce"); - long nonce = _context.random().nextInt(Integer.MAX_VALUE); + long nonce = _context.random().nextInt(Integer.MAX_VALUE - 1) + 1; //if (_log.shouldLog(Log.DEBUG)) _log.debug("before sync state"); MessageState state = new MessageState(_context, nonce, getPrefix()); //state.setKey(key); diff --git a/core/java/src/net/i2p/data/i2cp/SendMessageExpiresMessage.java b/core/java/src/net/i2p/data/i2cp/SendMessageExpiresMessage.java index c473e44c5..b60cce67f 100644 --- a/core/java/src/net/i2p/data/i2cp/SendMessageExpiresMessage.java +++ b/core/java/src/net/i2p/data/i2cp/SendMessageExpiresMessage.java @@ -105,17 +105,23 @@ public class SendMessageExpiresMessage extends SendMessageMessage { */ @Override public void writeMessage(OutputStream out) throws I2CPMessageException, IOException { - if ((getSessionId() == null) || (getDestination() == null) || (getPayload() == null) || (getNonce() <= 0)) - throw new I2CPMessageException("Unable to write out the message as there is not enough data"); - int len = 2 + getDestination().size() + getPayload().getSize() + 4 + 4 + DataHelper.DATE_LENGTH; + if (_sessionId == null) + throw new I2CPMessageException("No session ID"); + if (_destination == null) + throw new I2CPMessageException("No dest"); + if (_payload == null) + throw new I2CPMessageException("No payload"); + if (_nonce < 0) + throw new I2CPMessageException("No nonce"); + int len = 2 + _destination.size() + _payload.getSize() + 4 + 4 + DataHelper.DATE_LENGTH; try { DataHelper.writeLong(out, 4, len); - DataHelper.writeLong(out, 1, getType()); - getSessionId().writeBytes(out); - getDestination().writeBytes(out); - getPayload().writeBytes(out); - DataHelper.writeLong(out, 4, getNonce()); + DataHelper.writeLong(out, 1, MESSAGE_TYPE); + _sessionId.writeBytes(out); + _destination.writeBytes(out); + _payload.writeBytes(out); + DataHelper.writeLong(out, 4, _nonce); _daf.writeBytes(out); } catch (DataFormatException dfe) { throw new I2CPMessageException("Error writing the msg", dfe); @@ -142,12 +148,12 @@ public class SendMessageExpiresMessage extends SendMessageMessage { @Override public String toString() { StringBuilder buf = new StringBuilder(); - buf.append("[SendMessageMessage: "); - buf.append("\n\tSessionId: ").append(getSessionId()); - buf.append("\n\tNonce: ").append(getNonce()); - buf.append("\n\tDestination: ").append(getDestination()); + buf.append("[SendMessageExpiresMessage: "); + buf.append("\n\tSessionId: ").append(_sessionId); + buf.append("\n\tNonce: ").append(_nonce); + buf.append("\n\tDestination: ").append(_destination); buf.append("\n\tExpiration: ").append(getExpiration()); - buf.append("\n\tPayload: ").append(getPayload()); + buf.append("\n\tPayload: ").append(_payload); buf.append("]"); return buf.toString(); } diff --git a/core/java/src/net/i2p/data/i2cp/SendMessageMessage.java b/core/java/src/net/i2p/data/i2cp/SendMessageMessage.java index dc2cef33d..956c530c3 100644 --- a/core/java/src/net/i2p/data/i2cp/SendMessageMessage.java +++ b/core/java/src/net/i2p/data/i2cp/SendMessageMessage.java @@ -26,10 +26,10 @@ import net.i2p.data.Payload; */ public class SendMessageMessage extends I2CPMessageImpl { public final static int MESSAGE_TYPE = 5; - private SessionId _sessionId; - private Destination _destination; - private Payload _payload; - private long _nonce; + protected SessionId _sessionId; + protected Destination _destination; + protected Payload _payload; + protected long _nonce; public SendMessageMessage() { } @@ -58,10 +58,16 @@ public class SendMessageMessage extends I2CPMessageImpl { _payload = payload; } + /** + * @return 0 to 0xffffffff + */ public long getNonce() { return _nonce; } + /** + * @param 0 to 0xffffffff + */ public void setNonce(long nonce) { _nonce = nonce; } @@ -109,8 +115,14 @@ public class SendMessageMessage extends I2CPMessageImpl { */ @Override public void writeMessage(OutputStream out) throws I2CPMessageException, IOException { - if ((_sessionId == null) || (_destination == null) || (_payload == null) || (_nonce <= 0)) - throw new I2CPMessageException("Unable to write out the message as there is not enough data"); + if (_sessionId == null) + throw new I2CPMessageException("No session ID"); + if (_destination == null) + throw new I2CPMessageException("No dest"); + if (_payload == null) + throw new I2CPMessageException("No payload"); + if (_nonce < 0) + throw new I2CPMessageException("No nonce"); int len = 2 + _destination.size() + _payload.getSize() + 4 + 4; try { diff --git a/history.txt b/history.txt index e201c66c5..9e0b07bd6 100644 --- a/history.txt +++ b/history.txt @@ -1,6 +1,14 @@ +2012-12-05 zzz + * GarlicMessage: Fix notes and log in GarlicMessageHandler and HandleGarlicMessageJob, + they are used for netdb messages received by floodfills http://zzz.i2p/topics/1282 + * I2CP: Fix external I2CP apps, including i2ping, caused by 0 nonce value, + broken in 0.9.2 (tickets #799, #801). Allow nonces == 0. + * Reseed: Don't go on to the next host if we have enough http://zzz.i2p/topics/1287 + * SSU: Fix rare NPE (ticket #798) + 2012-11-28 kytv -* Chinese, French, Italian, Polish, and Ukrainian translation updates from - Transifex. + * Chinese, French, Italian, Polish, and Ukrainian translation updates from + Transifex. 2012-11-24 zzz * Addressbook: Disable unused wakeup via http diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index e36cd3b14..7f4edb975 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 = 12; + public final static long BUILD = 13; /** 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 36b368906..bdb60ccf2 100644 --- a/router/java/src/net/i2p/router/client/ClientConnectionRunner.java +++ b/router/java/src/net/i2p/router/client/ClientConnectionRunner.java @@ -379,9 +379,10 @@ class ClientConnectionRunner { * Send a notification to the client that their message (id specified) was accepted * for delivery (but not necessarily delivered) * Doesn't do anything if i2cp.messageReliability = "none" + * or if the nonce is 0. */ void ackSendMessage(MessageId id, long nonce) { - if (_dontSendMSM) + if (_dontSendMSM || nonce == 0) return; SessionId sid = _sessionId; if (sid == null) return;