From d7c410910f5de32efc22a5a8a3d30dfbd4f55ca4 Mon Sep 17 00:00:00 2001 From: Raja Subramanian Date: Mon, 7 Apr 2025 14:47:03 +0530 Subject: [PATCH] Exclude RED from enabled codecs for Flutter + 2.4.2 + Android. (#3587) * Exclude RED from enabled codecs for Flutter + 2.4.2 + Android. That causes client to get confused and generate invalid SDP. Also make SDK version rule check based on semantic versioning compare. * deps --- go.mod | 10 ++--- go.sum | 8 ++-- pkg/clientconfiguration/conf.go | 9 +++++ pkg/clientconfiguration/match.go | 67 +++++++++++++++++++++++++++++++- 4 files changed, 82 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index f3553e1a4..9e28cdf1f 100644 --- a/go.mod +++ b/go.mod @@ -38,14 +38,10 @@ require ( github.com/pion/rtcp v1.2.15 github.com/pion/rtp v1.8.13 github.com/pion/sctp v1.8.37 - // sdp/v3 3.0.11 (https://github.com/pion/sdp/releases/tag/v3.0.11) - // errors on conflicting codec values in SDP. - // Some clients (especially Android) seems to be sending invalid SDP - // which fails when trying to set preferred codec. - github.com/pion/sdp/v3 v3.0.10 + github.com/pion/sdp/v3 v3.0.11 github.com/pion/transport/v3 v3.0.7 github.com/pion/turn/v4 v4.0.0 - github.com/pion/webrtc/v4 v4.0.13 + github.com/pion/webrtc/v4 v4.0.14 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.20.5 github.com/redis/go-redis/v9 v9.7.3 @@ -60,6 +56,7 @@ require ( go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 + golang.org/x/mod v0.24.0 golang.org/x/sync v0.12.0 google.golang.org/protobuf v1.36.6 gopkg.in/yaml.v3 v3.0.1 @@ -136,7 +133,6 @@ require ( github.com/zeebo/xxh3 v1.0.2 // indirect go.uber.org/zap/exp v0.3.0 // indirect golang.org/x/crypto v0.36.0 // indirect - golang.org/x/mod v0.24.0 // indirect golang.org/x/net v0.38.0 // indirect golang.org/x/sys v0.31.0 // indirect golang.org/x/text v0.23.0 // indirect diff --git a/go.sum b/go.sum index 55d187da2..77f1aee75 100644 --- a/go.sum +++ b/go.sum @@ -254,8 +254,8 @@ github.com/pion/rtp v1.8.13 h1:8uSUPpjSL4OlwZI8Ygqu7+h2p9NPFB+yAZ461Xn5sNg= github.com/pion/rtp v1.8.13/go.mod h1:8uMBJj32Pa1wwx8Fuv/AsFhn8jsgw+3rUC2PfoBZ8p4= github.com/pion/sctp v1.8.37 h1:ZDmGPtRPX9mKCiVXtMbTWybFw3z/hVKAZgU81wcOrqs= github.com/pion/sctp v1.8.37/go.mod h1:cNiLdchXra8fHQwmIoqw0MbLLMs+f7uQ+dGMG2gWebE= -github.com/pion/sdp/v3 v3.0.10 h1:6MChLE/1xYB+CjumMw+gZ9ufp2DPApuVSnDT8t5MIgA= -github.com/pion/sdp/v3 v3.0.10/go.mod h1:88GMahN5xnScv1hIMTqLdu/cOcUkj6a9ytbncwMCq2E= +github.com/pion/sdp/v3 v3.0.11 h1:VhgVSopdsBKwhCFoyyPmT1fKMeV9nLMrEKxNOdy3IVI= +github.com/pion/sdp/v3 v3.0.11/go.mod h1:88GMahN5xnScv1hIMTqLdu/cOcUkj6a9ytbncwMCq2E= github.com/pion/srtp/v3 v3.0.4 h1:2Z6vDVxzrX3UHEgrUyIGM4rRouoC7v+NiF1IHtp9B5M= github.com/pion/srtp/v3 v3.0.4/go.mod h1:1Jx3FwDoxpRaTh1oRV8A/6G1BnFL+QI82eK4ms8EEJQ= github.com/pion/stun/v3 v3.0.0 h1:4h1gwhWLWuZWOJIJR9s2ferRO+W3zA/b6ijOI6mKzUw= @@ -264,8 +264,8 @@ github.com/pion/transport/v3 v3.0.7 h1:iRbMH05BzSNwhILHoBoAPxoB9xQgOaJk+591KC9P1 github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uPLGhhz9rwo= github.com/pion/turn/v4 v4.0.0 h1:qxplo3Rxa9Yg1xXDxxH8xaqcyGUtbHYw4QSCvmFWvhM= github.com/pion/turn/v4 v4.0.0/go.mod h1:MuPDkm15nYSklKpN8vWJ9W2M0PlyQZqYt1McGuxG7mA= -github.com/pion/webrtc/v4 v4.0.13 h1:XuUaWTjRufsiGJRC+G71OgiSMe7tl7mQ0kkd4bAqIaQ= -github.com/pion/webrtc/v4 v4.0.13/go.mod h1:Fadzxm0CbY99YdCEfxrgiVr0L4jN1l8bf8DBkPPpJbs= +github.com/pion/webrtc/v4 v4.0.14 h1:nyds/sFRR+HvmWoBa6wrL46sSfpArE0qR883MBW96lg= +github.com/pion/webrtc/v4 v4.0.14/go.mod h1:R3+qTnQTS03UzwDarYecgioNf7DYgTsldxnCXB821Kk= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/pkg/clientconfiguration/conf.go b/pkg/clientconfiguration/conf.go index 992cca92d..2a344a324 100644 --- a/pkg/clientconfiguration/conf.go +++ b/pkg/clientconfiguration/conf.go @@ -43,4 +43,13 @@ var StaticConfigurations = []ConfigurationItem{ }, Merge: false, }, + { + Match: &ScriptMatch{Expr: `(c.sdk == "flutter" && c.version == "2.4.2" && c.os == "android"`}, + Configuration: &livekit.ClientConfiguration{ + DisabledCodecs: &livekit.DisabledCodecs{ + Publish: []*livekit.Codec{{Mime: mime.MimeTypeRED.String()}}, + }, + }, + Merge: false, + }, } diff --git a/pkg/clientconfiguration/match.go b/pkg/clientconfiguration/match.go index b915c2c6a..57d7f7c26 100644 --- a/pkg/clientconfiguration/match.go +++ b/pkg/clientconfiguration/match.go @@ -20,6 +20,8 @@ import ( "strings" "github.com/d5/tengo/v2" + "github.com/d5/tengo/v2/token" + "golang.org/x/mod/semver" "github.com/livekit/protocol/livekit" ) @@ -49,6 +51,8 @@ func (m *ScriptMatch) Match(clientInfo *livekit.ClientInfo) (bool, error) { return false, errors.New("invalid match expression result") } +// ------------------------------------------------ + type clientObject struct { tengo.ObjectImpl info *livekit.ClientInfo @@ -72,7 +76,7 @@ func (c *clientObject) IndexGet(index tengo.Object) (res tengo.Object, err error case "sdk": return &tengo.String{Value: strings.ToLower(c.info.Sdk.String())}, nil case "version": - return &tengo.String{Value: c.info.Version}, nil + return &ruleSdkVersion{sdkVersion: c.info.Version}, nil case "protocol": return &tengo.Int{Value: int64(c.info.Protocol)}, nil case "os": @@ -90,3 +94,64 @@ func (c *clientObject) IndexGet(index tengo.Object) (res tengo.Object, err error } return &tengo.Undefined{}, nil } + +// ------------------------------------------ + +type ruleSdkVersion struct { + tengo.ObjectImpl + sdkVersion string +} + +func (r *ruleSdkVersion) TypeName() string { + return "sdkVersion" +} + +func (r *ruleSdkVersion) String() string { + return r.sdkVersion +} + +func (r *ruleSdkVersion) BinaryOp(op token.Token, rhs tengo.Object) (tengo.Object, error) { + if rhs, ok := rhs.(*tengo.String); ok { + cmp := r.compare(rhs.Value) + + isMatch := false + switch op { + case token.Greater: + isMatch = cmp > 0 + case token.GreaterEq: + isMatch = cmp >= 0 + default: + return nil, tengo.ErrInvalidOperator + } + + if isMatch { + return tengo.TrueValue, nil + } + return tengo.FalseValue, nil + } + + return nil, tengo.ErrInvalidOperator +} + +func (r *ruleSdkVersion) Equals(rhs tengo.Object) bool { + if rhs, ok := rhs.(*tengo.String); ok { + return r.compare(rhs.Value) == 0 + } + + return false +} + +func (r *ruleSdkVersion) compare(rhsSdkVersion string) int { + if !semver.IsValid("v"+r.sdkVersion) || !semver.IsValid("v"+rhsSdkVersion) { + // if not valid semver, do string compare + switch { + case r.sdkVersion < rhsSdkVersion: + return -1 + case r.sdkVersion > rhsSdkVersion: + return 1 + } + } else { + return semver.Compare("v"+r.sdkVersion, "v"+rhsSdkVersion) + } + return 0 +}