From 7680ecbdc414ae1224fee8f6df8c68c6866a1a1c Mon Sep 17 00:00:00 2001
From: zzz <zzz@mail.i2p>
Date: Fri, 11 Dec 2015 15:28:39 +0000
Subject: [PATCH] Transport: More deadlock prevention (ticket #1722)

---
 router/java/src/net/i2p/router/Router.java          |  5 +++--
 .../src/net/i2p/router/transport/TransportImpl.java | 13 ++++++-------
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java
index 30c9b6bfd5..5817446512 100644
--- a/router/java/src/net/i2p/router/Router.java
+++ b/router/java/src/net/i2p/router/Router.java
@@ -92,6 +92,7 @@ public class Router implements RouterClock.ClockShiftListener {
     private State _state = State.UNINITIALIZED;
     private FamilyKeyCrypto _familyKeyCrypto;
     private boolean _familyKeyCryptoFail;
+    public final Object _familyKeyLock = new Object();
     
     public final static String PROP_CONFIG_FILE = "router.configLocation";
     
@@ -877,7 +878,7 @@ public class Router implements RouterClock.ClockShiftListener {
      *  @since 0.9.24
      */
     public FamilyKeyCrypto getFamilyKeyCrypto() {
-        synchronized (_routerInfoLock) {
+        synchronized (_familyKeyLock) {
             if (_familyKeyCrypto == null) {
                 if (!_familyKeyCryptoFail) {
                     try {
@@ -918,7 +919,7 @@ public class Router implements RouterClock.ClockShiftListener {
      *
      *  @return a capabilities string to be added to the RI
      */
-    String getCapabilities() {
+    public String getCapabilities() {
         StringBuilder rv = new StringBuilder(4);
         int bwLim = Math.min(_context.bandwidthLimiter().getInboundKBytesPerSecond(),
                              _context.bandwidthLimiter().getOutboundKBytesPerSecond());
diff --git a/router/java/src/net/i2p/router/transport/TransportImpl.java b/router/java/src/net/i2p/router/transport/TransportImpl.java
index 11fb08b96a..7cea14d435 100644
--- a/router/java/src/net/i2p/router/transport/TransportImpl.java
+++ b/router/java/src/net/i2p/router/transport/TransportImpl.java
@@ -141,9 +141,10 @@ public abstract class TransportImpl implements Transport {
         else // shouldn't happen
             maxProp = "i2np." + style.toLowerCase(Locale.US) + ".maxConnections";
         int def = MAX_CONNECTION_FACTOR;
-        RouterInfo ri = _context.router().getRouterInfo();
-        if (ri != null) {
-            char bw = ri.getBandwidthTier().charAt(0);
+        // get it from here, not the RI, to avoid deadlock
+        String caps = _context.router().getCapabilities();
+
+            char bw = caps.charAt(0);
             switch (bw) {
                 case Router.CAPABILITY_BW12:
                 case 'u':  // unknown
@@ -168,7 +169,7 @@ public abstract class TransportImpl implements Transport {
                     def *= 12;
                     break;
             }
-        }
+
         if (_context.netDb().floodfillEnabled()) {
             // && !SystemVersion.isWindows()) {
             def *= 17; def /= 10;  // 425 for Class O ff
@@ -747,13 +748,11 @@ public abstract class TransportImpl implements Transport {
      *  This can be called before startListening() to set an initial address,
      *  or after the transport is running.
      *
-     *  This implementation does nothing. Transports should override if they want notification.
-     *
      *  @param source defined in Transport.java
      *  @param ip typ. IPv4 or IPv6 non-local; may be null to indicate IPv4 failure or port info only
      *  @param port 0 for unknown or unchanged
      */
-    public void externalAddressReceived(AddressSource source, byte[] ip, int port) {}
+    public abstract void externalAddressReceived(AddressSource source, byte[] ip, int port);
 
     /**
      *  Notify a transport of an external address change.
-- 
GitLab