Skip to content

Commit 4cbefae

Browse files
authored
Add a workaround for invalid IP masks in SIP. (#956)
1 parent e430b4b commit 4cbefae

File tree

3 files changed

+132
-10
lines changed

3 files changed

+132
-10
lines changed

.changeset/big-snails-type.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"github.com/livekit/protocol": patch
3+
---
4+
5+
Add a workaround for invalid IP masks in SIP.

sip/sip.go

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,34 @@ func ValidateTrunksIter(it iters.Iter[*livekit.SIPInboundTrunkInfo]) error {
334334
return nil
335335
}
336336

337+
func isValidMask(mask string) bool {
338+
if !strings.Contains(mask, "/") {
339+
expIP, err := netip.ParseAddr(mask)
340+
if err != nil {
341+
return false
342+
}
343+
return expIP.IsValid()
344+
}
345+
pref, err := netip.ParsePrefix(mask)
346+
if err != nil {
347+
return false
348+
}
349+
return pref.IsValid()
350+
}
351+
352+
func filterInvalidAddrMasks(masks []string) []string {
353+
if len(masks) == 0 {
354+
return nil
355+
}
356+
out := make([]string, 0, len(masks))
357+
for _, m := range masks {
358+
if isValidMask(m) {
359+
out = append(out, m)
360+
}
361+
}
362+
return out
363+
}
364+
337365
func matchAddrMask(ip netip.Addr, mask string) bool {
338366
if !strings.Contains(mask, "/") {
339367
expIP, err := netip.ParseAddr(mask)
@@ -350,7 +378,11 @@ func matchAddrMask(ip netip.Addr, mask string) bool {
350378
}
351379

352380
func matchAddrMasks(addr netip.Addr, masks []string) bool {
353-
if !addr.IsValid() || len(masks) == 0 {
381+
if !addr.IsValid() {
382+
return true
383+
}
384+
masks = filterInvalidAddrMasks(masks)
385+
if len(masks) == 0 {
354386
return true
355387
}
356388
for _, mask := range masks {

sip/sip_test.go

Lines changed: 94 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -652,21 +652,106 @@ func TestEvaluateDispatchRule(t *testing.T) {
652652

653653
func TestMatchIP(t *testing.T) {
654654
cases := []struct {
655-
addr string
656-
mask string
657-
exp bool
655+
addr string
656+
mask string
657+
valid bool
658+
exp bool
658659
}{
659-
{addr: "192.168.0.10", mask: "192.168.0.10", exp: true},
660-
{addr: "192.168.0.10", mask: "192.168.0.11", exp: false},
661-
{addr: "192.168.0.10", mask: "192.168.0.0/24", exp: true},
662-
{addr: "192.168.0.10", mask: "192.168.0.10/0", exp: true},
663-
{addr: "192.168.0.10", mask: "192.170.0.0/24", exp: false},
660+
{addr: "192.168.0.10", mask: "192.168.0.10", valid: true, exp: true},
661+
{addr: "192.168.0.10", mask: "192.168.0.11", valid: true, exp: false},
662+
{addr: "192.168.0.10", mask: "192.168.0.0/24", valid: true, exp: true},
663+
{addr: "192.168.0.10", mask: "192.168.0.10/0", valid: true, exp: true},
664+
{addr: "192.168.0.10", mask: "192.170.0.0/24", valid: true, exp: false},
664665
}
665666
for _, c := range cases {
666667
t.Run(c.mask, func(t *testing.T) {
667668
ip, err := netip.ParseAddr(c.addr)
668669
require.NoError(t, err)
669-
got := matchAddrMask(ip, c.mask)
670+
got := isValidMask(c.mask)
671+
require.Equal(t, c.valid, got)
672+
got = matchAddrMask(ip, c.mask)
673+
require.Equal(t, c.exp, got)
674+
})
675+
}
676+
}
677+
678+
func TestMatchMasks(t *testing.T) {
679+
cases := []struct {
680+
name string
681+
addr string
682+
masks []string
683+
exp bool
684+
}{
685+
{
686+
name: "no masks",
687+
addr: "192.168.0.10",
688+
masks: nil,
689+
exp: true,
690+
},
691+
{
692+
name: "single ip",
693+
addr: "192.168.0.10",
694+
masks: []string{
695+
"192.168.0.10",
696+
},
697+
exp: true,
698+
},
699+
{
700+
name: "wrong ip",
701+
addr: "192.168.0.10",
702+
masks: []string{
703+
"192.168.0.11",
704+
},
705+
exp: false,
706+
},
707+
{
708+
name: "ip mask",
709+
addr: "192.168.0.10",
710+
masks: []string{
711+
"192.168.0.0/24",
712+
},
713+
exp: true,
714+
},
715+
{
716+
name: "wrong mask",
717+
addr: "192.168.0.10",
718+
masks: []string{
719+
"192.168.1.0/24",
720+
},
721+
exp: false,
722+
},
723+
{
724+
name: "invalid range",
725+
addr: "192.168.0.10",
726+
masks: []string{
727+
"some.domain",
728+
},
729+
exp: true,
730+
},
731+
{
732+
name: "invalid and valid range",
733+
addr: "192.168.0.10",
734+
masks: []string{
735+
"some.domain",
736+
"192.168.0.0/24",
737+
},
738+
exp: true,
739+
},
740+
{
741+
name: "invalid and wrong range",
742+
addr: "192.168.0.10",
743+
masks: []string{
744+
"some.domain",
745+
"192.168.1.0/24",
746+
},
747+
exp: false,
748+
},
749+
}
750+
for _, c := range cases {
751+
t.Run(c.name, func(t *testing.T) {
752+
ip, err := netip.ParseAddr(c.addr)
753+
require.NoError(t, err)
754+
got := matchAddrMasks(ip, c.masks)
670755
require.Equal(t, c.exp, got)
671756
})
672757
}

0 commit comments

Comments
 (0)