From 6ab90a88fe5c7eb2c25c3188a769b57747b53c16 Mon Sep 17 00:00:00 2001 From: hechen-eng Date: Thu, 23 Apr 2026 15:12:58 -0700 Subject: [PATCH] TEL-543: same trunk can match duplicate normalized SIP numbers --- sip/sip.go | 3 ++- sip/sip_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/sip/sip.go b/sip/sip.go index 87f9cec79..69500c3bb 100644 --- a/sip/sip.go +++ b/sip/sip.go @@ -550,7 +550,8 @@ func MatchTrunkDetailed(it iters.Iter[*livekit.SIPInboundTrunkInfo], call *rpc.S result.MatchType = TrunkMatchSpecific return result, nil } - // Keep searching! We want to know if there are any conflicting Trunk definitions. + // A trunk matches at most once per call; remaining numbers on this trunk cannot change the decision. + break } else { opt.Filtered(tr, TrunkFilteredCalledNumberDisallowed) } diff --git a/sip/sip_test.go b/sip/sip_test.go index bed65407c..d4f3258dc 100644 --- a/sip/sip_test.go +++ b/sip/sip_test.go @@ -287,6 +287,32 @@ func TestSIPMatchTrunk(t *testing.T) { } } +// TestSIPMatchTrunkSameTrunkDuplicateNumberForms verifies that a trunk listing +// the same number in both +E.164 and bare forms is not treated as a conflict +// with itself. Regression test for "Multiple SIP Trunks matched" when a user +// configures both "+19793169351" and "19793169351" on one trunk. +func TestSIPMatchTrunkSameTrunkDuplicateNumberForms(t *testing.T) { + trunks := []*livekit.SIPInboundTrunkInfo{ + {SipTrunkId: "aaa", Numbers: []string{"+" + sipNumber2, sipNumber2}}, + } + for _, toNum := range []string{sipNumber2, "+" + sipNumber2} { + t.Run("to="+toNum, func(t *testing.T) { + call := &rpc.SIPCall{ + SipCallId: "test-call-id", + SourceIp: "1.1.1.1", + From: &livekit.SIPUri{User: sipNumber1, Host: "sip.example.com"}, + To: &livekit.SIPUri{User: toNum}, + } + call.Address = call.To + got, err := MatchTrunkIter(iters.Slice(trunks), call, WithTrunkConflict(func(t1, t2 *livekit.SIPInboundTrunkInfo, reason TrunkConflictReason) { + t.Fatalf("unexpected conflict: %v\n%v\nvs\n%v", reason, t1, t2) + })) + require.NoError(t, err) + require.Equal(t, trunks[0], got) + }) + } +} + func TestSIPValidateTrunks(t *testing.T) { for _, c := range trunkCases { c := c