diff options
author | Daniel Lublin <daniel@lublin.se> | 2020-04-14 13:07:50 +0300 |
---|---|---|
committer | Daniel Lublin <daniel@lublin.se> | 2020-04-14 13:07:53 +0300 |
commit | 404b14e2226b056a3368c6d99bcd2b971708765c (patch) | |
tree | 2d263de4443b0e78226ed753926e945f1bcc2ff8 | |
parent | ae87b212035ede8d5dcbe5fd90f48da8c61c0164 (diff) |
Resolve SRV record before trying to connecting
Only done if Server.mPort is set to 0 *and* address is not an IP (but a
domain).
-rw-r--r-- | build.gradle | 1 | ||||
-rw-r--r-- | src/main/java/se/lublin/humla/HumlaService.java | 3 | ||||
-rw-r--r-- | src/main/java/se/lublin/humla/model/Server.java | 88 |
3 files changed, 89 insertions, 3 deletions
diff --git a/build.gradle b/build.gradle index 8b88493..36f2fdd 100644 --- a/build.gradle +++ b/build.gradle @@ -42,6 +42,7 @@ dependencies { implementation 'com.googlecode.javacpp:javacpp:0.7' implementation 'org.jetbrains:annotations:18.0.0' + implementation 'org.minidns:minidns-hla:0.3.4' } android { diff --git a/src/main/java/se/lublin/humla/HumlaService.java b/src/main/java/se/lublin/humla/HumlaService.java index 4d94eb8..f2667a4 100644 --- a/src/main/java/se/lublin/humla/HumlaService.java +++ b/src/main/java/se/lublin/humla/HumlaService.java @@ -296,8 +296,7 @@ public class HumlaService extends Service implements IHumlaService, IHumlaSessio mCallbacks.onConnecting(); - mConnection.connect(mServer.getHost(), - mServer.getPort() == 0 ? Constants.DEFAULT_PORT : mServer.getPort()); + mConnection.connect(mServer.getResolvedHost(), mServer.getResolvedPort()); } catch (HumlaException e) { e.printStackTrace(); mCallbacks.onDisconnected(e); diff --git a/src/main/java/se/lublin/humla/model/Server.java b/src/main/java/se/lublin/humla/model/Server.java index e308214..4d20261 100644 --- a/src/main/java/se/lublin/humla/model/Server.java +++ b/src/main/java/se/lublin/humla/model/Server.java @@ -19,6 +19,21 @@ package se.lublin.humla.model; import android.os.Parcel; import android.os.Parcelable; +import android.util.Log; +import android.util.Patterns; + +import org.minidns.hla.ResolverApi; +import org.minidns.hla.SrvResolverResult; +import org.minidns.record.SRV; +import org.minidns.util.SrvUtil; + +import java.io.IOException; +import java.util.List; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; + +import se.lublin.humla.Constants; public class Server implements Parcelable { @@ -29,6 +44,10 @@ public class Server implements Parcelable { private String mUsername; private String mPassword; + // TODO SRV should we remove the cache when disconnecting? maybe + private String mResolvedHost = null; + private int mResolvedPort; + public static final Parcelable.Creator<Server> CREATOR = new Parcelable.Creator<Server>() { @Override @@ -49,11 +68,11 @@ public class Server implements Parcelable { mPort = port; mUsername = username; mPassword = password; + mResolvedHost = null; } private Server(Parcel in) { readFromParcel(in); - } @Override @@ -73,6 +92,7 @@ public class Server implements Parcelable { mPort = in.readInt(); mUsername = in.readString(); mPassword = in.readString(); + mResolvedHost = null; } @Override @@ -106,6 +126,7 @@ public class Server implements Parcelable { public void setHost(String mHost) { this.mHost = mHost; + this.mResolvedHost = null; } public int getPort() { @@ -114,6 +135,7 @@ public class Server implements Parcelable { public void setPort(int mPort) { this.mPort = mPort; + this.mResolvedHost = null; } public String getUsername() { @@ -139,4 +161,68 @@ public class Server implements Parcelable { public boolean isSaved() { return mId != -1; } + + public String getResolvedHost() { + resolveSRV(); + return mResolvedHost; + } + + public int getResolvedPort() { + resolveSRV(); + return mResolvedPort; + } + + private void resolveSRV() { + if (mResolvedHost != null) { + return; + } + mResolvedHost = mHost; + mResolvedPort = mPort; + if (mResolvedPort != 0) { + return; + } + mResolvedPort = Constants.DEFAULT_PORT; + if (Patterns.IP_ADDRESS.matcher(mResolvedHost).matches()) { + return; + } + final AtomicReference<String> host = new AtomicReference<>(mResolvedHost); + final AtomicInteger port = new AtomicInteger(mResolvedPort); + try { + Thread t = new Thread(new Runnable() { + @Override + public void run() { + try { + SrvResolverResult res = ResolverApi.INSTANCE.resolveSrv("_mumble._tcp." + host.get()); + if (!res.wasSuccessful()) { + Log.d(Constants.TAG, "resolveSrv " + res.getResponseCode()); + return; + } + Set<SRV> answers = res.getAnswersOrEmptySet(); + if (answers.isEmpty()) { + Log.d(Constants.TAG, "resolveSrv " + res.getResponseCode() + " but 0 answers"); + return; + } + List<SRV> srvs = SrvUtil.sortSrvRecords(answers); + for (SRV srv : srvs) { + Log.d(Constants.TAG, "SRV resolved: " + srv.toString()); + host.set(srv.target.toString()); + port.set(srv.port); + // TODO SRV just picking the first record. + return; + } + } catch (IOException e) { + Log.d(Constants.TAG, "resolveSRV() run() " + e); + } + } + }); + t.start(); + t.join(); + } + catch (Exception e) { + Log.d(Constants.TAG, "resolveSRV() " + e); + } + mResolvedHost = host.get(); + mResolvedPort = port.get(); + } + } |