From 22ba65170372f2b0cf2eaa97c3c1319e53deb0fb Mon Sep 17 00:00:00 2001 From: cnderrauber Date: Thu, 5 Nov 2026 22:01:40 +0800 Subject: [PATCH] Pick DTLS server role when ice-lite is enabled (#5143) To speed up data channel and warp. Exclude sdks (unknown || esp32) that may have problem to support answer dtls server role. --- go.mod | 4 ++-- go.sum | 4 ++-- pkg/rtc/clientinfo.go | 5 ++++ pkg/rtc/config.go | 7 ++++++ pkg/rtc/transport.go | 5 ++++ pkg/rtc/transport_test.go | 49 ++++++++++++++++++++++++++++++++++++++ pkg/service/roommanager.go | 2 +- 7 files changed, 71 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 3c5b74556..030270168 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/jellydator/ttlcache/v3 v3.4.1 github.com/jxskiss/base62 v1.1.0 github.com/livekit/mageutil v0.0.0-20250511045019-0f1ff63f7731 - github.com/livekit/mediatransportutil v0.0.0-20261104095513-c341f61ad457 + github.com/livekit/mediatransportutil v0.0.0-20261105133908-2cf1b1487796 github.com/livekit/protocol v1.53.2 github.com/livekit/psrpc v0.8.2 github.com/mackerelio/go-osstat v0.2.8 @@ -143,7 +143,7 @@ require ( github.com/pion/mdns/v2 v2.2.2 // indirect github.com/pion/randutil v0.1.0 // indirect github.com/pion/srtp/v3 v3.1.3 // indirect - github.com/pion/stun/v3 v3.1.7 + github.com/pion/stun/v3 v3.1.7 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_model v0.6.3 github.com/prometheus/common v0.72.0 // indirect diff --git a/go.sum b/go.sum index 1da184208..cfb49535e 100644 --- a/go.sum +++ b/go.sum @@ -162,8 +162,8 @@ github.com/livekit/ice/v4 v4.4.8-warp.2 h1:CED3dys57JySsNmKrPFAwA1j/9eDSOJA3MZJ/ github.com/livekit/ice/v4 v4.4.8-warp.2/go.mod h1:zCRRg4Mkpdbx9B+75fd4z2APvIXeIraeUOB7IMPt8mU= github.com/livekit/mageutil v0.0.0-20250511045019-0f1ff63f7731 h1:9x+U2HGLrSw5ATTo469PQPkqzdoU7be46ryiCDO3boc= github.com/livekit/mageutil v0.0.0-20250511045019-0f1ff63f7731/go.mod h1:Rs3MhFwutWhGwmY1VQsygw28z5bWcnEYmS1OG9OxjOQ= -github.com/livekit/mediatransportutil v0.0.0-20261104095513-c341f61ad457 h1:iefcssQv9onCyTQQYTbIn4OwBUnkjD+5uD9a5mjJMTo= -github.com/livekit/mediatransportutil v0.0.0-20261104095513-c341f61ad457/go.mod h1:/T+BvdqiQN7mYJJk5EFFqbdbe7yBAvR8Ilx5kMVzT4M= +github.com/livekit/mediatransportutil v0.0.0-20261105133908-2cf1b1487796 h1:Ywn57x0LFvbUbHFV1gESlPA/4u8FHIpuEJIwQH3CQZA= +github.com/livekit/mediatransportutil v0.0.0-20261105133908-2cf1b1487796/go.mod h1:/T+BvdqiQN7mYJJk5EFFqbdbe7yBAvR8Ilx5kMVzT4M= github.com/livekit/protocol v1.53.2 h1:IuT1oM3XdP6m/FjeH5IhV3pRkF2iF3bqO5K4S3xND64= github.com/livekit/protocol v1.53.2/go.mod h1:oSYtuivQ/y77D+cCZStm9heI6yE+w9lAacWnzSIRLiQ= github.com/livekit/psrpc v0.8.2 h1:7tbkhBJoYlK5Csfkdv1XYbZjyAQeaEZgupvIXNCv7Dc= diff --git a/pkg/rtc/clientinfo.go b/pkg/rtc/clientinfo.go index 899d60a70..3dfde07ef 100644 --- a/pkg/rtc/clientinfo.go +++ b/pkg/rtc/clientinfo.go @@ -115,6 +115,11 @@ func (c ClientInfo) SupportsSctpZeroChecksum() bool { (!c.isGo() || c.compareVersion("2.4.0") >= 0) } +func (c ClientInfo) SupportsAnswerDTLSRoleServer() bool { + sdk := c.ClientInfo.GetSdk() + return sdk != livekit.ClientInfo_UNKNOWN && sdk != livekit.ClientInfo_ESP32 +} + func (c ClientInfo) SupportsTransceiverReuse() bool { return !c.isSafari() } diff --git a/pkg/rtc/config.go b/pkg/rtc/config.go index d6b248db7..4b963070a 100644 --- a/pkg/rtc/config.go +++ b/pkg/rtc/config.go @@ -38,6 +38,7 @@ type WebRTCConfig struct { Receiver ReceiverConfig Publisher DirectionConfig Subscriber DirectionConfig + ICELite bool flexFEC config.FlexFECConfig } @@ -102,10 +103,16 @@ func NewWebRTCConfig(conf *config.Config) (*WebRTCConfig, error) { }, Publisher: getPublisherConfig(false, flexFEC), Subscriber: subscriberConfig, + ICELite: rtcConf.UseICELite, flexFEC: flexFEC, }, nil } +func (c *WebRTCConfig) DisableICELite() { + c.SettingEngine.SetLite(false) + c.ICELite = false +} + func (c *WebRTCConfig) UpdatePublisherConfig(consolidated bool) { c.Publisher = getPublisherConfig(consolidated, c.flexFEC) } diff --git a/pkg/rtc/transport.go b/pkg/rtc/transport.go index ce7555d5e..1e2eb0d57 100644 --- a/pkg/rtc/transport.go +++ b/pkg/rtc/transport.go @@ -412,6 +412,7 @@ func newPeerConnection( // se.DisableSRTPReplayProtection(true) se.DisableSRTCPReplayProtection(true) + iceLite := params.Config.ICELite if !params.ProtocolVersion.SupportsICELite() || !params.ClientInfo.SupportsPrflxOverRelay() { // if client don't support prflx over relay which is only Firefox, disable ICE Lite to ensure that // aggressive nomination is handled properly. Firefox does aggressive nomination even if peer is @@ -421,6 +422,10 @@ func newPeerConnection( // ending up with different candidates. // As Firefox does not support migration, ICE Lite can be disabled. se.SetLite(false) + iceLite = false + } + if iceLite && params.ClientInfo.SupportsAnswerDTLSRoleServer() { + _ = se.SetAnsweringDTLSRole(webrtc.DTLSRoleServer) } // ICE checks already prove the remote address, so the HelloVerifyRequest cookie only adds a round trip. // pion applies this only when this side ends up as the DTLS server. diff --git a/pkg/rtc/transport_test.go b/pkg/rtc/transport_test.go index 4962f0724..71c488002 100644 --- a/pkg/rtc/transport_test.go +++ b/pkg/rtc/transport_test.go @@ -1073,3 +1073,52 @@ func TestRemoteOfferParsedFollowsICERestartFragment(t *testing.T) { require.Equal(t, "restartUfrag", ufrag) require.Equal(t, "restartPwd0123456789abcdef", pwd) } + +func TestAnsweringDTLSRole(t *testing.T) { + sdkInfo := func(sdk livekit.ClientInfo_SDK) ClientInfo { + return ClientInfo{ClientInfo: &livekit.ClientInfo{Sdk: sdk}} + } + cases := []struct { + name string + iceLite bool + clientInfo ClientInfo + expected sdp.ConnectionRole + }{ + {name: "ice lite", iceLite: true, clientInfo: sdkInfo(livekit.ClientInfo_JS), expected: sdp.ConnectionRolePassive}, + {name: "no ice lite", clientInfo: sdkInfo(livekit.ClientInfo_JS), expected: sdp.ConnectionRoleActive}, + {name: "unknown sdk", iceLite: true, clientInfo: ClientInfo{}, expected: sdp.ConnectionRoleActive}, + {name: "esp32", iceLite: true, clientInfo: sdkInfo(livekit.ClientInfo_ESP32), expected: sdp.ConnectionRoleActive}, + } + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + conf := &WebRTCConfig{ICELite: c.iceLite} + conf.SettingEngine.SetLite(c.iceLite) + answerer, err := NewPCTransport(TransportParams{ + Config: conf, + ProtocolVersion: 16, + ClientInfo: c.clientInfo, + Handler: &transportfakes.FakeHandler{}, + }) + require.NoError(t, err) + defer answerer.Close() + + offerer, err := webrtc.NewPeerConnection(webrtc.Configuration{}) + require.NoError(t, err) + defer offerer.Close() + _, err = offerer.CreateDataChannel("test", nil) + require.NoError(t, err) + offer, err := offerer.CreateOffer(nil) + require.NoError(t, err) + + require.NoError(t, answerer.pc.SetRemoteDescription(offer)) + answer, err := answerer.pc.CreateAnswer(nil) + require.NoError(t, err) + + parsed, err := answer.Unmarshal() + require.NoError(t, err) + setup, ok := parsed.MediaDescriptions[0].Attribute(sdp.AttrKeyConnectionSetup) + require.True(t, ok) + require.Equal(t, c.expected.String(), setup) + }) + } +} diff --git a/pkg/service/roommanager.go b/pkg/service/roommanager.go index ee49eaea2..3c52dc140 100644 --- a/pkg/service/roommanager.go +++ b/pkg/service/roommanager.go @@ -445,7 +445,7 @@ func (r *RoomManager) StartSession( rtcConf := *r.rtcConfig rtcConf.SetBufferFactory(room.GetBufferFactory()) if pi.DisableICELite { - rtcConf.SettingEngine.SetLite(false) + rtcConf.DisableICELite() } rtcConf.UpdatePublisherConfig(pi.UseSinglePeerConnection)