abort on 'continue' - no client support
This commit is contained in:
parent
6202cbe26b
commit
928a16d31d
|
@ -640,6 +640,7 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable
|
||||||
TLS_ERROR,
|
TLS_ERROR,
|
||||||
TLS_ERROR_DOMAIN,
|
TLS_ERROR_DOMAIN,
|
||||||
INCOMPATIBLE_SERVER,
|
INCOMPATIBLE_SERVER,
|
||||||
|
INCOMPATIBLE_CLIENT,
|
||||||
TOR_NOT_AVAILABLE,
|
TOR_NOT_AVAILABLE,
|
||||||
DOWNGRADE_ATTACK,
|
DOWNGRADE_ATTACK,
|
||||||
SESSION_FAILURE,
|
SESSION_FAILURE,
|
||||||
|
@ -709,6 +710,8 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable
|
||||||
return R.string.account_status_tls_error_domain;
|
return R.string.account_status_tls_error_domain;
|
||||||
case INCOMPATIBLE_SERVER:
|
case INCOMPATIBLE_SERVER:
|
||||||
return R.string.account_status_incompatible_server;
|
return R.string.account_status_incompatible_server;
|
||||||
|
case INCOMPATIBLE_CLIENT:
|
||||||
|
return R.string.account_status_incompatible_client;
|
||||||
case TOR_NOT_AVAILABLE:
|
case TOR_NOT_AVAILABLE:
|
||||||
return R.string.account_status_tor_unavailable;
|
return R.string.account_status_tor_unavailable;
|
||||||
case BIND_FAILURE:
|
case BIND_FAILURE:
|
||||||
|
|
|
@ -56,11 +56,17 @@ public class Tag {
|
||||||
this.attributes = attributes;
|
this.attributes = attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isStart(String needle) {
|
public boolean isStart(final String needle) {
|
||||||
if (needle == null) return false;
|
if (needle == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return (this.type == START) && (needle.equals(this.name));
|
return (this.type == START) && (needle.equals(this.name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isStart(final String name, final String namespace) {
|
||||||
|
return isStart(name) && namespace != null && namespace.equals(this.getAttribute("xmlns"));
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isEnd(String needle) {
|
public boolean isEnd(String needle) {
|
||||||
if (needle == null) return false;
|
if (needle == null) return false;
|
||||||
return (this.type == END) && (needle.equals(this.name));
|
return (this.type == END) && (needle.equals(this.name));
|
||||||
|
|
|
@ -466,7 +466,7 @@ public class XmppConnection implements Runnable {
|
||||||
processStreamError(nextTag);
|
processStreamError(nextTag);
|
||||||
} else if (nextTag.isStart("features")) {
|
} else if (nextTag.isStart("features")) {
|
||||||
processStreamFeatures(nextTag);
|
processStreamFeatures(nextTag);
|
||||||
} else if (nextTag.isStart("proceed")) {
|
} else if (nextTag.isStart("proceed", Namespace.TLS)) {
|
||||||
switchOverToTls();
|
switchOverToTls();
|
||||||
} else if (nextTag.isStart("success")) {
|
} else if (nextTag.isStart("success")) {
|
||||||
final Element success = tagReader.readElement(nextTag);
|
final Element success = tagReader.readElement(nextTag);
|
||||||
|
@ -499,8 +499,13 @@ public class XmppConnection implements Runnable {
|
||||||
account.setKey(
|
account.setKey(
|
||||||
Account.PINNED_MECHANISM_KEY, String.valueOf(saslMechanism.getPriority()));
|
Account.PINNED_MECHANISM_KEY, String.valueOf(saslMechanism.getPriority()));
|
||||||
if (version == SaslMechanism.Version.SASL_2) {
|
if (version == SaslMechanism.Version.SASL_2) {
|
||||||
final String authorizationIdentifier = success.findChildContent("authorization-identifier");
|
final String authorizationIdentifier =
|
||||||
Log.d(Config.LOGTAG,account.getJid().asBareJid()+": SASL 2.0 authorization identifier was "+authorizationIdentifier);
|
success.findChildContent("authorization-identifier");
|
||||||
|
Log.d(
|
||||||
|
Config.LOGTAG,
|
||||||
|
account.getJid().asBareJid()
|
||||||
|
+ ": SASL 2.0 authorization identifier was "
|
||||||
|
+ authorizationIdentifier);
|
||||||
}
|
}
|
||||||
if (version == SaslMechanism.Version.SASL) {
|
if (version == SaslMechanism.Version.SASL) {
|
||||||
tagReader.reset();
|
tagReader.reset();
|
||||||
|
@ -513,11 +518,10 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} else if (nextTag.isStart("failure", Namespace.TLS)) {
|
||||||
|
throw new StateChangingException(Account.State.TLS_ERROR);
|
||||||
} else if (nextTag.isStart("failure")) {
|
} else if (nextTag.isStart("failure")) {
|
||||||
final Element failure = tagReader.readElement(nextTag);
|
final Element failure = tagReader.readElement(nextTag);
|
||||||
if (Namespace.TLS.equals(failure.getNamespace())) {
|
|
||||||
throw new StateChangingException(Account.State.TLS_ERROR);
|
|
||||||
}
|
|
||||||
final SaslMechanism.Version version;
|
final SaslMechanism.Version version;
|
||||||
try {
|
try {
|
||||||
version = SaslMechanism.Version.of(failure);
|
version = SaslMechanism.Version.of(failure);
|
||||||
|
@ -547,6 +551,8 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new StateChangingException(Account.State.UNAUTHORIZED);
|
throw new StateChangingException(Account.State.UNAUTHORIZED);
|
||||||
|
} else if (nextTag.isStart("continue", Namespace.SASL_2)) {
|
||||||
|
throw new StateChangingException(Account.State.INCOMPATIBLE_CLIENT);
|
||||||
} else if (nextTag.isStart("challenge")) {
|
} else if (nextTag.isStart("challenge")) {
|
||||||
final Element challenge = tagReader.readElement(nextTag);
|
final Element challenge = tagReader.readElement(nextTag);
|
||||||
final SaslMechanism.Version version;
|
final SaslMechanism.Version version;
|
||||||
|
@ -575,12 +581,19 @@ public class XmppConnection implements Runnable {
|
||||||
final Element enabled = tagReader.readElement(nextTag);
|
final Element enabled = tagReader.readElement(nextTag);
|
||||||
if ("true".equals(enabled.getAttribute("resume"))) {
|
if ("true".equals(enabled.getAttribute("resume"))) {
|
||||||
this.streamId = enabled.getAttribute("id");
|
this.streamId = enabled.getAttribute("id");
|
||||||
Log.d(Config.LOGTAG, account.getJid().asBareJid().toString()
|
Log.d(
|
||||||
+ ": stream management(" + smVersion
|
Config.LOGTAG,
|
||||||
|
account.getJid().asBareJid().toString()
|
||||||
|
+ ": stream management("
|
||||||
|
+ smVersion
|
||||||
+ ") enabled (resumable)");
|
+ ") enabled (resumable)");
|
||||||
} else {
|
} else {
|
||||||
Log.d(Config.LOGTAG, account.getJid().asBareJid().toString()
|
Log.d(
|
||||||
+ ": stream management(" + smVersion + ") enabled");
|
Config.LOGTAG,
|
||||||
|
account.getJid().asBareJid().toString()
|
||||||
|
+ ": stream management("
|
||||||
|
+ smVersion
|
||||||
|
+ ") enabled");
|
||||||
}
|
}
|
||||||
this.stanzasReceived = 0;
|
this.stanzasReceived = 0;
|
||||||
this.inSmacksSession = true;
|
this.inSmacksSession = true;
|
||||||
|
@ -599,11 +612,15 @@ public class XmppConnection implements Runnable {
|
||||||
synchronized (this.mStanzaQueue) {
|
synchronized (this.mStanzaQueue) {
|
||||||
final int serverCount = Integer.parseInt(h);
|
final int serverCount = Integer.parseInt(h);
|
||||||
if (serverCount < stanzasSent) {
|
if (serverCount < stanzasSent) {
|
||||||
Log.d(Config.LOGTAG, account.getJid().asBareJid().toString()
|
Log.d(
|
||||||
|
Config.LOGTAG,
|
||||||
|
account.getJid().asBareJid().toString()
|
||||||
+ ": session resumed with lost packages");
|
+ ": session resumed with lost packages");
|
||||||
stanzasSent = serverCount;
|
stanzasSent = serverCount;
|
||||||
} else {
|
} else {
|
||||||
Log.d(Config.LOGTAG, account.getJid().asBareJid().toString() + ": session resumed");
|
Log.d(
|
||||||
|
Config.LOGTAG,
|
||||||
|
account.getJid().asBareJid().toString() + ": session resumed");
|
||||||
}
|
}
|
||||||
acknowledgedMessages = acknowledgeStanzaUpTo(serverCount);
|
acknowledgedMessages = acknowledgeStanzaUpTo(serverCount);
|
||||||
for (int i = 0; i < this.mStanzaQueue.size(); ++i) {
|
for (int i = 0; i < this.mStanzaQueue.size(); ++i) {
|
||||||
|
@ -618,7 +635,8 @@ public class XmppConnection implements Runnable {
|
||||||
for (AbstractAcknowledgeableStanza packet : failedStanzas) {
|
for (AbstractAcknowledgeableStanza packet : failedStanzas) {
|
||||||
if (packet instanceof MessagePacket) {
|
if (packet instanceof MessagePacket) {
|
||||||
MessagePacket message = (MessagePacket) packet;
|
MessagePacket message = (MessagePacket) packet;
|
||||||
mXmppConnectionService.markMessage(account,
|
mXmppConnectionService.markMessage(
|
||||||
|
account,
|
||||||
message.getTo().asBareJid(),
|
message.getTo().asBareJid(),
|
||||||
message.getId(),
|
message.getId(),
|
||||||
Message.STATUS_UNSEND);
|
Message.STATUS_UNSEND);
|
||||||
|
@ -627,12 +645,20 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
} catch (final NumberFormatException ignored) {
|
} catch (final NumberFormatException ignored) {
|
||||||
}
|
}
|
||||||
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": online with resource " + account.getResource());
|
Log.d(
|
||||||
|
Config.LOGTAG,
|
||||||
|
account.getJid().asBareJid()
|
||||||
|
+ ": online with resource "
|
||||||
|
+ account.getResource());
|
||||||
changeStatus(Account.State.ONLINE);
|
changeStatus(Account.State.ONLINE);
|
||||||
} else if (nextTag.isStart("r")) {
|
} else if (nextTag.isStart("r")) {
|
||||||
tagReader.readElement(nextTag);
|
tagReader.readElement(nextTag);
|
||||||
if (Config.EXTENDED_SM_LOGGING) {
|
if (Config.EXTENDED_SM_LOGGING) {
|
||||||
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": acknowledging stanza #" + this.stanzasReceived);
|
Log.d(
|
||||||
|
Config.LOGTAG,
|
||||||
|
account.getJid().asBareJid()
|
||||||
|
+ ": acknowledging stanza #"
|
||||||
|
+ this.stanzasReceived);
|
||||||
}
|
}
|
||||||
final AckPacket ack = new AckPacket(this.stanzasReceived, smVersion);
|
final AckPacket ack = new AckPacket(this.stanzasReceived, smVersion);
|
||||||
tagWriter.writeStanzaAsync(ack);
|
tagWriter.writeStanzaAsync(ack);
|
||||||
|
@ -642,10 +668,19 @@ public class XmppConnection implements Runnable {
|
||||||
if (mWaitingForSmCatchup.compareAndSet(true, false)) {
|
if (mWaitingForSmCatchup.compareAndSet(true, false)) {
|
||||||
final int messageCount = mSmCatchupMessageCounter.get();
|
final int messageCount = mSmCatchupMessageCounter.get();
|
||||||
final int pendingIQs = packetCallbacks.size();
|
final int pendingIQs = packetCallbacks.size();
|
||||||
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": SM catchup complete (messages=" + messageCount + ", pending IQs=" + pendingIQs + ")");
|
Log.d(
|
||||||
|
Config.LOGTAG,
|
||||||
|
account.getJid().asBareJid()
|
||||||
|
+ ": SM catchup complete (messages="
|
||||||
|
+ messageCount
|
||||||
|
+ ", pending IQs="
|
||||||
|
+ pendingIQs
|
||||||
|
+ ")");
|
||||||
accountUiNeedsRefresh = true;
|
accountUiNeedsRefresh = true;
|
||||||
if (messageCount > 0) {
|
if (messageCount > 0) {
|
||||||
mXmppConnectionService.getNotificationService().finishBacklog(true, account);
|
mXmppConnectionService
|
||||||
|
.getNotificationService()
|
||||||
|
.finishBacklog(true, account);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -664,13 +699,20 @@ public class XmppConnection implements Runnable {
|
||||||
mXmppConnectionService.updateConversationUi();
|
mXmppConnectionService.updateConversationUi();
|
||||||
}
|
}
|
||||||
} catch (NumberFormatException | NullPointerException e) {
|
} catch (NumberFormatException | NullPointerException e) {
|
||||||
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": server send ack without sequence number");
|
Log.d(
|
||||||
|
Config.LOGTAG,
|
||||||
|
account.getJid().asBareJid()
|
||||||
|
+ ": server send ack without sequence number");
|
||||||
}
|
}
|
||||||
} else if (nextTag.isStart("failed")) {
|
} else if (nextTag.isStart("failed")) {
|
||||||
Element failed = tagReader.readElement(nextTag);
|
Element failed = tagReader.readElement(nextTag);
|
||||||
try {
|
try {
|
||||||
final int serverCount = Integer.parseInt(failed.getAttribute("h"));
|
final int serverCount = Integer.parseInt(failed.getAttribute("h"));
|
||||||
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": resumption failed but server acknowledged stanza #" + serverCount);
|
Log.d(
|
||||||
|
Config.LOGTAG,
|
||||||
|
account.getJid().asBareJid()
|
||||||
|
+ ": resumption failed but server acknowledged stanza #"
|
||||||
|
+ serverCount);
|
||||||
final boolean acknowledgedMessages;
|
final boolean acknowledgedMessages;
|
||||||
synchronized (this.mStanzaQueue) {
|
synchronized (this.mStanzaQueue) {
|
||||||
acknowledgedMessages = acknowledgeStanzaUpTo(serverCount);
|
acknowledgedMessages = acknowledgeStanzaUpTo(serverCount);
|
||||||
|
|
|
@ -168,6 +168,7 @@
|
||||||
<string name="account_status_tls_error_domain">Domain not verifiable</string>
|
<string name="account_status_tls_error_domain">Domain not verifiable</string>
|
||||||
<string name="account_status_policy_violation">Policy violation</string>
|
<string name="account_status_policy_violation">Policy violation</string>
|
||||||
<string name="account_status_incompatible_server">Incompatible server</string>
|
<string name="account_status_incompatible_server">Incompatible server</string>
|
||||||
|
<string name="account_status_incompatible_client">Incompatible client</string>
|
||||||
<string name="account_status_stream_error">Stream error</string>
|
<string name="account_status_stream_error">Stream error</string>
|
||||||
<string name="account_status_stream_opening_error">Stream opening error</string>
|
<string name="account_status_stream_opening_error">Stream opening error</string>
|
||||||
<string name="encryption_choice_unencrypted">Unencrypted</string>
|
<string name="encryption_choice_unencrypted">Unencrypted</string>
|
||||||
|
|
Loading…
Reference in a new issue