From dba534560db31dc8b90a0a61d339bdacc7b6877a Mon Sep 17 00:00:00 2001 From: Karol Konkol Date: Thu, 24 Jul 2025 16:17:55 +0200 Subject: [PATCH 1/2] Add host_to_srflx_ip_mapper --- lib/ex_webrtc/peer_connection.ex | 1 + lib/ex_webrtc/peer_connection/configuration.ex | 14 ++++++++++++++ mix.exs | 2 +- mix.lock | 2 +- 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/ex_webrtc/peer_connection.ex b/lib/ex_webrtc/peer_connection.ex index 9cc47277..c07df426 100644 --- a/lib/ex_webrtc/peer_connection.ex +++ b/lib/ex_webrtc/peer_connection.ex @@ -612,6 +612,7 @@ defmodule ExWebRTC.PeerConnection do ice_transport_policy: config.ice_transport_policy, ip_filter: config.ice_ip_filter, aggressive_nomination: config.ice_aggressive_nomination, + host_to_srflx_ip_mapper: config.host_to_srflx_ip_mapper, ports: config.ice_port_range, on_data: nil ] diff --git a/lib/ex_webrtc/peer_connection/configuration.ex b/lib/ex_webrtc/peer_connection/configuration.ex index 7f668d5c..0a34dc6f 100644 --- a/lib/ex_webrtc/peer_connection/configuration.ex +++ b/lib/ex_webrtc/peer_connection/configuration.ex @@ -164,6 +164,17 @@ defmodule ExWebRTC.PeerConnection.Configuration do at the very end of the whole connection establishment process. To mitigate this issue, you can eitehr add an empty ICE candidate (this will indicate that there won't be further remote candidates and once all connectivity checks pass, ICE will nominate the pair), or use aggressive nomination. Defaults to false. + * `host_to_srflx_ip_mapper` - function called for each host candidate to derive a new "fabricated" srflx candidate from it. + This function takes host's ip as an argument and should return srflx's ip as a result or nil if for given host candidate + there should be no srflx one. + + Note that each returned IP address must be unique. + If the mapping function repeatedly returns the same address, + it will be ignored, and only one server reflexive candidate will be created. + + This function is meant to be used for server implementations where the public addresses are well known. + NAT uses 1 to 1 port mapping and using STUN server for discovering public IP is undesirable + (e.g. because of unknown response time). * `audio_codecs` and `video_codecs` - lists of audio and video codecs to negotiate. By default these are equal to `default_audio_codecs/0` and `default_video_codecs/0`. To extend the list with your own codecs, do `audio_codecs: Configuration.default_audio_codecs() ++ my_codecs`. @@ -189,6 +200,7 @@ defmodule ExWebRTC.PeerConnection.Configuration do ice_ip_filter: ICEAgent.ip_filter(), ice_port_range: Enumerable.t(non_neg_integer()), ice_aggressive_nomination: boolean(), + host_to_srflx_ip_mapper: ICEAgent.host_to_srflx_ip_mapper(), audio_codecs: [RTPCodecParameters.t()] | [audio_codec_name()], video_codecs: [RTPCodecParameters.t()] | [video_codec_name()], features: [feature()], @@ -209,6 +221,7 @@ defmodule ExWebRTC.PeerConnection.Configuration do ice_ip_filter: (:inet.ip_address() -> boolean()) | nil, ice_port_range: Enumerable.t(non_neg_integer()), ice_aggressive_nomination: boolean(), + host_to_srflx_ip_mapper: ICEAgent.host_to_srflx_ip_mapper() | nil, audio_codecs: [RTPCodecParameters.t()], video_codecs: [RTPCodecParameters.t()], audio_extensions: [Extmap.t()], @@ -228,6 +241,7 @@ defmodule ExWebRTC.PeerConnection.Configuration do ice_transport_policy: :all, ice_port_range: [0], ice_aggressive_nomination: false, + host_to_srflx_ip_mapper: nil, audio_codecs: @default_audio_codecs, video_codecs: @default_video_codecs, features: @default_features diff --git a/mix.exs b/mix.exs index 44420cc3..56c7d60c 100644 --- a/mix.exs +++ b/mix.exs @@ -57,7 +57,7 @@ defmodule ExWebRTC.MixProject do defp deps do [ {:ex_sdp, "~> 1.0"}, - {:ex_ice, "~> 0.13.0"}, + {:ex_ice, github: "elixir-webrtc/ex_ice", ref: "a4f930b19a1e92c5bbaf64e24e0035942f6ff280"}, {:ex_dtls, "~> 0.18.0"}, {:ex_libsrtp, "~> 0.7.1"}, {:ex_rtp, "~> 0.4.0"}, diff --git a/mix.lock b/mix.lock index 9279cb99..2b019aaa 100644 --- a/mix.lock +++ b/mix.lock @@ -12,7 +12,7 @@ "erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"}, "ex_doc": {:hex, :ex_doc, "0.38.2", "504d25eef296b4dec3b8e33e810bc8b5344d565998cd83914ffe1b8503737c02", [:mix], [{:earmark_parser, "~> 1.4.44", [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", "732f2d972e42c116a70802f9898c51b54916e542cc50968ac6980512ec90f42b"}, "ex_dtls": {:hex, :ex_dtls, "0.18.0", "0815e3384bb0c1e6c06559012479cf9a94a501ddf46c3df54dc2d1b169e29d5c", [:mix], [{:bundlex, "~> 1.5.3", [hex: :bundlex, repo: "hexpm", optional: false]}, {:unifex, "~> 1.0", [hex: :unifex, repo: "hexpm", optional: false]}], "hexpm", "562eda1815eeaed8360b2b5c34d4db5b453794bc096404a4c64f193fa7b18bf2"}, - "ex_ice": {:hex, :ex_ice, "0.13.0", "13a6ae106b26bb5f2957a586bf20d4031299e5b968533828e637bb4ac7645d31", [: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", "0d65afa15e36b5610d0f51e72e4c25b22346caa9a6d7d2f6f1cfd8db94bd494e"}, + "ex_ice": {:git, "https://github.com/elixir-webrtc/ex_ice.git", "a4f930b19a1e92c5bbaf64e24e0035942f6ff280", [ref: "a4f930b19a1e92c5bbaf64e24e0035942f6ff280"]}, "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"}, "ex_rtp": {:hex, :ex_rtp, "0.4.0", "1f1b5c1440a904706011e3afbb41741f5da309ce251cb986690ce9fd82636658", [:mix], [], "hexpm", "0f72d80d5953a62057270040f0f1ee6f955c08eeae82ac659c038001d7d5a790"}, From 955dcb9eb72f73415fe06b2633972c0bb4b7ef3d Mon Sep 17 00:00:00 2001 From: Karol Konkol Date: Thu, 24 Jul 2025 18:21:37 +0200 Subject: [PATCH 2/2] Update deps --- mix.exs | 2 +- mix.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mix.exs b/mix.exs index 56c7d60c..c002366b 100644 --- a/mix.exs +++ b/mix.exs @@ -57,7 +57,7 @@ defmodule ExWebRTC.MixProject do defp deps do [ {:ex_sdp, "~> 1.0"}, - {:ex_ice, github: "elixir-webrtc/ex_ice", ref: "a4f930b19a1e92c5bbaf64e24e0035942f6ff280"}, + {:ex_ice, github: "elixir-webrtc/ex_ice"}, {:ex_dtls, "~> 0.18.0"}, {:ex_libsrtp, "~> 0.7.1"}, {:ex_rtp, "~> 0.4.0"}, diff --git a/mix.lock b/mix.lock index 2b019aaa..fd3dc940 100644 --- a/mix.lock +++ b/mix.lock @@ -12,7 +12,7 @@ "erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"}, "ex_doc": {:hex, :ex_doc, "0.38.2", "504d25eef296b4dec3b8e33e810bc8b5344d565998cd83914ffe1b8503737c02", [:mix], [{:earmark_parser, "~> 1.4.44", [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", "732f2d972e42c116a70802f9898c51b54916e542cc50968ac6980512ec90f42b"}, "ex_dtls": {:hex, :ex_dtls, "0.18.0", "0815e3384bb0c1e6c06559012479cf9a94a501ddf46c3df54dc2d1b169e29d5c", [:mix], [{:bundlex, "~> 1.5.3", [hex: :bundlex, repo: "hexpm", optional: false]}, {:unifex, "~> 1.0", [hex: :unifex, repo: "hexpm", optional: false]}], "hexpm", "562eda1815eeaed8360b2b5c34d4db5b453794bc096404a4c64f193fa7b18bf2"}, - "ex_ice": {:git, "https://github.com/elixir-webrtc/ex_ice.git", "a4f930b19a1e92c5bbaf64e24e0035942f6ff280", [ref: "a4f930b19a1e92c5bbaf64e24e0035942f6ff280"]}, + "ex_ice": {:git, "https://github.com/elixir-webrtc/ex_ice.git", "a4f930b19a1e92c5bbaf64e24e0035942f6ff280", []}, "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"}, "ex_rtp": {:hex, :ex_rtp, "0.4.0", "1f1b5c1440a904706011e3afbb41741f5da309ce251cb986690ce9fd82636658", [:mix], [], "hexpm", "0f72d80d5953a62057270040f0f1ee6f955c08eeae82ac659c038001d7d5a790"},