aboutsummaryrefslogtreecommitdiff
path: root/plugins/ice
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/ice')
-rw-r--r--plugins/ice/src/dtls_srtp.vala86
-rw-r--r--plugins/ice/src/plugin.vala7
-rw-r--r--plugins/ice/src/transport_parameters.vala60
3 files changed, 86 insertions, 67 deletions
diff --git a/plugins/ice/src/dtls_srtp.vala b/plugins/ice/src/dtls_srtp.vala
index ca398e69..c5b2eb75 100644
--- a/plugins/ice/src/dtls_srtp.vala
+++ b/plugins/ice/src/dtls_srtp.vala
@@ -37,40 +37,30 @@ public class Handler {
this.own_fingerprint = creds.own_fingerprint;
}
- public uint8[]? process_incoming_data(uint component_id, uint8[] data) {
+ public uint8[]? process_incoming_data(uint component_id, uint8[] data) throws Crypto.Error {
if (srtp_session.has_decrypt) {
- try {
- if (component_id == 1) {
- if (data.length >= 2 && data[1] >= 192 && data[1] < 224) {
- return srtp_session.decrypt_rtcp(data);
- }
- return srtp_session.decrypt_rtp(data);
+ if (component_id == 1) {
+ if (data.length >= 2 && data[1] >= 192 && data[1] < 224) {
+ return srtp_session.decrypt_rtcp(data);
}
- if (component_id == 2) return srtp_session.decrypt_rtcp(data);
- } catch (Error e) {
- warning("%s (%d)", e.message, e.code);
- return null;
+ return srtp_session.decrypt_rtp(data);
}
+ if (component_id == 2) return srtp_session.decrypt_rtcp(data);
} else if (component_id == 1) {
on_data_rec(data);
}
return null;
}
- public uint8[]? process_outgoing_data(uint component_id, uint8[] data) {
+ public uint8[]? process_outgoing_data(uint component_id, uint8[] data) throws Crypto.Error {
if (srtp_session.has_encrypt) {
- try {
- if (component_id == 1) {
- if (data.length >= 2 && data[1] >= 192 && data[1] < 224) {
- return srtp_session.encrypt_rtcp(data);
- }
- return srtp_session.encrypt_rtp(data);
+ if (component_id == 1) {
+ if (data.length >= 2 && data[1] >= 192 && data[1] < 224) {
+ return srtp_session.encrypt_rtcp(data);
}
- if (component_id == 2) return srtp_session.encrypt_rtcp(data);
- } catch (Error e) {
- warning("%s (%d)", e.message, e.code);
- return null;
+ return srtp_session.encrypt_rtp(data);
}
+ if (component_id == 2) return srtp_session.encrypt_rtcp(data);
}
return null;
}
@@ -122,6 +112,19 @@ public class Handler {
}
public async Xmpp.Xep.Jingle.ContentEncryption? setup_dtls_connection() {
+ MainContext context = MainContext.current_source().get_context();
+ var thread = new Thread<Xmpp.Xep.Jingle.ContentEncryption>("dtls-connection", () => {
+ var res = setup_dtls_connection_thread();
+ Source source = new IdleSource();
+ source.set_callback(setup_dtls_connection.callback);
+ source.attach(context);
+ return res;
+ });
+ yield;
+ return thread.join();
+ }
+
+ private Xmpp.Xep.Jingle.ContentEncryption? setup_dtls_connection_thread() {
buffer_mutex.lock();
if (stop) {
restart = true;
@@ -156,28 +159,23 @@ public class Handler {
session.set_push_function(push_function);
session.set_verify_function(verify_function);
- Thread<int> thread = new Thread<int> (null, () => {
- DateTime maximum_time = new DateTime.now_utc().add_seconds(20);
- do {
- err = session.handshake();
+ DateTime maximum_time = new DateTime.now_utc().add_seconds(20);
+ do {
+ err = session.handshake();
+
+ DateTime current_time = new DateTime.now_utc();
+ if (maximum_time.compare(current_time) < 0) {
+ warning("DTLS handshake timeouted");
+ err = ErrorCode.APPLICATION_ERROR_MIN + 1;
+ break;
+ }
+ if (stop) {
+ debug("DTLS handshake stopped");
+ err = ErrorCode.APPLICATION_ERROR_MIN + 2;
+ break;
+ }
+ } while (err < 0 && !((ErrorCode)err).is_fatal());
- DateTime current_time = new DateTime.now_utc();
- if (maximum_time.compare(current_time) < 0) {
- warning("DTLS handshake timeouted");
- err = ErrorCode.APPLICATION_ERROR_MIN + 1;
- break;
- }
- if (stop) {
- debug("DTLS handshake stopped");
- err = ErrorCode.APPLICATION_ERROR_MIN + 2;
- break;
- }
- } while (err < 0 && !((ErrorCode)err).is_fatal());
- Idle.add(setup_dtls_connection.callback);
- return err;
- });
- yield;
- err = thread.join();
buffer_mutex.lock();
if (stop) {
stop = false;
@@ -186,7 +184,7 @@ public class Handler {
buffer_mutex.unlock();
if (restart) {
debug("Restarting DTLS handshake");
- return yield setup_dtls_connection();
+ return setup_dtls_connection_thread();
}
return null;
}
diff --git a/plugins/ice/src/plugin.vala b/plugins/ice/src/plugin.vala
index f145dd6d..4abf042c 100644
--- a/plugins/ice/src/plugin.vala
+++ b/plugins/ice/src/plugin.vala
@@ -15,7 +15,12 @@ public class Dino.Plugins.Ice.Plugin : RootInterface, Object {
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);
+ if (stream.get_module(Socks5Bytestreams.Module.IDENTITY) != null) {
+ stream.get_module(Socks5Bytestreams.Module.IDENTITY).set_local_ip_address_handler(get_local_ip_addresses);
+ }
+ if (stream.get_module(JingleRawUdp.Module.IDENTITY) != null) {
+ stream.get_module(JingleRawUdp.Module.IDENTITY).set_local_ip_address_handler(get_local_ip_addresses);
+ }
});
app.stream_interactor.stream_negotiated.connect(on_stream_negotiated);
}
diff --git a/plugins/ice/src/transport_parameters.vala b/plugins/ice/src/transport_parameters.vala
index 62c04906..f684e411 100644
--- a/plugins/ice/src/transport_parameters.vala
+++ b/plugins/ice/src/transport_parameters.vala
@@ -10,16 +10,14 @@ public class Dino.Plugins.Ice.TransportParameters : JingleIceUdp.IceUdpTransport
private bool remote_credentials_set;
private Map<uint8, DatagramConnection> connections = new HashMap<uint8, DatagramConnection>();
private DtlsSrtp.Handler? dtls_srtp_handler;
+ private MainContext thread_context;
+ private MainLoop thread_loop;
private class DatagramConnection : Jingle.DatagramConnection {
private Nice.Agent agent;
private DtlsSrtp.Handler? dtls_srtp_handler;
private uint stream_id;
private string? error;
- private ulong sent;
- private ulong sent_reported;
- private ulong recv;
- private ulong recv_reported;
private ulong datagram_received_id;
public DatagramConnection(Nice.Agent agent, DtlsSrtp.Handler? dtls_srtp_handler, uint stream_id, uint8 component_id) {
@@ -28,11 +26,7 @@ public class Dino.Plugins.Ice.TransportParameters : JingleIceUdp.IceUdpTransport
this.stream_id = stream_id;
this.component_id = component_id;
this.datagram_received_id = this.datagram_received.connect((datagram) => {
- recv += datagram.length;
- if (recv > recv_reported + 100000) {
- debug("Received %lu bytes via stream %u component %u", recv, stream_id, component_id);
- recv_reported = recv;
- }
+ bytes_received += datagram.length;
});
}
@@ -45,16 +39,22 @@ public class Dino.Plugins.Ice.TransportParameters : JingleIceUdp.IceUdpTransport
public override void send_datagram(Bytes datagram) {
if (this.agent != null && is_component_ready(agent, stream_id, component_id)) {
- uint8[] encrypted_data = null;
- if (dtls_srtp_handler != null) {
- encrypted_data = dtls_srtp_handler.process_outgoing_data(component_id, datagram.get_data());
- if (encrypted_data == null) return;
- }
- agent.send(stream_id, component_id, encrypted_data ?? datagram.get_data());
- sent += datagram.length;
- if (sent > sent_reported + 100000) {
- debug("Sent %lu bytes via stream %u component %u", sent, stream_id, component_id);
- sent_reported = sent;
+ try {
+ if (dtls_srtp_handler != null) {
+ uint8[] encrypted_data = dtls_srtp_handler.process_outgoing_data(component_id, datagram.get_data());
+ if (encrypted_data == null) return;
+ // TODO: Nonblocking might require certain libnice versions?
+ GLib.OutputVector[] vectors = {{ encrypted_data, encrypted_data.length }};
+ Nice.OutputMessage[] messages = {{ vectors }};
+ agent.send_messages_nonblocking(stream_id, component_id, messages);
+ } else {
+ GLib.OutputVector[] vectors = {{ datagram.get_data(), datagram.get_size() }};
+ Nice.OutputMessage[] messages = {{ vectors }};
+ agent.send_messages_nonblocking(stream_id, component_id, messages);
+ }
+ bytes_sent += datagram.length;
+ } catch (GLib.Error e) {
+ warning("%s while send_datagram stream %u component %u", e.message, stream_id, component_id);
}
}
}
@@ -93,6 +93,14 @@ public class Dino.Plugins.Ice.TransportParameters : JingleIceUdp.IceUdpTransport
agent.controlling_mode = !incoming;
stream_id = agent.add_stream(components);
+ thread_context = new MainContext();
+ new Thread<void*>(@"ice-thread-$stream_id", () => {
+ thread_context.push_thread_default();
+ thread_loop = new MainLoop(thread_context, false);
+ thread_loop.run();
+ thread_context.pop_thread_default();
+ return null;
+ });
if (turn_ip != null) {
for (uint8 component_id = 1; component_id <= components; component_id++) {
@@ -107,7 +115,7 @@ public class Dino.Plugins.Ice.TransportParameters : JingleIceUdp.IceUdpTransport
for (uint8 component_id = 1; component_id <= components; component_id++) {
// We don't properly get local candidates before this call
- agent.attach_recv(stream_id, component_id, MainContext.@default(), on_recv);
+ agent.attach_recv(stream_id, component_id, thread_context, on_recv);
}
agent.gather_candidates(stream_id);
@@ -260,8 +268,13 @@ public class Dino.Plugins.Ice.TransportParameters : JingleIceUdp.IceUdpTransport
if (stream_id != this.stream_id) return;
uint8[] decrypt_data = null;
if (dtls_srtp_handler != null) {
- decrypt_data = dtls_srtp_handler.process_incoming_data(component_id, data);
- if (decrypt_data == null) return;
+ try {
+ decrypt_data = dtls_srtp_handler.process_incoming_data(component_id, data);
+ if (decrypt_data == null) return;
+ } catch (Crypto.Error e) {
+ warning("%s while on_recv stream %u component %u", e.message, stream_id, component_id);
+ return;
+ }
}
may_consider_ready(stream_id, component_id);
if (connections.has_key((uint8) component_id)) {
@@ -341,5 +354,8 @@ public class Dino.Plugins.Ice.TransportParameters : JingleIceUdp.IceUdpTransport
agent = null;
dtls_srtp_handler = null;
connections.clear();
+ if (thread_loop != null) {
+ thread_loop.quit();
+ }
}
}