]> www.infradead.org Git - pidgin-chime.git/commitdiff
Start hooking up DTLS transport
authorDavid Woodhouse <dwmw@amazon.co.uk>
Mon, 9 Apr 2018 12:06:40 +0000 (14:06 +0200)
committerDavid Woodhouse <dwmw@amazon.co.uk>
Mon, 9 Apr 2018 12:06:42 +0000 (14:06 +0200)
First, resolve the address at least...

chime/chime-call-audio.h
chime/chime-call-transport.c

index 786067a9fc747d12f5dae390611fdb5caf5716e6..9fdeedf6b9ce78fa37009eb129843ead4f5cf461 100644 (file)
@@ -37,6 +37,9 @@ struct _ChimeCallAudio {
        gboolean silent; /* No audio; only participant data */
        GMutex transport_lock;
        SoupWebsocketConnection *ws;
+
+       GCancellable *cancel;
+
        guint data_ack_source;
        guint32 data_next_seq;
        guint64 data_ack_mask;
index 0033d2b0e5f16c6fcec469b88ccc30e15ec470c1..6dfb16fd9e722c2a3e4c94054c371e9b96126d6e 100644 (file)
@@ -148,8 +148,11 @@ static void audio_ws_connect_cb(GObject *obj, GAsyncResult *res, gpointer _audio
        GError *error = NULL;
        SoupWebsocketConnection *ws = chime_connection_websocket_connect_finish(cxn, res, &error);
        if (!ws) {
-               chime_debug("audio ws error %s\n", error->message);
-               audio->state = CHIME_AUDIO_STATE_FAILED;
+               if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+                       chime_debug("audio ws error %s\n", error->message);
+                       audio->state = CHIME_AUDIO_STATE_FAILED;
+               }
+               g_clear_error(&error);
                g_object_unref(cxn);
                return;
        }
@@ -163,25 +166,64 @@ static void audio_ws_connect_cb(GObject *obj, GAsyncResult *res, gpointer _audio
 }
 
 
-void chime_call_transport_connect(ChimeCallAudio *audio, gboolean silent)
+static void chime_call_transport_connect_ws(ChimeCallAudio *audio)
 {
-       /* Grrr, GDtlsClientConnection doesn't actually exist yet. Let's stick
-          with the WebSocket for now... */
        SoupURI *uri = soup_uri_new_printf(chime_call_get_audio_ws_url(audio->call), "/audio");
        SoupMessage *msg = soup_message_new_from_uri("GET", uri);
 
-       audio->silent = silent;
-
        char *protocols[] = { (char *)"opus-med", NULL };
        gchar *origin = g_strdup_printf("http://%s", soup_uri_get_host(uri));
        soup_uri_free(uri);
 
        ChimeConnection *cxn = chime_call_get_connection(audio->call);
-       chime_connection_websocket_connect_async(g_object_ref(cxn), msg, origin, protocols, NULL,
-                                                audio_ws_connect_cb, audio);
+       chime_connection_websocket_connect_async(g_object_ref(cxn), msg, origin, protocols,
+                                                audio->cancel, audio_ws_connect_cb, audio);
        g_free(origin);
 }
 
+static void audio_dtls_one(GObject *obj, GAsyncResult *res, gpointer user_data)
+{
+       GSocketAddressEnumerator *enumerator = G_SOCKET_ADDRESS_ENUMERATOR(obj);
+       ChimeCallAudio *audio = user_data;
+       GError *error = NULL;
+
+       GSocketAddress *addr = g_socket_address_enumerator_next_finish(enumerator, res, &error);
+       if (!addr) {
+               if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+                       chime_call_transport_connect_ws(audio);
+               g_clear_error(&error);
+               g_object_unref(obj);
+               return;
+       }
+
+       GInetAddress *inet = g_inet_socket_address_get_address(G_INET_SOCKET_ADDRESS(addr));
+       guint16 port = g_inet_socket_address_get_port(G_INET_SOCKET_ADDRESS(addr));
+       gchar *addr_str = g_inet_address_to_string(inet);
+       chime_debug("DTLS address %s:%d\n", addr_str, port);
+
+       g_socket_address_enumerator_next_async(enumerator, audio->cancel,
+                                              (GAsyncReadyCallback)audio_dtls_one, audio);
+}
+void chime_call_transport_connect(ChimeCallAudio *audio, gboolean silent)
+{
+
+       audio->silent = silent;
+       audio->cancel = g_cancellable_new();
+
+       GSocketConnectable *addr = g_network_address_parse(chime_call_get_media_host(audio->call),
+                                                          0, NULL);
+       if (!addr) {
+               chime_call_transport_connect_ws(audio);
+               return;
+       }
+       GSocketAddressEnumerator *enumerator = g_socket_connectable_enumerate(addr);
+       g_object_unref(addr);
+
+       g_socket_address_enumerator_next_async(enumerator, audio->cancel,
+                                              (GAsyncReadyCallback)audio_dtls_one, audio);
+}
+
+
 static void on_final_audiows_close(SoupWebsocketConnection *ws, gpointer _unused)
 {
        chime_debug("audio ws close\n");
@@ -193,12 +235,21 @@ void chime_call_transport_disconnect(ChimeCallAudio *audio, gboolean hangup)
 {
        if (hangup)
                audio_send_hangup_packet(audio);
+
        g_mutex_lock(&audio->transport_lock);
-       soup_websocket_connection_close(audio->ws, 0, NULL);
-       g_signal_handlers_disconnect_matched(G_OBJECT(audio->ws), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, audio);
-       g_signal_connect(G_OBJECT(audio->ws), "closed", G_CALLBACK(on_final_audiows_close), NULL);
+
+       if (audio->cancel) {
+               g_cancellable_cancel(audio->cancel);
+               g_object_unref(audio->cancel);
+               audio->cancel = NULL;
+       }
+       if (audio->ws) {
+               soup_websocket_connection_close(audio->ws, 0, NULL);
+               g_signal_handlers_disconnect_matched(G_OBJECT(audio->ws), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, audio);
+               g_signal_connect(G_OBJECT(audio->ws), "closed", G_CALLBACK(on_final_audiows_close), NULL);
+               audio->ws = NULL;
+       }
        g_mutex_unlock(&audio->transport_lock);
-       audio->ws = NULL;
 }