diff --git a/peerconnection.go b/peerconnection.go index 4b2a16e39ca..5ac160c9afd 100644 --- a/peerconnection.go +++ b/peerconnection.go @@ -2417,7 +2417,7 @@ func (pc *PeerConnection) startTransports(iceRole ICERole, dtlsRole DTLSRole, re } pc.dtlsTransport.internalOnCloseHandler = func() { - if pc.isClosed.get() { + if pc.isClosed.get() || pc.api.settingEngine.disableCloseByDTLS { return } diff --git a/settingengine.go b/settingengine.go index 5fcafeb7615..fb2c40bc5fc 100644 --- a/settingengine.go +++ b/settingengine.go @@ -102,6 +102,7 @@ type SettingEngine struct { receiveMTU uint iceMaxBindingRequests *uint16 fireOnTrackBeforeFirstRTP bool + disableCloseByDTLS bool } // getReceiveMTU returns the configured MTU. If SettingEngine's MTU is configured to 0 it returns the default @@ -501,3 +502,10 @@ func (e *SettingEngine) SetICEBindingRequestHandler(bindingRequestHandler func(m func (e *SettingEngine) SetFireOnTrackBeforeFirstRTP(fireOnTrackBeforeFirstRTP bool) { e.fireOnTrackBeforeFirstRTP = fireOnTrackBeforeFirstRTP } + +// DisableCloseByDTLS sets if the connection should be closed when dtls transport is closed. +// Setting this to true will keep the connection open when dtls transport is closed +// and relies on the ice failed state to detect the connection is interrupted. +func (e *SettingEngine) DisableCloseByDTLS(isEnabled bool) { + e.disableCloseByDTLS = isEnabled +} diff --git a/settingengine_test.go b/settingengine_test.go index 6912694f497..8b786859fc7 100644 --- a/settingengine_test.go +++ b/settingengine_test.go @@ -394,3 +394,26 @@ func TestSetFireOnTrackBeforeFirstRTP(t *testing.T) { closePairNow(t, offerer, answerer) } + +func TestDisableCloseByDTLS(t *testing.T) { + lim := test.TimeOut(time.Second * 30) + defer lim.Stop() + + report := test.CheckRoutines(t) + defer report() + + s := SettingEngine{} + s.DisableCloseByDTLS(true) + + offer, answer, err := NewAPI(WithSettingEngine(s)).newPair(Configuration{}) + assert.NoError(t, err) + + assert.NoError(t, signalPair(offer, answer)) + + untilConnectionState(PeerConnectionStateConnected, offer, answer).Wait() + assert.NoError(t, answer.Close()) + + time.Sleep(time.Second) + assert.True(t, offer.ConnectionState() == PeerConnectionStateConnected) + assert.NoError(t, offer.Close()) +}