mirror of
https://github.com/livekit/livekit.git
synced 2026-08-28 00:44:12 +00:00
Force DTLS role client for the simulated client side peer connection (#403)
* Force DTLE role client for the simulated client side peer connection during migration. Without that, with remote side being ice-lite (i. e. server offer is subscriber peer connection), pion chooses the server DTLS role and both side end up being servers. * pion/webrtc -> 3.1.21 * remove local reference * Use setup from previous answer * more comments
This commit is contained in:
@@ -28,7 +28,7 @@ require (
|
||||
github.com/pion/stun v0.3.5
|
||||
github.com/pion/transport v0.13.0
|
||||
github.com/pion/turn/v2 v2.0.6
|
||||
github.com/pion/webrtc/v3 v3.1.20
|
||||
github.com/pion/webrtc/v3 v3.1.21
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.11.0
|
||||
github.com/rs/cors v1.8.2
|
||||
@@ -73,10 +73,10 @@ require (
|
||||
github.com/prometheus/procfs v0.6.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
go.uber.org/multierr v1.6.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838 // indirect
|
||||
golang.org/x/mod v0.5.1 // indirect
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
|
||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/tools v0.1.7 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
|
||||
@@ -205,8 +205,8 @@ github.com/pion/turn/v2 v2.0.6 h1:AsXjSPR6Im15DMTB39NlfdTY9BQfieANPBjdg/aVNwY=
|
||||
github.com/pion/turn/v2 v2.0.6/go.mod h1:+y7xl719J8bAEVpSXBXvTxStjJv3hbz9YFflvkpcGPw=
|
||||
github.com/pion/udp v0.1.1 h1:8UAPvyqmsxK8oOjloDk4wUt63TzFe9WEJkg5lChlj7o=
|
||||
github.com/pion/udp v0.1.1/go.mod h1:6AFo+CMdKQm7UiA0eUPA8/eVCTx8jBIITLZHc9DWX5M=
|
||||
github.com/pion/webrtc/v3 v3.1.20 h1:rOTH68dp/K4MXh4d+9NQFzzKJXAoMy874zFglSUwB+8=
|
||||
github.com/pion/webrtc/v3 v3.1.20/go.mod h1:dIT2ETlP5dnlkgp46fAH56UizvOKuXJ9ySgFkhtmBbw=
|
||||
github.com/pion/webrtc/v3 v3.1.21 h1:6b/65m5hSw2mF+sssHBx7Q2WPccklA0U0veEYtqZSuM=
|
||||
github.com/pion/webrtc/v3 v3.1.21/go.mod h1:dIT2ETlP5dnlkgp46fAH56UizvOKuXJ9ySgFkhtmBbw=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
@@ -286,8 +286,9 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838 h1:71vQrMauZZhcTVK6KdYM+rklehEEwb3E+ZhaE5jrPrE=
|
||||
golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
@@ -359,8 +360,9 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 h1:XDXtA5hveEEV8JB2l7nhMTp3t3cHp9ZpwcdjqyEWLlo=
|
||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
||||
+53
-6
@@ -392,7 +392,20 @@ func (t *PCTransport) preparePC(previousAnswer webrtc.SessionDescription) error
|
||||
}
|
||||
t.pc.SetLocalDescription(offer)
|
||||
|
||||
pc2, err := webrtc.NewPeerConnection(webrtc.Configuration{})
|
||||
//
|
||||
// Simulcate client side peer connection and set DTLS role from previous answer.
|
||||
// Role needs to be set properly (one side needs to be server and the other side
|
||||
// eeds to be the client) for DTLS connection to form properly. As this is
|
||||
// trying to replicate previous setup, read from previous answer and use that role.
|
||||
//
|
||||
se := webrtc.SettingEngine{}
|
||||
se.SetAnsweringDTLSRole(extractDTLSRole(parsed))
|
||||
api := webrtc.NewAPI(
|
||||
webrtc.WithSettingEngine(se),
|
||||
)
|
||||
pc2, err := api.NewPeerConnection(webrtc.Configuration{
|
||||
SDPSemantics: webrtc.SDPSemanticsUnifiedPlan,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -432,12 +445,12 @@ func (t *PCTransport) preparePC(previousAnswer webrtc.SessionDescription) error
|
||||
return t.pc.SetRemoteDescription(ans)
|
||||
}
|
||||
|
||||
func (t *PCTransport) initPCWithPreviousAnswer(previousOffer webrtc.SessionDescription) error {
|
||||
if err := t.preparePC(previousOffer); err != nil {
|
||||
func (t *PCTransport) initPCWithPreviousAnswer(previousAnswer webrtc.SessionDescription) error {
|
||||
if err := t.preparePC(previousAnswer); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
parsed, err := previousOffer.Unmarshal()
|
||||
parsed, err := previousAnswer.Unmarshal()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -492,11 +505,11 @@ func (t *PCTransport) RemoveTrack(subTrack types.SubscribedTrack) {
|
||||
t.streamAllocator.RemoveTrack(subTrack.DownTrack())
|
||||
}
|
||||
|
||||
func (t *PCTransport) SetPreviousAnswer(offer *webrtc.SessionDescription) {
|
||||
func (t *PCTransport) SetPreviousAnswer(answer *webrtc.SessionDescription) {
|
||||
t.lock.Lock()
|
||||
defer t.lock.Unlock()
|
||||
if t.pc.RemoteDescription() == nil && t.previousAnswer == nil {
|
||||
t.previousAnswer = offer
|
||||
t.previousAnswer = answer
|
||||
t.initPCWithPreviousAnswer(*t.previousAnswer)
|
||||
}
|
||||
}
|
||||
@@ -539,3 +552,37 @@ func extractFingerprint(desc *sdp.SessionDescription) (string, string, error) {
|
||||
}
|
||||
return parts[1], parts[0], nil
|
||||
}
|
||||
|
||||
func extractDTLSRole(desc *sdp.SessionDescription) webrtc.DTLSRole {
|
||||
for _, md := range desc.MediaDescriptions {
|
||||
setup, ok := md.Attribute(sdp.AttrKeyConnectionSetup)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if setup == sdp.ConnectionRoleActive.String() {
|
||||
return webrtc.DTLSRoleClient
|
||||
}
|
||||
|
||||
if setup == sdp.ConnectionRolePassive.String() {
|
||||
return webrtc.DTLSRoleServer
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// If 'setup' attribute is not available, use client role
|
||||
// as that is the default behaviour of answerers
|
||||
//
|
||||
// There seems to be some differences in how role is decided.
|
||||
// libwebrtc (Chrome) code - (https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/pc/jsep_transport.cc;l=592;drc=369fb686729e7eb20d2bd09717cec14269a399d7)
|
||||
// does not mention anything about ICE role when determining
|
||||
// DTLS Role.
|
||||
//
|
||||
// But, ORTC has this - https://github.com/w3c/ortc/issues/167#issuecomment-69409953
|
||||
// and pion/webrtc follows that (https://github.com/pion/webrtc/blob/e071a4eded1efd5d9b401bcfc4efacb3a2a5a53c/dtlstransport.go#L269)
|
||||
//
|
||||
// So if remote is ice-lite, pion will use DTLSRoleServer when answering
|
||||
// while browsers pick DTLSRoleClient.
|
||||
//
|
||||
return webrtc.DTLSRoleClient
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user