diff --git a/router/java/src/net/i2p/router/transport/TransportImpl.java b/router/java/src/net/i2p/router/transport/TransportImpl.java
index 9e43a79eb309f295319c39f39f782ddbeeb757c2..afab743d9fe06926452fc4972ed3f9d9687e9432 100644
--- a/router/java/src/net/i2p/router/transport/TransportImpl.java
+++ b/router/java/src/net/i2p/router/transport/TransportImpl.java
@@ -25,7 +25,6 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.ConcurrentHashMap;
 
 import net.i2p.data.DataHelper;
@@ -55,7 +54,7 @@ import net.i2p.util.VersionComparator;
 public abstract class TransportImpl implements Transport {
     private final Log _log;
     private TransportEventListener _listener;
-    protected final List<RouterAddress> _currentAddresses;
+    private final List<RouterAddress> _currentAddresses;
     // Only used by NTCP. SSU does not use. See send() below.
     private final BlockingQueue<OutNetMessage> _sendPool;
     protected final RouterContext _context;
@@ -112,7 +111,7 @@ public abstract class TransportImpl implements Transport {
         //_context.statManager().createRateStat("transport.sendProcessingTime." + getStyle(), "Time to process and send a message (ms)", "Transport", new long[] { 60*1000l });
         _context.statManager().createRateStat("transport.expiredOnQueueLifetime", "How long a message that expires on our outbound queue is processed", "Transport", new long[] { 60*1000l, 10*60*1000l, 60*60*1000l, 24*60*60*1000l } );
 
-        _currentAddresses = new CopyOnWriteArrayList<RouterAddress>();
+        _currentAddresses = new ArrayList<RouterAddress>(3);
         if (getStyle().equals("NTCP"))
             _sendPool = new ArrayBlockingQueue<OutNetMessage>(8);
         else
@@ -550,11 +549,13 @@ public abstract class TransportImpl implements Transport {
     /**
      *  What addresses are we currently listening to?
      *  Replaces getCurrentAddress()
-     *  @return all addresses, non-null
+     *  @return a copy of all addresses, non-null
      *  @since IPv6
      */
     public List<RouterAddress> getCurrentAddresses() {
-        return _currentAddresses;
+        synchronized(_currentAddresses) {
+            return new ArrayList<RouterAddress>(_currentAddresses);
+        }
     }
 
     /**
@@ -568,9 +569,11 @@ public abstract class TransportImpl implements Transport {
      *  @since IPv6
      */
     public RouterAddress getCurrentAddress(boolean ipv6) {
-        for (RouterAddress ra : _currentAddresses) {
-            if (ipv6 == TransportUtil.isIPv6(ra))
-                return ra;
+        synchronized(_currentAddresses) {
+            for (RouterAddress ra : _currentAddresses) {
+                if (ipv6 == TransportUtil.isIPv6(ra))
+                    return ra;
+            }
         }
         return null;
     }
@@ -580,17 +583,21 @@ public abstract class TransportImpl implements Transport {
      *  @since IPv6
      */
     public boolean hasCurrentAddress() {
-        return !_currentAddresses.isEmpty();
+        synchronized(_currentAddresses) {
+            return !_currentAddresses.isEmpty();
+        }
     }
 
     /**
      * Ask the transport to update its address based on current information and return it
      * Transports should override.
-     * @return all addresses, non-null
+     * @return a copy of all addresses, non-null
      * @since 0.7.12
      */
     public List<RouterAddress> updateAddress() {
-        return _currentAddresses;
+        synchronized(_currentAddresses) {
+            return new ArrayList<RouterAddress>(_currentAddresses);
+        }
     }
 
     /**
@@ -603,21 +610,27 @@ public abstract class TransportImpl implements Transport {
      *  @param address null to remove all
      */
     protected void replaceAddress(RouterAddress address) {
-        if (_log.shouldLog(Log.WARN))
-             _log.warn("Replacing address with " + address, new Exception());
-        if (address == null) {
-            _currentAddresses.clear();
-        } else {
-            boolean isIPv6 = TransportUtil.isIPv6(address);
-            for (RouterAddress ra : _currentAddresses) {
-                if (isIPv6 == TransportUtil.isIPv6(ra))
-                    // COWAL
-                    _currentAddresses.remove(ra);
+        boolean isIPv6 = TransportUtil.isIPv6(address);
+        if (_log.shouldWarn())
+            _log.warn("Replacing  IPv" + (isIPv6 ? '6' : '4') + " address with " + address, new Exception());
+        int sz;
+        synchronized(_currentAddresses) {
+            if (address == null) {
+                _currentAddresses.clear();
+                sz = 0;
+            } else {
+                for (Iterator<RouterAddress> iter = _currentAddresses.iterator(); iter.hasNext(); ) {
+                    RouterAddress ra = iter.next();
+                    if (isIPv6 == TransportUtil.isIPv6(ra)) {
+                        iter.remove();
+                    }
+                }
+                _currentAddresses.add(address);
+                sz = _currentAddresses.size();
             }
-            _currentAddresses.add(address);
         }
-        if (_log.shouldLog(Log.WARN))
-             _log.warn(getStyle() + " now has " + _currentAddresses.size() + " addresses");
+        if (_log.shouldWarn())
+            _log.warn(getStyle() + " now has " + sz + " addresses");
         if (_listener != null)
             _listener.transportAddressChanged();
     }
@@ -633,11 +646,15 @@ public abstract class TransportImpl implements Transport {
     protected void removeAddress(RouterAddress address) {
         if (_log.shouldWarn())
              _log.warn("Removing address " + address, new Exception());
-        boolean changed = _currentAddresses.remove(address);
-            changed = true;
+        boolean changed;
+        int sz;
+        synchronized(_currentAddresses) {
+            changed = _currentAddresses.remove(address);
+            sz = _currentAddresses.size();
+        }
         if (changed) {
             if (_log.shouldWarn())
-                 _log.warn(getStyle() + " now has " + _currentAddresses.size() + " addresses");
+                 _log.warn(getStyle() + " now has " + sz + " addresses");
             if (_listener != null)
                 _listener.transportAddressChanged();
         } else {
@@ -658,16 +675,20 @@ public abstract class TransportImpl implements Transport {
         if (_log.shouldWarn())
              _log.warn("Removing addresses, ipv6? " + ipv6, new Exception());
         boolean changed = false;
-        for (RouterAddress ra : _currentAddresses) {
-            if (ipv6 == TransportUtil.isIPv6(ra)) {
-                // COWAL
-                if (_currentAddresses.remove(ra))
+        int sz;
+        synchronized(_currentAddresses) {
+            for (Iterator<RouterAddress> iter = _currentAddresses.iterator(); iter.hasNext(); ) {
+                RouterAddress ra = iter.next();
+                if (ipv6 == TransportUtil.isIPv6(ra)) {
+                    iter.remove();
                     changed = true;
+                }
             }
+            sz = _currentAddresses.size();
         }
         if (changed) {
             if (_log.shouldWarn())
-                 _log.warn(getStyle() + " now has " + _currentAddresses.size() + " addresses");
+                 _log.warn(getStyle() + " now has " + sz + " addresses");
             if (_listener != null)
                 _listener.transportAddressChanged();
         } else {