From 7d6891c07715df9f259f6c83fd3c13e24f216b25 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 3 Mar 2021 13:38:25 +0100 Subject: [PATCH 01/25] Smack 4.4.2-SNAPSHOT --- version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version b/version index cca25a93c..6be5f1e43 100644 --- a/version +++ b/version @@ -1 +1 @@ -4.4.1 +4.4.2-SNAPSHOT From ba6968fc79c36aa4299cf082a25b8fd0877b2060 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 3 Mar 2021 21:41:07 +0100 Subject: [PATCH 02/25] [xmlparser-stax] Fix potential IAE in StaxXmlPullParser.getNamespace() StAX's NamespaceContext.getNamespaceURI(String) is allowed to throw an IllegalArgumentException in case the argument is null. We simply re-use getNamespace(String) which will substitute the default namespace if the argument is null to avoid this. Connection closed due to an exception java.lang.IllegalArgumentException: Illegal to pass null as argument at com.ctc.wstx.sr.NsInputElementStack.getNamespaceURI(NsInputElementStack.java:486) at org.jivesoftware.smack.xml.stax.StaxXmlPullParser.getNamespace(StaxXmlPullParser.java:113) at org.jivesoftware.smack.AbstractXMPPConnection.parseFeatures(AbstractXMPPConnection.java:1852) at org.jivesoftware.smack.AbstractXMPPConnection.parseFeaturesAndNotify(AbstractXMPPConnection.java:1887) at org.jivesoftware.smack.tcp.XMPPTCPConnection.access$1300(XMPPTCPConnection.java:130) at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:983) at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$700(XMPPTCPConnection.java:913) at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:936) at java.lang.Thread.run(Thread.java:748) Fixes SMACK-903 --- .../org/jivesoftware/smack/xml/stax/StaxXmlPullParser.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/smack-xmlparser-stax/src/main/java/org/jivesoftware/smack/xml/stax/StaxXmlPullParser.java b/smack-xmlparser-stax/src/main/java/org/jivesoftware/smack/xml/stax/StaxXmlPullParser.java index 56542fc97..10f3453eb 100644 --- a/smack-xmlparser-stax/src/main/java/org/jivesoftware/smack/xml/stax/StaxXmlPullParser.java +++ b/smack-xmlparser-stax/src/main/java/org/jivesoftware/smack/xml/stax/StaxXmlPullParser.java @@ -108,9 +108,8 @@ public final class StaxXmlPullParser implements XmlPullParser { @Override public String getNamespace() { - NamespaceContext namespaceContext = xmlStreamReader.getNamespaceContext(); String prefix = getPrefix(); - return namespaceContext.getNamespaceURI(prefix); + return getNamespace(prefix); } @Override From 3bef905ef5873b7d9dba2a5dc0bf6fa7671a2ddc Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 3 Mar 2021 21:43:43 +0100 Subject: [PATCH 03/25] [xmlparser-stax] Move getNamespace() to its friends within the file --- .../smack/xml/stax/StaxXmlPullParser.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/smack-xmlparser-stax/src/main/java/org/jivesoftware/smack/xml/stax/StaxXmlPullParser.java b/smack-xmlparser-stax/src/main/java/org/jivesoftware/smack/xml/stax/StaxXmlPullParser.java index 10f3453eb..e1282af0d 100644 --- a/smack-xmlparser-stax/src/main/java/org/jivesoftware/smack/xml/stax/StaxXmlPullParser.java +++ b/smack-xmlparser-stax/src/main/java/org/jivesoftware/smack/xml/stax/StaxXmlPullParser.java @@ -73,6 +73,12 @@ public final class StaxXmlPullParser implements XmlPullParser { return namespaceContext.getNamespaceURI(prefix); } + @Override + public String getNamespace() { + String prefix = getPrefix(); + return getNamespace(prefix); + } + @Override public int getDepth() { return depth; @@ -106,12 +112,6 @@ public final class StaxXmlPullParser implements XmlPullParser { return xmlStreamReader.getText(); } - @Override - public String getNamespace() { - String prefix = getPrefix(); - return getNamespace(prefix); - } - @Override public String getName() { QName qname = getQName(); From 4adbd21a0f57574497dc93ad0b44ddcd1f611bba Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 3 Mar 2021 22:25:32 +0100 Subject: [PATCH 04/25] [smack-xmlparser] Allow override of used XmlPullParserFactory --- .../org/jivesoftware/smack/xml/SmackXmlParser.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/smack-xmlparser/src/main/java/org/jivesoftware/smack/xml/SmackXmlParser.java b/smack-xmlparser/src/main/java/org/jivesoftware/smack/xml/SmackXmlParser.java index a8e76c294..0e23fbea7 100644 --- a/smack-xmlparser/src/main/java/org/jivesoftware/smack/xml/SmackXmlParser.java +++ b/smack-xmlparser/src/main/java/org/jivesoftware/smack/xml/SmackXmlParser.java @@ -1,6 +1,6 @@ /** * - * Copyright 2019 Florian Schmaus. + * Copyright 2019-2021 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,14 @@ public class SmackXmlParser { xmlPullParserFactoryServiceLoader = ServiceLoader.load(XmlPullParserFactory.class); } + private static XmlPullParserFactory xmlPullParserFactory; + public static XmlPullParserFactory getXmlPullParserFactory() { + final XmlPullParserFactory xmlPullParserFactory = SmackXmlParser.xmlPullParserFactory; + if (xmlPullParserFactory != null) { + return xmlPullParserFactory; + } + Iterator iterator = xmlPullParserFactoryServiceLoader.iterator(); if (!iterator.hasNext()) { throw new IllegalStateException( @@ -37,6 +44,10 @@ public class SmackXmlParser { return iterator.next(); } + public static void setXmlPullParserFactory(XmlPullParserFactory xmlPullParserFactory) { + SmackXmlParser.xmlPullParserFactory = xmlPullParserFactory; + } + /** * Creates a new XmlPullParser suitable for parsing XMPP. This means in particular that * FEATURE_PROCESS_NAMESPACES is enabled. From f9114f780ddb10ec88d120591b62f2cf967de676 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Tue, 9 Mar 2021 13:10:40 +0100 Subject: [PATCH 05/25] [tcp] Ignore exceptions in reader thread if writer was terminated If we do not ignore the exception, then users may receive an exception via connectionClosedOnError() on connection termination. Those exceptions are typically unwanted if they are caused e.g. because the server does not send a closing stream tag. We previously ignored exceptions in this case already, but that behavior was changed with [1: 57961a8cc1f2]. This commit re-adds the behavior. 1: 57961a8cc1f2df6ecc1afa8c4f8460794d8d2dce Remove SynchronizationPoint --- .../smack/tcp/XMPPTCPConnection.java | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java index aeb9d109b..c9884a3d0 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java @@ -1141,16 +1141,26 @@ public class XMPPTCPConnection extends AbstractXMPPConnection { } } catch (Exception e) { - // The exception can be ignored if the the connection is 'done' - // or if the it was caused because the socket got closed. - if (!done) { - // Set running to false since this thread will exit here and notifyConnectionError() will wait until - // the reader and writer thread's 'running' value is false. - running = false; - // Close the connection and notify connection listeners of the - // error. - notifyConnectionError(e); + // Set running to false since this thread will exit here and notifyConnectionError() will wait until + // the reader and writer thread's 'running' value is false. + running = false; + + String ignoreReasonThread = null; + + boolean writerThreadWasShutDown = packetWriter.queue.isShutdown(); + if (writerThreadWasShutDown) { + ignoreReasonThread = "writer"; + } else if (done) { + ignoreReasonThread = "reader"; } + + if (ignoreReasonThread != null) { + LOGGER.log(Level.FINER, "Ignoring " + e + " as " + ignoreReasonThread + " was already shut down"); + return; + } + + // Close the connection and notify connection listeners of the error. + notifyConnectionError(e); } } } From 7cf0112487728cf24d93b831c6fa412d2969b6fc Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Fri, 12 Mar 2021 22:19:55 +0100 Subject: [PATCH 06/25] [omemo] Cleanup CryptoFailedException Remove the unused list of exceptions and add a (String, Exception) constructor. --- .../exceptions/CryptoFailedException.java | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/exceptions/CryptoFailedException.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/exceptions/CryptoFailedException.java index 4e452af44..2b2978f50 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/exceptions/CryptoFailedException.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/exceptions/CryptoFailedException.java @@ -1,6 +1,6 @@ /** * - * Copyright 2017 Paul Schaub + * Copyright 2017 Paul Schaub, 2021 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,6 @@ */ package org.jivesoftware.smackx.omemo.exceptions; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - /** * Exception gets thrown when some cryptographic function failed. * @@ -27,20 +23,18 @@ import java.util.List; */ public class CryptoFailedException extends Exception { - private static final long serialVersionUID = 3466888654338119924L; + private static final long serialVersionUID = 1; - private final ArrayList exceptions = new ArrayList<>(); + public CryptoFailedException(String message, Exception wrappedException) { + super(message, wrappedException); + } public CryptoFailedException(String message) { - super(message); + this(message, null); } public CryptoFailedException(Exception e) { - super(e); - exceptions.add(e); + this("Crypto failed " + e.getMessage(), e); } - public List getExceptions() { - return Collections.unmodifiableList(exceptions); - } } From 17ac41c8cb1b10cff70a33b0d1701817f2aae544 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Fri, 12 Mar 2021 22:21:22 +0100 Subject: [PATCH 07/25] [core] Add RandomUtil.fillWithSecureRandom(byte[]) --- .../main/java/org/jivesoftware/smack/util/RandomUtil.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/RandomUtil.java b/smack-core/src/main/java/org/jivesoftware/smack/util/RandomUtil.java index 857557869..88c71e7aa 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/RandomUtil.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/RandomUtil.java @@ -1,6 +1,6 @@ /** * - * Copyright 2003-2007 Jive Software, 2016-2019 Florian Schmaus. + * Copyright 2003-2007 Jive Software, 2016-2021 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,4 +47,8 @@ public class RandomUtil { public static int nextSecureRandomInt() { return SECURE_RANDOM.get().nextInt(); } + + public static void fillWithSecureRandom(byte[] bytes) { + SECURE_RANDOM.get().nextBytes(bytes); + } } From b7905d585d0ebaa8d58466019429d7ddc334a43b Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Fri, 12 Mar 2021 22:21:58 +0100 Subject: [PATCH 08/25] [omemo] Use RandomUtil.fillWithSecureRandom() to generate IV --- .../jivesoftware/smackx/omemo/util/OmemoMessageBuilder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/util/OmemoMessageBuilder.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/util/OmemoMessageBuilder.java index 6e49db945..7f20e17bb 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/util/OmemoMessageBuilder.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/util/OmemoMessageBuilder.java @@ -36,6 +36,7 @@ import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; +import org.jivesoftware.smack.util.RandomUtil; import org.jivesoftware.smackx.omemo.OmemoRatchet; import org.jivesoftware.smackx.omemo.OmemoService; import org.jivesoftware.smackx.omemo.element.OmemoElement; @@ -278,9 +279,8 @@ public class OmemoMessageBuilder Date: Fri, 12 Mar 2021 22:23:01 +0100 Subject: [PATCH 09/25] [omemo] Introduce OmemoAesCipher as central AES API OmemoAesCipher is the sole point where OMEMO related AES operations are performed. This allows OmemoAesCipher to check in a static block if AES is available. If AES is not available it throws a (hopefully) helpfull exception message. Typically AES is not available on Android if no security provider providing AES, like Bouncy Castle, has been explicitly configured. --- .../smackx/omemo/OmemoRatchet.java | 16 +-- .../omemo/internal/CipherAndAuthTag.java | 33 ++----- .../smackx/omemo/internal/OmemoAesCipher.java | 99 +++++++++++++++++++ .../omemo/util/OmemoMessageBuilder.java | 21 +--- .../smackx/omemo/WrapperObjectsTest.java | 2 - 5 files changed, 120 insertions(+), 51 deletions(-) create mode 100644 smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/internal/OmemoAesCipher.java diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoRatchet.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoRatchet.java index 838784806..9c0ff2d30 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoRatchet.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoRatchet.java @@ -1,6 +1,6 @@ /** * - * Copyright 2017 Paul Schaub + * Copyright 2017 Paul Schaub, 2021 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,9 @@ package org.jivesoftware.smackx.omemo; import java.io.IOException; -import java.nio.charset.StandardCharsets; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; @@ -25,6 +27,7 @@ import java.util.logging.Logger; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; import org.jivesoftware.smackx.omemo.element.OmemoElement; import org.jivesoftware.smackx.omemo.element.OmemoKeyElement; @@ -172,11 +175,10 @@ public abstract class OmemoRatchet Date: Fri, 12 Mar 2021 22:25:50 +0100 Subject: [PATCH 10/25] [core] Add AndFilter(List) constructor --- .../smack/filter/AbstractListFilter.java | 13 +++++++++++-- .../org/jivesoftware/smack/filter/AndFilter.java | 13 ++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/AbstractListFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/AbstractListFilter.java index d06ddad47..0d55777ce 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/filter/AbstractListFilter.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/AbstractListFilter.java @@ -1,6 +1,6 @@ /** * - * Copyright 2015 Florian Schmaus + * Copyright 2015-2021 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,11 +44,20 @@ public abstract class AbstractListFilter implements StanzaFilter { * @param filters the filters to add. */ protected AbstractListFilter(StanzaFilter... filters) { + this(new ArrayList(Arrays.asList(filters))); + } + + /** + * Creates an filter using the specified filters. + * + * @param filters the filters to add. + */ + protected AbstractListFilter(List filters) { Objects.requireNonNull(filters, "Parameter must not be null."); for (StanzaFilter filter : filters) { Objects.requireNonNull(filter, "Parameter must not be null."); } - this.filters = new ArrayList(Arrays.asList(filters)); + this.filters = filters; } /** diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/AndFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/AndFilter.java index cbdccd6e6..686ce2491 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/filter/AndFilter.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/AndFilter.java @@ -1,6 +1,6 @@ /** * - * Copyright 2003-2007 Jive Software. + * Copyright 2003-2007 Jive Software, 2021 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,8 @@ package org.jivesoftware.smack.filter; +import java.util.List; + import org.jivesoftware.smack.packet.Stanza; /** @@ -44,6 +46,15 @@ public class AndFilter extends AbstractListFilter implements StanzaFilter { super(filters); } + /** + * Creates an AND filter using the specified filters. + * + * @param filters the filters to add. + */ + public AndFilter(List filters) { + super(filters); + } + @Override public boolean accept(Stanza packet) { for (StanzaFilter filter : filters) { From 9d1b88a87726d7f4867a01d643f6fbd4007c7e7b Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Fri, 12 Mar 2021 22:26:36 +0100 Subject: [PATCH 11/25] [muc] Do not filter for presence ID if #stable_id is not announced On leave(), do not filter for presence ID if the MUC service does not announce #stable_id. --- .../smackx/muc/MultiUserChat.java | 32 +++++++++++++------ .../smackx/muc/MultiUserChatConstants.java | 4 ++- .../smackx/muc/MultiUserChatManager.java | 27 ++++++++++------ 3 files changed, 42 insertions(+), 21 deletions(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java index 51f267694..f7480becd 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java @@ -1,6 +1,6 @@ /** * - * Copyright 2003-2007 Jive Software. 2020 Florian Schmaus + * Copyright 2003-2007 Jive Software. 2020-2021 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -149,6 +149,8 @@ public class MultiUserChat { private EntityFullJid myRoomJid; private StanzaCollector messageCollector; + private DiscoverInfo mucServiceDiscoInfo; + /** * Used to signal that the reflected self-presence was received and processed by us. */ @@ -342,7 +344,8 @@ public class MultiUserChat { private Presence enter(MucEnterConfiguration conf) throws NotConnectedException, NoResponseException, XMPPErrorException, InterruptedException, NotAMucServiceException { final DomainBareJid mucService = room.asDomainBareJid(); - if (!multiUserChatManager.providesMucService(mucService)) { + mucServiceDiscoInfo = multiUserChatManager.getMucServiceDiscoInfo(mucService); + if (mucServiceDiscoInfo == null) { throw new NotAMucServiceException(this); } // We enter a room by sending a presence packet where the "to" @@ -757,6 +760,10 @@ public class MultiUserChat { throw new MucNotJoinedException(this); } + // TODO: Consider adding a origin-id to the presence, once it is moved form smack-experimental into + // smack-extensions, in case the MUC service does not support stable IDs, and modify + // reflectedLeavePresenceFilters accordingly. + // We leave a room by sending a presence packet where the "to" // field is in the form "roomName@service/nickname" Presence leavePresence = connection.getStanzaFactory().buildPresenceStanza() @@ -764,14 +771,19 @@ public class MultiUserChat { .to(myRoomJid) .build(); - StanzaFilter reflectedLeavePresenceFilter = new AndFilter( - StanzaTypeFilter.PRESENCE, - new StanzaIdFilter(leavePresence), - new OrFilter( - new AndFilter(FromMatchesFilter.createFull(myRoomJid), PresenceTypeFilter.UNAVAILABLE, MUCUserStatusCodeFilter.STATUS_110_PRESENCE_TO_SELF), - new AndFilter(fromRoomFilter, PresenceTypeFilter.ERROR) - ) - ); + List reflectedLeavePresenceFilters = new ArrayList<>(3); + reflectedLeavePresenceFilters.add(StanzaTypeFilter.PRESENCE); + reflectedLeavePresenceFilters.add(new OrFilter( + new AndFilter(FromMatchesFilter.createFull(myRoomJid), PresenceTypeFilter.UNAVAILABLE, + MUCUserStatusCodeFilter.STATUS_110_PRESENCE_TO_SELF), + new AndFilter(fromRoomFilter, PresenceTypeFilter.ERROR))); + + boolean supportsStableId = mucServiceDiscoInfo.containsFeature(MultiUserChatConstants.STABLE_ID_FEATURE); + if (supportsStableId) { + reflectedLeavePresenceFilters.add(new StanzaIdFilter(leavePresence)); + } + + StanzaFilter reflectedLeavePresenceFilter = new AndFilter(reflectedLeavePresenceFilters); // Reset occupant information first so that we are assume that we left the room even if sendStanza() would // throw. diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatConstants.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatConstants.java index ffc00a5a9..35167c081 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatConstants.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatConstants.java @@ -1,6 +1,6 @@ /** * - * Copyright 2020 Florian Schmaus + * Copyright 2020-2021 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,4 +20,6 @@ public class MultiUserChatConstants { public static final String NAMESPACE = "http://jabber.org/protocol/muc"; + public static final String STABLE_ID_FEATURE = NAMESPACE + "#stable_id"; + } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java index 7d92e9817..2cf5778ff 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2014-2020 Florian Schmaus + * Copyright © 2014-2021 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -137,7 +137,7 @@ public final class MultiUserChatManager extends Manager { private static final StanzaFilter INVITATION_FILTER = new AndFilter(StanzaTypeFilter.MESSAGE, new StanzaExtensionFilter(new MUCUser()), new NotFilter(MessageTypeFilter.ERROR)); - private static final ExpirationCache KNOWN_MUC_SERVICES = new ExpirationCache<>( + private static final ExpirationCache KNOWN_MUC_SERVICES = new ExpirationCache<>( 100, 1000 * 60 * 60 * 24); private final Set invitationsListeners = new CopyOnWriteArraySet(); @@ -396,16 +396,23 @@ public final class MultiUserChatManager extends Manager { */ public boolean providesMucService(DomainBareJid domainBareJid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { - boolean contains = KNOWN_MUC_SERVICES.containsKey(domainBareJid); - if (!contains) { - if (serviceDiscoveryManager.supportsFeature(domainBareJid, - MUCInitialPresence.NAMESPACE)) { - KNOWN_MUC_SERVICES.put(domainBareJid, null); - return true; - } + return getMucServiceDiscoInfo(domainBareJid) != null; + } + + DiscoverInfo getMucServiceDiscoInfo(DomainBareJid mucServiceAddress) + throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { + DiscoverInfo discoInfo = KNOWN_MUC_SERVICES.get(mucServiceAddress); + if (discoInfo != null) { + return discoInfo; } - return contains; + discoInfo = serviceDiscoveryManager.discoverInfo(mucServiceAddress); + if (!discoInfo.containsFeature(MUCInitialPresence.NAMESPACE)) { + return null; + } + + KNOWN_MUC_SERVICES.put(mucServiceAddress, discoInfo); + return discoInfo; } /** From f2b44f65d938a075648bfa038d034f844e61a6d5 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 14 Mar 2021 17:51:33 +0100 Subject: [PATCH 12/25] [tcp] Add code comment why we need to set "running = false" here --- .../java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java index c9884a3d0..c1dc8b7ee 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java @@ -1142,7 +1142,8 @@ public class XMPPTCPConnection extends AbstractXMPPConnection { } catch (Exception e) { // Set running to false since this thread will exit here and notifyConnectionError() will wait until - // the reader and writer thread's 'running' value is false. + // the reader and writer thread's 'running' value is false. Hence we need to set it to false before calling + // notifyConnetctionError() below, even though run() also sets it to false. Therefore, do not remove this. running = false; String ignoreReasonThread = null; From c564c89c40a776d54f8e8252cb15f2cae3d315c3 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 14 Mar 2021 17:52:12 +0100 Subject: [PATCH 13/25] [extensions] Add OutgoingFileTransfer.setCallback() Some methods of OutgoingFileTransfer take already the NegotiationProgress callback as argument, some do not. The API is not ideal, and adding a setter for the callback at least makes it possible to always have the callback. --- .../smackx/filetransfer/OutgoingFileTransfer.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/OutgoingFileTransfer.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/OutgoingFileTransfer.java index 3e33208e6..6553f1cdf 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/OutgoingFileTransfer.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/OutgoingFileTransfer.java @@ -324,6 +324,10 @@ public class OutgoingFileTransfer extends FileTransfer { transferThread.start(); } + public void setCallback(NegotiationProgress negotiationProcess) { + this.callback = negotiationProcess; + } + private void handleXMPPException(XMPPErrorException e) { StanzaError error = e.getStanzaError(); if (error != null) { From 2779187d8cfee7e79a7157e37682229b92753bc8 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 14 Mar 2021 17:54:03 +0100 Subject: [PATCH 14/25] [filetransfer] Set the status to error in setException() FileTransfer would previously not change the status, even though an exception has been set, leading users to believe that the transfer is still ongoing, when it is not. --- .../org/jivesoftware/smackx/filetransfer/FileTransfer.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransfer.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransfer.java index cac3147cf..8c5dc63d3 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransfer.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransfer.java @@ -183,6 +183,10 @@ public abstract class FileTransfer { protected void setException(Exception exception) { this.exception = exception; + Status currentStatus = getStatus(); + if (currentStatus != Status.error) { + updateStatus(currentStatus, Status.error); + } } protected void setStatus(Status status) { From 73941629f37d6f623ff290787954589804f0f989 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 14 Mar 2021 17:57:13 +0100 Subject: [PATCH 15/25] [sinttest] Call OutgoingFiletransfer.getException() in case of error --- .../filetransfer/FileTransferIntegrationTest.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferIntegrationTest.java index 5d536aedb..ac79e46ec 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferIntegrationTest.java @@ -1,6 +1,6 @@ /** * - * Copyright 2015-2020 Florian Schmaus + * Copyright 2015-2021 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ import java.util.Arrays; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.util.StringUtils; +import org.jivesoftware.smackx.filetransfer.FileTransfer.Status; import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; @@ -98,9 +99,12 @@ public class FileTransferIntegrationTest extends AbstractSmackIntegrationTest { oft.sendStream(new ByteArrayInputStream(dataToSend), "hello.txt", dataToSend.length, "A greeting"); int duration = 0; while (!oft.isDone()) { - switch (oft.getStatus()) { + Status status = oft.getStatus(); + switch (status) { case error: - throw new Exception("FileTransfer error: " + oft.getError()); + FileTransfer.Error error = oft.getError(); + Exception exception = oft.getException(); + throw new Exception("FileTransfer error: " + error, exception); default: LOGGER.info("FileTransfer status: " + oft.getStatus() + ". Progress: " + oft.getProgress()); break; From adc159186ca1a2d3f18061e74a6bf791b708e074 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 14 Mar 2021 17:58:13 +0100 Subject: [PATCH 16/25] [formtypes] Introduce LOOKASIDE_FIELD_REGISTRY Some field's like stream-method of XEP-0096, which is of type list-single, need to be pre-registered. --- .../smackx/formtypes/FormFieldRegistry.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/formtypes/FormFieldRegistry.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/formtypes/FormFieldRegistry.java index 97156974f..9eab79b73 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/formtypes/FormFieldRegistry.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/formtypes/FormFieldRegistry.java @@ -36,6 +36,8 @@ public class FormFieldRegistry { private static final Map CLARK_NOTATION_FIELD_REGISTRY = new ConcurrentHashMap<>(); + private static final Map LOOKASIDE_FIELD_REGISTRY = new ConcurrentHashMap<>(); + @SuppressWarnings("ReferenceEquality") public static void register(DataForm dataForm) { // TODO: Also allow forms of type 'result'? @@ -98,11 +100,11 @@ public class FormFieldRegistry { public static FormField.Type lookup(String formType, String fieldName) { if (formType == null) { - if (!XmlUtil.isClarkNotation(fieldName)) { - return null; + if (XmlUtil.isClarkNotation(fieldName)) { + return CLARK_NOTATION_FIELD_REGISTRY.get(fieldName); } - return CLARK_NOTATION_FIELD_REGISTRY.get(fieldName); + return LOOKASIDE_FIELD_REGISTRY.get(fieldName); } synchronized (REGISTRY) { @@ -122,4 +124,7 @@ public class FormFieldRegistry { return lookup(null, fieldName); } + public static void addLookasideFieldRegistryEntry(String fieldName, FormField.Type formFieldType) { + LOOKASIDE_FIELD_REGISTRY.put(fieldName, formFieldType); + } } From d75cd2acb8553f750bf83ff7adf2dde0e1703f4d Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 14 Mar 2021 19:34:28 +0100 Subject: [PATCH 17/25] [filetransfer] Pre-register 'stream-method' form field Fixes SMACK-904. --- .../smackx/filetransfer/FileTransferNegotiator.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java index ac789adcc..4dc9067cf 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java @@ -40,6 +40,7 @@ import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.filetransfer.FileTransferException.NoAcceptableTransferMechanisms; import org.jivesoftware.smackx.filetransfer.FileTransferException.NoStreamMethodsOfferedException; +import org.jivesoftware.smackx.formtypes.FormFieldRegistry; import org.jivesoftware.smackx.si.packet.StreamInitiation; import org.jivesoftware.smackx.xdata.FormField; import org.jivesoftware.smackx.xdata.ListSingleFormField; @@ -66,6 +67,9 @@ public final class FileTransferNegotiator extends Manager { private static final String STREAM_INIT_PREFIX = "jsi_"; protected static final String STREAM_DATA_FIELD_NAME = "stream-method"; + static { + FormFieldRegistry.addLookasideFieldRegistryEntry(STREAM_DATA_FIELD_NAME, FormField.Type.list_single); + } private static final Random randomGenerator = new Random(); From ad8eeebc0df7268b0b68662a2a7d4b65145d5ef5 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 15 Mar 2021 19:21:55 +0100 Subject: [PATCH 18/25] [sinttest] Allow maxPayloadChunks == 0 --- .../igniterealtime/smack/XmppConnectionStressTest.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java index 712d75783..0ecba033e 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java @@ -90,7 +90,13 @@ public class XmppConnectionStressTest { MessageBuilder messageBuilder = fromConnection.getStanzaFactory().buildMessageStanza(); messageBuilder.to(toConnection.getUser()); - int payloadChunkCount = random.nextInt(configuration.maxPayloadChunks) + 1; + final int payloadChunkCount; + if (configuration.maxPayloadChunks == 0) { + payloadChunkCount = 0; + } else { + payloadChunkCount = random.nextInt(configuration.maxPayloadChunks) + 1; + } + for (int c = 0; c < payloadChunkCount; c++) { int payloadChunkSize = random.nextInt(configuration.maxPayloadChunkSize) + 1; String payloadCunk = StringUtils.randomString(payloadChunkSize, random); From f91598e10cc216aefc9014d877b0d7c6d93f75e5 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 15 Mar 2021 19:22:26 +0100 Subject: [PATCH 19/25] [sinttest] Improve NotAllMessageReceivedException --- .../java/org/igniterealtime/smack/XmppConnectionStressTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java index 0ecba033e..4a93d6dad 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java @@ -301,7 +301,7 @@ public class XmppConnectionStressTest { sb.append(markerToConnectionId) .append(" is missing ").append(numberOfFalseMarkers) .append(" messages from ").append(markerFromConnectionId) - .append(" :"); + .append(": "); for (int i = 0; i < marker.length; i++) { if (marker[i]) { continue; From 11a486d84d8828db638db72586203431c35d0d8d Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 15 Mar 2021 19:22:57 +0100 Subject: [PATCH 20/25] [sinttest] Add header to NotAllMessagesReceivedException This header maps the internal connection ID to the connection. --- .../java/org/igniterealtime/smack/XmppConnectionStressTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java index 4a93d6dad..5a6192fd9 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java @@ -282,6 +282,7 @@ public class XmppConnectionStressTest { XMPPConnection connection = connections.get(i); EntityFullJid connectionAddress = connection.getUser(); connectionIds.put(connectionAddress, i); + sb.append(i).append(": ").append(connection).append('\n'); } for (Map.Entry> entry : receiveMarkers.entrySet()) { From 9520aa7d90f7ca80828eeed9ed980db1525c4a1e Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 15 Mar 2021 19:24:19 +0100 Subject: [PATCH 21/25] [sinttest] Do not create myReceiveMarkers on demand --- .../igniterealtime/smack/XmppConnectionStressTest.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java index 5a6192fd9..adc0a5be9 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java @@ -134,6 +134,9 @@ public class XmppConnectionStressTest { Map> receiveMarkers = new ConcurrentHashMap<>(connections.size()); for (XMPPConnection connection : connections) { + final Map myReceiveMarkers = new HashMap<>(connections.size()); + receiveMarkers.put(connection, myReceiveMarkers); + connection.addSyncStanzaListener(new StanzaListener() { @Override public void processStanza(Stanza stanza) { @@ -145,12 +148,6 @@ public class XmppConnectionStressTest { Integer messageNumber = (Integer) extension.getProperty(MESSAGE_NUMBER_PROPERTY); - Map myReceiveMarkers = receiveMarkers.get(connection); - if (myReceiveMarkers == null) { - myReceiveMarkers = new HashMap<>(connections.size()); - receiveMarkers.put(connection, myReceiveMarkers); - } - boolean[] fromMarkers = myReceiveMarkers.get(from); if (fromMarkers == null) { fromMarkers = new boolean[configuration.messagesPerConnection]; From 47178fd27d1800a4c5770f570517d645a00a4e98 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 18 Mar 2021 09:01:03 +0100 Subject: [PATCH 22/25] Bump JUnit to 5.7.1 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a39bc7439..e63e2009c 100644 --- a/build.gradle +++ b/build.gradle @@ -125,7 +125,7 @@ allprojects { jxmppVersion = '[1.0.0, 1.0.999]' miniDnsVersion = '[1.0.0, 1.0.999]' smackMinAndroidSdk = 19 - junitVersion = '5.6.2' + junitVersion = '5.7.1' commonsIoVersion = '2.6' bouncyCastleVersion = '1.65' From 35cd1a8f88edd2518b347aafea7d6072df236191 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 18 Mar 2021 21:30:43 +0100 Subject: [PATCH 23/25] [sinttest] Do not lazily create fromMarkers If we do not create the fromMarkers initialized with 'false' at the start, then it may appear like all messages are received, because we only check for false markers. But if there is not even the fromMarkers array, then we do not see those 'false' markers. --- .../smack/XmppConnectionStressTest.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java index adc0a5be9..8f07f98cf 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java @@ -136,6 +136,10 @@ public class XmppConnectionStressTest { for (XMPPConnection connection : connections) { final Map myReceiveMarkers = new HashMap<>(connections.size()); receiveMarkers.put(connection, myReceiveMarkers); + for (XMPPConnection otherConnection : connections) { + boolean[] fromMarkers = new boolean[configuration.messagesPerConnection]; + myReceiveMarkers.put(otherConnection.getUser(), fromMarkers); + } connection.addSyncStanzaListener(new StanzaListener() { @Override @@ -149,10 +153,6 @@ public class XmppConnectionStressTest { Integer messageNumber = (Integer) extension.getProperty(MESSAGE_NUMBER_PROPERTY); boolean[] fromMarkers = myReceiveMarkers.get(from); - if (fromMarkers == null) { - fromMarkers = new boolean[configuration.messagesPerConnection]; - myReceiveMarkers.put(from, fromMarkers); - } // Sanity check: All markers before must be true, all markers including the messageNumber marker must be false. for (int i = 0; i < fromMarkers.length; i++) { @@ -191,10 +191,6 @@ public class XmppConnectionStressTest { fromMarkers[messageNumber] = true; - if (myReceiveMarkers.size() != connections.size()) { - return; - } - for (boolean[] markers : myReceiveMarkers.values()) { if (BooleansUtils.contains(markers, false)) { return; From ddf96828e4c382c053f1be8091504c6b44d2795c Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 18 Mar 2021 21:32:21 +0100 Subject: [PATCH 24/25] [sinttest] Add fromMarkers array to exception message --- .../org/igniterealtime/smack/XmppConnectionStressTest.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java index 8f07f98cf..f741c7cc2 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java @@ -16,6 +16,7 @@ */ package org.igniterealtime.smack; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -176,7 +177,9 @@ public class XmppConnectionStressTest { exceptionMessage.append(i); exceptionMessage.append("\nMessage with id ").append(stanza.getStanzaId()) .append(" from ").append(from) - .append(" to ").append(stanza.getTo()); + .append(" to ").append(stanza.getTo()) + .append('\n'); + exceptionMessage.append("From Markers: ").append(Arrays.toString(fromMarkers)).append('\n'); Exception exception = new Exception(exceptionMessage.toString()); receiveExceptions.put(connection, exception); From b276b89916b89f6d9ac03548ec5bec27493a0f1c Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 18 Mar 2021 21:32:37 +0100 Subject: [PATCH 25/25] [sinttest] Add code comment and empty line --- .../org/igniterealtime/smack/XmppConnectionStressTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java index f741c7cc2..f9d988308 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java @@ -196,9 +196,12 @@ public class XmppConnectionStressTest { for (boolean[] markers : myReceiveMarkers.values()) { if (BooleansUtils.contains(markers, false)) { + // There is at least one message we did not receive yet, therefore do not signal the + // receivedSemaphore. return; } } + // All markers set to true, this means we received all messages. receivedSemaphore.release(); }