Skip to content

Commit

Permalink
Fix DTLS handshake initiation in active mode
Browse files Browse the repository at this point in the history
  • Loading branch information
LVala committed Nov 2, 2023
1 parent 8f3fac2 commit 1dab515
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 4 deletions.
1 change: 1 addition & 0 deletions examples/example.exs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ defmodule Peer do
offer = %SessionDescription{type: :offer, sdp: sdp}
:ok = PeerConnection.set_remote_description(state.peer_connection, offer)
{:ok, answer} = PeerConnection.create_answer(state.peer_connection)
:ok = PeerConnection.set_local_description(state.peer_connection, answer)
msg = %{"type" => "answer", "sdp" => answer.sdp}
:gun.ws_send(state.conn, state.stream, {:text, Jason.encode!(msg)})
end
Expand Down
59 changes: 55 additions & 4 deletions lib/ex_webrtc/peer_connection.ex
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ defmodule ExWebRTC.PeerConnection do
:pending_remote_desc,
:ice_agent,
:ice_state,
:dtls_client,
:dtls_buffered_packets,
dtls_client: nil,
dtls_finished: false,
initiate_dtls: false,
transceivers: [],
signaling_state: :stable,
last_offer: nil,
Expand Down Expand Up @@ -114,13 +115,11 @@ defmodule ExWebRTC.PeerConnection do
|> Enum.filter(&String.starts_with?(&1, "stun:"))

{:ok, ice_agent} = ICEAgent.start_link(:controlled, stun_servers: stun_servers)
{:ok, dtls_client} = ExDTLS.start_link(client_mode: false, dtls_srtp: true)

state = %__MODULE__{
owner: owner,
config: config,
ice_agent: ice_agent,
dtls_client: dtls_client
ice_agent: ice_agent
}

{:ok, state}
Expand All @@ -144,6 +143,12 @@ defmodule ExWebRTC.PeerConnection do
transceivers = assign_mids(state.transceivers, next_mid)

{:ok, ice_ufrag, ice_pwd} = ICEAgent.get_local_credentials(state.ice_agent)

# TODO this will fail on subsequent calls
# or when answer contains setup: passive
{:ok, dtls_client} = ExDTLS.start_link(client_mode: false, dtls_srtp: true)
state = %__MODULE__{state | dtls_client: dtls_client}

{:ok, dtls_fingerprint} = ExDTLS.get_cert_fingerprint(state.dtls_client)

offer =
Expand Down Expand Up @@ -200,6 +205,10 @@ defmodule ExWebRTC.PeerConnection do
{:offer, remote_offer} = state.pending_remote_desc

{:ok, ice_ufrag, ice_pwd} = ICEAgent.get_local_credentials(state.ice_agent)
# TODO this will fail on subsequent calls
{:ok, dtls_client} = ExDTLS.start_link(client_mode: true, dtls_srtp: true)
state = %__MODULE__{state | dtls_client: dtls_client}

{:ok, dtls_fingerprint} = ExDTLS.get_cert_fingerprint(state.dtls_client)

answer =
Expand Down Expand Up @@ -322,6 +331,14 @@ defmodule ExWebRTC.PeerConnection do

@impl true
def handle_info({:ex_ice, _from, :connected}, state) do
state =
if state.initiate_dtls do
start_dtls_handshake(state)
%__MODULE__{state | initiate_dtls: false}

Check warning on line 337 in lib/ex_webrtc/peer_connection.ex

View check run for this annotation

Codecov / codecov/patch

lib/ex_webrtc/peer_connection.ex#L334-L337

Added lines #L334 - L337 were not covered by tests
else
state

Check warning on line 339 in lib/ex_webrtc/peer_connection.ex

View check run for this annotation

Codecov / codecov/patch

lib/ex_webrtc/peer_connection.ex#L339

Added line #L339 was not covered by tests
end

if state.dtls_buffered_packets do
Logger.debug("Sending buffered DTLS packets")
ICEAgent.send_data(state.ice_agent, state.dtls_buffered_packets)
Expand Down Expand Up @@ -401,6 +418,14 @@ defmodule ExWebRTC.PeerConnection do
new_transceivers = update_local_transceivers(type, state.transceivers, sdp)
state = set_description(:local, type, sdp, state)

state =
if type == :answer do
{:setup, setup} = ExSDP.Media.get_attribute(hd(sdp.media), :setup)
start_dtls(setup, state)
else
state
end

{:ok, %{state | transceivers: new_transceivers}}
end

Expand Down Expand Up @@ -437,6 +462,14 @@ defmodule ExWebRTC.PeerConnection do

state = set_description(:remote, type, sdp, state)

state =
if type == :answer do
{:setup, setup} = ExSDP.Media.get_attribute(hd(sdp.media), :setup)
start_dtls(setup, state)
else
state
end

{:ok, %{state | transceivers: new_transceivers}}
else
error -> error
Expand Down Expand Up @@ -466,6 +499,24 @@ defmodule ExWebRTC.PeerConnection do
new_transceivers
end

defp start_dtls(:active, %{ice_state: :connected} = state) do
start_dtls_handshake(state)
state

Check warning on line 504 in lib/ex_webrtc/peer_connection.ex

View check run for this annotation

Codecov / codecov/patch

lib/ex_webrtc/peer_connection.ex#L503-L504

Added lines #L503 - L504 were not covered by tests
end

defp start_dtls(:active, state) do
%__MODULE__{state | initiate_dtls: true}
end

defp start_dtls(_setup, state) do
state

Check warning on line 512 in lib/ex_webrtc/peer_connection.ex

View check run for this annotation

Codecov / codecov/patch

lib/ex_webrtc/peer_connection.ex#L512

Added line #L512 was not covered by tests
end

defp start_dtls_handshake(state) do
{:ok, packets} = ExDTLS.do_handshake(state.dtls_client)
:ok = ICEAgent.send_data(state.ice_agent, packets)

Check warning on line 517 in lib/ex_webrtc/peer_connection.ex

View check run for this annotation

Codecov / codecov/patch

lib/ex_webrtc/peer_connection.ex#L516-L517

Added lines #L516 - L517 were not covered by tests
end

defp find_next_mid(state) do
# next mid must be unique, it's acomplished by looking for values
# greater than any mid in remote description or our own transceivers
Expand Down

0 comments on commit 1dab515

Please sign in to comment.