diff --git a/apps/routerconsole/java/src/net/i2p/router/web/helpers/TunnelRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/helpers/TunnelRenderer.java index 2d36e2bf84..59c09436f9 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/helpers/TunnelRenderer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/helpers/TunnelRenderer.java @@ -138,17 +138,19 @@ class TunnelRenderer { if (++displayed > DISPLAY_LIMIT) continue; out.write(""); - if (cfg.getReceiveTunnel() != null) + long recv = cfg.getReceiveTunnelId(); + if (recv != 0) out.write("" + - cfg.getReceiveTunnel().getTunnelId() + ""); + recv + ""); else out.write("n/a"); if (cfg.getReceiveFrom() != null) out.write("" + netDbLink(cfg.getReceiveFrom()) +""); else out.write(" "); - if (cfg.getSendTunnel() != null) - out.write("" + cfg.getSendTunnel().getTunnelId() +""); + long send = cfg.getSendTunnelId(); + if (send != 0) + out.write("" + send +""); else out.write(" "); if (cfg.getSendTo() != null) diff --git a/core/java/src/net/i2p/data/TunnelId.java b/core/java/src/net/i2p/data/TunnelId.java index 0d5de2e732..bdb2dec685 100644 --- a/core/java/src/net/i2p/data/TunnelId.java +++ b/core/java/src/net/i2p/data/TunnelId.java @@ -22,9 +22,15 @@ import java.io.OutputStream; * as the DatabaseStoreMessage uses a zero ID to request * a direct reply. * + * 4 bytes, usually of random data. + * + * Not recommended for external use, subject to change. + * + * As of 0.9.48, does NOT extend DataStructureImpl, to save space + * * @author jrandom */ -public class TunnelId extends DataStructureImpl { +public class TunnelId { private long _tunnelId; public static final long MAX_ID_VALUE = 0xffffffffL; @@ -62,26 +68,6 @@ public class TunnelId extends DataStructureImpl { DataHelper.writeLong(out, 4, _tunnelId); } - /** - * Overridden for efficiency. - */ - @Override - public byte[] toByteArray() { - return DataHelper.toLong(4, _tunnelId); - } - - /** - * Overridden for efficiency. - * @param data non-null - * @throws DataFormatException if null or wrong length - */ - @Override - public void fromByteArray(byte data[]) throws DataFormatException { - if (data == null) throw new DataFormatException("Null data passed in"); - if (data.length != 4) throw new DataFormatException("Bad data length"); - _tunnelId = (int) DataHelper.fromLong(data, 0, 4); - } - @Override public boolean equals(Object obj) { if (obj == this) return true; diff --git a/core/java/test/junit/net/i2p/data/TunnelIdTest.java b/core/java/test/junit/net/i2p/data/TunnelIdTest.java index 1926ed8123..ffa9f303d6 100644 --- a/core/java/test/junit/net/i2p/data/TunnelIdTest.java +++ b/core/java/test/junit/net/i2p/data/TunnelIdTest.java @@ -16,9 +16,21 @@ package net.i2p.data; */ public class TunnelIdTest extends StructureTest { public DataStructure createDataStructure() throws DataFormatException { - TunnelId id = new TunnelId(); + TunnelIdStructure id = new TunnelIdStructure(); id.setTunnelId(42); return id; } - public DataStructure createStructureToRead() { return new TunnelId(); } + public DataStructure createStructureToRead() { return new TunnelIdStructure(); } + + /** + * so we can test it as a structure + * @since 0.9.48 TunnelId no longer extends DataStructureImpl + */ + private class TunnelIdStructure extends TunnelId implements DataStructure { + public Hash calculateHash() { return null; } + public void fromByteArray(byte[] in) {} + public byte[] toByteArray() { return null; } + public void fromBase64(String in) {} + public String toBase64() { return null; } + } } diff --git a/router/java/src/net/i2p/router/tunnel/BatchedRouterPreprocessor.java b/router/java/src/net/i2p/router/tunnel/BatchedRouterPreprocessor.java index be7cb5e1a9..aea80b2044 100644 --- a/router/java/src/net/i2p/router/tunnel/BatchedRouterPreprocessor.java +++ b/router/java/src/net/i2p/router/tunnel/BatchedRouterPreprocessor.java @@ -48,20 +48,24 @@ class BatchedRouterPreprocessor extends BatchedPreprocessor { private static String getName(HopConfig cfg) { if (cfg == null) return "IB??"; - if (cfg.getReceiveTunnel() != null) - return "IB " + cfg.getReceiveTunnel().getTunnelId(); - else if (cfg.getSendTunnel() != null) - return "IB " + cfg.getSendTunnel().getTunnelId(); + long id = cfg.getReceiveTunnelId(); + if (id != 0) + return "IB " + id; + id = cfg.getSendTunnelId(); + if (id != 0) + return "IB " + id; else return "IB??"; } private static String getName(TunnelCreatorConfig cfg) { if (cfg == null) return "OB??"; - if (cfg.getReceiveTunnelId(0) != null) - return "OB " + cfg.getReceiveTunnelId(0).getTunnelId(); - else if (cfg.getSendTunnelId(0) != null) - return "OB " + cfg.getSendTunnelId(0).getTunnelId(); + long id = cfg.getConfig(0).getReceiveTunnelId(); + if (id != 0) + return "OB " + id; + id = cfg.getConfig(0).getSendTunnelId(); + if (id != 0) + return "OB " + id; else return "OB??"; } diff --git a/router/java/src/net/i2p/router/tunnel/HopConfig.java b/router/java/src/net/i2p/router/tunnel/HopConfig.java index e1dc40b777..20d411fb80 100644 --- a/router/java/src/net/i2p/router/tunnel/HopConfig.java +++ b/router/java/src/net/i2p/router/tunnel/HopConfig.java @@ -15,10 +15,8 @@ import net.i2p.data.TunnelId; * TunnelCreatorConfig to save space. */ public class HopConfig { - private byte _receiveTunnelId[]; private TunnelId _receiveTunnel; private Hash _receiveFrom; - private byte _sendTunnelId[]; private TunnelId _sendTunnel; private Hash _sendTo; private SessionKey _layerKey; @@ -42,41 +40,67 @@ public class HopConfig { _expiration = -1; } - /** what tunnel ID are we receiving on? */ - public byte[] getReceiveTunnelId() { return _receiveTunnelId; } + /** + * What tunnel ID are we receiving on? (0 if uninitialized) + */ + public long getReceiveTunnelId() { return (_receiveTunnel != null) ? _receiveTunnel.getTunnelId() : 0; } + + /** + * What tunnel ID are we receiving on? (null if uninitialized) + */ public TunnelId getReceiveTunnel() { - if (_receiveTunnel == null) - _receiveTunnel = getTunnel(_receiveTunnelId); return _receiveTunnel; } - public void setReceiveTunnelId(byte id[]) { _receiveTunnelId = id; } - public void setReceiveTunnelId(TunnelId id) { _receiveTunnelId = DataHelper.toLong(4, id.getTunnelId()); } - + public void setReceiveTunnelId(TunnelId id) { _receiveTunnel = id; } + + /** + * @param id 1 to 0xffffffff + * @throws IllegalArgumentException if less than or equal to zero or greater than max value + * @since 0.9.48 + */ + public void setReceiveTunnelId(long id) { _receiveTunnel = new TunnelId(id); } + /** what is the previous peer in the tunnel (null if gateway) */ public Hash getReceiveFrom() { return _receiveFrom; } + + /** + * Do not set for gateway + */ public void setReceiveFrom(Hash from) { _receiveFrom = from; } - /** what is the next tunnel ID we are sending to? (null if endpoint) */ - public byte[] getSendTunnelId() { return _sendTunnelId; } + /** + * What is the next tunnel ID we are sending to? (0 if endpoint) + */ + public long getSendTunnelId() { return (_sendTunnel != null) ? _sendTunnel.getTunnelId() : 0; } - /** what is the next tunnel we are sending to? (null if endpoint) */ + /** + * What is the next tunnel ID we are sending to? (null if endpoint) + */ public TunnelId getSendTunnel() { - if (_sendTunnel == null) - _sendTunnel = getTunnel(_sendTunnelId); return _sendTunnel; } - public void setSendTunnelId(byte id[]) { _sendTunnelId = id; } - - private static TunnelId getTunnel(byte id[]) { - if (id == null) - return null; - else - return new TunnelId(DataHelper.fromLong(id, 0, id.length)); - } + + /** + * Do not set for endpoint + * @since 0.9.48 + */ + public void setSendTunnelId(TunnelId id) { _sendTunnel = id; } + + /** + * Do not set for endpoint + * @param id 1 to 0xffffffff + * @throws IllegalArgumentException if less than or equal to zero or greater than max value + * @since 0.9.48 + */ + public void setSendTunnelId(long id) { _sendTunnel = new TunnelId(id); } /** what is the next peer in the tunnel (null if endpoint) */ public Hash getSendTo() { return _sendTo; } + + /** + * Do not set for endpoint + */ public void setSendTo(Hash to) { _sendTo = to; } /** what key should we use to encrypt the layer before passing it on? */ @@ -156,16 +180,16 @@ public class HopConfig { @Override public String toString() { StringBuilder buf = new StringBuilder(64); - if (_receiveTunnelId != null) { + if (_receiveTunnel != null) { buf.append("recv on "); - buf.append(DataHelper.fromLong(_receiveTunnelId, 0, 4)); + buf.append(_receiveTunnel.getTunnelId()); buf.append(' '); } if (_sendTo != null) { buf.append("send to ").append(_sendTo.toBase64().substring(0,4)).append(":"); - if (_sendTunnelId != null) - buf.append(DataHelper.fromLong(_sendTunnelId, 0, 4)); + if (_sendTunnel != null) + buf.append(_sendTunnel.getTunnelId()); } buf.append(" exp. ").append(new Date(_expiration)); diff --git a/router/java/src/net/i2p/router/tunnel/OutboundTunnelEndpoint.java b/router/java/src/net/i2p/router/tunnel/OutboundTunnelEndpoint.java index 0b5a9999f3..af5b908f44 100644 --- a/router/java/src/net/i2p/router/tunnel/OutboundTunnelEndpoint.java +++ b/router/java/src/net/i2p/router/tunnel/OutboundTunnelEndpoint.java @@ -79,6 +79,6 @@ class OutboundTunnelEndpoint { /** @since 0.9.8 */ @Override public String toString() { - return "OBEP " + _config.getReceiveTunnel(); + return "OBEP " + _config.getReceiveTunnelId(); } } diff --git a/router/java/src/net/i2p/router/tunnel/ThrottledPumpedTunnelGateway.java b/router/java/src/net/i2p/router/tunnel/ThrottledPumpedTunnelGateway.java index 388fedc979..f46f9d767a 100644 --- a/router/java/src/net/i2p/router/tunnel/ThrottledPumpedTunnelGateway.java +++ b/router/java/src/net/i2p/router/tunnel/ThrottledPumpedTunnelGateway.java @@ -48,6 +48,6 @@ class ThrottledPumpedTunnelGateway extends PumpedTunnelGateway { /** @since 0.9.8 */ @Override public String toString() { - return "IBGW " + _config.getReceiveTunnel(); + return "IBGW " + _config.getReceiveTunnelId(); } } diff --git a/router/java/src/net/i2p/router/tunnel/TunnelCreatorConfig.java b/router/java/src/net/i2p/router/tunnel/TunnelCreatorConfig.java index fb8bb6cdb7..a6716f04e4 100644 --- a/router/java/src/net/i2p/router/tunnel/TunnelCreatorConfig.java +++ b/router/java/src/net/i2p/router/tunnel/TunnelCreatorConfig.java @@ -96,19 +96,21 @@ public abstract class TunnelCreatorConfig implements TunnelInfo { * hop 0. */ public HopConfig getConfig(int hop) { return _config[hop]; } + /** * retrieve the tunnelId that the given hop receives messages on. * the gateway is hop 0. * */ public TunnelId getReceiveTunnelId(int hop) { return _config[hop].getReceiveTunnel(); } + /** * retrieve the tunnelId that the given hop sends messages on. * the gateway is hop 0. * */ public TunnelId getSendTunnelId(int hop) { return _config[hop].getSendTunnel(); } - + /** retrieve the peer at the given hop. the gateway is hop 0 */ public Hash getPeer(int hop) { return _peers[hop]; } public void setPeer(int hop, Hash peer) { _peers[hop] = peer; } @@ -354,13 +356,15 @@ public abstract class TunnelCreatorConfig implements TunnelInfo { for (int i = 0; i < _peers.length; i++) { buf.append(_peers[i].toBase64().substring(0,4)); buf.append(isEC(i) ? " EC:" : " ElG:"); - if (_config[i].getReceiveTunnel() != null) - buf.append(_config[i].getReceiveTunnel()); + long id = _config[i].getReceiveTunnelId(); + if (id != 0) + buf.append(id); else buf.append("me"); - if (_config[i].getSendTunnel() != null) { + id = _config[i].getSendTunnelId(); + if (id != 0) { buf.append('.'); - buf.append(_config[i].getSendTunnel()); + buf.append(id); } else if (_isInbound || i == 0) { buf.append(".me"); } diff --git a/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java b/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java index fbd2bcd062..63c31a121d 100644 --- a/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java +++ b/router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java @@ -392,13 +392,13 @@ public class TunnelDispatcher implements Service { * does not fully prevent joinOutbound() from failing later. * @since 0.9.5 */ - public long getNewOBGWID() { - long rv; - TunnelId tid; + public TunnelId getNewOBGWID() { + long id; + TunnelId rv; do { - rv = 1 + _context.random().nextLong(TunnelId.MAX_ID_VALUE); - tid = new TunnelId(rv); - } while (_outboundGateways.containsKey(tid)); + id = 1 + _context.random().nextLong(TunnelId.MAX_ID_VALUE); + rv = new TunnelId(id); + } while (_outboundGateways.containsKey(rv)); return rv; } @@ -409,13 +409,13 @@ public class TunnelDispatcher implements Service { * does not fully prevent joinInbound() from failing later. * @since 0.9.5 */ - public long getNewIBEPID() { - long rv; - TunnelId tid; + public TunnelId getNewIBEPID() { + long id; + TunnelId rv; do { - rv = 1 + _context.random().nextLong(TunnelId.MAX_ID_VALUE); - tid = new TunnelId(rv); - } while (_participants.containsKey(tid)); + id = 1 + _context.random().nextLong(TunnelId.MAX_ID_VALUE); + rv = new TunnelId(id); + } while (_participants.containsKey(rv)); return rv; } @@ -426,13 +426,13 @@ public class TunnelDispatcher implements Service { * does not fully prevent joinInbound() from failing later. * @since 0.9.5 */ - public long getNewIBZeroHopID() { - long rv; - TunnelId tid; + public TunnelId getNewIBZeroHopID() { + long id; + TunnelId rv; do { - rv = 1 + _context.random().nextLong(TunnelId.MAX_ID_VALUE); - tid = new TunnelId(rv); - } while (_inboundGateways.containsKey(tid)); + id = 1 + _context.random().nextLong(TunnelId.MAX_ID_VALUE); + rv = new TunnelId(id); + } while (_inboundGateways.containsKey(rv)); return rv; } diff --git a/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java b/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java index 791ed87984..39a92abd90 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java +++ b/router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java @@ -864,14 +864,14 @@ class BuildHandler implements Runnable { return; } } - cfg.setReceiveTunnelId(DataHelper.toLong(4, ourId)); + cfg.setReceiveTunnelId(ourId); if (isOutEnd) { // default //cfg.setSendTo(null); //cfg.setSendTunnelId(null); } else { cfg.setSendTo(nextPeer); - cfg.setSendTunnelId(DataHelper.toLong(4, nextId)); + cfg.setSendTunnelId(nextId); } // now "actually" join diff --git a/router/java/src/net/i2p/router/tunnel/pool/BuildRequestor.java b/router/java/src/net/i2p/router/tunnel/pool/BuildRequestor.java index 9c4891c866..e158dda4d3 100644 --- a/router/java/src/net/i2p/router/tunnel/pool/BuildRequestor.java +++ b/router/java/src/net/i2p/router/tunnel/pool/BuildRequestor.java @@ -89,18 +89,18 @@ abstract class BuildRequestor { if ( (!isIB) && (i == 0) ) { // outbound gateway (us) doesn't receive on a tunnel id if (len <= 1) { // zero hop, pretend to have a send id - long id = ctx.tunnelDispatcher().getNewOBGWID(); - hop.setSendTunnelId(DataHelper.toLong(4, id)); + TunnelId id = ctx.tunnelDispatcher().getNewOBGWID(); + hop.setSendTunnelId(id); } } else { - long id; + TunnelId id; if (isIB && len == 1) id = ctx.tunnelDispatcher().getNewIBZeroHopID(); else if (isIB && i == len - 1) id = ctx.tunnelDispatcher().getNewIBEPID(); else - id = 1 + ctx.random().nextLong(TunnelId.MAX_ID_VALUE); - hop.setReceiveTunnelId(DataHelper.toLong(4, id)); + id = new TunnelId(1 + ctx.random().nextLong(TunnelId.MAX_ID_VALUE)); + hop.setReceiveTunnelId(id); } if (i > 0) diff --git a/router/java/test/junit/net/i2p/router/tunnel/InboundTest.java b/router/java/test/junit/net/i2p/router/tunnel/InboundTest.java index 4f0b829555..af36d454d6 100644 --- a/router/java/test/junit/net/i2p/router/tunnel/InboundTest.java +++ b/router/java/test/junit/net/i2p/router/tunnel/InboundTest.java @@ -14,6 +14,7 @@ import static org.junit.Assert.assertTrue; import net.i2p.data.DataHelper; import net.i2p.data.Hash; +import net.i2p.data.TunnelId; import net.i2p.router.RouterContext; /** @@ -56,12 +57,12 @@ public class InboundTest extends TestCase { private TunnelCreatorConfig prepareConfig(int numHops) { Hash peers[] = new Hash[numHops]; - byte tunnelIds[][] = new byte[numHops][4]; + long tunnelIds[] = new long[numHops]; for (int i = 0; i < numHops; i++) { peers[i] = new Hash(); peers[i].setData(new byte[Hash.HASH_LENGTH]); _context.random().nextBytes(peers[i].getData()); - _context.random().nextBytes(tunnelIds[i]); + tunnelIds[i] = 1 + _context.random().nextLong(TunnelId.MAX_ID_VALUE); } TunnelCreatorConfig config = new TCConfig(_context, numHops, false); @@ -73,15 +74,10 @@ public class InboundTest extends TestCase { cfg.setLayerKey(_context.keyGenerator().generateSessionKey()); if (i > 0) cfg.setReceiveFrom(peers[i-1]); - else - cfg.setReceiveFrom(null); cfg.setReceiveTunnelId(tunnelIds[i]); if (i < numHops - 1) { cfg.setSendTo(peers[i+1]); cfg.setSendTunnelId(tunnelIds[i+1]); - } else { - cfg.setSendTo(null); - cfg.setSendTunnelId(null); } } return config; diff --git a/router/java/test/junit/net/i2p/router/tunnel/OutboundTest.java b/router/java/test/junit/net/i2p/router/tunnel/OutboundTest.java index f352d2e337..624246204b 100644 --- a/router/java/test/junit/net/i2p/router/tunnel/OutboundTest.java +++ b/router/java/test/junit/net/i2p/router/tunnel/OutboundTest.java @@ -12,6 +12,7 @@ import junit.framework.TestCase; import net.i2p.data.DataHelper; import net.i2p.data.Hash; +import net.i2p.data.TunnelId; import net.i2p.router.RouterContext; /** @@ -55,12 +56,12 @@ public class OutboundTest extends TestCase{ private TunnelCreatorConfig prepareConfig(int numHops) { Hash peers[] = new Hash[numHops]; - byte tunnelIds[][] = new byte[numHops][4]; + long tunnelIds[] = new long[numHops]; for (int i = 0; i < numHops; i++) { peers[i] = new Hash(); peers[i].setData(new byte[Hash.HASH_LENGTH]); _context.random().nextBytes(peers[i].getData()); - _context.random().nextBytes(tunnelIds[i]); + tunnelIds[i] = 1 + _context.random().nextLong(TunnelId.MAX_ID_VALUE); } TunnelCreatorConfig config = new TCConfig(_context, numHops, false); @@ -72,15 +73,10 @@ public class OutboundTest extends TestCase{ cfg.setLayerKey(_context.keyGenerator().generateSessionKey()); if (i > 0) cfg.setReceiveFrom(peers[i-1]); - else - cfg.setReceiveFrom(null); cfg.setReceiveTunnelId(tunnelIds[i]); if (i < numHops - 1) { cfg.setSendTo(peers[i+1]); cfg.setSendTunnelId(tunnelIds[i+1]); - } else { - cfg.setSendTo(null); - cfg.setSendTunnelId(null); } } return config; diff --git a/router/java/test/junit/net/i2p/router/tunnel/RouterITBase.java b/router/java/test/junit/net/i2p/router/tunnel/RouterITBase.java index 7d70ff4c0b..d677cd3e5d 100644 --- a/router/java/test/junit/net/i2p/router/tunnel/RouterITBase.java +++ b/router/java/test/junit/net/i2p/router/tunnel/RouterITBase.java @@ -1,6 +1,7 @@ package net.i2p.router.tunnel; import net.i2p.data.Hash; +import net.i2p.data.TunnelId; import net.i2p.data.router.RouterIdentity; import net.i2p.data.router.RouterInfo; import net.i2p.router.Router; @@ -34,12 +35,12 @@ public abstract class RouterITBase { private static TunnelCreatorConfig prepareConfig(int numHops) { Hash peers[] = new Hash[numHops]; - byte tunnelIds[][] = new byte[numHops][4]; + long tunnelIds[] = new long[numHops]; for (int i = 0; i < numHops; i++) { peers[i] = new Hash(); peers[i].setData(new byte[Hash.HASH_LENGTH]); _context.random().nextBytes(peers[i].getData()); - _context.random().nextBytes(tunnelIds[i]); + tunnelIds[i] = 1 + _context.random().nextLong(TunnelId.MAX_ID_VALUE); } TunnelCreatorConfig config = new TCConfig(_context, numHops, false); @@ -51,15 +52,10 @@ public abstract class RouterITBase { cfg.setLayerKey(_context.keyGenerator().generateSessionKey()); if (i > 0) cfg.setReceiveFrom(peers[i-1]); - else - cfg.setReceiveFrom(null); cfg.setReceiveTunnelId(tunnelIds[i]); if (i < numHops - 1) { cfg.setSendTo(peers[i+1]); cfg.setSendTunnelId(tunnelIds[i+1]); - } else { - cfg.setSendTo(null); - cfg.setSendTunnelId(null); } } return config;