aboutsummaryrefslogtreecommitdiff
path: root/plugins/ice
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/ice')
-rw-r--r--plugins/ice/src/plugin.vala34
1 files changed, 31 insertions, 3 deletions
diff --git a/plugins/ice/src/plugin.vala b/plugins/ice/src/plugin.vala
index 4abf042c..d1655a74 100644
--- a/plugins/ice/src/plugin.vala
+++ b/plugins/ice/src/plugin.vala
@@ -6,6 +6,8 @@ using Xmpp.Xep;
private extern const size_t NICE_ADDRESS_STRING_LEN;
public class Dino.Plugins.Ice.Plugin : RootInterface, Object {
+ private HashMap<Account, uint> timeouts = new HashMap<Account, uint>(Account.hash_func, Account.equals_func);
+
public Dino.Application app;
public void registered(Dino.Application app) {
@@ -22,18 +24,24 @@ public class Dino.Plugins.Ice.Plugin : RootInterface, Object {
stream.get_module(JingleRawUdp.Module.IDENTITY).set_local_ip_address_handler(get_local_ip_addresses);
}
});
- app.stream_interactor.stream_negotiated.connect(on_stream_negotiated);
+ app.stream_interactor.stream_negotiated.connect(external_discovery_refresh_services);
}
- private async void on_stream_negotiated(Account account, XmppStream stream) {
+ private async void external_discovery_refresh_services(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);
+ InetAddress? ip = yield lookup_ipv4_addess(service.host);
if (ip == null) continue;
+ if (ip.is_any || ip.is_link_local || ip.is_loopback || ip.is_multicast || ip.is_site_local) {
+ warning("Ignoring STUN/TURN server at %s", service.host);
+ 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();
@@ -54,6 +62,26 @@ public class Dino.Plugins.Ice.Plugin : RootInterface, Object {
ice_udp_module.stun_ip = ip.to_string();
ice_udp_module.stun_port = 7886;
}
+
+ // Refresh TURN credentials before they expire
+ if (ice_udp_module.turn_service != null) {
+ DateTime? expires = ice_udp_module.turn_service.expires;
+ if (expires != null) {
+ uint refresh_delay = (uint) (expires.to_unix() - new DateTime.now_utc().to_unix()) / 2;
+
+ if (refresh_delay >= 300 && refresh_delay <= (int64) uint.MAX) { // 5 min < refetch < max
+ debug("Re-fetching TURN credentials in %u sec", refresh_delay);
+
+ timeouts.unset(account);
+ timeouts[account] = Timeout.add_seconds((uint) refresh_delay, () => {
+ external_discovery_refresh_services.begin(account, stream);
+ return false;
+ });
+ } else {
+ warning("TURN credentials' expiry time = %u, *not* re-fetching", refresh_delay);
+ }
+ }
+ }
}
public void shutdown() {