aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java')
-rw-r--r--src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java80
1 files changed, 47 insertions, 33 deletions
diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
index a45cce01..b9094a61 100644
--- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
+++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
@@ -185,18 +185,18 @@ public class XmppConnection implements Runnable {
@Override
public void onIqPacketReceived(Account account, IqPacket packet) {
if (packet.getType() == IqPacket.TYPE.RESULT) {
- account.setOption(Account.OPTION_REGISTER,
- false);
+ account.setOption(Account.OPTION_REGISTER, false);
+ forceCloseSocket();
changeStatus(Account.State.REGISTRATION_SUCCESSFUL);
} else if (packet.hasChild("error")
- && (packet.findChild("error")
- .hasChild("conflict"))) {
+ && (packet.findChild("error").hasChild("conflict"))) {
+ forceCloseSocket();
changeStatus(Account.State.REGISTRATION_CONFLICT);
} else {
+ forceCloseSocket();
changeStatus(Account.State.REGISTRATION_FAILED);
Log.d(Config.LOGTAG, packet.toString());
}
- disconnect(true);
}
};
}
@@ -333,7 +333,7 @@ public class XmppConnection implements Runnable {
} catch (final IOException | XmlPullParserException | NoSuchAlgorithmException e) {
Logging.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": " + e.getMessage());
this.changeStatus(Account.State.OFFLINE);
- this.attempt--; //don't count attempt when reconnecting instantly anyway
+ this.attempt = Math.max(0, this.attempt - 1);
} finally {
forceCloseSocket();
if (wakeLock.isHeld()) {
@@ -459,7 +459,7 @@ public class XmppConnection implements Runnable {
if ("true".equals(enabled.getAttribute("resume"))) {
this.streamId = enabled.getAttribute("id");
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString()
- + ": stream managment(" + smVersion
+ + ": stream management(" + smVersion
+ ") enabled (resumable)");
} else {
Log.d(Config.LOGTAG, account.getJid().toBareJid().toString()
@@ -515,12 +515,18 @@ public class XmppConnection implements Runnable {
try {
final int serverSequence = Integer.parseInt(ack.getAttribute("h"));
acknowledgeStanzaUpTo(serverSequence);
- } catch (NumberFormatException e) {
+ } catch (NumberFormatException | NullPointerException e) {
Log.d(Config.LOGTAG,account.getJid().toBareJid()+": server send ack without sequence number");
}
} else if (nextTag.isStart("failed")) {
- tagReader.readElement(nextTag);
- Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": resumption failed");
+ Element failed = tagReader.readElement(nextTag);
+ try {
+ final int serverCount = Integer.parseInt(failed.getAttribute("h"));
+ Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": resumption failed but server acknowledged stanza #"+serverCount);
+ acknowledgeStanzaUpTo(serverCount);
+ } catch (NumberFormatException | NullPointerException e) {
+ Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": resumption failed");
+ }
resetStreamId();
if (account.getStatus() != Account.State.ONLINE) {
sendBindRequest();
@@ -714,8 +720,8 @@ public class XmppConnection implements Runnable {
}
} else if (!this.streamFeatures.hasChild("register")
&& account.isOptionSet(Account.OPTION_REGISTER)) {
+ forceCloseSocket();
changeStatus(Account.State.REGISTRATION_NOT_SUPPORTED);
- disconnect(true);
} else if (this.streamFeatures.hasChild("mechanisms")
&& shouldAuthenticate
&& (features.encryptionEnabled || Config.ALLOW_NON_TLS_CONNECTIONS)) {
@@ -783,15 +789,6 @@ public class XmppConnection implements Runnable {
return mechanisms;
}
- public void sendCaptchaRegistryRequest(String id, Data data) {
- if (data == null) {
- setAccountCreationFailed("");
- } else {
- IqPacket request = getIqGenerator().generateCreateAccountWithCaptcha(account, id, data);
- sendIqPacket(request, createPacketReceiveHandler());
- }
- }
-
private void sendRegistryRequest() {
final IqPacket register = new IqPacket(IqPacket.TYPE.GET);
register.query("jabber:iq:register");
@@ -861,6 +858,7 @@ public class XmppConnection implements Runnable {
}
public void resetEverything() {
+ resetAttemptCount();
resetStreamId();
clearIqCallbacks();
mStanzaQueue.clear();
@@ -903,12 +901,15 @@ public class XmppConnection implements Runnable {
}
} else {
Logging.d(Config.LOGTAG, account.getJid() + ": disconnecting because of bind failure. (no jid)");
- disconnect(true);
}
} else {
Logging.d(Config.LOGTAG, account.getJid() + ": disconnecting because of bind failure ("+packet.toString());
- disconnect(true);
}
+ } else {
+ Logging.d(Config.LOGTAG, account.getJid() + ": disconnecting because of bind failure (" + packet.toString());
+ }
+ forceCloseSocket();
+ changeStatus(Account.State.BIND_FAILURE);
}
});
}
@@ -1002,7 +1003,7 @@ public class XmppConnection implements Runnable {
final String ver = caps == null ? null : caps.getAttribute("ver");
ServiceDiscoveryResult discoveryResult = null;
if (hash != null && ver != null) {
- discoveryResult = mXmppConnectionService.databaseBackend.findDiscoveryResult(hash, ver);
+ discoveryResult = mXmppConnectionService.getCachedServiceDiscoveryResult(new Pair<>(hash, ver));
}
if (discoveryResult == null) {
sendServiceDiscoveryInfo(account.getServer());
@@ -1153,15 +1154,20 @@ public class XmppConnection implements Runnable {
private void processStreamError(final Tag currentTag)
throws XmlPullParserException, IOException {
final Element streamError = tagReader.readElement(currentTag);
- if (streamError != null && streamError.hasChild("conflict")) {
+ if (streamError == null) {
+ return;
+ }
+ Logging.d(Config.LOGTAG,account.getJid().toBareJid()+": stream error "+streamError.toString());
+ if (streamError.hasChild("conflict")) {
final String resource = account.getResource().split("\\.")[0];
account.setResource(resource + "." + nextRandomId());
Logging.d(Config.LOGTAG,
account.getJid().toBareJid() + ": switching resource due to conflict ("
+ account.getResource() + ")");
- } else if (streamError != null) {
- Logging.d(Config.LOGTAG,account.getJid().toBareJid()+": stream error "+streamError.toString());
+ } else if (streamError.hasChild("host-unknown")) {
+ changeStatus(Account.State.HOST_UNKNOWN);
}
+ forceCloseSocket();
}
private void sendStartStream() throws IOException {
@@ -1285,10 +1291,8 @@ public class XmppConnection implements Runnable {
}
socket.close();
Logging.d(Config.LOGTAG,account.getJid().toBareJid()+": closed tcp without closing stream");
- } catch (IOException e) {
- e.printStackTrace();
- } catch (InterruptedException e) {
- e.printStackTrace();
+ } catch (IOException | InterruptedException e) {
+ return;
}
}
}).start();
@@ -1308,8 +1312,13 @@ public class XmppConnection implements Runnable {
}
}
+ public void interrupt() {
+ Thread.currentThread().interrupt();
+ }
+
public void disconnect(final boolean force) {
- Logging.d(Config.LOGTAG, account.getJid().toBareJid() + ": disconnecting force="+Boolean.valueOf(force));
+ interrupt();
+ Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": disconnecting force="+Boolean.valueOf(force));
if (force) {
forceCloseSocket();
return;
@@ -1389,7 +1398,7 @@ public class XmppConnection implements Runnable {
}
public int getTimeToNextAttempt() {
- final int interval = (int) (25 * Math.pow(1.5, attempt));
+ final int interval = Math.min((int) (25 * Math.pow(1.3, attempt)), 300);
final int secondsSinceLast = (int) ((SystemClock.elapsedRealtime() - this.lastConnect) / 1000);
return interval - secondsSinceLast;
}
@@ -1547,7 +1556,12 @@ public class XmppConnection implements Runnable {
if (items.size() > 0) {
try {
long maxsize = Long.parseLong(items.get(0).getValue().getExtendedDiscoInformation(Xmlns.HTTP_UPLOAD, "max-file-size"));
- return filesize <= maxsize;
+ if(filesize <= maxsize) {
+ return true;
+ } else {
+ Log.d(Config.LOGTAG,account.getJid().toBareJid()+": http upload is not available for files with size "+filesize+" (max is "+maxsize+")");
+ return false;
+ }
} catch (Exception e) {
return true;
}