From 471c5d49d1902a4e5c37f2d3ddbe2a168c2ca2fc Mon Sep 17 00:00:00 2001 From: zzz Date: Sun, 2 Jun 2019 10:59:39 +0000 Subject: [PATCH] I2CP: Cleanups for single-byte reads Stub out new error codes for prop. 123 --- .../src/net/i2p/data/i2cp/AbuseSeverity.java | 5 ++++- .../net/i2p/data/i2cp/HostLookupMessage.java | 5 ++++- .../net/i2p/data/i2cp/HostReplyMessage.java | 11 +++++++++- .../net/i2p/data/i2cp/I2CPMessageHandler.java | 22 +++++++++---------- .../net/i2p/data/i2cp/I2CPMessageImpl.java | 10 ++++----- .../i2p/data/i2cp/MessageStatusMessage.java | 12 +++++++++- .../i2p/data/i2cp/RequestLeaseSetMessage.java | 3 ++- .../i2cp/RequestVariableLeaseSetMessage.java | 5 ++++- .../i2p/data/i2cp/SessionStatusMessage.java | 5 ++++- 9 files changed, 53 insertions(+), 25 deletions(-) diff --git a/core/java/src/net/i2p/data/i2cp/AbuseSeverity.java b/core/java/src/net/i2p/data/i2cp/AbuseSeverity.java index 00855844c..13cfcb974 100644 --- a/core/java/src/net/i2p/data/i2cp/AbuseSeverity.java +++ b/core/java/src/net/i2p/data/i2cp/AbuseSeverity.java @@ -9,6 +9,7 @@ package net.i2p.data.i2cp; * */ +import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -40,7 +41,9 @@ public class AbuseSeverity extends DataStructureImpl { } public void readBytes(InputStream in) throws DataFormatException, IOException { - _severityId = (int) DataHelper.readLong(in, 1); + _severityId = in.read(); + if (_severityId < 0) + throw new EOFException(); } public void writeBytes(OutputStream out) throws DataFormatException, IOException { diff --git a/core/java/src/net/i2p/data/i2cp/HostLookupMessage.java b/core/java/src/net/i2p/data/i2cp/HostLookupMessage.java index 66835ef9f..b25b4b351 100644 --- a/core/java/src/net/i2p/data/i2cp/HostLookupMessage.java +++ b/core/java/src/net/i2p/data/i2cp/HostLookupMessage.java @@ -6,6 +6,7 @@ package net.i2p.data.i2cp; */ import java.io.ByteArrayOutputStream; +import java.io.EOFException; import java.io.IOException; import java.io.InputStream; @@ -127,7 +128,9 @@ public class HostLookupMessage extends I2CPMessageImpl { _sessionId.readBytes(in); _reqID = DataHelper.readLong(in, 4); _timeout = DataHelper.readLong(in, 4); - _lookupType = (int) DataHelper.readLong(in, 1); + _lookupType = in.read(); + if (_lookupType < 0) + throw new EOFException(); if (_lookupType == LOOKUP_HASH) { _hash = Hash.create(in); } else if (_lookupType == LOOKUP_HOST) { diff --git a/core/java/src/net/i2p/data/i2cp/HostReplyMessage.java b/core/java/src/net/i2p/data/i2cp/HostReplyMessage.java index ad182d6a6..04e502202 100644 --- a/core/java/src/net/i2p/data/i2cp/HostReplyMessage.java +++ b/core/java/src/net/i2p/data/i2cp/HostReplyMessage.java @@ -7,6 +7,7 @@ package net.i2p.data.i2cp; */ import java.io.ByteArrayOutputStream; +import java.io.EOFException; import java.io.IOException; import java.io.InputStream; @@ -30,6 +31,12 @@ public class HostReplyMessage extends I2CPMessageImpl { public static final int RESULT_SUCCESS = 0; /** generic fail, other codes TBD */ public static final int RESULT_FAILURE = 1; + /** @since 0.9.41 */ + public static final int RESULT_SECRET_REQUIRED = 2; + /** @since 0.9.41 */ + public static final int RESULT_KEY_REQUIRED = 3; + /** @since 0.9.41 */ + public static final int RESULT_SECRET_AND_KEY_REQUIRED = 4; private static final long MAX_INT = (1L << 32) - 1; @@ -109,7 +116,9 @@ public class HostReplyMessage extends I2CPMessageImpl { _sessionId = new SessionId(); _sessionId.readBytes(in); _reqID = DataHelper.readLong(in, 4); - _code = (int) DataHelper.readLong(in, 1); + _code = in.read(); + if (_code < 0) + throw new EOFException(); if (_code == RESULT_SUCCESS) _dest = Destination.create(in); } catch (DataFormatException dfe) { diff --git a/core/java/src/net/i2p/data/i2cp/I2CPMessageHandler.java b/core/java/src/net/i2p/data/i2cp/I2CPMessageHandler.java index 5c5d76885..49224d112 100644 --- a/core/java/src/net/i2p/data/i2cp/I2CPMessageHandler.java +++ b/core/java/src/net/i2p/data/i2cp/I2CPMessageHandler.java @@ -9,6 +9,7 @@ package net.i2p.data.i2cp; * */ +import java.io.EOFException; import java.io.IOException; import java.io.InputStream; @@ -45,18 +46,15 @@ public class I2CPMessageHandler { } if (length > MAX_LENGTH) throw new I2CPMessageException("Invalid message length specified"); - try { - int type = (int) DataHelper.readLong(in, 1); - I2CPMessage msg = createMessage(type); - // Note that the readMessage() calls don't, in general, read and discard - // extra data, so we can't add new fields to the end of messages - // in a compatible way. And the readers could read beyond the length too. - // To fix this we'd have to read into a BAOS/BAIS or use a filter input stream - msg.readMessage(in, length, type); - return msg; - } catch (DataFormatException dfe) { - throw new I2CPMessageException("Error reading the message", dfe); - } + int type = in.read(); + if (type < 0) + throw new EOFException(); + I2CPMessage msg = createMessage(type); + // extra data, so we can't add new fields to the end of messages + // in a compatible way. And the readers could read beyond the length too. + // To fix this we'd have to read into a BAOS/BAIS or use a filter input stream + msg.readMessage(in, length, type); + return msg; } /** diff --git a/core/java/src/net/i2p/data/i2cp/I2CPMessageImpl.java b/core/java/src/net/i2p/data/i2cp/I2CPMessageImpl.java index 4049535f7..9a4641513 100644 --- a/core/java/src/net/i2p/data/i2cp/I2CPMessageImpl.java +++ b/core/java/src/net/i2p/data/i2cp/I2CPMessageImpl.java @@ -9,6 +9,7 @@ package net.i2p.data.i2cp; * */ +import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -40,12 +41,9 @@ public abstract class I2CPMessageImpl extends DataStructureImpl implements I2CPM throw new I2CPMessageException("Error reading the length bytes", dfe); } if (length < 0) throw new I2CPMessageException("Invalid message length specified"); - int type = -1; - try { - type = (int) DataHelper.readLong(in, 1); - } catch (DataFormatException dfe) { - throw new I2CPMessageException("Error reading the type byte", dfe); - } + int type = in.read(); + if (type < 0) + throw new EOFException(); readMessage(in, length, type); } diff --git a/core/java/src/net/i2p/data/i2cp/MessageStatusMessage.java b/core/java/src/net/i2p/data/i2cp/MessageStatusMessage.java index b3612eccd..822efe603 100644 --- a/core/java/src/net/i2p/data/i2cp/MessageStatusMessage.java +++ b/core/java/src/net/i2p/data/i2cp/MessageStatusMessage.java @@ -179,6 +179,15 @@ public class MessageStatusMessage extends I2CPMessageImpl { */ public final static int STATUS_SEND_FAILURE_NO_LEASESET = 21; + /** + * The far-end destination's lease set was a meta lease set, + * and cannot be sent to. The client should request the meta + * lease set's contents with a HostLookupMessage, and select + * one of the hashes contained within to lookup and send to. + * This is a guaranteed failure. + * @since 0.9.41 + */ + public final static int STATUS_SEND_FAILURE_META_LEASESET = 22; public MessageStatusMessage() { @@ -301,7 +310,8 @@ public class MessageStatusMessage extends I2CPMessageImpl { try { _sessionId = (int) DataHelper.readLong(in, 2); _messageId = DataHelper.readLong(in, 4); - _status = (int) DataHelper.readLong(in, 1); + _status = in.read(); + // EOF will be caught below _size = DataHelper.readLong(in, 4); _nonce = DataHelper.readLong(in, 4); } catch (DataFormatException dfe) { diff --git a/core/java/src/net/i2p/data/i2cp/RequestLeaseSetMessage.java b/core/java/src/net/i2p/data/i2cp/RequestLeaseSetMessage.java index ea8e714b9..dfd6ad654 100644 --- a/core/java/src/net/i2p/data/i2cp/RequestLeaseSetMessage.java +++ b/core/java/src/net/i2p/data/i2cp/RequestLeaseSetMessage.java @@ -98,7 +98,8 @@ public class RequestLeaseSetMessage extends I2CPMessageImpl { try { _sessionId = new SessionId(); _sessionId.readBytes(in); - int numTunnels = (int) DataHelper.readLong(in, 1); + int numTunnels = in.read(); + // EOF will be caught below _endpoints.clear(); for (int i = 0; i < numTunnels; i++) { //Hash router = new Hash(); diff --git a/core/java/src/net/i2p/data/i2cp/RequestVariableLeaseSetMessage.java b/core/java/src/net/i2p/data/i2cp/RequestVariableLeaseSetMessage.java index 4562ba93f..39213369d 100644 --- a/core/java/src/net/i2p/data/i2cp/RequestVariableLeaseSetMessage.java +++ b/core/java/src/net/i2p/data/i2cp/RequestVariableLeaseSetMessage.java @@ -10,6 +10,7 @@ package net.i2p.data.i2cp; */ import java.io.ByteArrayOutputStream; +import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; @@ -91,7 +92,9 @@ public class RequestVariableLeaseSetMessage extends I2CPMessageImpl { throw new IllegalStateException(); _sessionId = new SessionId(); _sessionId.readBytes(in); - int numTunnels = (int) DataHelper.readLong(in, 1); + int numTunnels = in.read(); + if (numTunnels < 0) + throw new EOFException(); for (int i = 0; i < numTunnels; i++) { Lease lease = new Lease(); lease.readBytes(in); diff --git a/core/java/src/net/i2p/data/i2cp/SessionStatusMessage.java b/core/java/src/net/i2p/data/i2cp/SessionStatusMessage.java index 49509a552..2ccdea12c 100644 --- a/core/java/src/net/i2p/data/i2cp/SessionStatusMessage.java +++ b/core/java/src/net/i2p/data/i2cp/SessionStatusMessage.java @@ -10,6 +10,7 @@ package net.i2p.data.i2cp; */ import java.io.ByteArrayOutputStream; +import java.io.EOFException; import java.io.IOException; import java.io.InputStream; @@ -69,7 +70,9 @@ public class SessionStatusMessage extends I2CPMessageImpl { try { _sessionId = new SessionId(); _sessionId.readBytes(in); - _status = (int) DataHelper.readLong(in, 1); + _status = in.read(); + if (_status < 0) + throw new EOFException(); } catch (DataFormatException dfe) { throw new I2CPMessageException("Unable to load the message data", dfe); }