From d9246e96100bbb6eec3a48be3b87dfae2e178865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=9Aled=C5=BA?= Date: Fri, 18 Apr 2025 17:55:24 +0200 Subject: [PATCH 1/3] Migrate to new ExDTLS version that supports cert fragmentation --- lib/ex_webrtc/dtls_transport.ex | 12 ++++++++---- mix.exs | 2 +- mix.lock | 6 +++--- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/ex_webrtc/dtls_transport.ex b/lib/ex_webrtc/dtls_transport.ex index b93e5a93..5695358f 100644 --- a/lib/ex_webrtc/dtls_transport.ex +++ b/lib/ex_webrtc/dtls_transport.ex @@ -242,7 +242,7 @@ defmodule ExWebRTC.DTLSTransport do @impl true def handle_cast({:send_rtp, data}, %{dtls_state: :connected, ice_connected: true} = state) do case ExLibSRTP.protect(state.out_srtp, data) do - {:ok, protected} -> do_send(state, protected) + {:ok, protected} -> :ok = do_send(state, protected) {:error, reason} -> Logger.warning("Unable to protect RTP: #{inspect(reason)}") end @@ -274,7 +274,7 @@ defmodule ExWebRTC.DTLSTransport do @impl true def handle_cast({:send_data, data}, %{dtls_state: :connected, ice_connected: true} = state) do case ExDTLS.write_data(state.dtls, data) do - {:ok, protected} -> do_send(state, protected) + {:ok, packets} -> :ok = do_send(state, packets) {:error, reason} -> Logger.warning("Unable to protect data: #{inspect(reason)}") end @@ -297,7 +297,7 @@ defmodule ExWebRTC.DTLSTransport do def handle_info(:dtls_timeout, %{buffered_local_packets: buffered_local_packets} = state) do case ExDTLS.handle_timeout(state.dtls) do {:retransmit, packets, timeout} when state.ice_connected -> - do_send(state, packets) + :ok = do_send(state, packets) Logger.debug("Retransmitted DTLS packets") Process.send_after(self(), :dtls_timeout, timeout) @@ -374,7 +374,7 @@ defmodule ExWebRTC.DTLSTransport do {:handshake_finished, lkm, rkm, profile, packets} -> Logger.debug("DTLS handshake finished") state = update_remote_cert_info(state) - do_send(state, packets) + :ok = do_send(state, packets) peer_fingerprint = state.dtls @@ -494,6 +494,10 @@ defmodule ExWebRTC.DTLSTransport do %{state | buffered_remote_rtp_packets: []} end + defp do_send(state, data) when is_list(data) do + Enum.each(data, &(:ok = do_send(state, &1))) + end + defp do_send(%{packet_loss: 0} = state, data), do: state.ice_transport.send_data(state.ice_pid, data) diff --git a/mix.exs b/mix.exs index e17a729c..ac124187 100644 --- a/mix.exs +++ b/mix.exs @@ -58,7 +58,7 @@ defmodule ExWebRTC.MixProject do [ {:ex_sdp, "~> 1.0"}, {:ex_ice, "~> 0.12.0"}, - {:ex_dtls, "~> 0.16.0"}, + {:ex_dtls, github: "elixir-webrtc/ex_dtls", branch: "cert-fragmentation"}, {:ex_libsrtp, "~> 0.7.1"}, {:ex_rtp, "~> 0.4.0"}, {:ex_rtcp, "~> 0.4.0"}, diff --git a/mix.lock b/mix.lock index e0e27f58..f2badbec 100644 --- a/mix.lock +++ b/mix.lock @@ -11,7 +11,7 @@ "elixir_uuid": {:hex, :elixir_uuid, "1.2.1", "dce506597acb7e6b0daeaff52ff6a9043f5919a4c3315abb4143f0b00378c097", [:mix], [], "hexpm", "f7eba2ea6c3555cea09706492716b0d87397b88946e6380898c2889d68585752"}, "erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"}, "ex_doc": {:hex, :ex_doc, "0.37.3", "f7816881a443cd77872b7d6118e8a55f547f49903aef8747dbcb345a75b462f9", [:mix], [{:earmark_parser, "~> 1.4.42", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "e6aebca7156e7c29b5da4daa17f6361205b2ae5f26e5c7d8ca0d3f7e18972233"}, - "ex_dtls": {:hex, :ex_dtls, "0.16.0", "3ae38025ccc77f6db573e2e391602fa9bbc02253c137d8d2d59469a66cbe806b", [:mix], [{:bundlex, "~> 1.5.3", [hex: :bundlex, repo: "hexpm", optional: false]}, {:unifex, "~> 1.0", [hex: :unifex, repo: "hexpm", optional: false]}], "hexpm", "2a4e30d74c6ddf95cc5b796423293c06a0da295454c3823819808ff031b4b361"}, + "ex_dtls": {:git, "https://github.com/elixir-webrtc/ex_dtls.git", "2c9e31a3efb714204cac55bfdd5b06dc9beee052", [branch: "cert-fragmentation"]}, "ex_ice": {:hex, :ex_ice, "0.12.0", "b52ec3ff878d5fb632ef9facc7657dfdf59e2ff9f23e634b0918e6ce1a05af48", [:mix], [{:elixir_uuid, "~> 1.0", [hex: :elixir_uuid, repo: "hexpm", optional: false]}, {:ex_stun, "~> 0.2.0", [hex: :ex_stun, repo: "hexpm", optional: false]}, {:ex_turn, "~> 0.2.0", [hex: :ex_turn, repo: "hexpm", optional: false]}], "hexpm", "a86024a5fbf9431082784be4bb3606d3cde9218fb325a9f208ccd6e0abfd0d73"}, "ex_libsrtp": {:hex, :ex_libsrtp, "0.7.2", "211bd89c08026943ce71f3e2c0231795b99cee748808ed3ae7b97cd8d2450b6b", [:mix], [{:bunch, "~> 1.6", [hex: :bunch, repo: "hexpm", optional: false]}, {:bundlex, "~> 1.3", [hex: :bundlex, repo: "hexpm", optional: false]}, {:membrane_precompiled_dependency_provider, "~> 0.1.0", [hex: :membrane_precompiled_dependency_provider, repo: "hexpm", optional: false]}, {:unifex, "~> 1.1", [hex: :unifex, repo: "hexpm", optional: false]}], "hexpm", "2e20645d0d739a4ecdcf8d4810a0c198120c8a2f617f2b75b2e2e704d59f492a"}, "ex_rtcp": {:hex, :ex_rtcp, "0.4.0", "f9e515462a9581798ff6413583a25174cfd2101c94a2ebee871cca7639886f0a", [:mix], [], "hexpm", "28956602cf210d692fcdaf3f60ca49681634e1deb28ace41246aee61ee22dc3b"}, @@ -23,7 +23,7 @@ "excoveralls": {:hex, :excoveralls, "0.18.5", "e229d0a65982613332ec30f07940038fe451a2e5b29bce2a5022165f0c9b157e", [:mix], [{:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "523fe8a15603f86d64852aab2abe8ddbd78e68579c8525ae765facc5eae01562"}, "file_system": {:hex, :file_system, "1.1.0", "08d232062284546c6c34426997dd7ef6ec9f8bbd090eb91780283c9016840e8f", [:mix], [], "hexpm", "bfcf81244f416871f2a2e15c1b515287faa5db9c6bcf290222206d120b3d43f6"}, "finch": {:hex, :finch, "0.19.0", "c644641491ea854fc5c1bbaef36bfc764e3f08e7185e1f084e35e0672241b76d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fc5324ce209125d1e2fa0fcd2634601c52a787aff1cd33ee833664a5af4ea2b6"}, - "hpax": {:hex, :hpax, "1.0.2", "762df951b0c399ff67cc57c3995ec3cf46d696e41f0bba17da0518d94acd4aac", [:mix], [], "hexpm", "2f09b4c1074e0abd846747329eaa26d535be0eb3d189fa69d812bfb8bfefd32f"}, + "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "makeup": {:hex, :makeup, "1.2.1", "e90ac1c65589ef354378def3ba19d401e739ee7ee06fb47f94c687016e3713d1", [:mix], [{:nimble_parsec, "~> 1.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "d36484867b0bae0fea568d10131197a4c2e47056a6fbe84922bf6ba71c8d17ce"}, "makeup_elixir": {:hex, :makeup_elixir, "1.0.1", "e928a4f984e795e41e3abd27bfc09f51db16ab8ba1aebdba2b3a575437efafc2", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "7284900d412a3e5cfd97fdaed4f5ed389b8f2b4cb49efc0eb3bd10e2febf9507"}, @@ -35,7 +35,7 @@ "nimble_parsec": {:hex, :nimble_parsec, "1.4.2", "8efba0122db06df95bfaa78f791344a89352ba04baedd3849593bfce4d0dc1c6", [:mix], [], "hexpm", "4b21398942dda052b403bbe1da991ccd03a053668d147d53fb8c4e0efe09c973"}, "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, "qex": {:hex, :qex, "0.5.1", "0d82c0f008551d24fffb99d97f8299afcb8ea9cf99582b770bd004ed5af63fd6", [:mix], [], "hexpm", "935a39fdaf2445834b95951456559e9dc2063d0a055742c558a99987b38d6bab"}, - "req": {:hex, :req, "0.5.9", "09072dcd91a70c58734c4dd4fa878a9b6d36527291152885100ec33a5a07f1d6", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "2f027043003275918f5e79e6a4e57b10cb17161a1ab41c959aa40ecfb2142e5a"}, + "req": {:hex, :req, "0.5.10", "a3a063eab8b7510785a467f03d30a8d95f66f5c3d9495be3474b61459c54376c", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "8a604815743f8a2d3b5de0659fa3137fa4b1cffd636ecb69b30b2b9b2c2559be"}, "rustler": {:hex, :rustler, "0.36.1", "2d4b1ff57ea2789a44756a40dbb5fbb73c6ee0a13d031dcba96d0a5542598a6a", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:toml, "~> 0.7", [hex: :toml, repo: "hexpm", optional: false]}], "hexpm", "f3fba4ad272970e0d1bc62972fc4a99809651e54a125c5242de9bad4574b2d02"}, "shmex": {:hex, :shmex, "0.5.1", "81dd209093416bf6608e66882cb7e676089307448a1afd4fc906c1f7e5b94cf4", [:mix], [{:bunch_native, "~> 0.5.0", [hex: :bunch_native, repo: "hexpm", optional: false]}, {:bundlex, "~> 1.0", [hex: :bundlex, repo: "hexpm", optional: false]}], "hexpm", "c29f8286891252f64c4e1dac40b217d960f7d58def597c4e606ff8fbe71ceb80"}, "telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"}, From dc7989e2721ce923469ebf0cb4c50d77d26d7e82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=9Aled=C5=BA?= Date: Fri, 18 Apr 2025 18:43:11 +0200 Subject: [PATCH 2/3] Bump ex_dtls to 0.17.0 --- mix.exs | 2 +- mix.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mix.exs b/mix.exs index ac124187..6fd8efbe 100644 --- a/mix.exs +++ b/mix.exs @@ -58,7 +58,7 @@ defmodule ExWebRTC.MixProject do [ {:ex_sdp, "~> 1.0"}, {:ex_ice, "~> 0.12.0"}, - {:ex_dtls, github: "elixir-webrtc/ex_dtls", branch: "cert-fragmentation"}, + {:ex_dtls, "~> 0.17.0"}, {:ex_libsrtp, "~> 0.7.1"}, {:ex_rtp, "~> 0.4.0"}, {:ex_rtcp, "~> 0.4.0"}, diff --git a/mix.lock b/mix.lock index f2badbec..827508a0 100644 --- a/mix.lock +++ b/mix.lock @@ -11,7 +11,7 @@ "elixir_uuid": {:hex, :elixir_uuid, "1.2.1", "dce506597acb7e6b0daeaff52ff6a9043f5919a4c3315abb4143f0b00378c097", [:mix], [], "hexpm", "f7eba2ea6c3555cea09706492716b0d87397b88946e6380898c2889d68585752"}, "erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"}, "ex_doc": {:hex, :ex_doc, "0.37.3", "f7816881a443cd77872b7d6118e8a55f547f49903aef8747dbcb345a75b462f9", [:mix], [{:earmark_parser, "~> 1.4.42", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "e6aebca7156e7c29b5da4daa17f6361205b2ae5f26e5c7d8ca0d3f7e18972233"}, - "ex_dtls": {:git, "https://github.com/elixir-webrtc/ex_dtls.git", "2c9e31a3efb714204cac55bfdd5b06dc9beee052", [branch: "cert-fragmentation"]}, + "ex_dtls": {:hex, :ex_dtls, "0.17.0", "dbe1d494583a307c26148cb5ea5d7c14e65daa8ec96cc73002cc3313ce4b9a81", [:mix], [{:bundlex, "~> 1.5.3", [hex: :bundlex, repo: "hexpm", optional: false]}, {:unifex, "~> 1.0", [hex: :unifex, repo: "hexpm", optional: false]}], "hexpm", "3eaa7221ec08fa9e4bc9430e426cbd5eb4feb8d8f450b203cf39b2114a94d713"}, "ex_ice": {:hex, :ex_ice, "0.12.0", "b52ec3ff878d5fb632ef9facc7657dfdf59e2ff9f23e634b0918e6ce1a05af48", [:mix], [{:elixir_uuid, "~> 1.0", [hex: :elixir_uuid, repo: "hexpm", optional: false]}, {:ex_stun, "~> 0.2.0", [hex: :ex_stun, repo: "hexpm", optional: false]}, {:ex_turn, "~> 0.2.0", [hex: :ex_turn, repo: "hexpm", optional: false]}], "hexpm", "a86024a5fbf9431082784be4bb3606d3cde9218fb325a9f208ccd6e0abfd0d73"}, "ex_libsrtp": {:hex, :ex_libsrtp, "0.7.2", "211bd89c08026943ce71f3e2c0231795b99cee748808ed3ae7b97cd8d2450b6b", [:mix], [{:bunch, "~> 1.6", [hex: :bunch, repo: "hexpm", optional: false]}, {:bundlex, "~> 1.3", [hex: :bundlex, repo: "hexpm", optional: false]}, {:membrane_precompiled_dependency_provider, "~> 0.1.0", [hex: :membrane_precompiled_dependency_provider, repo: "hexpm", optional: false]}, {:unifex, "~> 1.1", [hex: :unifex, repo: "hexpm", optional: false]}], "hexpm", "2e20645d0d739a4ecdcf8d4810a0c198120c8a2f617f2b75b2e2e704d59f492a"}, "ex_rtcp": {:hex, :ex_rtcp, "0.4.0", "f9e515462a9581798ff6413583a25174cfd2101c94a2ebee871cca7639886f0a", [:mix], [], "hexpm", "28956602cf210d692fcdaf3f60ca49681634e1deb28ace41246aee61ee22dc3b"}, From 7aa30e07f8f2bce4a70ef0486cd475353b699394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=9Aled=C5=BA?= Date: Fri, 18 Apr 2025 18:56:19 +0200 Subject: [PATCH 3/3] Fix tests --- test/ex_webrtc/dtls_transport_test.exs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/test/ex_webrtc/dtls_transport_test.exs b/test/ex_webrtc/dtls_transport_test.exs index 25f93944..e556cb68 100644 --- a/test/ex_webrtc/dtls_transport_test.exs +++ b/test/ex_webrtc/dtls_transport_test.exs @@ -130,7 +130,7 @@ defmodule ExWebRTC.DTLSTransportTest do remote_dtls = ExDTLS.init(mode: :client, dtls_srtp: true) {packets, _timeout} = ExDTLS.do_handshake(remote_dtls) - ice_transport.send_dtls(ice_pid, {:data, packets}) + Enum.each(packets, &ice_transport.send_dtls(ice_pid, {:data, &1})) refute_receive {:mock_ice, _packets} :ok = DTLSTransport.start_dtls(dtls, :passive, @fingerprint) @@ -182,7 +182,7 @@ defmodule ExWebRTC.DTLSTransportTest do remote_dtls = ExDTLS.init(mode: :client, dtls_srtp: true) {packets, _timeout} = ExDTLS.do_handshake(remote_dtls) - ice_transport.send_dtls(ice_pid, {:data, packets}) + Enum.each(packets, &ice_transport.send_dtls(ice_pid, {:data, &1})) refute_receive {:mock_ice, _packets} :ok = DTLSTransport.set_ice_connected(dtls) @@ -231,7 +231,7 @@ defmodule ExWebRTC.DTLSTransportTest do {packets, _timeout} = ExDTLS.do_handshake(remote_dtls) :ok = DTLSTransport.set_ice_connected(dtls) - ice_transport.send_dtls(ice_pid, {:data, packets}) + Enum.each(packets, &ice_transport.send_dtls(ice_pid, {:data, &1})) assert :ok == check_handshake(dtls, ice_transport, ice_pid, remote_dtls) assert_receive {:dtls_transport, ^dtls, {:state_change, :connecting}} @@ -282,12 +282,15 @@ defmodule ExWebRTC.DTLSTransportTest do assert_receive {:mock_ice, packets} case ExDTLS.handle_data(remote_dtls, packets) do + :handshake_want_read -> + check_handshake(dtls, ice_transport, ice_pid, remote_dtls) + {:handshake_packets, packets, _timeout} -> - ice_transport.send_dtls(ice_pid, {:data, packets}) + Enum.each(packets, &ice_transport.send_dtls(ice_pid, {:data, &1})) check_handshake(dtls, ice_transport, ice_pid, remote_dtls) {:handshake_finished, _, _, _, packets} -> - ice_transport.send_dtls(ice_pid, {:data, packets}) + Enum.each(packets, &ice_transport.send_dtls(ice_pid, {:data, &1})) :ok {:handshake_finished, _, _, _} ->