aboutsummaryrefslogtreecommitdiff
path: root/plugins/ice/src/plugin.vala
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/ice/src/plugin.vala')
-rw-r--r--plugins/ice/src/plugin.vala63
1 files changed, 52 insertions, 11 deletions
diff --git a/plugins/ice/src/plugin.vala b/plugins/ice/src/plugin.vala
index f1c41a27..3ee8a72a 100644
--- a/plugins/ice/src/plugin.vala
+++ b/plugins/ice/src/plugin.vala
@@ -1,30 +1,71 @@
using Gee;
-using Nice;
+using Dino.Entities;
using Xmpp;
+using Xmpp.Xep;
-namespace Dino.Plugins.Ice {
+private extern const size_t NICE_ADDRESS_STRING_LEN;
-public class Plugin : RootInterface, Object {
+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(Xmpp.Xep.Socks5Bytestreams.Module.IDENTITY).set_local_ip_address_handler(get_local_ip_addresses);
+ 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 Gee.List<string> get_local_ip_addresses() {
- Gee.List<string> result = new ArrayList<string>();
- foreach (string ip_address in Nice.interfaces_get_local_ips(false)) {
- result.add(ip_address);
+ 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;
}
- return result;
}
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