Add option to disable close by dtls

Close peerconnection on DTLS.CloseNotify
could break ice restart with dtls restart,
when the dtls finger-print changed, the
browser could teardown the old dtlstransport
and establish new one then pion could close
the peerconnection and restart failed. So
browser don't do this and spec also don't
say peerconnection should close when dtls
is closed.
This commit is contained in:
cnderrauber
2024-11-29 16:31:55 +08:00
committed by Sean DuBois
parent 2553783e53
commit 8e2c8682de
3 changed files with 32 additions and 1 deletions

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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())
}