mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-26 05:52:06 +01:00
Merge branch '4.2'
This commit is contained in:
commit
384c285fbc
20 changed files with 303 additions and 79 deletions
|
@ -396,6 +396,12 @@ subprojects {
|
||||||
}
|
}
|
||||||
|
|
||||||
clirr {
|
clirr {
|
||||||
|
// 2018-08-14: Disabled Clirr because
|
||||||
|
// - It reports an breaking change in android.jar (seems right, but there is nothing we can do about it)
|
||||||
|
// - Only the first smack-* projects are correctly checked,
|
||||||
|
// the other ones have the output of a clirr report from a previous project
|
||||||
|
// (Look at the clirr reports).
|
||||||
|
enabled false
|
||||||
semver false
|
semver false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
18
repl
18
repl
|
@ -3,15 +3,29 @@ set -e
|
||||||
set -u
|
set -u
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
|
JDWP=false
|
||||||
|
JDWP_PORT=8000
|
||||||
|
|
||||||
while getopts d OPTION "$@"; do
|
while getopts djp: OPTION "$@"; do
|
||||||
case $OPTION in
|
case $OPTION in
|
||||||
d)
|
d)
|
||||||
set -x
|
set -x
|
||||||
;;
|
;;
|
||||||
|
j)
|
||||||
|
JDWP=true
|
||||||
|
;;
|
||||||
|
p)
|
||||||
|
JDWP_PORT=$OPTARG
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
|
EXTRA_JAVA_ARGS=()
|
||||||
|
if $JDWP; then
|
||||||
|
EXTRA_JAVA_ARGS+=("-Xdebug")
|
||||||
|
EXTRA_JAVA_ARGS+=("-Xrunjdwp:server=y,transport=dt_socket,address=${JDWP_PORT},suspend=n")
|
||||||
|
fi
|
||||||
|
|
||||||
PROJECT_ROOT=$(dirname "${BASH_SOURCE[0]}")
|
PROJECT_ROOT=$(dirname "${BASH_SOURCE[0]}")
|
||||||
cd "${PROJECT_ROOT}"
|
cd "${PROJECT_ROOT}"
|
||||||
|
|
||||||
|
@ -27,7 +41,7 @@ GRADLE_CLASSPATH="$(gradle :smack-repl:printClasspath --quiet |\
|
||||||
tail -n1)"
|
tail -n1)"
|
||||||
echo "Finished, starting REPL"
|
echo "Finished, starting REPL"
|
||||||
|
|
||||||
java \
|
java "${EXTRA_JAVA_ARGS[@]}" \
|
||||||
-Dscala.usejavacp=true \
|
-Dscala.usejavacp=true \
|
||||||
-classpath "${GRADLE_CLASSPATH}" \
|
-classpath "${GRADLE_CLASSPATH}" \
|
||||||
ammonite.Main \
|
ammonite.Main \
|
||||||
|
|
|
@ -43,7 +43,10 @@ import org.jivesoftware.smack.util.Async;
|
||||||
* </ol>
|
* </ol>
|
||||||
*
|
*
|
||||||
* {@link ReconnectionPolicy#FIXED_DELAY} - The reconnection mechanism will try to reconnect after a fixed delay
|
* {@link ReconnectionPolicy#FIXED_DELAY} - The reconnection mechanism will try to reconnect after a fixed delay
|
||||||
* independently from the number of reconnection attempts already performed
|
* independently from the number of reconnection attempts already performed.
|
||||||
|
* <p>
|
||||||
|
* Interrupting the reconnection thread will abort the reconnection mechanism.
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Francisco Vives
|
* @author Francisco Vives
|
||||||
* @author Luca Stucchi
|
* @author Luca Stucchi
|
||||||
|
@ -163,7 +166,7 @@ public final class ReconnectionManager {
|
||||||
private ReconnectionManager(AbstractXMPPConnection connection) {
|
private ReconnectionManager(AbstractXMPPConnection connection) {
|
||||||
weakRefConnection = new WeakReference<AbstractXMPPConnection>(connection);
|
weakRefConnection = new WeakReference<AbstractXMPPConnection>(connection);
|
||||||
|
|
||||||
reconnectionRunnable = new Thread() {
|
reconnectionRunnable = new Runnable() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the current number of reconnection attempts
|
* Holds the current number of reconnection attempts
|
||||||
|
@ -211,6 +214,10 @@ public final class ReconnectionManager {
|
||||||
if (connection == null) {
|
if (connection == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset attempts to zero since a new reconnection cycle is started once this runs.
|
||||||
|
attempts = 0;
|
||||||
|
|
||||||
// The process will try to reconnect until the connection is established or
|
// The process will try to reconnect until the connection is established or
|
||||||
// the user cancel the reconnection process AbstractXMPPConnection.disconnect().
|
// the user cancel the reconnection process AbstractXMPPConnection.disconnect().
|
||||||
while (isReconnectionPossible(connection)) {
|
while (isReconnectionPossible(connection)) {
|
||||||
|
@ -219,7 +226,10 @@ public final class ReconnectionManager {
|
||||||
// Sleep until we're ready for the next reconnection attempt. Notify
|
// Sleep until we're ready for the next reconnection attempt. Notify
|
||||||
// listeners once per second about how much time remains before the next
|
// listeners once per second about how much time remains before the next
|
||||||
// reconnection attempt.
|
// reconnection attempt.
|
||||||
while (isReconnectionPossible(connection) && remainingSeconds > 0) {
|
while (remainingSeconds > 0) {
|
||||||
|
if (!isReconnectionPossible(connection)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
remainingSeconds--;
|
remainingSeconds--;
|
||||||
|
@ -228,8 +238,9 @@ public final class ReconnectionManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (InterruptedException e) {
|
catch (InterruptedException e) {
|
||||||
LOGGER.log(Level.FINE, "waiting for reconnection interrupted", e);
|
LOGGER.log(Level.FINE, "Reconnection Thread was interrupted, aborting reconnection mechanism", e);
|
||||||
break;
|
// Exit the reconnection thread in case it was interrupted.
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,37 +248,40 @@ public final class ReconnectionManager {
|
||||||
listener.reconnectingIn(0);
|
listener.reconnectingIn(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isReconnectionPossible(connection)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Makes a reconnection attempt
|
// Makes a reconnection attempt
|
||||||
try {
|
try {
|
||||||
if (isReconnectionPossible(connection)) {
|
|
||||||
try {
|
try {
|
||||||
connection.connect();
|
connection.connect();
|
||||||
} catch (SmackException.AlreadyConnectedException e) {
|
}
|
||||||
|
catch (SmackException.AlreadyConnectedException e) {
|
||||||
LOGGER.log(Level.FINER, "Connection was already connected on reconnection attempt", e);
|
LOGGER.log(Level.FINER, "Connection was already connected on reconnection attempt", e);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// TODO Starting with Smack 4.2, connect() will no
|
|
||||||
// longer login automatically. So change this and the
|
|
||||||
// previous lines to connection.connect().login() in the
|
|
||||||
// 4.2, or any later, branch.
|
|
||||||
if (!connection.isAuthenticated()) {
|
|
||||||
connection.login();
|
connection.login();
|
||||||
}
|
}
|
||||||
// Successfully reconnected.
|
|
||||||
attempts = 0;
|
|
||||||
}
|
|
||||||
catch (SmackException.AlreadyLoggedInException e) {
|
catch (SmackException.AlreadyLoggedInException e) {
|
||||||
// This can happen if another thread concurrently triggers a reconnection
|
// This can happen if another thread concurrently triggers a reconnection
|
||||||
// and/or login. Obviously it should not be handled as a reconnection
|
// and/or login. Obviously it should not be handled as a reconnection
|
||||||
// failure. See also SMACK-725.
|
// failure. See also SMACK-725.
|
||||||
LOGGER.log(Level.FINER, "Reconnection not required, was already logged in", e);
|
LOGGER.log(Level.FINER, "Reconnection not required, was already logged in", e);
|
||||||
}
|
}
|
||||||
catch (SmackException | IOException | XMPPException | InterruptedException e) {
|
catch (SmackException | IOException | XMPPException e) {
|
||||||
// Fires the failed reconnection notification
|
// Fires the failed reconnection notification
|
||||||
for (ConnectionListener listener : connection.connectionListeners) {
|
for (ConnectionListener listener : connection.connectionListeners) {
|
||||||
listener.reconnectionFailed(e);
|
listener.reconnectionFailed(e);
|
||||||
}
|
}
|
||||||
|
// Failed to reconnect, try again.
|
||||||
|
continue;
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
LOGGER.log(Level.FINE, "Reconnection Thread was interrupted, aborting reconnection mechanism", e);
|
||||||
|
// Exit the reconnection thread in case it was interrupted.
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Successfully reconnected .
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -314,7 +328,7 @@ public final class ReconnectionManager {
|
||||||
*
|
*
|
||||||
* @return true, if the reconnection mechanism is enabled.
|
* @return true, if the reconnection mechanism is enabled.
|
||||||
*/
|
*/
|
||||||
public boolean isAutomaticReconnectEnabled() {
|
public synchronized boolean isAutomaticReconnectEnabled() {
|
||||||
return automaticReconnectEnabled;
|
return automaticReconnectEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,6 +362,20 @@ public final class ReconnectionManager {
|
||||||
"Smack Reconnection Manager (" + connection.getConnectionCounter() + ')');
|
"Smack Reconnection Manager (" + connection.getConnectionCounter() + ')');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abort a possibly running reconnection mechanism.
|
||||||
|
*
|
||||||
|
* @since 4.2.2
|
||||||
|
*/
|
||||||
|
public synchronized void abortPossiblyRunningReconnection() {
|
||||||
|
if (reconnectionThread == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
reconnectionThread.interrupt();
|
||||||
|
reconnectionThread = null;
|
||||||
|
}
|
||||||
|
|
||||||
private final ConnectionListener connectionListener = new AbstractConnectionListener() {
|
private final ConnectionListener connectionListener = new AbstractConnectionListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -339,7 +339,7 @@ public final class SmackConfiguration {
|
||||||
return defaultHostnameVerififer;
|
return defaultHostnameVerififer;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum UnknownIqRequestReplyMode {
|
public enum UnknownIqRequestReplyMode {
|
||||||
doNotReply,
|
doNotReply,
|
||||||
replyFeatureNotImplemented,
|
replyFeatureNotImplemented,
|
||||||
replyServiceUnavailable,
|
replyServiceUnavailable,
|
||||||
|
|
|
@ -23,6 +23,7 @@ import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.util.Objects;
|
||||||
import org.jivesoftware.smack.util.PacketUtil;
|
import org.jivesoftware.smack.util.PacketUtil;
|
||||||
import org.jivesoftware.smack.util.XmlStringBuilder;
|
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||||
|
|
||||||
|
@ -85,6 +86,7 @@ public class AbstractError {
|
||||||
* @return the descriptive text or null.
|
* @return the descriptive text or null.
|
||||||
*/
|
*/
|
||||||
public String getDescriptiveText(String xmllang) {
|
public String getDescriptiveText(String xmllang) {
|
||||||
|
Objects.requireNonNull(xmllang, "xmllang must not be null");
|
||||||
return descriptiveTexts.get(xmllang);
|
return descriptiveTexts.get(xmllang);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,7 +107,8 @@ public class AbstractError {
|
||||||
String xmllang = entry.getKey();
|
String xmllang = entry.getKey();
|
||||||
String text = entry.getValue();
|
String text = entry.getValue();
|
||||||
xml.halfOpenElement("text").xmlnsAttribute(textNamespace)
|
xml.halfOpenElement("text").xmlnsAttribute(textNamespace)
|
||||||
.xmllangAttribute(xmllang).rightAngleBracket();
|
.optXmlLangAttribute(xmllang)
|
||||||
|
.rightAngleBracket();
|
||||||
xml.escape(text);
|
xml.escape(text);
|
||||||
xml.closeElement("text");
|
xml.closeElement("text");
|
||||||
}
|
}
|
||||||
|
@ -120,6 +123,15 @@ public class AbstractError {
|
||||||
protected List<ExtensionElement> extensions;
|
protected List<ExtensionElement> extensions;
|
||||||
|
|
||||||
public B setDescriptiveTexts(Map<String, String> descriptiveTexts) {
|
public B setDescriptiveTexts(Map<String, String> descriptiveTexts) {
|
||||||
|
if (descriptiveTexts == null) {
|
||||||
|
this.descriptiveTexts = null;
|
||||||
|
return getThis();
|
||||||
|
}
|
||||||
|
for (String key : descriptiveTexts.keySet()) {
|
||||||
|
if (key == null) {
|
||||||
|
throw new IllegalArgumentException("descriptiveTexts cannot contain null key");
|
||||||
|
}
|
||||||
|
}
|
||||||
if (this.descriptiveTexts == null) {
|
if (this.descriptiveTexts == null) {
|
||||||
this.descriptiveTexts = descriptiveTexts;
|
this.descriptiveTexts = descriptiveTexts;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,14 +38,14 @@ import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||||
* <tr><td>conflict</td><td>CANCEL</td><td>8.3.3.2</td></tr>
|
* <tr><td>conflict</td><td>CANCEL</td><td>8.3.3.2</td></tr>
|
||||||
* <tr><td>feature-not-implemented</td><td>CANCEL</td><td>8.3.3.3</td></tr>
|
* <tr><td>feature-not-implemented</td><td>CANCEL</td><td>8.3.3.3</td></tr>
|
||||||
* <tr><td>forbidden</td><td>AUTH</td><td>8.3.3.4</td></tr>
|
* <tr><td>forbidden</td><td>AUTH</td><td>8.3.3.4</td></tr>
|
||||||
* <tr><td>gone</td><td>MODIFY</td><td>8.3.3.5</td></tr>
|
* <tr><td>gone</td><td>CANCEL</td><td>8.3.3.5</td></tr>
|
||||||
* <tr><td>internal-server-error</td><td>WAIT</td><td>8.3.3.6</td></tr>
|
* <tr><td>internal-server-error</td><td>WAIT</td><td>8.3.3.6</td></tr>
|
||||||
* <tr><td>item-not-found</td><td>CANCEL</td><td>8.3.3.7</td></tr>
|
* <tr><td>item-not-found</td><td>CANCEL</td><td>8.3.3.7</td></tr>
|
||||||
* <tr><td>jid-malformed</td><td>MODIFY</td><td>8.3.3.8</td></tr>
|
* <tr><td>jid-malformed</td><td>MODIFY</td><td>8.3.3.8</td></tr>
|
||||||
* <tr><td>not-acceptable</td><td> MODIFY</td><td>8.3.3.9</td></tr>
|
* <tr><td>not-acceptable</td><td>MODIFY</td><td>8.3.3.9</td></tr>
|
||||||
* <tr><td>not-allowed</td><td>CANCEL</td><td>8.3.3.10</td></tr>
|
* <tr><td>not-allowed</td><td>CANCEL</td><td>8.3.3.10</td></tr>
|
||||||
* <tr><td>not-authorized</td><td>AUTH</td><td>8.3.3.11</td></tr>
|
* <tr><td>not-authorized</td><td>AUTH</td><td>8.3.3.11</td></tr>
|
||||||
* <tr><td>policy-violation</td><td>AUTH</td><td>8.3.3.12</td></tr>
|
* <tr><td>policy-violation</td><td>MODIFY</td><td>8.3.3.12</td></tr>
|
||||||
* <tr><td>recipient-unavailable</td><td>WAIT</td><td>8.3.3.13</td></tr>
|
* <tr><td>recipient-unavailable</td><td>WAIT</td><td>8.3.3.13</td></tr>
|
||||||
* <tr><td>redirect</td><td>MODIFY</td><td>8.3.3.14</td></tr>
|
* <tr><td>redirect</td><td>MODIFY</td><td>8.3.3.14</td></tr>
|
||||||
* <tr><td>registration-required</td><td>AUTH</td><td>8.3.3.15</td></tr>
|
* <tr><td>registration-required</td><td>AUTH</td><td>8.3.3.15</td></tr>
|
||||||
|
@ -54,7 +54,7 @@ import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||||
* <tr><td>resource-constraint</td><td>WAIT</td><td>8.3.3.18</td></tr>
|
* <tr><td>resource-constraint</td><td>WAIT</td><td>8.3.3.18</td></tr>
|
||||||
* <tr><td>service-unavailable</td><td>CANCEL</td><td>8.3.3.19</td></tr>
|
* <tr><td>service-unavailable</td><td>CANCEL</td><td>8.3.3.19</td></tr>
|
||||||
* <tr><td>subscription-required</td><td>AUTH</td><td>8.3.3.20</td></tr>
|
* <tr><td>subscription-required</td><td>AUTH</td><td>8.3.3.20</td></tr>
|
||||||
* <tr><td>undefined-condition</td><td>WAIT</td><td>8.3.3.21</td></tr>
|
* <tr><td>undefined-condition</td><td>MODIFY</td><td>8.3.3.21</td></tr>
|
||||||
* <tr><td>unexpected-request</td><td>WAIT</td><td>8.3.3.22</td></tr>
|
* <tr><td>unexpected-request</td><td>WAIT</td><td>8.3.3.22</td></tr>
|
||||||
* </table>
|
* </table>
|
||||||
*
|
*
|
||||||
|
@ -69,7 +69,7 @@ public class XMPPError extends AbstractError {
|
||||||
public static final String ERROR = "error";
|
public static final String ERROR = "error";
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(XMPPError.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(XMPPError.class.getName());
|
||||||
private static final Map<Condition, Type> CONDITION_TO_TYPE = new HashMap<Condition, Type>();
|
static final Map<Condition, Type> CONDITION_TO_TYPE = new HashMap<Condition, Type>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
CONDITION_TO_TYPE.put(Condition.bad_request, Type.MODIFY);
|
CONDITION_TO_TYPE.put(Condition.bad_request, Type.MODIFY);
|
||||||
|
@ -90,9 +90,10 @@ public class XMPPError extends AbstractError {
|
||||||
CONDITION_TO_TYPE.put(Condition.remote_server_not_found, Type.CANCEL);
|
CONDITION_TO_TYPE.put(Condition.remote_server_not_found, Type.CANCEL);
|
||||||
CONDITION_TO_TYPE.put(Condition.remote_server_timeout, Type.WAIT);
|
CONDITION_TO_TYPE.put(Condition.remote_server_timeout, Type.WAIT);
|
||||||
CONDITION_TO_TYPE.put(Condition.resource_constraint, Type.WAIT);
|
CONDITION_TO_TYPE.put(Condition.resource_constraint, Type.WAIT);
|
||||||
CONDITION_TO_TYPE.put(Condition.service_unavailable, Type.WAIT);
|
CONDITION_TO_TYPE.put(Condition.service_unavailable, Type.CANCEL);
|
||||||
CONDITION_TO_TYPE.put(Condition.subscription_required, Type.WAIT);
|
CONDITION_TO_TYPE.put(Condition.subscription_required, Type.AUTH);
|
||||||
CONDITION_TO_TYPE.put(Condition.unexpected_request, Type.MODIFY);
|
CONDITION_TO_TYPE.put(Condition.undefined_condition, Type.MODIFY);
|
||||||
|
CONDITION_TO_TYPE.put(Condition.unexpected_request, Type.WAIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Condition condition;
|
private final Condition condition;
|
||||||
|
|
|
@ -749,6 +749,12 @@ public class PacketParserUtils {
|
||||||
descriptiveTexts = new HashMap<String, String>();
|
descriptiveTexts = new HashMap<String, String>();
|
||||||
}
|
}
|
||||||
String xmllang = getLanguageAttribute(parser);
|
String xmllang = getLanguageAttribute(parser);
|
||||||
|
if (xmllang == null) {
|
||||||
|
// XMPPError assumes the default locale, 'en', or the empty string.
|
||||||
|
// Establish the invariant that there is never null as a key.
|
||||||
|
xmllang = "";
|
||||||
|
}
|
||||||
|
|
||||||
String text = parser.nextText();
|
String text = parser.nextText();
|
||||||
String previousValue = descriptiveTexts.put(xmllang, text);
|
String previousValue = descriptiveTexts.put(xmllang, text);
|
||||||
assert (previousValue == null);
|
assert (previousValue == null);
|
||||||
|
|
|
@ -361,7 +361,7 @@ public class XmlStringBuilder implements Appendable, CharSequence {
|
||||||
}
|
}
|
||||||
|
|
||||||
public XmlStringBuilder optXmlLangAttribute(String lang) {
|
public XmlStringBuilder optXmlLangAttribute(String lang) {
|
||||||
if (lang != null) {
|
if (!StringUtils.isNullOrEmpty(lang)) {
|
||||||
xmllangAttribute(lang);
|
xmllangAttribute(lang);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -59,6 +59,20 @@ public abstract class DNSResolver {
|
||||||
return new HostAddress(name, port, inetAddresses);
|
return new HostAddress(name, port, inetAddresses);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup the IP addresses of a given host name. Returns <code>null</code> if there was an error, in which the error
|
||||||
|
* reason will be added in form of a <code>HostAddress</code> to <code>failedAddresses</code>. Returns a empty list
|
||||||
|
* in case the DNS name exists but has no associated A or AAAA resource records. Otherwise, if the resolution was
|
||||||
|
* successful <em>and</em> there is at least one A or AAAA resource record, then a non-empty list will be returned.
|
||||||
|
* <p>
|
||||||
|
* Concrete DNS resolver implementations are free to overwrite this, but have to stick to the interface contract.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param name the DNS name to lookup
|
||||||
|
* @param failedAddresses a list with the failed addresses
|
||||||
|
* @param dnssecMode the selected DNSSEC mode
|
||||||
|
* @return A list, either empty or non-empty, or <code>null</code>
|
||||||
|
*/
|
||||||
protected List<InetAddress> lookupHostAddress0(String name, List<HostAddress> failedAddresses, DnssecMode dnssecMode) {
|
protected List<InetAddress> lookupHostAddress0(String name, List<HostAddress> failedAddresses, DnssecMode dnssecMode) {
|
||||||
// Default implementation of a DNS name lookup for A/AAAA records. It is assumed that this method does never
|
// Default implementation of a DNS name lookup for A/AAAA records. It is assumed that this method does never
|
||||||
// support DNSSEC. Subclasses are free to override this method.
|
// support DNSSEC. Subclasses are free to override this method.
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright © 2017 Ingo Bauersachs
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.jivesoftware.smack.packet;
|
||||||
|
|
||||||
|
import static org.jivesoftware.smack.packet.XMPPError.Condition;
|
||||||
|
import static org.jivesoftware.smack.packet.XMPPError.Type;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class XMPPErrorTest {
|
||||||
|
@Test
|
||||||
|
public void testConditionHasDefaultTypeMapping() throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
Map<Condition, Type> conditionToTypeMap = XMPPError.CONDITION_TO_TYPE;
|
||||||
|
assertEquals("CONDITION_TO_TYPE map is likely out of sync with Condition enum",
|
||||||
|
Condition.values().length,
|
||||||
|
conditionToTypeMap.size());
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,7 +25,9 @@ import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import javax.xml.parsers.FactoryConfigurationError;
|
import javax.xml.parsers.FactoryConfigurationError;
|
||||||
|
@ -35,6 +37,7 @@ import javax.xml.transform.TransformerException;
|
||||||
import org.jivesoftware.smack.packet.Message;
|
import org.jivesoftware.smack.packet.Message;
|
||||||
import org.jivesoftware.smack.packet.Presence;
|
import org.jivesoftware.smack.packet.Presence;
|
||||||
import org.jivesoftware.smack.packet.Stanza;
|
import org.jivesoftware.smack.packet.Stanza;
|
||||||
|
import org.jivesoftware.smack.packet.XMPPError;
|
||||||
import org.jivesoftware.smack.sasl.SASLError;
|
import org.jivesoftware.smack.sasl.SASLError;
|
||||||
import org.jivesoftware.smack.sasl.packet.SaslStreamElements;
|
import org.jivesoftware.smack.sasl.packet.SaslStreamElements;
|
||||||
import org.jivesoftware.smack.sasl.packet.SaslStreamElements.SASLFailure;
|
import org.jivesoftware.smack.sasl.packet.SaslStreamElements.SASLFailure;
|
||||||
|
@ -867,4 +870,44 @@ public class PacketParserUtilsTest {
|
||||||
return otherLanguage;
|
return otherLanguage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void descriptiveTextNullLangPassedMap() throws Exception {
|
||||||
|
final String text = "Dummy descriptive text";
|
||||||
|
Map<String, String> texts = new HashMap<>();
|
||||||
|
texts.put(null, text);
|
||||||
|
XMPPError
|
||||||
|
.getBuilder(XMPPError.Condition.internal_server_error)
|
||||||
|
.setDescriptiveTexts(texts)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ensureNoEmptyLangInDescriptiveText() throws Exception {
|
||||||
|
final String text = "Dummy descriptive text";
|
||||||
|
Map<String, String> texts = new HashMap<>();
|
||||||
|
texts.put("", text);
|
||||||
|
XMPPError error = XMPPError
|
||||||
|
.getBuilder(XMPPError.Condition.internal_server_error)
|
||||||
|
.setDescriptiveTexts(texts)
|
||||||
|
.build();
|
||||||
|
final String errorXml = XMLBuilder
|
||||||
|
.create(XMPPError.ERROR).a("type", "cancel").up()
|
||||||
|
.element("internal-server-error", XMPPError.NAMESPACE).up()
|
||||||
|
.element("text", XMPPError.NAMESPACE).t(text).up()
|
||||||
|
.asString();
|
||||||
|
XmlUnitUtils.assertSimilar(errorXml, error.toXML());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ensureNoNullLangInParsedDescriptiveTexts() throws Exception {
|
||||||
|
final String text = "Dummy descriptive text";
|
||||||
|
final String errorXml = XMLBuilder
|
||||||
|
.create(XMPPError.ERROR).a("type", "cancel").up()
|
||||||
|
.element("internal-server-error", XMPPError.NAMESPACE).up()
|
||||||
|
.element("text", XMPPError.NAMESPACE).t(text).up()
|
||||||
|
.asString();
|
||||||
|
XmlPullParser parser = TestUtils.getParser(errorXml);
|
||||||
|
XMPPError error = PacketParserUtils.parseError(parser).build();
|
||||||
|
assertEquals(text, error.getDescriptiveText());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,13 +87,32 @@ public final class PushNotificationsManager extends Manager {
|
||||||
* @throws XMPPErrorException
|
* @throws XMPPErrorException
|
||||||
* @throws NotConnectedException
|
* @throws NotConnectedException
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
|
* @deprecated Use {@link #isSupported()} instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
|
// TODO: Remove in Smack 4.3
|
||||||
public boolean isSupportedByServer()
|
public boolean isSupportedByServer()
|
||||||
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||||
return ServiceDiscoveryManager.getInstanceFor(connection())
|
return ServiceDiscoveryManager.getInstanceFor(connection())
|
||||||
.serverSupportsFeature(PushNotificationsElements.NAMESPACE);
|
.serverSupportsFeature(PushNotificationsElements.NAMESPACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if Push Notifications are supported by this account.
|
||||||
|
*
|
||||||
|
* @return true if Push Notifications are supported by this account.
|
||||||
|
* @throws NoResponseException
|
||||||
|
* @throws XMPPErrorException
|
||||||
|
* @throws NotConnectedException
|
||||||
|
* @throws InterruptedException
|
||||||
|
* @since 4.2.2
|
||||||
|
*/
|
||||||
|
public boolean isSupported()
|
||||||
|
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||||
|
return ServiceDiscoveryManager.getInstanceFor(connection()).accountSupportsFeatures(
|
||||||
|
PushNotificationsElements.NAMESPACE);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable push notifications.
|
* Enable push notifications.
|
||||||
*
|
*
|
||||||
|
|
|
@ -52,6 +52,7 @@ import org.jivesoftware.smackx.disco.packet.DiscoverItems;
|
||||||
import org.jivesoftware.smackx.xdata.packet.DataForm;
|
import org.jivesoftware.smackx.xdata.packet.DataForm;
|
||||||
|
|
||||||
import org.jxmpp.jid.DomainBareJid;
|
import org.jxmpp.jid.DomainBareJid;
|
||||||
|
import org.jxmpp.jid.EntityBareJid;
|
||||||
import org.jxmpp.jid.Jid;
|
import org.jxmpp.jid.Jid;
|
||||||
import org.jxmpp.util.cache.Cache;
|
import org.jxmpp.util.cache.Cache;
|
||||||
import org.jxmpp.util.cache.ExpirationCache;
|
import org.jxmpp.util.cache.ExpirationCache;
|
||||||
|
@ -680,6 +681,41 @@ public final class ServiceDiscoveryManager extends Manager {
|
||||||
return supportsFeatures(connection().getXMPPServiceDomain(), features);
|
return supportsFeatures(connection().getXMPPServiceDomain(), features);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the given features are supported by the connection account. This means that the discovery information
|
||||||
|
* lookup will be performed on the bare JID of the connection managed by this ServiceDiscoveryManager.
|
||||||
|
*
|
||||||
|
* @param features the features to check
|
||||||
|
* @return <code>true</code> if all features are supported by the connection account, <code>false</code> otherwise
|
||||||
|
* @throws NoResponseException
|
||||||
|
* @throws XMPPErrorException
|
||||||
|
* @throws NotConnectedException
|
||||||
|
* @throws InterruptedException
|
||||||
|
* @since 4.2.2
|
||||||
|
*/
|
||||||
|
public boolean accountSupportsFeatures(CharSequence... features)
|
||||||
|
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||||
|
return accountSupportsFeatures(Arrays.asList(features));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the given collection of features are supported by the connection account. This means that the discovery
|
||||||
|
* information lookup will be performed on the bare JID of the connection managed by this ServiceDiscoveryManager.
|
||||||
|
*
|
||||||
|
* @param features a collection of features
|
||||||
|
* @return <code>true</code> if all features are supported by the connection account, <code>false</code> otherwise
|
||||||
|
* @throws NoResponseException
|
||||||
|
* @throws XMPPErrorException
|
||||||
|
* @throws NotConnectedException
|
||||||
|
* @throws InterruptedException
|
||||||
|
* @since 4.2.2
|
||||||
|
*/
|
||||||
|
public boolean accountSupportsFeatures(Collection<? extends CharSequence> features)
|
||||||
|
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||||
|
EntityBareJid accountJid = connection().getUser().asEntityBareJid();
|
||||||
|
return supportsFeatures(accountJid, features);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queries the remote entity for it's features and returns true if the given feature is found.
|
* Queries the remote entity for it's features and returns true if the given feature is found.
|
||||||
*
|
*
|
||||||
|
|
|
@ -215,7 +215,7 @@ public final class Roster extends Manager {
|
||||||
* Returns the default subscription processing mode to use when a new Roster is created. The
|
* Returns the default subscription processing mode to use when a new Roster is created. The
|
||||||
* subscription processing mode dictates what action Smack will take when subscription
|
* subscription processing mode dictates what action Smack will take when subscription
|
||||||
* requests from other users are made. The default subscription mode
|
* requests from other users are made. The default subscription mode
|
||||||
* is {@link SubscriptionMode#accept_all}.
|
* is {@link SubscriptionMode#reject_all}.
|
||||||
*
|
*
|
||||||
* @return the default subscription mode to use for new Rosters
|
* @return the default subscription mode to use for new Rosters
|
||||||
*/
|
*/
|
||||||
|
@ -227,7 +227,7 @@ public final class Roster extends Manager {
|
||||||
* Sets the default subscription processing mode to use when a new Roster is created. The
|
* Sets the default subscription processing mode to use when a new Roster is created. The
|
||||||
* subscription processing mode dictates what action Smack will take when subscription
|
* subscription processing mode dictates what action Smack will take when subscription
|
||||||
* requests from other users are made. The default subscription mode
|
* requests from other users are made. The default subscription mode
|
||||||
* is {@link SubscriptionMode#accept_all}.
|
* is {@link SubscriptionMode#reject_all}.
|
||||||
*
|
*
|
||||||
* @param subscriptionMode the default subscription mode to use for new Rosters.
|
* @param subscriptionMode the default subscription mode to use for new Rosters.
|
||||||
*/
|
*/
|
||||||
|
@ -385,7 +385,7 @@ public final class Roster extends Manager {
|
||||||
/**
|
/**
|
||||||
* Returns the subscription processing mode, which dictates what action
|
* Returns the subscription processing mode, which dictates what action
|
||||||
* Smack will take when subscription requests from other users are made.
|
* Smack will take when subscription requests from other users are made.
|
||||||
* The default subscription mode is {@link SubscriptionMode#accept_all}.
|
* The default subscription mode is {@link SubscriptionMode#reject_all}.
|
||||||
* <p>
|
* <p>
|
||||||
* If using the manual mode, a PacketListener should be registered that
|
* If using the manual mode, a PacketListener should be registered that
|
||||||
* listens for Presence packets that have a type of
|
* listens for Presence packets that have a type of
|
||||||
|
@ -401,7 +401,7 @@ public final class Roster extends Manager {
|
||||||
/**
|
/**
|
||||||
* Sets the subscription processing mode, which dictates what action
|
* Sets the subscription processing mode, which dictates what action
|
||||||
* Smack will take when subscription requests from other users are made.
|
* Smack will take when subscription requests from other users are made.
|
||||||
* The default subscription mode is {@link SubscriptionMode#accept_all}.
|
* The default subscription mode is {@link SubscriptionMode#reject_all}.
|
||||||
* <p>
|
* <p>
|
||||||
* If using the manual mode, a PacketListener should be registered that
|
* If using the manual mode, a PacketListener should be registered that
|
||||||
* listens for Presence packets that have a type of
|
* listens for Presence packets that have a type of
|
||||||
|
@ -1409,14 +1409,14 @@ public final class Roster extends Manager {
|
||||||
public enum SubscriptionMode {
|
public enum SubscriptionMode {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Automatically accept all subscription and unsubscription requests. This is
|
* Automatically accept all subscription and unsubscription requests.
|
||||||
* the default mode and is suitable for simple client. More complex client will
|
* This is suitable for simple clients. More complex clients will
|
||||||
* likely wish to handle subscription requests manually.
|
* likely wish to handle subscription requests manually.
|
||||||
*/
|
*/
|
||||||
accept_all,
|
accept_all,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Automatically reject all subscription requests.
|
* Automatically reject all subscription requests. This is the default mode.
|
||||||
*/
|
*/
|
||||||
reject_all,
|
reject_all,
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ import static junit.framework.TestCase.assertNotNull;
|
||||||
import static junit.framework.TestCase.assertNotSame;
|
import static junit.framework.TestCase.assertNotSame;
|
||||||
import static junit.framework.TestCase.assertNull;
|
import static junit.framework.TestCase.assertNull;
|
||||||
import static junit.framework.TestCase.assertTrue;
|
import static junit.framework.TestCase.assertTrue;
|
||||||
|
import static org.jivesoftware.smackx.omemo.OmemoIntegrationTestHelper.cleanServerSideTraces;
|
||||||
import static org.jivesoftware.smackx.omemo.OmemoIntegrationTestHelper.deletePath;
|
import static org.jivesoftware.smackx.omemo.OmemoIntegrationTestHelper.deletePath;
|
||||||
import static org.jivesoftware.smackx.omemo.OmemoIntegrationTestHelper.setUpOmemoManager;
|
import static org.jivesoftware.smackx.omemo.OmemoIntegrationTestHelper.setUpOmemoManager;
|
||||||
|
|
||||||
|
@ -154,6 +155,8 @@ public class OmemoStoreTest extends AbstractOmemoIntegrationTest {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void after() {
|
public void after() {
|
||||||
|
cleanServerSideTraces(alice);
|
||||||
|
cleanServerSideTraces(bob);
|
||||||
alice.shutdown();
|
alice.shutdown();
|
||||||
bob.shutdown();
|
bob.shutdown();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.jivesoftware.smackx.omemo;
|
||||||
import static org.jivesoftware.smackx.omemo.util.OmemoConstants.BODY_OMEMO_HINT;
|
import static org.jivesoftware.smackx.omemo.util.OmemoConstants.BODY_OMEMO_HINT;
|
||||||
import static org.jivesoftware.smackx.omemo.util.OmemoConstants.OMEMO;
|
import static org.jivesoftware.smackx.omemo.util.OmemoConstants.OMEMO;
|
||||||
import static org.jivesoftware.smackx.omemo.util.OmemoConstants.OMEMO_NAMESPACE_V_AXOLOTL;
|
import static org.jivesoftware.smackx.omemo.util.OmemoConstants.OMEMO_NAMESPACE_V_AXOLOTL;
|
||||||
|
import static org.jivesoftware.smackx.omemo.util.OmemoConstants.PEP_NODE_DEVICE_LIST_NOTIFY;
|
||||||
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -132,6 +133,9 @@ public final class OmemoManager extends Manager {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
PEPManager.getInstanceFor(connection).addPEPListener(deviceListUpdateListener);
|
||||||
|
ServiceDiscoveryManager.getInstanceFor(connection).addFeature(PEP_NODE_DEVICE_LIST_NOTIFY);
|
||||||
|
|
||||||
service = OmemoService.getInstance();
|
service = OmemoService.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -810,17 +814,24 @@ public final class OmemoManager extends Manager {
|
||||||
Set<Integer> deviceListIds = omemoDeviceListElement.copyDeviceIds();
|
Set<Integer> deviceListIds = omemoDeviceListElement.copyDeviceIds();
|
||||||
//enroll at the deviceList
|
//enroll at the deviceList
|
||||||
deviceListIds.add(ourDeviceId);
|
deviceListIds.add(ourDeviceId);
|
||||||
omemoDeviceListElement = new OmemoDeviceListVAxolotlElement(deviceListIds);
|
final OmemoDeviceListVAxolotlElement newOmemoDeviceListElement = new OmemoDeviceListVAxolotlElement(deviceListIds);
|
||||||
|
|
||||||
|
// PEPListener is a synchronous listener. Avoid any deadlocks by using an async task to update the device list.
|
||||||
|
Async.go(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
try {
|
try {
|
||||||
OmemoService.publishDeviceIds(OmemoManager.this, omemoDeviceListElement);
|
OmemoService.publishDeviceIds(OmemoManager.this, newOmemoDeviceListElement);
|
||||||
} catch (SmackException | InterruptedException | XMPPException.XMPPErrorException e) {
|
}
|
||||||
//TODO: It might be dangerous NOT to retry publishing our deviceId
|
catch (SmackException | InterruptedException | XMPPException.XMPPErrorException e) {
|
||||||
|
// TODO: It might be dangerous NOT to retry publishing our deviceId
|
||||||
LOGGER.log(Level.SEVERE,
|
LOGGER.log(Level.SEVERE,
|
||||||
"Could not publish our device list after an update without our id was received: "
|
"Could not publish our device list after an update without our id was received: "
|
||||||
+ e.getMessage());
|
+ e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,7 +19,6 @@ package org.jivesoftware.smackx.omemo;
|
||||||
import static org.jivesoftware.smackx.omemo.util.OmemoConstants.OMEMO_NAMESPACE_V_AXOLOTL;
|
import static org.jivesoftware.smackx.omemo.util.OmemoConstants.OMEMO_NAMESPACE_V_AXOLOTL;
|
||||||
import static org.jivesoftware.smackx.omemo.util.OmemoConstants.PEP_NODE_BUNDLE_FROM_DEVICE_ID;
|
import static org.jivesoftware.smackx.omemo.util.OmemoConstants.PEP_NODE_BUNDLE_FROM_DEVICE_ID;
|
||||||
import static org.jivesoftware.smackx.omemo.util.OmemoConstants.PEP_NODE_DEVICE_LIST;
|
import static org.jivesoftware.smackx.omemo.util.OmemoConstants.PEP_NODE_DEVICE_LIST;
|
||||||
import static org.jivesoftware.smackx.omemo.util.OmemoConstants.PEP_NODE_DEVICE_LIST_NOTIFY;
|
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.security.InvalidAlgorithmParameterException;
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
|
@ -55,7 +54,6 @@ import org.jivesoftware.smack.util.Async;
|
||||||
import org.jivesoftware.smackx.carbons.CarbonCopyReceivedListener;
|
import org.jivesoftware.smackx.carbons.CarbonCopyReceivedListener;
|
||||||
import org.jivesoftware.smackx.carbons.CarbonManager;
|
import org.jivesoftware.smackx.carbons.CarbonManager;
|
||||||
import org.jivesoftware.smackx.carbons.packet.CarbonExtension;
|
import org.jivesoftware.smackx.carbons.packet.CarbonExtension;
|
||||||
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
|
||||||
import org.jivesoftware.smackx.forward.packet.Forwarded;
|
import org.jivesoftware.smackx.forward.packet.Forwarded;
|
||||||
import org.jivesoftware.smackx.mam.MamManager;
|
import org.jivesoftware.smackx.mam.MamManager;
|
||||||
import org.jivesoftware.smackx.muc.MultiUserChat;
|
import org.jivesoftware.smackx.muc.MultiUserChat;
|
||||||
|
@ -79,7 +77,6 @@ import org.jivesoftware.smackx.omemo.internal.OmemoMessageInformation;
|
||||||
import org.jivesoftware.smackx.omemo.internal.OmemoSession;
|
import org.jivesoftware.smackx.omemo.internal.OmemoSession;
|
||||||
import org.jivesoftware.smackx.omemo.util.OmemoConstants;
|
import org.jivesoftware.smackx.omemo.util.OmemoConstants;
|
||||||
import org.jivesoftware.smackx.omemo.util.OmemoMessageBuilder;
|
import org.jivesoftware.smackx.omemo.util.OmemoMessageBuilder;
|
||||||
import org.jivesoftware.smackx.pep.PEPManager;
|
|
||||||
import org.jivesoftware.smackx.pubsub.LeafNode;
|
import org.jivesoftware.smackx.pubsub.LeafNode;
|
||||||
import org.jivesoftware.smackx.pubsub.PayloadItem;
|
import org.jivesoftware.smackx.pubsub.PayloadItem;
|
||||||
import org.jivesoftware.smackx.pubsub.PubSubException;
|
import org.jivesoftware.smackx.pubsub.PubSubException;
|
||||||
|
@ -228,7 +225,6 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
||||||
publishDeviceIdIfNeeded(omemoManager, false, mustPublishId);
|
publishDeviceIdIfNeeded(omemoManager, false, mustPublishId);
|
||||||
publishBundle(omemoManager);
|
publishBundle(omemoManager);
|
||||||
|
|
||||||
subscribeToDeviceLists(omemoManager);
|
|
||||||
registerOmemoMessageStanzaListeners(omemoManager); //Wait for new OMEMO messages
|
registerOmemoMessageStanzaListeners(omemoManager); //Wait for new OMEMO messages
|
||||||
getOmemoStoreBackend().initializeOmemoSessions(omemoManager); //Preload existing OMEMO sessions
|
getOmemoStoreBackend().initializeOmemoSessions(omemoManager); //Preload existing OMEMO sessions
|
||||||
}
|
}
|
||||||
|
@ -588,16 +584,6 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
||||||
return new OmemoDeviceListVAxolotlElement(emptySet);
|
return new OmemoDeviceListVAxolotlElement(emptySet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Subscribe to the device lists of our contacts using PEP.
|
|
||||||
*
|
|
||||||
* @param omemoManager omemoManager we want to subscribe with
|
|
||||||
*/
|
|
||||||
private static void subscribeToDeviceLists(OmemoManager omemoManager) {
|
|
||||||
registerDeviceListListener(omemoManager);
|
|
||||||
ServiceDiscoveryManager.getInstanceFor(omemoManager.getConnection()).addFeature(PEP_NODE_DEVICE_LIST_NOTIFY);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build sessions for all devices of the contact that we do not have a session with yet.
|
* Build sessions for all devices of the contact that we do not have a session with yet.
|
||||||
*
|
*
|
||||||
|
@ -694,16 +680,6 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
|
||||||
*/
|
*/
|
||||||
protected abstract void processBundle(OmemoManager omemoManager, T_Bundle bundle, OmemoDevice device) throws CorruptedOmemoKeyException;
|
protected abstract void processBundle(OmemoManager omemoManager, T_Bundle bundle, OmemoDevice device) throws CorruptedOmemoKeyException;
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a PEPListener that listens for deviceList updates.
|
|
||||||
*
|
|
||||||
* @param omemoManager omemoManager we want to register with.
|
|
||||||
*/
|
|
||||||
private static void registerDeviceListListener(final OmemoManager omemoManager) {
|
|
||||||
PEPManager.getInstanceFor(omemoManager.getConnection()).removePEPListener(omemoManager.deviceListUpdateListener);
|
|
||||||
PEPManager.getInstanceFor(omemoManager.getConnection()).addPEPListener(omemoManager.deviceListUpdateListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process a received message. Try to decrypt it in case we are a recipient device. If we are not a recipient
|
* Process a received message. Try to decrypt it in case we are a recipient device. If we are not a recipient
|
||||||
* device, return null.
|
* device, return null.
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.jivesoftware.smack.util.dns.dnsjava;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import org.jivesoftware.smack.ConnectionConfiguration.DnssecMode;
|
import org.jivesoftware.smack.ConnectionConfiguration.DnssecMode;
|
||||||
import org.jivesoftware.smack.initializer.SmackInitializer;
|
import org.jivesoftware.smack.initializer.SmackInitializer;
|
||||||
|
@ -73,7 +74,13 @@ public class DNSJavaResolver extends DNSResolver implements SmackInitializer {
|
||||||
int weight = srvRecord.getWeight();
|
int weight = srvRecord.getWeight();
|
||||||
|
|
||||||
List<InetAddress> hostAddresses = lookupHostAddress0(host, failedAddresses, dnssecMode);
|
List<InetAddress> hostAddresses = lookupHostAddress0(host, failedAddresses, dnssecMode);
|
||||||
if (hostAddresses == null) {
|
if (hostAddresses == null || hostAddresses.isEmpty()) {
|
||||||
|
// If hostAddresses is not null but empty, then the DNS resolution was successful but the domain did not
|
||||||
|
// have any A or AAAA resource records.
|
||||||
|
if (hostAddresses.isEmpty()) {
|
||||||
|
LOGGER.log(Level.INFO, "The DNS name " + name + ", points to a hostname (" + host
|
||||||
|
+ ") which has neither A or AAAA resource records. This is an indication of a broken DNS setup.");
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,13 @@ public class JavaxResolver extends DNSResolver implements SmackInitializer {
|
||||||
String host = srvRecordEntries[srvRecordEntries.length - 1];
|
String host = srvRecordEntries[srvRecordEntries.length - 1];
|
||||||
|
|
||||||
List<InetAddress> hostAddresses = lookupHostAddress0(host, failedAddresses, dnssecMode);
|
List<InetAddress> hostAddresses = lookupHostAddress0(host, failedAddresses, dnssecMode);
|
||||||
if (hostAddresses == null) {
|
if (hostAddresses == null || hostAddresses.isEmpty()) {
|
||||||
|
// If hostAddresses is not null but empty, then the DNS resolution was successful but the domain did not
|
||||||
|
// have any A or AAAA resource records.
|
||||||
|
if (hostAddresses.isEmpty()) {
|
||||||
|
LOGGER.log(Level.INFO, "The DNS name " + name + ", points to a hostname (" + host
|
||||||
|
+ ") which has neither A or AAAA resource records. This is an indication of a broken DNS setup.");
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import org.jivesoftware.smack.ConnectionConfiguration.DnssecMode;
|
import org.jivesoftware.smack.ConnectionConfiguration.DnssecMode;
|
||||||
import org.jivesoftware.smack.initializer.SmackInitializer;
|
import org.jivesoftware.smack.initializer.SmackInitializer;
|
||||||
|
@ -90,7 +91,13 @@ public class MiniDnsResolver extends DNSResolver implements SmackInitializer {
|
||||||
for (SRV srv : result.getAnswers()) {
|
for (SRV srv : result.getAnswers()) {
|
||||||
String hostname = srv.name.ace;
|
String hostname = srv.name.ace;
|
||||||
List<InetAddress> hostAddresses = lookupHostAddress0(hostname, failedAddresses, dnssecMode);
|
List<InetAddress> hostAddresses = lookupHostAddress0(hostname, failedAddresses, dnssecMode);
|
||||||
if (hostAddresses == null) {
|
if (hostAddresses == null || hostAddresses.isEmpty()) {
|
||||||
|
// If hostAddresses is not null but empty, then the DNS resolution was successful but the domain did not
|
||||||
|
// have any A or AAAA resource records.
|
||||||
|
if (hostAddresses.isEmpty()) {
|
||||||
|
LOGGER.log(Level.INFO, "The DNS name " + name + ", points to a hostname (" + hostname
|
||||||
|
+ ") which has neither A or AAAA resource records. This is an indication of a broken DNS setup.");
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue