From b29d52fddae832d275e66dbd1b494e06ce11d0da Mon Sep 17 00:00:00 2001 From: fiaxh Date: Wed, 9 Aug 2017 20:44:15 +0200 Subject: SRV records for XMPP over TLS --- xmpp-vala/src/core/xmpp_stream.vala | 56 ++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 4 deletions(-) (limited to 'xmpp-vala/src/core') diff --git a/xmpp-vala/src/core/xmpp_stream.vala b/xmpp-vala/src/core/xmpp_stream.vala index 715e7832..eb6ffaa5 100644 --- a/xmpp-vala/src/core/xmpp_stream.vala +++ b/xmpp-vala/src/core/xmpp_stream.vala @@ -21,8 +21,9 @@ public class XmppStream { private StanzaReader? reader; private StanzaWriter? writer; - private ArrayList flags = new ArrayList(); - private ArrayList modules = new ArrayList(); + private Gee.List flags = new ArrayList(); + private Gee.List modules = new ArrayList(); + private Gee.List connection_providers = new ArrayList(); private bool setup_needed = false; private bool negotiation_complete = false; @@ -35,11 +36,24 @@ public class XmppStream { public signal void received_nonza(XmppStream stream, StanzaNode node); public signal void stream_negotiated(XmppStream stream); + public XmppStream() { + register_connection_provider(new StartTlsConnectionProvider()); + } + public void connect(string? remote_name = null) throws IOStreamError { if (remote_name != null) this.remote_name = (!)remote_name; - SocketClient client = new SocketClient(); try { - SocketConnection? stream = client.connect(new NetworkService("xmpp-client", "tcp", this.remote_name)); + int min_priority = -1; + ConnectionProvider? best_provider = null; + foreach (ConnectionProvider connection_provider in connection_providers) { + int? priority = connection_provider.get_priority(remote_name); + if (priority != null && (priority < min_priority || min_priority == -1)) { + min_priority = priority; + best_provider = connection_provider; + } + } + if (best_provider == null) throw new IOStreamError.CONNECT("no suitable connection provider"); + IOStream? stream = best_provider.connect(this); if (stream == null) throw new IOStreamError.CONNECT("client.connect() returned null"); reset_stream((!)stream); } catch (Error e) { @@ -142,6 +156,10 @@ public class XmppStream { return null; } + public void register_connection_provider(ConnectionProvider connection_provider) { + connection_providers.add(connection_provider); + } + private void setup() throws IOStreamError { StanzaNode outs = new StanzaNode.build("stream", "http://etherx.jabber.org/streams") .put_attribute("to", remote_name) @@ -294,4 +312,34 @@ public abstract class XmppStreamNegotiationModule : XmppStreamModule { public abstract bool negotiation_active(XmppStream stream); } +public abstract class ConnectionProvider { + public abstract int? get_priority(string remote_name); + public abstract IOStream? connect(XmppStream stream); + public abstract string get_id(); +} + +public class StartTlsConnectionProvider : ConnectionProvider { + private SrvTarget? srv_target; + + public override int? get_priority(string remote_name) { + GLib.List? xmpp_target = null; + try { + Resolver resolver = Resolver.get_default(); + xmpp_target = resolver.lookup_service("xmpp-client", "tcp", remote_name, null); + } catch (Error e) { + return null; + } + xmpp_target.sort((a, b) => { return a.get_priority() - b.get_priority(); }); + srv_target = xmpp_target.nth(0).data; + return xmpp_target.nth(0).data.get_priority(); + } + + public override IOStream? connect(XmppStream stream) { + SocketClient client = new SocketClient(); + return client.connect_to_host(srv_target.get_hostname(), srv_target.get_port()); + } + + public override string get_id() { return "start_tls"; } +} + } -- cgit v1.2.3-70-g09d2