Skip to content

Commit 97714ba

Browse files
committed
fix SIP trunk-level MediaEncryption being silently dropped
1 parent a0e7280 commit 97714ba

5 files changed

Lines changed: 59 additions & 2 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@livekit/protocol": patch
3+
"github.com/livekit/protocol": patch
4+
---
5+
6+
Fix SIP trunk-level MediaEncryption being silently dropped on outbound and inbound calls. The early `req.Upgrade()` / `rule.Upgrade()` calls pinned `Media.Encryption` to the (legacy) request/rule field before the trunk's MediaEncryption was merged, causing INVITEs to omit SRTP when only the trunk had it configured.

rpc/sip.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ func NewCreateSIPParticipantRequest(
7373
req *livekit.CreateSIPParticipantRequest,
7474
trunk *livekit.SIPOutboundTrunkInfo,
7575
) (*InternalCreateSIPParticipantRequest, error) {
76-
req.Upgrade()
7776
if err := req.Validate(); err != nil {
7877
return nil, err
7978
}

rpc/sip_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,3 +150,28 @@ func TestNewCreateSIPParticipantRequest(t *testing.T) {
150150
require.NoError(t, err)
151151
require.True(t, proto.Equal(exp, res), "%v\nvs\n%v", exp, res)
152152
}
153+
154+
// Regression: trunk-level MediaEncryption must be honored when the request specifies
155+
// neither MediaEncryption nor Media. A prior version called req.Upgrade() at the top of
156+
// NewCreateSIPParticipantRequest, which pinned req.Media.Encryption to req.MediaEncryption (0)
157+
// before the trunk was consulted, causing outbound INVITEs to omit SRTP and upstream
158+
// providers (e.g. Twilio) to reject with 488 / 32208.
159+
func TestNewCreateSIPParticipantRequest_TrunkOnlyEncryption(t *testing.T) {
160+
r := &livekit.CreateSIPParticipantRequest{
161+
SipTrunkId: "trunk",
162+
SipCallTo: "+3333",
163+
RoomName: "room",
164+
}
165+
tr := &livekit.SIPOutboundTrunkInfo{
166+
SipTrunkId: "trunk",
167+
Address: "sip.example.com",
168+
Numbers: []string{"+1111"},
169+
MediaEncryption: livekit.SIPMediaEncryption_SIP_MEDIA_ENCRYPT_REQUIRE,
170+
}
171+
res, err := NewCreateSIPParticipantRequest("p_123", "call-id", "xyz.sip.livekit.cloud", "url", "token", r, tr)
172+
require.NoError(t, err)
173+
require.Equal(t, livekit.SIPMediaEncryption_SIP_MEDIA_ENCRYPT_REQUIRE, res.MediaEncryption)
174+
require.NotNil(t, res.Media)
175+
require.NotNil(t, res.Media.Encryption)
176+
require.Equal(t, livekit.SIPMediaEncryption_SIP_MEDIA_ENCRYPT_REQUIRE, *res.Media.Encryption)
177+
}

sip/sip.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -834,7 +834,6 @@ func MatchDispatchRuleIter(trunk *livekit.SIPInboundTrunkInfo, rules iters.Iter[
834834

835835
// EvaluateDispatchRule checks a selected Dispatch Rule against the provided request.
836836
func EvaluateDispatchRule(projectID string, trunk *livekit.SIPInboundTrunkInfo, rule *livekit.SIPDispatchRuleInfo, req *rpc.EvaluateSIPDispatchRulesRequest) (*rpc.EvaluateSIPDispatchRulesResponse, error) {
837-
rule.Upgrade()
838837
call := req.SIPCall()
839838
sentPin := req.GetPin()
840839

sip/sip_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,34 @@ func TestEvaluateDispatchRule(t *testing.T) {
933933
})
934934
}
935935

936+
// Regression: trunk-level MediaEncryption must be honored when the dispatch rule specifies
937+
// neither MediaEncryption nor Media. A prior version called rule.Upgrade() at the top of
938+
// EvaluateDispatchRule, which pinned rule.Media.Encryption to rule.MediaEncryption (0)
939+
// before the trunk was consulted, causing the inbound trunk's encryption setting to be
940+
// silently dropped.
941+
func TestEvaluateDispatchRule_TrunkOnlyEncryption(t *testing.T) {
942+
d := &livekit.SIPDispatchRuleInfo{
943+
SipDispatchRuleId: "rule",
944+
Rule: newDirectDispatch("room", ""),
945+
}
946+
r := &rpc.EvaluateSIPDispatchRulesRequest{
947+
SipCallId: "call-id",
948+
CallingNumber: "+11112222",
949+
CallingHost: "sip.example.com",
950+
CalledNumber: "+3333",
951+
}
952+
tr := &livekit.SIPInboundTrunkInfo{
953+
SipTrunkId: "trunk",
954+
MediaEncryption: livekit.SIPMediaEncryption_SIP_MEDIA_ENCRYPT_REQUIRE,
955+
}
956+
res, err := EvaluateDispatchRule("p_123", tr, d, r)
957+
require.NoError(t, err)
958+
require.Equal(t, livekit.SIPMediaEncryption_SIP_MEDIA_ENCRYPT_REQUIRE, res.MediaEncryption)
959+
require.NotNil(t, res.Media)
960+
require.NotNil(t, res.Media.Encryption)
961+
require.Equal(t, livekit.SIPMediaEncryption_SIP_MEDIA_ENCRYPT_REQUIRE, *res.Media.Encryption)
962+
}
963+
936964
func TestMatchIP(t *testing.T) {
937965
cases := []struct {
938966
addr string

0 commit comments

Comments
 (0)