| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- // Copyright 2019 Yunion
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package secrules
- import (
- "sort"
- )
- type ports []uint16
- func newPortsFromInts(ints ...int) ports {
- ps := make(ports, len(ints))
- for i := range ints {
- // panic on invalid value
- ps[i] = uint16(ints[i])
- }
- return ps
- }
- func (ps ports) IntSlice() []int {
- ints := make([]int, len(ps))
- for i := range ps {
- ints[i] = int(ps[i])
- }
- return ints
- }
- func (ps ports) Len() int {
- return len(ps)
- }
- func (ps ports) Swap(i, j int) {
- ps[i], ps[j] = ps[j], ps[i]
- }
- func (ps ports) Less(i, j int) bool {
- return ps[i] < ps[j]
- }
- func (ps ports) contains(p uint16) bool {
- for _, p0 := range ps {
- if p0 == p {
- return true
- }
- }
- return false
- }
- func (ps ports) containsPorts(ps1 ports) bool {
- for _, p := range ps1 {
- if !ps.contains(p) {
- return false
- }
- }
- return true
- }
- func (ps ports) dedup() ports {
- ps1 := make(ports, len(ps))
- copy(ps1, ps)
- sort.Sort(ps1)
- for i := len(ps1) - 1; i > 0; i-- {
- if ps1[i] == ps1[i-1] {
- ps1 = append(ps1[:i], ps1[i+1:]...)
- }
- }
- return ps1
- }
- func (ps ports) sameAs(ps1 ports) bool {
- if len(ps) != len(ps1) {
- return false
- }
- for i := range ps {
- if ps[i] != ps1[i] {
- return false
- }
- }
- return true
- }
- func (ps ports) substractPortRange(pr *portRange) (left, subs ports) {
- left = ports{}
- subs = ports{}
- for _, p := range ps {
- if pr.contains(p) {
- subs = append(subs, p)
- } else {
- left = append(left, p)
- }
- }
- return
- }
- func (ps ports) substractPorts(ps1 ports) (left, subs ports) {
- left = ports{}
- subs = ports{}
- for _, p0 := range ps {
- if ps1.contains(p0) {
- subs = append(subs, p0)
- } else {
- left = append(left, p0)
- }
- }
- return
- }
- type portRange struct {
- start uint16
- end uint16
- }
- func newPortRange(s, e uint16) *portRange {
- // panic on s > e
- return &portRange{
- start: s,
- end: e,
- }
- }
- func (pr *portRange) equals(pr1 *portRange) bool {
- return pr.start == pr1.start && pr.end == pr1.end
- }
- func (pr *portRange) contains(p uint16) bool {
- return p >= pr.start && p <= pr.end
- }
- func (pr *portRange) containsRange(pr1 *portRange) bool {
- return pr.start <= pr1.start && pr.end >= pr1.end
- }
- func (pr *portRange) count() uint16 {
- return pr.end - pr.start + 1
- }
- func (pr *portRange) substractPortRange(pr1 *portRange) (lefts []*portRange, sub *portRange) {
- // no intersection, no substract
- if pr.end < pr1.start || pr.start > pr1.end {
- l := *pr
- lefts = []*portRange{&l}
- return
- }
- // pr contains pr1
- if pr.containsRange(pr1) {
- nns := [][2]int32{
- [2]int32{int32(pr.start), int32(pr1.start) - 1},
- [2]int32{int32(pr1.end) + 1, int32(pr.end)},
- }
- lefts = []*portRange{}
- for _, nn := range nns {
- if nn[0] <= nn[1] {
- lefts = append(lefts, &portRange{
- start: uint16(nn[0]),
- end: uint16(nn[1]),
- })
- }
- }
- s := *pr1
- sub = &s
- return
- }
- // pr contained by pr1
- if pr1.containsRange(pr) {
- s := *pr
- sub = &s
- return
- }
- // intersect, pr on the left
- if pr.start < pr1.start && pr.end >= pr1.start {
- lefts = []*portRange{&portRange{start: pr.start, end: pr1.start - 1}}
- sub = &portRange{pr1.start, pr.end}
- return
- }
- // intersect, pr on the right
- if pr.start <= pr1.end && pr.end > pr1.end {
- lefts = []*portRange{&portRange{pr1.end + 1, pr.end}}
- sub = &portRange{pr.start, pr1.end}
- return
- }
- // no intersection
- return
- }
- func (pr *portRange) substractPorts(ps1 ports) (lefts []*portRange, subs ports) {
- // no duplicate
- // then ordered
- ps2 := make(ports, len(ps1))
- copy(ps2, ps1)
- sort.Sort(ps2)
- lefts = []*portRange{}
- subs = ports{}
- s := pr.start
- for _, p := range ps2 {
- if pr.contains(p) {
- if p > s {
- lefts = append(lefts, &portRange{
- start: s,
- end: p - 1,
- })
- }
- subs = append(subs, p)
- s = p + 1
- }
- }
- if s != 0 && s <= pr.end {
- lefts = append(lefts, &portRange{
- start: s,
- end: pr.end,
- })
- }
- return
- }
|