mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-25 15:52:06 +01:00
Improve handling of error response "Pongs"
This commit is contained in:
parent
48b5dc5fe7
commit
5aab471d64
1 changed files with 33 additions and 2 deletions
|
@ -41,6 +41,7 @@ import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler;
|
||||||
import org.jivesoftware.smack.iqrequest.IQRequestHandler.Mode;
|
import org.jivesoftware.smack.iqrequest.IQRequestHandler.Mode;
|
||||||
import org.jivesoftware.smack.packet.IQ;
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
import org.jivesoftware.smack.packet.IQ.Type;
|
import org.jivesoftware.smack.packet.IQ.Type;
|
||||||
|
import org.jivesoftware.smack.packet.XMPPError;
|
||||||
import org.jivesoftware.smack.util.SmackExecutorThreadFactory;
|
import org.jivesoftware.smack.util.SmackExecutorThreadFactory;
|
||||||
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
||||||
import org.jivesoftware.smackx.ping.packet.Ping;
|
import org.jivesoftware.smackx.ping.packet.Ping;
|
||||||
|
@ -142,6 +143,36 @@ public final class PingManager extends Manager {
|
||||||
maybeSchedulePingServerTask();
|
maybeSchedulePingServerTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isValidErrorPong(Jid destinationJid, XMPPErrorException xmppErrorException) {
|
||||||
|
// If it is an error error response and the destination was our own service, then this must mean that the
|
||||||
|
// service responded, i.e. is up and pingable.
|
||||||
|
if (destinationJid.equals(connection().getServiceName())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
final XMPPError xmppError = xmppErrorException.getXMPPError();
|
||||||
|
|
||||||
|
// We may received an error response from an intermediate service returning an error like
|
||||||
|
// 'remote-server-not-found' or 'remote-server-timeout' to us (which would fake the 'from' address,
|
||||||
|
// see RFC 6120 § 8.3.1 2.). Or the recipient could became unavailable.
|
||||||
|
|
||||||
|
// Sticking with the current rules of RFC 6120/6121, it is undecidable at this point whether we received an
|
||||||
|
// error response from the pinged entity or not. This is because a service-unavailable error condition is
|
||||||
|
// *required* (as per the RFCs) to be send back in both relevant cases:
|
||||||
|
// 1. When the receiving entity is unaware of the IQ request type. RFC 6120 § 8.4.:
|
||||||
|
// "If an intended recipient receives an IQ stanza of type "get" or
|
||||||
|
// "set" containing a child element qualified by a namespace it does
|
||||||
|
// not understand, then the entity MUST return an IQ stanza of type
|
||||||
|
// "error" with an error condition of <service-unavailable/>.
|
||||||
|
// 2. When the receiving resource is not available. RFC 6121 § 8.5.3.2.3.
|
||||||
|
|
||||||
|
// Some clients don't obey the first rule and instead send back a feature-not-implement condition with type 'cancel',
|
||||||
|
// which allows us to consider this response as valid "error response" pong.
|
||||||
|
XMPPError.Type type = xmppError.getType();
|
||||||
|
XMPPError.Condition condition = xmppError.getCondition();
|
||||||
|
return type == XMPPError.Type.CANCEL && condition == XMPPError.Condition.feature_not_implemented;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pings the given jid. This method will return false if an error occurs. The exception
|
* Pings the given jid. This method will return false if an error occurs. The exception
|
||||||
* to this, is a server ping, which will always return true if the server is reachable,
|
* to this, is a server ping, which will always return true if the server is reachable,
|
||||||
|
@ -168,8 +199,8 @@ public final class PingManager extends Manager {
|
||||||
try {
|
try {
|
||||||
connection.createStanzaCollectorAndSend(ping).nextResultOrThrow(pingTimeout);
|
connection.createStanzaCollectorAndSend(ping).nextResultOrThrow(pingTimeout);
|
||||||
}
|
}
|
||||||
catch (XMPPException exc) {
|
catch (XMPPErrorException e) {
|
||||||
return jid.equals(connection.getXMPPServiceDomain());
|
return isValidErrorPong(jid, e);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue