From d1b93e070532332939af9d05d576f18f64d5f584 Mon Sep 17 00:00:00 2001
From: zzz <zzz@mail.i2p>
Date: Fri, 8 Nov 2013 14:39:43 +0000
Subject: [PATCH] DeliveryInstructions:   - Comment out unused encryption
 fields to save space   - New static immutable LOCAL instruction to reduce
 object churn

---
 .../i2p/data/i2np/DeliveryInstructions.java   | 113 ++++++++++++++++--
 .../src/net/i2p/router/RouterVersion.java     |   2 +-
 .../OutboundClientMessageJobHelper.java       |  22 +---
 .../networkdb/kademlia/MessageWrapper.java    |  15 +--
 .../net/i2p/router/tunnel/pool/TestJob.java   |   5 +-
 5 files changed, 110 insertions(+), 47 deletions(-)

diff --git a/router/java/src/net/i2p/data/i2np/DeliveryInstructions.java b/router/java/src/net/i2p/data/i2np/DeliveryInstructions.java
index 23309dcb48..2126fd3975 100644
--- a/router/java/src/net/i2p/data/i2np/DeliveryInstructions.java
+++ b/router/java/src/net/i2p/data/i2np/DeliveryInstructions.java
@@ -33,8 +33,8 @@ import net.i2p.data.TunnelId;
  */
 public class DeliveryInstructions extends DataStructureImpl {
     //private final static Log _log = new Log(DeliveryInstructions.class);
-    private boolean _encrypted;
-    private SessionKey _encryptionKey;
+    //private boolean _encrypted;
+    //private SessionKey _encryptionKey;
     private int _deliveryMode;
     public final static int DELIVERY_MODE_LOCAL = 0;
     public final static int DELIVERY_MODE_DESTINATION = 1;
@@ -56,6 +56,13 @@ public class DeliveryInstructions extends DataStructureImpl {
     private final static long FLAG_MODE = 96;
     private final static long FLAG_DELAY = 16;
     
+    /**
+     *  Immutable local instructions, no options
+     *
+     *  @since 0.9.9
+     */
+    public static final DeliveryInstructions LOCAL = new LocalInstructions();
+
     public DeliveryInstructions() {
         _deliveryMode = -1;
     }
@@ -64,25 +71,25 @@ public class DeliveryInstructions extends DataStructureImpl {
      * For cloves only (not tunnels), default false, unused
      * @deprecated unused
      */
-    public boolean getEncrypted() { return _encrypted; }
+    public boolean getEncrypted() { return /* _encrypted */ false; }
     
     /**
      * For cloves only (not tunnels), default false, unused
      * @deprecated unused
      */
-    public void setEncrypted(boolean encrypted) { _encrypted = encrypted; }
+    public void setEncrypted(boolean encrypted) { /* _encrypted = encrypted; */ }
 
     /**
      * For cloves only (not tunnels), default null, unused
      * @deprecated unused
      */
-    public SessionKey getEncryptionKey() { return _encryptionKey; }
+    public SessionKey getEncryptionKey() { return /* _encryptionKey */ null; }
 
     /**
      * For cloves only (not tunnels), default null, unused
      * @deprecated unused
      */
-    public void setEncryptionKey(SessionKey key) { _encryptionKey = key; }
+    public void setEncryptionKey(SessionKey key) { /* _encryptionKey = key; */ }
 
     /** default -1 */
     public int getDeliveryMode() { return _deliveryMode; }
@@ -121,7 +128,7 @@ public class DeliveryInstructions extends DataStructureImpl {
     public void setDelayRequested(boolean req) { _delayRequested = req; }
     
     /**
-     * default 0, unusedx
+     * default 0, unused
      * @deprecated unused
      */
     public long getDelaySeconds() { return _delaySeconds; }
@@ -252,20 +259,20 @@ public class DeliveryInstructions extends DataStructureImpl {
      * @deprecated unused
      */
 /****
-    private boolean flagEncrypted(long flags) {
+    private static boolean flagEncrypted(long flags) {
         return (0 != (flags & FLAG_ENCRYPTED));
     }
 ****/
     
     /** high bits */
-    private int flagMode(long flags) {
+    private static int flagMode(long flags) {
         long v = flags & FLAG_MODE;
         v >>>= 5;
         return (int)v;
     }
     
     /**  unused */
-    private boolean flagDelay(long flags) {
+    private static boolean flagDelay(long flags) {
         return (0 != (flags & FLAG_DELAY));
     }
     
@@ -492,4 +499,90 @@ public class DeliveryInstructions extends DataStructureImpl {
         
         return buf.toString();
     }
+
+    /**
+     *  An immutable local delivery instructions with no options
+     *  for efficiency.
+     *
+     *  @since 0.9.9
+     */
+    private static final class LocalInstructions extends DeliveryInstructions {
+        //private static final byte flag = DELIVERY_MODE_LOCAL << 5;  // 0
+
+        @Override
+        public void setEncrypted(boolean encrypted) {
+            throw new RuntimeException("immutable");
+        }
+
+        @Override
+        public void setEncryptionKey(SessionKey key) {
+            throw new RuntimeException("immutable");
+        }
+
+        @Override
+        public int getDeliveryMode() { return DELIVERY_MODE_LOCAL; }
+
+        @Override
+        public void setDeliveryMode(int mode) {
+            throw new RuntimeException("immutable");
+        }
+
+        @Override
+        public void setDestination(Hash dest) {
+            throw new RuntimeException("immutable");
+        }
+
+        @Override
+        public void setRouter(Hash router) {
+            throw new RuntimeException("immutable");
+        }
+
+        @Override
+        public void setTunnelId(TunnelId id) {
+            throw new RuntimeException("immutable");
+        }
+
+        @Override
+        public void setDelayRequested(boolean req) {
+            throw new RuntimeException("immutable");
+        }
+
+        @Override
+        public void setDelaySeconds(long seconds) {
+            throw new RuntimeException("immutable");
+        }
+
+        @Override
+        public void readBytes(InputStream in) throws DataFormatException, IOException {
+            throw new RuntimeException("immutable");
+        }
+
+        @Override
+        public int readBytes(byte data[], int offset) throws DataFormatException {
+            throw new RuntimeException("immutable");
+        }
+
+        @Override
+        public void writeBytes(OutputStream out) throws DataFormatException, IOException {
+            out.write((byte) 0);
+        }
+
+        @Override
+        public int writeBytes(byte target[], int offset) {
+            target[offset] = 0;
+            return 1;
+        }
+
+        @Override
+        public int getSize() {
+            return 1;
+        }
+
+        @Override
+        public String toString() {
+            return "[DeliveryInstructions: " +
+                   "\n\tDelivery mode: " +
+                   "local]";
+        }
+    }
 }
diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java
index 9319fc01c9..0bd65feeba 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 = 22;
+    public final static long BUILD = 23;
 
     /** for example "-test" */
     public final static String EXTRA = "";
diff --git a/router/java/src/net/i2p/router/message/OutboundClientMessageJobHelper.java b/router/java/src/net/i2p/router/message/OutboundClientMessageJobHelper.java
index 820e7d6b12..c6fc18b551 100644
--- a/router/java/src/net/i2p/router/message/OutboundClientMessageJobHelper.java
+++ b/router/java/src/net/i2p/router/message/OutboundClientMessageJobHelper.java
@@ -122,18 +122,8 @@ class OutboundClientMessageJobHelper {
         // and get the leaseset stored before handling the data
         config.addClove(dataClove);
 
-        DeliveryInstructions instructions = new DeliveryInstructions();
-        instructions.setDeliveryMode(DeliveryInstructions.DELIVERY_MODE_LOCAL);
-        // defaults
-        //instructions.setDelayRequested(false);
-        //instructions.setDelaySeconds(0);
-        //instructions.setEncrypted(false);
-        //instructions.setEncryptionKey(null);
-        //instructions.setRouter(null);
-        //instructions.setTunnelId(null);
-        
         config.setCertificate(Certificate.NULL_CERT);
-        config.setDeliveryInstructions(instructions);
+        config.setDeliveryInstructions(DeliveryInstructions.LOCAL);
         config.setId(ctx.random().nextLong(I2NPMessage.MAX_ID_VALUE));
         config.setExpiration(expiration); // +2*Router.CLOCK_FUDGE_FACTOR);
         config.setRecipientPublicKey(recipientPK);
@@ -233,16 +223,8 @@ class OutboundClientMessageJobHelper {
      */
     static PayloadGarlicConfig buildLeaseSetClove(RouterContext ctx, long expiration, LeaseSet replyLeaseSet) {
         PayloadGarlicConfig clove = new PayloadGarlicConfig();
-        
-        DeliveryInstructions instructions = new DeliveryInstructions();
-        instructions.setDeliveryMode(DeliveryInstructions.DELIVERY_MODE_LOCAL);
-        // defaults
-        //instructions.setDelayRequested(false);
-        //instructions.setDelaySeconds(0);
-        //instructions.setEncrypted(false);
-        
         clove.setCertificate(Certificate.NULL_CERT);
-        clove.setDeliveryInstructions(instructions);
+        clove.setDeliveryInstructions(DeliveryInstructions.LOCAL);
         clove.setExpiration(expiration);
         clove.setId(ctx.random().nextLong(I2NPMessage.MAX_ID_VALUE));
         DatabaseStoreMessage msg = new DatabaseStoreMessage(ctx);
diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/MessageWrapper.java b/router/java/src/net/i2p/router/networkdb/kademlia/MessageWrapper.java
index 3930aebca9..672f862885 100644
--- a/router/java/src/net/i2p/router/networkdb/kademlia/MessageWrapper.java
+++ b/router/java/src/net/i2p/router/networkdb/kademlia/MessageWrapper.java
@@ -43,15 +43,12 @@ public class MessageWrapper {
      *  @return null on encrypt failure
      */
     static WrappedMessage wrap(RouterContext ctx, I2NPMessage m, Hash from, RouterInfo to) {
-        DeliveryInstructions instructions = new DeliveryInstructions();
-        instructions.setDeliveryMode(DeliveryInstructions.DELIVERY_MODE_LOCAL);
-
         PayloadGarlicConfig payload = new PayloadGarlicConfig();
         payload.setCertificate(Certificate.NULL_CERT);
         payload.setId(ctx.random().nextLong(I2NPMessage.MAX_ID_VALUE));
         payload.setPayload(m);
         payload.setRecipient(to);
-        payload.setDeliveryInstructions(instructions);
+        payload.setDeliveryInstructions(DeliveryInstructions.LOCAL);
         payload.setExpiration(m.getMessageExpiration());
 
         SessionKeyManager skm;
@@ -127,15 +124,12 @@ public class MessageWrapper {
      *  @since 0.9.5
      */
     static GarlicMessage wrap(RouterContext ctx, I2NPMessage m, RouterInfo to) {
-        DeliveryInstructions instructions = new DeliveryInstructions();
-        instructions.setDeliveryMode(DeliveryInstructions.DELIVERY_MODE_LOCAL);
-
         PayloadGarlicConfig payload = new PayloadGarlicConfig();
         payload.setCertificate(Certificate.NULL_CERT);
         payload.setId(ctx.random().nextLong(I2NPMessage.MAX_ID_VALUE));
         payload.setPayload(m);
         payload.setRecipient(to);
-        payload.setDeliveryInstructions(instructions);
+        payload.setDeliveryInstructions(DeliveryInstructions.LOCAL);
         payload.setExpiration(m.getMessageExpiration());
 
         SessionKey sentKey = ctx.keyGenerator().generateSessionKey();
@@ -215,14 +209,11 @@ public class MessageWrapper {
      *  @since 0.9.7
      */
     public static GarlicMessage wrap(RouterContext ctx, I2NPMessage m, SessionKey encryptKey, SessionTag encryptTag) {
-        DeliveryInstructions instructions = new DeliveryInstructions();
-        instructions.setDeliveryMode(DeliveryInstructions.DELIVERY_MODE_LOCAL);
-
         PayloadGarlicConfig payload = new PayloadGarlicConfig();
         payload.setCertificate(Certificate.NULL_CERT);
         payload.setId(ctx.random().nextLong(I2NPMessage.MAX_ID_VALUE));
         payload.setPayload(m);
-        payload.setDeliveryInstructions(instructions);
+        payload.setDeliveryInstructions(DeliveryInstructions.LOCAL);
         payload.setExpiration(m.getMessageExpiration());
 
         GarlicMessage msg = GarlicMessageBuilder.buildMessage(ctx, payload, null, null, 
diff --git a/router/java/src/net/i2p/router/tunnel/pool/TestJob.java b/router/java/src/net/i2p/router/tunnel/pool/TestJob.java
index f5f6b8b425..bd17333efd 100644
--- a/router/java/src/net/i2p/router/tunnel/pool/TestJob.java
+++ b/router/java/src/net/i2p/router/tunnel/pool/TestJob.java
@@ -115,15 +115,12 @@ class TestJob extends JobImpl {
         // can't tell its a test.  to simplify this, we encrypt it with a random key and tag,
         // remembering that key+tag so that we can decrypt it later.  this means we can do the
         // garlic encryption without any ElGamal (yay)
-        DeliveryInstructions instructions = new DeliveryInstructions();
-        instructions.setDeliveryMode(DeliveryInstructions.DELIVERY_MODE_LOCAL);
-
         PayloadGarlicConfig payload = new PayloadGarlicConfig();
         payload.setCertificate(Certificate.NULL_CERT);
         payload.setId(getContext().random().nextLong(I2NPMessage.MAX_ID_VALUE));
         payload.setPayload(m);
         payload.setRecipient(getContext().router().getRouterInfo());
-        payload.setDeliveryInstructions(instructions);
+        payload.setDeliveryInstructions(DeliveryInstructions.LOCAL);
         payload.setExpiration(m.getMessageExpiration());
 
         SessionKey encryptKey = getContext().keyGenerator().generateSessionKey();
-- 
GitLab