From 9d49dc7af72d3d2462452f6c16e6eaae98c85fc9 Mon Sep 17 00:00:00 2001
From: zzz <zzz@i2pmail.org>
Date: Tue, 5 Apr 2022 07:47:56 -0400
Subject: [PATCH] SSU2: Fix NPE in PeerState.loadFrom()

---
 .../i2p/router/transport/udp/PeerState.java   | 78 ++++++++++---------
 1 file changed, 41 insertions(+), 37 deletions(-)

diff --git a/router/java/src/net/i2p/router/transport/udp/PeerState.java b/router/java/src/net/i2p/router/transport/udp/PeerState.java
index b5748f2660..8149fab8c9 100644
--- a/router/java/src/net/i2p/router/transport/udp/PeerState.java
+++ b/router/java/src/net/i2p/router/transport/udp/PeerState.java
@@ -1174,8 +1174,8 @@ public class PeerState {
         }
 
         if (!anyPending) {
-            if (_log.shouldLog(Log.DEBUG))
-                _log.debug(_remotePeer + " nothing pending, cancelling timer");
+            //if (_log.shouldLog(Log.DEBUG))
+            //    _log.debug(_remotePeer + " nothing pending, cancelling timer");
             _retransmitTimer = 0;
             exitFastRetransmit();
         } else {
@@ -2191,7 +2191,7 @@ public class PeerState {
     /**
      * Transfer the basic activity/state from the old peer to the current peer
      *
-     *  SSU 1 only.
+     *  SSU 1 or 2.
      *
      * @param oldPeer non-null
      */
@@ -2203,45 +2203,49 @@ public class PeerState {
         _sendWindowBytes = oldPeer._sendWindowBytes;
         oldPeer._dead = true;
 
-        List<Long> tmp = new ArrayList<Long>();
-        // AIOOBE from concurrent access
-        //tmp.addAll(oldPeer._currentACKs);
-        for (Long l : oldPeer._currentACKs) {
-            tmp.add(l);
-        }
-        oldPeer._currentACKs.clear();
-
-        if (!_dead) {
-            _currentACKs.addAll(tmp);
-	}
+        if (getVersion() == 1 && oldPeer.getVersion() == 1) {
+            List<Long> tmp = new ArrayList<Long>();
+            // AIOOBE from concurrent access
+            //tmp.addAll(oldPeer._currentACKs);
+            for (Long l : oldPeer._currentACKs) {
+                tmp.add(l);
+            }
+            oldPeer._currentACKs.clear();
 
-        List<ResendACK> tmp3 = new ArrayList<ResendACK>();
-        tmp3.addAll(oldPeer._currentACKsResend);
-        oldPeer._currentACKsResend.clear();
+            if (!_dead) {
+                _currentACKs.addAll(tmp);
+            }
 
-        if (!_dead) {
-            _currentACKsResend.addAll(tmp3);
-	}
+            List<ResendACK> tmp3 = new ArrayList<ResendACK>();
+            tmp3.addAll(oldPeer._currentACKsResend);
+            oldPeer._currentACKsResend.clear();
 
-        Map<Long, InboundMessageState> msgs = new HashMap<Long, InboundMessageState>();
-        synchronized (oldPeer._inboundMessages) {
-            msgs.putAll(oldPeer._inboundMessages);
-            oldPeer._inboundMessages.clear();
+            if (!_dead) {
+                _currentACKsResend.addAll(tmp3);
+            }
         }
-        if (!_dead) {
-            synchronized (_inboundMessages) { _inboundMessages.putAll(msgs); }
-	}
-        msgs.clear();
 
-        List<OutboundMessageState> tmp2 = new ArrayList<OutboundMessageState>();
-        OutboundMessageState retransmitter = null;
-        synchronized (oldPeer._outboundMessages) {
-            tmp2.addAll(oldPeer._outboundMessages);
-            oldPeer._outboundMessages.clear();
-        }
-        if (!_dead) {
-            synchronized (_outboundMessages) {
-                _outboundMessages.addAll(tmp2);
+        if (getVersion() == oldPeer.getVersion()) {
+            Map<Long, InboundMessageState> msgs = new HashMap<Long, InboundMessageState>();
+            synchronized (oldPeer._inboundMessages) {
+                msgs.putAll(oldPeer._inboundMessages);
+                oldPeer._inboundMessages.clear();
+            }
+            if (!_dead) {
+                synchronized (_inboundMessages) { _inboundMessages.putAll(msgs); }
+            }
+            msgs.clear();
+
+            List<OutboundMessageState> tmp2 = new ArrayList<OutboundMessageState>();
+            OutboundMessageState retransmitter = null;
+            synchronized (oldPeer._outboundMessages) {
+                tmp2.addAll(oldPeer._outboundMessages);
+                oldPeer._outboundMessages.clear();
+            }
+            if (!_dead) {
+                synchronized (_outboundMessages) {
+                    _outboundMessages.addAll(tmp2);
+                }
             }
         }
     }
-- 
GitLab