@@ -10,8 +10,10 @@ defmodule ExWebRTC.DTLSTransportTest do
1010 |> Utils . hex_dump ( )
1111
1212 @ rtp_header << 1 :: 1 , 0 :: 1 , 0 :: 1 , 0 :: 1 , 0 :: 4 , 0 :: 1 , 96 :: 7 , 1 :: 16 , 1 :: 32 , 1 :: 32 >>
13+ @ next_rtp_header << 1 :: 1 , 0 :: 1 , 0 :: 1 , 0 :: 1 , 0 :: 4 , 0 :: 1 , 96 :: 7 , 2 :: 16 , 1 :: 32 , 1 :: 32 >>
1314 @ rtp_payload << 0 >>
1415 @ rtp_packet << @ rtp_header :: binary , @ rtp_payload :: binary >>
16+ @ next_rtp_packet << @ next_rtp_header :: binary , @ rtp_payload :: binary >>
1517
1618 # empty rr packet
1719 @ rtcp_rr_header << 2 :: 2 , 0 :: 1 , 0 :: 5 , 201 :: 8 , 1 :: 16 , 1 :: 32 >>
@@ -128,7 +130,7 @@ defmodule ExWebRTC.DTLSTransportTest do
128130 :ok = DTLSTransport . set_ice_connected ( dtls )
129131
130132 remote_dtls = ExDTLS . init ( mode: :client , dtls_srtp: true )
131- { packets , _timeout } = ExDTLS . do_handshake ( remote_dtls )
133+ { :ok , packets , _timeout } = ExDTLS . do_handshake ( remote_dtls )
132134
133135 Enum . each ( packets , & ice_transport . send_dtls ( ice_pid , { :data , & 1 } ) )
134136 refute_receive { :mock_ice , _packets }
@@ -180,7 +182,7 @@ defmodule ExWebRTC.DTLSTransportTest do
180182 :ok = DTLSTransport . start_dtls ( dtls , :passive , @ fingerprint )
181183
182184 remote_dtls = ExDTLS . init ( mode: :client , dtls_srtp: true )
183- { packets , _timeout } = ExDTLS . do_handshake ( remote_dtls )
185+ { :ok , packets , _timeout } = ExDTLS . do_handshake ( remote_dtls )
184186
185187 Enum . each ( packets , & ice_transport . send_dtls ( ice_pid , { :data , & 1 } ) )
186188 refute_receive { :mock_ice , _packets }
@@ -200,7 +202,7 @@ defmodule ExWebRTC.DTLSTransportTest do
200202
201203 :ok = DTLSTransport . set_ice_connected ( dtls )
202204
203- assert :ok = check_handshake ( dtls , ice_transport , ice_pid , remote_dtls )
205+ assert { :ok , _ , _ , _ } = check_handshake ( dtls , ice_transport , ice_pid , remote_dtls )
204206 assert_receive { :dtls_transport , ^ dtls , { :state_change , :connecting } }
205207 assert_receive { :dtls_transport , ^ dtls , { :state_change , :connected } }
206208
@@ -228,12 +230,12 @@ defmodule ExWebRTC.DTLSTransportTest do
228230
229231 :ok = DTLSTransport . start_dtls ( dtls , :passive , remote_fingerprint )
230232
231- { packets , _timeout } = ExDTLS . do_handshake ( remote_dtls )
233+ { :ok , packets , _timeout } = ExDTLS . do_handshake ( remote_dtls )
232234 :ok = DTLSTransport . set_ice_connected ( dtls )
233235
234236 Enum . each ( packets , & ice_transport . send_dtls ( ice_pid , { :data , & 1 } ) )
235237
236- assert :ok = = check_handshake ( dtls , ice_transport , ice_pid , remote_dtls )
238+ assert { :ok , _ , _ , _ } = check_handshake ( dtls , ice_transport , ice_pid , remote_dtls )
237239 assert_receive { :dtls_transport , ^ dtls , { :state_change , :connecting } }
238240 assert_receive { :dtls_transport , ^ dtls , { :state_change , :connected } }
239241
@@ -256,7 +258,7 @@ defmodule ExWebRTC.DTLSTransportTest do
256258
257259 :ok = DTLSTransport . set_ice_connected ( dtls )
258260
259- assert :ok = check_handshake ( dtls , ice_transport , ice_pid , remote_dtls )
261+ assert { :ok , _ , _ , _ } = check_handshake ( dtls , ice_transport , ice_pid , remote_dtls )
260262 assert_receive { :dtls_transport , ^ dtls , { :state_change , :connecting } }
261263 assert_receive { :dtls_transport , ^ dtls , { :state_change , :connected } }
262264
@@ -278,6 +280,60 @@ defmodule ExWebRTC.DTLSTransportTest do
278280 refute_receive { :mock_ice , _datachannel_packet }
279281 end
280282
283+ test "closes on receiving close_notify DTLS alert" , % {
284+ dtls: dtls ,
285+ ice_transport: ice_transport ,
286+ ice_pid: ice_pid
287+ } do
288+ :ok = DTLSTransport . start_dtls ( dtls , :active , @ fingerprint )
289+ remote_dtls = ExDTLS . init ( mode: :server , dtls_srtp: true )
290+
291+ :ok = DTLSTransport . set_ice_connected ( dtls )
292+
293+ # perform DTLS-SRTP handshake
294+ assert { :ok , remote_lkm , remote_rkm , remote_profile } =
295+ check_handshake ( dtls , ice_transport , ice_pid , remote_dtls )
296+
297+ assert_receive { :dtls_transport , ^ dtls , { :state_change , :connecting } }
298+ assert_receive { :dtls_transport , ^ dtls , { :state_change , :connected } }
299+
300+ # create SRTP for remote side
301+ { _remote_in_srtp , remote_out_srtp } = setup_srtp ( remote_lkm , remote_rkm , remote_profile )
302+
303+ # assert packets can flow from remote to local
304+ { :ok , protected } = ExLibSRTP . protect ( remote_out_srtp , @ rtp_packet )
305+ ice_transport . send_dtls ( ice_pid , { :data , protected } )
306+ assert_receive { :dtls_transport , ^ dtls , { :rtp , @ rtp_packet } }
307+
308+ # disconnect and send close_notify from remote to local
309+ assert { :ok , packets } = ExDTLS . disconnect ( remote_dtls )
310+ Enum . each ( packets , & ice_transport . send_dtls ( ice_pid , { :data , & 1 } ) )
311+
312+ # assert local received close_notify and moved to the closed state
313+ assert_receive { :dtls_transport , ^ dtls , { :state_change , :closed } }
314+
315+ # assert that data cannot be sent by local
316+ :ok = DTLSTransport . send_rtp ( dtls , @ rtp_packet )
317+ refute_receive { :mock_ice , _rtp_packet }
318+ :ok = DTLSTransport . send_rtp ( dtls , @ rtcp_rr_packet )
319+ refute_receive { :mock_ice , _rtcp_packet }
320+ :ok = DTLSTransport . send_data ( dtls , << 1 , 2 , 3 >> )
321+ refute_receive { :mock_ice , _datachannel_packet }
322+
323+ # assert that incoming data is ignored by local
324+ { :ok , protected } = ExLibSRTP . protect ( remote_out_srtp , @ next_rtp_packet )
325+ ice_transport . send_dtls ( ice_pid , { :data , protected } )
326+ refute_receive { :dtls_transport , ^ dtls , { :rtp , _data } }
327+
328+ # assert getting certs still works
329+ assert % { local_cert_info: local_cert , remote_cert_info: remote_cert } =
330+ DTLSTransport . get_certs_info ( dtls )
331+
332+ assert local_cert != nil
333+ assert remote_cert != nil
334+ assert DTLSTransport . get_fingerprint ( dtls ) != nil
335+ end
336+
281337 defp check_handshake ( dtls , ice_transport , ice_pid , remote_dtls ) do
282338 assert_receive { :mock_ice , packets }
283339
@@ -289,17 +345,45 @@ defmodule ExWebRTC.DTLSTransportTest do
289345 Enum . each ( packets , & ice_transport . send_dtls ( ice_pid , { :data , & 1 } ) )
290346 check_handshake ( dtls , ice_transport , ice_pid , remote_dtls )
291347
292- { :handshake_finished , _ , _ , _ , packets } ->
348+ { :handshake_finished , lkm , rkm , profile , packets } ->
293349 Enum . each ( packets , & ice_transport . send_dtls ( ice_pid , { :data , & 1 } ) )
294- :ok
350+ { :ok , lkm , rkm , profile }
295351
296- { :handshake_finished , _ , _ , _ } ->
297- :ok
352+ { :handshake_finished , lkm , rkm , profile } ->
353+ { :ok , lkm , rkm , profile }
298354 end
299355 end
300356
301357 test "stop/1" , % { dtls: dtls } do
302358 assert :ok == DTLSTransport . stop ( dtls )
303359 assert false == Process . alive? ( dtls )
304360 end
361+
362+ defp setup_srtp ( lkm , rkm , profile ) do
363+ in_srtp = ExLibSRTP . new ( )
364+ out_srtp = ExLibSRTP . new ( )
365+
366+ { :ok , crypto_profile } =
367+ ExLibSRTP.Policy . crypto_profile_from_dtls_srtp_protection_profile ( profile )
368+
369+ inbound_policy = % ExLibSRTP.Policy {
370+ ssrc: :any_inbound ,
371+ key: rkm ,
372+ rtp: crypto_profile ,
373+ rtcp: crypto_profile
374+ }
375+
376+ :ok = ExLibSRTP . add_stream ( in_srtp , inbound_policy )
377+
378+ outbound_policy = % ExLibSRTP.Policy {
379+ ssrc: :any_outbound ,
380+ key: lkm ,
381+ rtp: crypto_profile ,
382+ rtcp: crypto_profile
383+ }
384+
385+ :ok = ExLibSRTP . add_stream ( out_srtp , outbound_policy )
386+
387+ { in_srtp , out_srtp }
388+ end
305389end
0 commit comments