From d467dc28b956b9afad6384fc5b67e8251370fc8e Mon Sep 17 00:00:00 2001
From: zzz <zzz@i2pmail.org>
Date: Sat, 28 May 2022 12:02:52 -0400
Subject: [PATCH] I2CP: Only send one notification to each session listener

for reportAbuse(), disconnected(), and errorOccurred(),
because a single listener may be registered for multiple ports/protocols
---
 .../client/impl/I2PSessionDemultiplexer.java  | 20 ++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/core/java/src/net/i2p/client/impl/I2PSessionDemultiplexer.java b/core/java/src/net/i2p/client/impl/I2PSessionDemultiplexer.java
index 2eb47f36b4..6480733e12 100644
--- a/core/java/src/net/i2p/client/impl/I2PSessionDemultiplexer.java
+++ b/core/java/src/net/i2p/client/impl/I2PSessionDemultiplexer.java
@@ -1,6 +1,8 @@
 package net.i2p.client.impl;
 
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.Collection;
+import java.util.HashSet;
 import java.util.Map;
 
 import net.i2p.I2PAppContext;
@@ -59,13 +61,21 @@ public class I2PSessionDemultiplexer implements I2PSessionMuxedListener {
     }
 
     public void reportAbuse(I2PSession session, int severity) {
-        for (I2PSessionMuxedListener l : _listeners.values()) {
+        Collection<I2PSessionMuxedListener> lsnrs = _listeners.values();
+        // dedup
+        if (lsnrs.size() > 1)
+            lsnrs = new HashSet<I2PSessionMuxedListener>(lsnrs);
+        for (I2PSessionMuxedListener l : lsnrs) {
             l.reportAbuse(session, severity);
         }
     }
 
     public void disconnected(I2PSession session) {
-        for (I2PSessionMuxedListener l : _listeners.values()) {
+        Collection<I2PSessionMuxedListener> lsnrs = _listeners.values();
+        // dedup
+        if (lsnrs.size() > 1)
+            lsnrs = new HashSet<I2PSessionMuxedListener>(lsnrs);
+        for (I2PSessionMuxedListener l : lsnrs) {
             if (_log.shouldInfo())
                 _log.info("Sending disconnected() to " + l);
             l.disconnected(session);
@@ -73,7 +83,11 @@ public class I2PSessionDemultiplexer implements I2PSessionMuxedListener {
     }
 
     public void errorOccurred(I2PSession session, String message, Throwable error) {
-        for (I2PSessionMuxedListener l : _listeners.values()) {
+        Collection<I2PSessionMuxedListener> lsnrs = _listeners.values();
+        // dedup
+        if (lsnrs.size() > 1)
+            lsnrs = new HashSet<I2PSessionMuxedListener>(lsnrs);
+        for (I2PSessionMuxedListener l : lsnrs) {
             if (_log.shouldInfo())
                  _log.info("Sending errorOccurred() \"" + message + "\" to " + l);
             l.errorOccurred(session, message, error);
-- 
GitLab