diff options
author | fiaxh <git@lightrise.org> | 2021-05-11 12:57:02 +0200 |
---|---|---|
committer | fiaxh <git@lightrise.org> | 2021-05-11 12:57:02 +0200 |
commit | d71604913dd5b3372a823320db83c37c845fac5c (patch) | |
tree | 2ffbff97a02c81d48d8aef4a4b7ee870507236e9 /plugins/ice/src/plugin.vala | |
parent | e92ed27317ae398c867c946cf7206b1f0b32f3b4 (diff) | |
parent | 90f9ecf62b2ebfef14de2874e7942552409632bf (diff) | |
download | dino-d71604913dd5b3372a823320db83c37c845fac5c.tar.gz dino-d71604913dd5b3372a823320db83c37c845fac5c.zip |
Merge remote-tracking branch 'origin/feature/calls'
Diffstat (limited to 'plugins/ice/src/plugin.vala')
-rw-r--r-- | plugins/ice/src/plugin.vala | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/plugins/ice/src/plugin.vala b/plugins/ice/src/plugin.vala new file mode 100644 index 00000000..3ee8a72a --- /dev/null +++ b/plugins/ice/src/plugin.vala @@ -0,0 +1,71 @@ +using Gee; +using Dino.Entities; +using Xmpp; +using Xmpp.Xep; + +private extern const size_t NICE_ADDRESS_STRING_LEN; + +public class Dino.Plugins.Ice.Plugin : RootInterface, Object { + public Dino.Application app; + + public void registered(Dino.Application app) { + Nice.debug_enable(true); + this.app = app; + app.stream_interactor.module_manager.initialize_account_modules.connect((account, list) => { + list.add(new Module()); + }); + app.stream_interactor.stream_attached_modules.connect((account, stream) => { + stream.get_module(Socks5Bytestreams.Module.IDENTITY).set_local_ip_address_handler(get_local_ip_addresses); + }); + app.stream_interactor.stream_negotiated.connect(on_stream_negotiated); + } + + private async void on_stream_negotiated(Account account, XmppStream stream) { + Module? ice_udp_module = stream.get_module(JingleIceUdp.Module.IDENTITY) as Module; + if (ice_udp_module == null) return; + Gee.List<Xep.ExternalServiceDiscovery.Service> services = yield ExternalServiceDiscovery.request_services(stream); + foreach (Xep.ExternalServiceDiscovery.Service service in services) { + if (service.transport == "udp" && (service.ty == "stun" || service.ty == "turn")) { + InetAddress ip = yield lookup_ipv4_addess(service.host); + if (ip == null) continue; + + if (service.ty == "stun") { + debug("Server offers STUN server: %s:%u, resolved to %s", service.host, service.port, ip.to_string()); + ice_udp_module.stun_ip = ip.to_string(); + ice_udp_module.stun_port = service.port; + } else if (service.ty == "turn") { + debug("Server offers TURN server: %s:%u, resolved to %s", service.host, service.port, ip.to_string()); + ice_udp_module.turn_ip = ip.to_string(); + ice_udp_module.turn_service = service; + } + } + } + if (ice_udp_module.stun_ip == null) { + InetAddress ip = yield lookup_ipv4_addess("stun.l.google.com"); + if (ip == null) return; + + debug("Using fallback STUN server: stun.l.google.com:19302, resolved to %s", ip.to_string()); + + ice_udp_module.stun_ip = ip.to_string(); + ice_udp_module.stun_port = 19302; + } + } + + public void shutdown() { + // Nothing to do + } + + private async InetAddress? lookup_ipv4_addess(string host) { + try { + Resolver resolver = Resolver.get_default(); + GLib.List<GLib.InetAddress>? ips = yield resolver.lookup_by_name_async(host); + foreach (GLib.InetAddress ina in ips) { + if (ina.get_family() != SocketFamily.IPV4) continue; + return ina; + } + } catch (Error e) { + warning("Failed looking up IP address of %s", host); + } + return null; + } +}
\ No newline at end of file |