git » sdk » commit 7d94163

Discover ICE servers

author Stephen Paul Weber
2023-09-27 18:11:44 UTC
committer Stephen Paul Weber
2023-09-27 18:11:44 UTC
parent 5c248ede9929ceede00ad23e984f354cb406c30c

Discover ICE servers

xmpp/Client.hx +24 -0
xmpp/queries/ExtDiscoGet.hx +47 -0

diff --git a/xmpp/Client.hx b/xmpp/Client.hx
index 730dbcd..c2401e9 100644
--- a/xmpp/Client.hx
+++ b/xmpp/Client.hx
@@ -3,6 +3,7 @@ package xmpp;
 import haxe.crypto.Base64;
 import haxe.io.Bytes;
 import haxe.io.BytesData;
+import js.html.rtc.IceServer; // only typedefs, should be portable
 import xmpp.Caps;
 import xmpp.Chat;
 import xmpp.EventEmitter;
@@ -10,6 +11,7 @@ import xmpp.EventHandler;
 import xmpp.PubsubEvent;
 import xmpp.Stream;
 import xmpp.queries.DiscoInfoGet;
+import xmpp.queries.ExtDiscoGet;
 import xmpp.queries.GenericQuery;
 import xmpp.queries.JabberIqGatewayGet;
 import xmpp.queries.PubsubGet;
@@ -302,6 +304,28 @@ class Client extends xmpp.EventEmitter {
 	}
 	#end
 
+	public function getIceServers(callback: (Array<IceServer>)->Void) {
+		final extDiscoGet = new ExtDiscoGet(JID.parse(this.jid).domain);
+		extDiscoGet.onFinished(() -> {
+			final servers = [];
+			for (service in extDiscoGet.getResult()) {
+				if (!["stun", "stuns", "turn", "turns"].contains(service.attr.get("type"))) continue;
+				final host = service.attr.get("host");
+				if (host == null || host == "") continue;
+				final port = Std.parseInt(service.attr.get("port"));
+				if (port == null || port < 1 || port > 65535) continue;
+				final isTurn = ["turn", "turns"].contains(service.attr.get("type"));
+				servers.push({
+					username: service.attr.get("username"),
+					credential: service.attr.get("password"),
+					urls: [service.attr.get("type") + ":" + (host.indexOf(":") >= 0 ? "[" + host + "]" : host) + ":" + port + (isTurn ? "?transport=" + service.attr.get("transport") : "")]
+				});
+			}
+			callback(servers);
+		});
+		sendQuery(extDiscoGet);
+	}
+
 	private function rosterGet() {
 		var rosterGet = new RosterGet();
 		rosterGet.onFinished(() -> {
diff --git a/xmpp/queries/ExtDiscoGet.hx b/xmpp/queries/ExtDiscoGet.hx
new file mode 100644
index 0000000..4ab5307
--- /dev/null
+++ b/xmpp/queries/ExtDiscoGet.hx
@@ -0,0 +1,47 @@
+package xmpp.queries;
+
+import haxe.DynamicAccess;
+import haxe.Exception;
+
+import xmpp.ID;
+import xmpp.ResultSet;
+import xmpp.Stanza;
+import xmpp.Stream;
+import xmpp.queries.GenericQuery;
+import xmpp.Caps;
+
+class ExtDiscoGet extends GenericQuery {
+	public var xmlns(default, null) = "urn:xmpp:extdisco:2";
+	public var queryId:String = null;
+	public var ver:String = null;
+	private var responseStanza:Stanza;
+	private var result: Array<Stanza>;
+
+	public function new(to: String) {
+		/* Build basic query */
+		queryId = ID.short();
+		queryStanza = new Stanza(
+			"iq",
+			{ to: to, type: "get", id: queryId }
+		).tag("services", { xmlns: xmlns }).up();
+	}
+
+	public function handleResponse(stanza:Stanza) {
+		responseStanza = stanza;
+		finish();
+	}
+
+	public function getResult() {
+		if (responseStanza == null) {
+			return null;
+		}
+		if(result == null) {
+			final q = responseStanza.getChild("services", xmlns);
+			if(q == null) {
+				return null;
+			}
+			result = q.allTags("service");
+		}
+		return result;
+	}
+}