From 9d5e8dd785584cac0d76e3c34c343e272453d2ba Mon Sep 17 00:00:00 2001
From: zzz <zzz@mail.i2p>
Date: Wed, 20 Jan 2016 16:44:40 +0000
Subject: [PATCH] make network ID configurable for testing

---
 router/java/src/net/i2p/router/Router.java    | 20 ++++++++++++++++++-
 .../src/net/i2p/router/StatisticsManager.java |  4 +++-
 .../FloodfillNetworkDatabaseFacade.java       |  2 +-
 .../KademliaNetworkDatabaseFacade.java        |  4 +++-
 .../kademlia/PersistentDataStore.java         |  4 +++-
 .../transport/udp/EstablishmentManager.java   |  6 ++++--
 .../router/transport/udp/UDPTransport.java    |  4 +++-
 7 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java
index 410890547a..03183a9949 100644
--- a/router/java/src/net/i2p/router/Router.java
+++ b/router/java/src/net/i2p/router/Router.java
@@ -100,7 +100,9 @@ public class Router implements RouterClock.ClockShiftListener {
     public final static long CLOCK_FUDGE_FACTOR = 1*60*1000; 
 
     /** used to differentiate routerInfo files on different networks */
-    public static final int NETWORK_ID = 2;
+    private static final int DEFAULT_NETWORK_ID = 2;
+    private static final String PROP_NETWORK_ID = "router.networkID";
+    private final int _networkID;
     
     /** coalesce stats this often - should be a little less than one minute, so the graphs get updated */
     public static final int COALESCE_TIME = 50*1000;
@@ -347,6 +349,14 @@ public class Router implements RouterClock.ClockShiftListener {
             _config.put("router.previousVersion", RouterVersion.VERSION);
             saveConfig();
         }
+        int id = DEFAULT_NETWORK_ID;
+        String sid = _config.get(PROP_NETWORK_ID);
+        if (sid != null) {
+            try {
+                id = Integer.parseInt(sid);
+            } catch (NumberFormatException nfe) {}
+        }
+        _networkID = id;
         changeState(State.INITIALIZED);
         // *********  Start no threads before here ********* //
     }
@@ -536,6 +546,14 @@ public class Router implements RouterClock.ClockShiftListener {
         if (_started <= 0) return 1000; // racing on startup
         return Math.max(1000, System.currentTimeMillis() - _started);
     }
+
+    /**
+     *  The network ID. Default 2.
+     *  May be changed with the config property router.networkID (restart required).
+     *  Change only if running a test network to prevent cross-network contamination.
+     *  @since 0.9.25
+     */
+    public int getNetworkID() { return _networkID; }
     
     /**
      *  Non-null, but take care when accessing context items before runRouter() is called
diff --git a/router/java/src/net/i2p/router/StatisticsManager.java b/router/java/src/net/i2p/router/StatisticsManager.java
index 21e0813cc3..9379df3504 100644
--- a/router/java/src/net/i2p/router/StatisticsManager.java
+++ b/router/java/src/net/i2p/router/StatisticsManager.java
@@ -32,6 +32,7 @@ import net.i2p.util.Log;
 public class StatisticsManager {
     private final Log _log;
     private final RouterContext _context;
+    private final String _networkID;
     
     public final static String PROP_PUBLISH_RANKINGS = "router.publishPeerRankings";
     private static final String PROP_CONTACT_NAME = "netdb.contact";
@@ -46,6 +47,7 @@ public class StatisticsManager {
         _fmt = new DecimalFormat("###,##0.00", new DecimalFormatSymbols(Locale.UK));
         _pct = new DecimalFormat("#0.00%", new DecimalFormatSymbols(Locale.UK));
         _log = context.logManager().getLog(StatisticsManager.class);
+        _networkID = Integer.toString(context.router().getNetworkID());
     }
         
     /**
@@ -72,7 +74,7 @@ public class StatisticsManager {
         // scheduled for removal, never used
         if (CoreVersion.VERSION.equals("0.9.23"))
             stats.setProperty("coreVersion", CoreVersion.VERSION);
-        stats.setProperty(RouterInfo.PROP_NETWORK_ID, Integer.toString(Router.NETWORK_ID));
+        stats.setProperty(RouterInfo.PROP_NETWORK_ID, _networkID);
         stats.setProperty(RouterInfo.PROP_CAPABILITIES, _context.router().getCapabilities());
 
         // No longer expose, to make build tracking more expensive
diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillNetworkDatabaseFacade.java b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillNetworkDatabaseFacade.java
index 0df3b32902..5e66134f15 100644
--- a/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillNetworkDatabaseFacade.java
+++ b/router/java/src/net/i2p/router/networkdb/kademlia/FloodfillNetworkDatabaseFacade.java
@@ -479,7 +479,7 @@ public class FloodfillNetworkDatabaseFacade extends KademliaNetworkDatabaseFacad
         // drop the peer in these cases
         // yikes don't do this - stack overflow //  getFloodfillPeers().size() == 0 ||
         // yikes2 don't do this either - deadlock! // getKnownRouters() < MIN_REMAINING_ROUTERS ||
-        if (info.getNetworkId() == Router.NETWORK_ID &&
+        if (info.getNetworkId() == _networkID &&
             (getKBucketSetSize() < MIN_REMAINING_ROUTERS ||
              _context.router().getUptime() < DONT_FAIL_PERIOD ||
              _context.commSystem().countActivePeers() <= MIN_ACTIVE_PEERS)) {
diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java b/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java
index ea0aa69084..f1b13aefe8 100644
--- a/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java
+++ b/router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java
@@ -70,6 +70,7 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
     private final ReseedChecker _reseedChecker;
     private volatile long _lastRIPublishTime;
     private NegativeLookupCache _negativeCache;
+    protected final int _networkID;
 
     /** 
      * Map of Hash to RepublishLeaseSetJob for leases we'realready managing.
@@ -156,6 +157,7 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
     public KademliaNetworkDatabaseFacade(RouterContext context) {
         _context = context;
         _log = _context.logManager().getLog(getClass());
+        _networkID = context.router().getNetworkID();
         _peerSelector = createPeerSelector();
         _publishingLeaseSets = new HashMap<Hash, RepublishLeaseSetJob>(8);
         _activeRequests = new HashMap<Hash, SearchJob>(8);
@@ -889,7 +891,7 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
                 _log.warn("Invalid routerInfo signature!  forged router structure!  router = " + routerInfo);
             return "Invalid routerInfo signature";
         }
-        if (routerInfo.getNetworkId() != Router.NETWORK_ID){
+        if (routerInfo.getNetworkId() != _networkID){
             _context.banlist().banlistRouter(key, "Not in our network");
             if (_log.shouldLog(Log.WARN))
                 _log.warn("Bad network: " + routerInfo);
diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java b/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java
index 80aae33e2d..b1bbcf0654 100644
--- a/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java
+++ b/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java
@@ -54,6 +54,7 @@ public class PersistentDataStore extends TransientDataStore {
     private final ReadJob _readJob;
     private volatile boolean _initialized;
     private final boolean _flat;
+    private final int _networkID;
     
     private final static int READ_DELAY = 2*60*1000;
     private static final String PROP_FLAT = "router.networkDatabase.flat";
@@ -65,6 +66,7 @@ public class PersistentDataStore extends TransientDataStore {
      */
     public PersistentDataStore(RouterContext ctx, String dbDir, KademliaNetworkDatabaseFacade facade) throws IOException {
         super(ctx);
+        _networkID = ctx.router().getNetworkID();
         _flat = ctx.getBooleanProperty(PROP_FLAT);
         _dbDir = getDbDir(dbDir);
         _facade = facade;
@@ -505,7 +507,7 @@ public class PersistentDataStore extends TransientDataStore {
                     fis = new BufferedInputStream(fis);
                     RouterInfo ri = new RouterInfo();
                     ri.readBytes(fis, true);  // true = verify sig on read
-                    if (ri.getNetworkId() != Router.NETWORK_ID) {
+                    if (ri.getNetworkId() != _networkID) {
                         corrupt = true;
                         if (_log.shouldLog(Log.ERROR))
                             _log.error("The router "
diff --git a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java
index 0fd9c83af9..60718e8f5b 100644
--- a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java
+++ b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java
@@ -42,6 +42,7 @@ class EstablishmentManager {
     private final Log _log;
     private final UDPTransport _transport;
     private final PacketBuilder _builder;
+    private final int _networkID;
 
     /** map of RemoteHostId to InboundEstablishState */
     private final ConcurrentHashMap<RemoteHostId, InboundEstablishState> _inboundStates;
@@ -143,6 +144,7 @@ class EstablishmentManager {
     public EstablishmentManager(RouterContext ctx, UDPTransport transport) {
         _context = ctx;
         _log = ctx.logManager().getLog(EstablishmentManager.class);
+        _networkID = ctx.router().getNetworkID();
         _transport = transport;
         _builder = new PacketBuilder(ctx, transport);
         _inboundStates = new ConcurrentHashMap<RemoteHostId, InboundEstablishState>();
@@ -252,7 +254,7 @@ class EstablishmentManager {
         }
         RouterIdentity toIdentity = toRouterInfo.getIdentity();
         Hash toHash = toIdentity.calculateHash();
-        if (toRouterInfo.getNetworkId() != Router.NETWORK_ID) {
+        if (toRouterInfo.getNetworkId() != _networkID) {
             _context.banlist().banlistRouter(toHash);
             _transport.markUnreachable(toHash);
             _transport.failed(msg, "Remote peer is on the wrong network, cannot establish");
@@ -765,7 +767,7 @@ class EstablishmentManager {
         if (_log.shouldLog(Log.INFO))
             _log.info("Completing to the peer after IB confirm: " + peer);
         DeliveryStatusMessage dsm = new DeliveryStatusMessage(_context);
-        dsm.setArrival(Router.NETWORK_ID); // overloaded, sure, but future versions can check this
+        dsm.setArrival(_networkID); // overloaded, sure, but future versions can check this
                                            // This causes huge values in the inNetPool.droppedDeliveryStatusDelay stat
                                            // so it needs to be caught in InNetMessagePool.
         dsm.setMessageExpiration(_context.clock().now() + DATA_MESSAGE_TIMEOUT);
diff --git a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java
index f0fa96e2b5..0202ee39fa 100644
--- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java
+++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java
@@ -87,6 +87,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
     private int _mtu;
     private int _mtu_ipv6;
     private boolean _mismatchLogged;
+    private final int _networkID;
 
     /**
      *  Do we have a public IPv6 address?
@@ -218,6 +219,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
 
     public UDPTransport(RouterContext ctx, DHSessionKeyBuilder.Factory dh) {
         super(ctx);
+        _networkID = ctx.router().getNetworkID();
         _dhFactory = dh;
         _log = ctx.logManager().getLog(UDPTransport.class);
         _peersByIdent = new ConcurrentHashMap<Hash, PeerState>(128);
@@ -1289,7 +1291,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
             if (entry == null)
                 return;
             if (entry.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO &&
-                ((RouterInfo) entry).getNetworkId() != Router.NETWORK_ID) {
+                ((RouterInfo) entry).getNetworkId() != _networkID) {
                 // this is pre-0.6.1.10, so it isn't going to happen any more
 
                 /*
-- 
GitLab