implement see-other-host stream error
This commit is contained in:
parent
a40d244bf5
commit
5b2444ea13
|
@ -787,6 +787,7 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable
|
|||
BIND_FAILURE,
|
||||
HOST_UNKNOWN,
|
||||
STREAM_ERROR,
|
||||
SEE_OTHER_HOST,
|
||||
STREAM_OPENING_ERROR,
|
||||
POLICY_VIOLATION,
|
||||
PAYMENT_REQUIRED,
|
||||
|
@ -874,6 +875,8 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable
|
|||
return R.string.account_status_stream_opening_error;
|
||||
case PAYMENT_REQUIRED:
|
||||
return R.string.payment_required;
|
||||
case SEE_OTHER_HOST:
|
||||
return R.string.reconnect_on_other_host;
|
||||
case MISSING_INTERNET_PERMISSION:
|
||||
return R.string.missing_internet_permission;
|
||||
case TEMPORARY_AUTH_FAILURE:
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package eu.siacs.conversations.utils;
|
||||
|
||||
import com.google.common.net.InetAddresses;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class IP {
|
||||
|
@ -27,4 +29,14 @@ public class IP {
|
|||
}
|
||||
}
|
||||
|
||||
public static String unwrapIPv6(final String host) {
|
||||
if (host.length() > 2 && host.charAt(0) == '[' && host.charAt(host.length() - 1) == ']') {
|
||||
final String ip = host.substring(1,host.length() -1);
|
||||
if (InetAddresses.isInetAddress(ip)) {
|
||||
return ip;
|
||||
}
|
||||
}
|
||||
return host;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,10 @@ import android.util.Log;
|
|||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.net.InetAddresses;
|
||||
import com.google.common.primitives.Ints;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
|
@ -446,6 +449,65 @@ public class Resolver {
|
|||
contentValues.put(AUTHENTICATED, authenticated ? 1 : 0);
|
||||
return contentValues;
|
||||
}
|
||||
|
||||
public Result seeOtherHost(final String seeOtherHost) {
|
||||
final String hostname = seeOtherHost.trim();
|
||||
if (hostname.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
final Result result = new Result();
|
||||
result.directTls = this.directTls;
|
||||
final int portSegmentStart = hostname.lastIndexOf(':');
|
||||
if (hostname.charAt(hostname.length() - 1) != ']'
|
||||
&& portSegmentStart >= 0
|
||||
&& hostname.length() >= portSegmentStart + 1) {
|
||||
final String hostPart = hostname.substring(0, portSegmentStart);
|
||||
final String portPart = hostname.substring(portSegmentStart + 1);
|
||||
final Integer port = Ints.tryParse(portPart);
|
||||
if (port == null || Strings.isNullOrEmpty(hostPart)) {
|
||||
return null;
|
||||
}
|
||||
final String host = eu.siacs.conversations.utils.IP.unwrapIPv6(hostPart);
|
||||
result.port = port;
|
||||
if (InetAddresses.isInetAddress(host)) {
|
||||
final InetAddress inetAddress;
|
||||
try {
|
||||
inetAddress = InetAddresses.forString(host);
|
||||
} catch (final IllegalArgumentException e) {
|
||||
return null;
|
||||
}
|
||||
result.ip = inetAddress;
|
||||
} else {
|
||||
if (hostPart.trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
result.hostname = DNSName.from(hostPart.trim());
|
||||
} catch (final Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
final String host = eu.siacs.conversations.utils.IP.unwrapIPv6(hostname);
|
||||
if (InetAddresses.isInetAddress(host)) {
|
||||
final InetAddress inetAddress;
|
||||
try {
|
||||
inetAddress = InetAddresses.forString(host);
|
||||
} catch (final IllegalArgumentException e) {
|
||||
return null;
|
||||
}
|
||||
result.ip = inetAddress;
|
||||
} else {
|
||||
try {
|
||||
result.hostname = DNSName.from(hostname);
|
||||
} catch (final Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
result.port = port;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -189,6 +189,8 @@ public class XmppConnection implements Runnable {
|
|||
private HashedToken.Mechanism hashTokenRequest;
|
||||
private HttpUrl redirectionUrl = null;
|
||||
private String verifiedHostname = null;
|
||||
private Resolver.Result currentResolverResult;
|
||||
private Resolver.Result seeOtherHostResolverResult;
|
||||
private volatile Thread mThread;
|
||||
private CountDownLatch mStreamCountDownLatch;
|
||||
|
||||
|
@ -360,7 +362,12 @@ public class XmppConnection implements Runnable {
|
|||
+ storedBackupResult);
|
||||
}
|
||||
}
|
||||
for (Iterator<Resolver.Result> iterator = results.iterator();
|
||||
final Resolver.Result seeOtherHost = this.seeOtherHostResolverResult;
|
||||
if (seeOtherHost != null) {
|
||||
Log.d(Config.LOGTAG,account.getJid().asBareJid()+": injected see-other-host on position 0");
|
||||
results.add(0, seeOtherHost);
|
||||
}
|
||||
for (final Iterator<Resolver.Result> iterator = results.iterator();
|
||||
iterator.hasNext(); ) {
|
||||
final Resolver.Result result = iterator.next();
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
|
@ -374,7 +381,6 @@ public class XmppConnection implements Runnable {
|
|||
features.encryptionEnabled = result.isDirectTls();
|
||||
verifiedHostname =
|
||||
result.isAuthenticated() ? result.getHostname().toString() : null;
|
||||
Log.d(Config.LOGTAG, "verified hostname " + verifiedHostname);
|
||||
final InetSocketAddress addr;
|
||||
if (result.getIp() != null) {
|
||||
addr = new InetSocketAddress(result.getIp(), result.getPort());
|
||||
|
@ -422,6 +428,8 @@ public class XmppConnection implements Runnable {
|
|||
mXmppConnectionService.databaseBackend.saveResolverResult(
|
||||
domain, result);
|
||||
}
|
||||
this.currentResolverResult = result;
|
||||
this.seeOtherHostResolverResult = null;
|
||||
break; // successfully connected to server that speaks xmpp
|
||||
} else {
|
||||
FileBackend.close(localSocket);
|
||||
|
@ -2166,6 +2174,21 @@ public class XmppConnection implements Runnable {
|
|||
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": policy violation. " + text);
|
||||
failPendingMessages(text);
|
||||
throw new StateChangingException(Account.State.POLICY_VIOLATION);
|
||||
} else if (streamError.hasChild("see-other-host")) {
|
||||
final String seeOtherHost = streamError.findChildContent("see-other-host");
|
||||
final Resolver.Result currentResolverResult = this.currentResolverResult;
|
||||
if (Strings.isNullOrEmpty(seeOtherHost) || currentResolverResult == null) {
|
||||
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": stream error " + streamError);
|
||||
throw new StateChangingException(Account.State.STREAM_ERROR);
|
||||
}
|
||||
Log.d(Config.LOGTAG,account.getJid().asBareJid()+": see other host: "+seeOtherHost+" "+currentResolverResult);
|
||||
final Resolver.Result seeOtherResult = currentResolverResult.seeOtherHost(seeOtherHost);
|
||||
if (seeOtherResult != null) {
|
||||
this.seeOtherHostResolverResult = seeOtherResult;
|
||||
throw new StateChangingException(Account.State.SEE_OTHER_HOST);
|
||||
} else {
|
||||
throw new StateChangingException(Account.State.STREAM_ERROR);
|
||||
}
|
||||
} else {
|
||||
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": stream error " + streamError);
|
||||
throw new StateChangingException(Account.State.STREAM_ERROR);
|
||||
|
|
|
@ -553,13 +553,13 @@ public class JingleRtpConnection extends AbstractJingleConnection
|
|||
sendSessionTerminate(Reason.FAILED_APPLICATION, cause.getMessage());
|
||||
return;
|
||||
}
|
||||
processCandidates(receivedContentAccept.contents.entrySet());
|
||||
updateEndUserState();
|
||||
Log.d(
|
||||
Config.LOGTAG,
|
||||
id.getAccount().getJid().asBareJid()
|
||||
+ ": remote has accepted content-add "
|
||||
+ ContentAddition.summary(receivedContentAccept));
|
||||
processCandidates(receivedContentAccept.contents.entrySet());
|
||||
updateEndUserState();
|
||||
}
|
||||
|
||||
private void receiveContentModify(final JinglePacket jinglePacket) {
|
||||
|
|
|
@ -587,6 +587,7 @@
|
|||
<string name="type_web">Web browser</string>
|
||||
<string name="type_console">Console</string>
|
||||
<string name="payment_required">Payment required</string>
|
||||
<string name="reconnect_on_other_host">Reconnect on other host</string>
|
||||
<string name="missing_internet_permission">Grant permission to use the Internet</string>
|
||||
<string name="me">Me</string>
|
||||
<string name="contact_asks_for_presence_subscription">Contact asks for presence subscription</string>
|
||||
|
|
Loading…
Reference in a new issue