Skip to content

Commit

Permalink
fix: optimized rules allowList count
Browse files Browse the repository at this point in the history
  • Loading branch information
Qu Xuan committed Nov 14, 2019
1 parent 4346cc3 commit dafef6b
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 1 deletion.
97 changes: 96 additions & 1 deletion util/secrules/secruleset.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ package secrules

import (
"bytes"
"net"
"sort"

"yunion.io/x/pkg/util/netutils"
)

type SecurityRuleSet []SecurityRule
Expand Down Expand Up @@ -191,5 +194,97 @@ func (srs SecurityRuleSet) collapse() SecurityRuleSet {
// save that contains, intersects
}
}
return srs1

if len(srs1) == 0 {
return srs1
}

//merge cidr
sort.Slice(srs1, func(i, j int) bool {
sr0 := &srs1[i]
sr1 := &srs1[j]
if sr0.Protocol != sr1.Protocol {
return sr0.Protocol < sr1.Protocol
}

if sr0.GetPortsString() != sr1.GetPortsString() {
return sr0.GetPortsString() < sr1.GetPortsString()
}
return sr0.Priority < sr1.Priority
})

srss := []SecurityRuleSet{
SecurityRuleSet{srs1[0]},
}

j := 0
for i := 1; i < len(srs1); i++ {
last := srss[j][len(srss[j])-1]
if last.Protocol != srs1[i].Protocol || last.GetPortsString() != srs1[i].GetPortsString() {
j++
srss = append(srss, SecurityRuleSet{srs1[i]})
} else {
srss[j] = append(srss[j], srs1[i])
}
}

result := SecurityRuleSet{}
for _, srs := range srss {
merged := srs.mergeCIDR()
result = append(result, merged...)
}

sort.Sort(result)
return result
}

type IPV4AddrRanges []netutils.IPV4AddrRange

func (addrs IPV4AddrRanges) Len() int {
return len(addrs)
}

func (addrs IPV4AddrRanges) Swap(i, j int) {
addrs[i], addrs[j] = addrs[j], addrs[i]
}

func (addrs IPV4AddrRanges) Less(i, j int) bool {
return addrs[i].EndIp() <= addrs[j].StartIp()
}

func (srs SecurityRuleSet) mergeCIDR() SecurityRuleSet {
addrRanges := IPV4AddrRanges{}
for _, s := range srs {
addrRanges = append(addrRanges, netutils.NewIPV4AddrRangeFromIPNet(s.IPNet))
}
sort.Sort(addrRanges)
ranges := IPV4AddrRanges{addrRanges[0]}
for i := 1; i < len(addrRanges); i++ {
last := ranges[len(ranges)-1]
if last.IsOverlap(addrRanges[i]) || last.EndIp()+1 == addrRanges[i].StartIp() {
start := last.StartIp()
if addrRanges[i].StartIp() < start {
start = addrRanges[i].StartIp()
}
end := last.EndIp()
if addrRanges[i].EndIp() > end {
end = addrRanges[i].EndIp()
}
ranges[len(ranges)-1] = netutils.NewIPV4AddrRange(start, end)
} else {
ranges = append(ranges, addrRanges[i])
}
}

ipNets := []*net.IPNet{}
for _, addr := range ranges {
ipNets = append(ipNets, addr.ToIPNets()...)
}
result := SecurityRuleSet{}
rule := srs[0]
for _, net := range ipNets {
rule.IPNet = net
result = append(result, rule)
}
return result
}
8 changes: 8 additions & 0 deletions util/secrules/secruleset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ import (
)

func TestSecRuleSet_AllowList(t *testing.T) {
srs0 := SecurityRuleSet{
*MustParseSecurityRule("out:deny 192.168.222.2 tcp 3389"),
*MustParseSecurityRule("out:allow any"),
}
rules := srs0.AllowList()
for _, rule := range rules {
t.Logf("rule: %s", rule.String())
}
dieIf := func(t *testing.T, srs0, srs1 SecurityRuleSet) {
if !srs0.equals(srs1) {
t.Fatalf("not equal:\n%s\n%s", srs0, srs1)
Expand Down

0 comments on commit dafef6b

Please sign in to comment.