From 5694206b35909dff37daf4a636899b93fb06444e Mon Sep 17 00:00:00 2001
From: jrandom <jrandom>
Date: Tue, 13 Sep 2005 23:02:35 +0000
Subject: [PATCH] 2005-09-13  jrandom     * More careful error handling with
 introductions (thanks dust!)     * Fix the forceIntroducers checkbox on
 config.jsp (thanks Complication!)     * Hide the shitlist on the summary so
 it doesn't confuse new users.

---
 .../net/i2p/router/web/ConfigNetHelper.java   |  5 ++
 apps/routerconsole/jsp/summary.jsp            |  2 +-
 history.txt                                   |  7 +-
 .../src/net/i2p/router/RouterVersion.java     |  4 +-
 .../transport/udp/EstablishmentManager.java   | 64 +++++++++++--------
 .../router/transport/udp/PacketBuilder.java   | 11 +++-
 .../router/transport/udp/PeerTestManager.java |  2 +-
 .../i2p/router/transport/udp/UDPAddress.java  |  1 +
 .../router/transport/udp/UDPTransport.java    |  7 +-
 .../i2p/router/tunnel/FragmentHandler.java    | 10 +++
 10 files changed, 79 insertions(+), 34 deletions(-)

diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHelper.java
index 12df19d01b..c5ebb16cf9 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHelper.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHelper.java
@@ -5,6 +5,7 @@ import net.i2p.router.RouterContext;
 import net.i2p.router.CommSystemFacade;
 import net.i2p.data.RouterAddress;
 import net.i2p.router.transport.udp.UDPAddress;
+import net.i2p.router.transport.udp.UDPTransport;
 
 public class ConfigNetHelper {
     private RouterContext _context;
@@ -66,11 +67,15 @@ public class ConfigNetHelper {
         short status = _context.commSystem().getReachabilityStatus();
         switch (status) {
             case CommSystemFacade.STATUS_OK:
+                if ("true".equalsIgnoreCase(_context.getProperty(UDPTransport.PROP_FORCE_INTRODUCERS, "false")))
+                    return "checked=\"true\"";
                 return "";
             case CommSystemFacade.STATUS_DIFFERENT:
             case CommSystemFacade.STATUS_REJECT_UNSOLICITED:
                 return "checked=\"true\"";
             case CommSystemFacade.STATUS_UNKNOWN:
+                if ("true".equalsIgnoreCase(_context.getProperty(UDPTransport.PROP_FORCE_INTRODUCERS, "false")))
+                    return "checked=\"true\"";
                 return "";
             default:
                 return "checked=\"true\"";
diff --git a/apps/routerconsole/jsp/summary.jsp b/apps/routerconsole/jsp/summary.jsp
index 4fa834e5aa..8fb1bf414e 100644
--- a/apps/routerconsole/jsp/summary.jsp
+++ b/apps/routerconsole/jsp/summary.jsp
@@ -40,7 +40,7 @@
  <b>High capacity:</b> <jsp:getProperty name="helper" property="highCapacityPeers" /><br />
  <b>Well integrated:</b> <jsp:getProperty name="helper" property="wellIntegratedPeers" /><br />
  <b>Failing:</b> <jsp:getProperty name="helper" property="failingPeers" /><br />
- <b>Shitlisted:</b> <jsp:getProperty name="helper" property="shitlistedPeers" /><br />
+ <!-- <b>Shitlisted:</b> <jsp:getProperty name="helper" property="shitlistedPeers" /><br /> -->
  <b>Known:</b> <jsp:getProperty name="helper" property="allPeers" /><br /><%
      if (helper.getActivePeers() <= 0) {
         %><b><a href="config.jsp">check your NAT/firewall</a></b><br /><%
diff --git a/history.txt b/history.txt
index ebebc0339a..7efc7ee060 100644
--- a/history.txt
+++ b/history.txt
@@ -1,4 +1,9 @@
-$Id: history.txt,v 1.247 2005/09/12 22:32:30 jrandom Exp $
+$Id: history.txt,v 1.248 2005/09/13 04:06:07 comwiz Exp $
+
+2005-09-13  jrandom
+    * More careful error handling with introductions (thanks dust!)
+    * Fix the forceIntroducers checkbox on config.jsp (thanks Complication!)
+    * Hide the shitlist on the summary so it doesn't confuse new users.
 
 2005-09-12  comwiz
     * Migrated the router tests to junit
diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java
index 4384bda4db..6efac71996 100644
--- a/router/java/src/net/i2p/router/RouterVersion.java
+++ b/router/java/src/net/i2p/router/RouterVersion.java
@@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
  *
  */
 public class RouterVersion {
-    public final static String ID = "$Revision: 1.233 $ $Date: 2005/09/12 20:12:43 $";
+    public final static String ID = "$Revision: 1.234 $ $Date: 2005/09/12 22:32:30 $";
     public final static String VERSION = "0.6.0.5";
-    public final static long BUILD = 8;
+    public final static long BUILD = 9;
     public static void main(String args[]) {
         System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
         System.out.println("Router ID: " + RouterVersion.ID);
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 62acf62567..1679b42564 100644
--- a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java
+++ b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java
@@ -764,36 +764,46 @@ public class EstablishmentManager {
     private class Establisher implements Runnable {
         public void run() {
             while (_alive) {
-                _activity = 0;
-                long now = _context.clock().now();
-                long nextSendTime = -1;
-                long nextSendInbound = handleInbound();
-                long nextSendOutbound = handleOutbound();
-                if (nextSendInbound > 0)
-                    nextSendTime = nextSendInbound;
-                if ( (nextSendTime < 0) || (nextSendOutbound < nextSendTime) )
-                    nextSendTime = nextSendOutbound;
+                try {
+                    doPass();
+                } catch (OutOfMemoryError oom) {
+                    throw oom;
+                } catch (RuntimeException re) {
+                    _log.log(Log.CRIT, "Error in the establisher", re);
+                }
+            }
+        }
+    }
+    
+    private void doPass() {
+        _activity = 0;
+        long now = _context.clock().now();
+        long nextSendTime = -1;
+        long nextSendInbound = handleInbound();
+        long nextSendOutbound = handleOutbound();
+        if (nextSendInbound > 0)
+            nextSendTime = nextSendInbound;
+        if ( (nextSendTime < 0) || (nextSendOutbound < nextSendTime) )
+            nextSendTime = nextSendOutbound;
 
-                long delay = nextSendTime - now;
-                if ( (nextSendTime == -1) || (delay > 0) ) {
-                    boolean interrupted = false;
-                    try {
-                        synchronized (_activityLock) {
-                            if (_activity > 0)
-                                continue;
-                            if (nextSendTime == -1)
-                                _activityLock.wait();
-                            else
-                                _activityLock.wait(delay);
-                        }
-                    } catch (InterruptedException ie) {
-                        interrupted = true;
-                    }
-                    if (_log.shouldLog(Log.DEBUG))
-                        _log.debug("After waiting w/ nextSend=" + nextSendTime 
-                                   + " and delay=" + delay + " and interrupted=" + interrupted);
+        long delay = nextSendTime - now;
+        if ( (nextSendTime == -1) || (delay > 0) ) {
+            boolean interrupted = false;
+            try {
+                synchronized (_activityLock) {
+                    if (_activity > 0)
+                        return;
+                    if (nextSendTime == -1)
+                        _activityLock.wait();
+                    else
+                        _activityLock.wait(delay);
                 }
+            } catch (InterruptedException ie) {
+                interrupted = true;
             }
+            if (_log.shouldLog(Log.DEBUG))
+                _log.debug("After waiting w/ nextSend=" + nextSendTime 
+                           + " and delay=" + delay + " and interrupted=" + interrupted);
         }
     }
 }
diff --git a/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java b/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java
index 3eedc3b80d..9b0eb07689 100644
--- a/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java
+++ b/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java
@@ -641,11 +641,20 @@ public class PacketBuilder {
     
     public UDPPacket buildRelayRequest(OutboundEstablishState state, SessionKey ourIntroKey) {
         UDPAddress addr = state.getRemoteAddress();
-        int index = _context.random().nextInt(UDPAddress.MAX_INTRODUCERS) % addr.getIntroducerCount();
+        int count = addr.getIntroducerCount();
+        if (count <= 0)
+            return null;
+        int index = _context.random().nextInt(count);
         InetAddress iaddr = addr.getIntroducerHost(index);
         int iport = addr.getIntroducerPort(index);
         byte ikey[] = addr.getIntroducerKey(index);
         long tag = addr.getIntroducerTag(index);
+        if ( (ikey == null) || (iport <= 0) || (iaddr == null) || (tag <= 0) ) {
+            if (_log.shouldLog(_log.ERROR))
+                _log.error("Cannot build a relay request to " + state.getRemoteIdentity().calculateHash().toBase64() 
+                           + ", as their UDP address is invalid: addr=" + addr + " index=" + index);
+            return null;
+        }
         return buildRelayRequest(iaddr, iport, ikey, tag, ourIntroKey, state.getIntroNonce(), true);
     }
     
diff --git a/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java b/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java
index eff77968e1..66b8562448 100644
--- a/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java
+++ b/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java
@@ -422,7 +422,7 @@ class PeerTestManager {
             aliceIP = InetAddress.getByAddress(from.getIP());
             aliceIntroKey = new SessionKey(new byte[SessionKey.KEYSIZE_BYTES]);
             testInfo.readIntroKey(aliceIntroKey.getData(), 0);
-            
+
             UDPAddress addr = new UDPAddress(charlieInfo.getTargetAddress(UDPTransport.STYLE));
             SessionKey charlieIntroKey = new SessionKey(addr.getIntroKey());
             
diff --git a/router/java/src/net/i2p/router/transport/udp/UDPAddress.java b/router/java/src/net/i2p/router/transport/udp/UDPAddress.java
index bca6884b0b..2ea29a4e5b 100644
--- a/router/java/src/net/i2p/router/transport/udp/UDPAddress.java
+++ b/router/java/src/net/i2p/router/transport/udp/UDPAddress.java
@@ -61,6 +61,7 @@ public class UDPAddress {
     }
     
     private void parse(RouterAddress addr) {
+        if (addr == null) return;
         Properties opts = addr.getOptions();
         _host = opts.getProperty(PROP_HOST);
         if (_host != null) _host = _host.trim();
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 2be15f3258..a863092cb5 100644
--- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java
+++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java
@@ -1173,7 +1173,12 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
             PeerState peer = (PeerState)peers.get(i);
             if ( (dontInclude != null) && (dontInclude.equals(peer.getRemoteHostId())) )
                 continue;
-            return peer;
+            RouterInfo peerInfo = _context.netDb().lookupRouterInfoLocally(peer.getRemotePeer());
+            if (peerInfo == null)
+                continue;
+            RouterAddress addr = peerInfo.getTargetAddress(STYLE);
+            if (addr != null)
+                return peer;
         }
         return null;
     }
diff --git a/router/java/src/net/i2p/router/tunnel/FragmentHandler.java b/router/java/src/net/i2p/router/tunnel/FragmentHandler.java
index e8f81d50b4..5a0cb91f2f 100644
--- a/router/java/src/net/i2p/router/tunnel/FragmentHandler.java
+++ b/router/java/src/net/i2p/router/tunnel/FragmentHandler.java
@@ -90,6 +90,8 @@ public class FragmentHandler {
                 }
                 offset = off;
             }
+        } catch (ArrayIndexOutOfBoundsException aioobe) {
+            _context.statManager().addRateData("tunnel.corruptMessage", 1, 1);
         } catch (RuntimeException e) {
             if (_log.shouldLog(Log.ERROR))
                 _log.error("Corrupt fragment received: offset = " + offset, e);
@@ -216,17 +218,23 @@ public class FragmentHandler {
         long messageId = -1;
         
         if (type == TYPE_TUNNEL) {
+            if (offset + 4 >= preprocessed.length)
+                return -1;
             long id = DataHelper.fromLong(preprocessed, offset, 4);
             tunnelId = new TunnelId(id);
             offset += 4;
         }
         if ( (type == TYPE_ROUTER) || (type == TYPE_TUNNEL) ) {
             byte h[] = new byte[Hash.HASH_LENGTH];
+            if (offset + Hash.HASH_LENGTH >= preprocessed.length)
+                return -1;
             System.arraycopy(preprocessed, offset, h, 0, Hash.HASH_LENGTH);
             router = new Hash(h);
             offset += Hash.HASH_LENGTH;
         }
         if (fragmented) {
+            if (offset + 4 >= preprocessed.length)
+                return -1;
             messageId = DataHelper.fromLong(preprocessed, offset, 4);
             if (_log.shouldLog(Log.DEBUG))
                 _log.debug("reading messageId " + messageId + " at offset "+ offset 
@@ -241,6 +249,8 @@ public class FragmentHandler {
             offset += extendedSize; // we don't interpret these yet, but skip them for now
         }
         
+        if (offset + 2 >= preprocessed.length)
+            return -1;
         int size = (int)DataHelper.fromLong(preprocessed, offset, 2);
         offset += 2;
         
-- 
GitLab