Update dependencies
This commit is contained in:
3
vendor/go4.org/netipx/.gitignore
generated
vendored
Normal file
3
vendor/go4.org/netipx/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
crashers
|
||||
suppressions
|
||||
netaddr-fuzz.zip
|
||||
3
vendor/go4.org/netipx/.gitmodules
generated
vendored
Normal file
3
vendor/go4.org/netipx/.gitmodules
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "corpus"]
|
||||
path = corpus
|
||||
url = https://github.com/inetaf/netaddr-corpus.git
|
||||
4
vendor/go4.org/netipx/AUTHORS
generated
vendored
Normal file
4
vendor/go4.org/netipx/AUTHORS
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
Alex Willmer <alex@moreati.org.uk>
|
||||
Matt Layher <mdlayher@gmail.com>
|
||||
Tailscale Inc.
|
||||
Tobias Klauser <tklauser@distanz.ch>
|
||||
27
vendor/go4.org/netipx/LICENSE
generated
vendored
Normal file
27
vendor/go4.org/netipx/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
Copyright (c) 2020 The Inet.af AUTHORS. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Tailscale Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
26
vendor/go4.org/netipx/README.md
generated
vendored
Normal file
26
vendor/go4.org/netipx/README.md
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
# netipx [](https://github.com/go4org/netipx/actions) [](https://pkg.go.dev/go4.org/netipx)
|
||||
|
||||
## What
|
||||
|
||||
This is a package containing the bits of the old `inet.af/netaddr` package that didn't make it
|
||||
into Go 1.18's `net/netip` standard library package.
|
||||
|
||||
As background, see:
|
||||
|
||||
* https://github.com/inetaf/netaddr/ (now deprecated)
|
||||
* https://tailscale.com/blog/netaddr-new-ip-type-for-go/ - blog post about why the package came to be originally
|
||||
* https://go.dev/doc/go1.18#netip - Go 1.18 release notes
|
||||
|
||||
This package requires Go 1.18+ to use and complements the `net/netip`.
|
||||
|
||||
## FAQ
|
||||
|
||||
**Why's it no longer under `inet.af`?** Since that joke started, that
|
||||
TLD is now under control of the Taliban. (Yes, we should've known
|
||||
better. We'd even previously scolded people for relying on
|
||||
questionable ccTLDs. Whoops.)
|
||||
|
||||
**Will this stuff make it into the standard library?** [Maybe](https://github.com/golang/go/issues/53236).
|
||||
We'll see.
|
||||
|
||||
|
||||
498
vendor/go4.org/netipx/ipset.go
generated
vendored
Normal file
498
vendor/go4.org/netipx/ipset.go
generated
vendored
Normal file
@@ -0,0 +1,498 @@
|
||||
// Copyright 2020 The Inet.Af AUTHORS. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package netipx
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/netip"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// IPSetBuilder builds an immutable IPSet.
|
||||
//
|
||||
// The zero value is a valid value representing a set of no IPs.
|
||||
//
|
||||
// The Add and Remove methods add or remove IPs to/from the set.
|
||||
// Removals only affect the current membership of the set, so in
|
||||
// general Adds should be called first. Input ranges may overlap in
|
||||
// any way.
|
||||
//
|
||||
// Most IPSetBuilder methods do not return errors.
|
||||
// Instead, errors are accumulated and reported by IPSetBuilder.IPSet.
|
||||
type IPSetBuilder struct {
|
||||
// in are the ranges in the set.
|
||||
in []IPRange
|
||||
|
||||
// out are the ranges to be removed from 'in'.
|
||||
out []IPRange
|
||||
|
||||
// errs are errors accumulated during construction.
|
||||
errs multiErr
|
||||
}
|
||||
|
||||
// normalize normalizes s: s.in becomes the minimal sorted list of
|
||||
// ranges required to describe s, and s.out becomes empty.
|
||||
func (s *IPSetBuilder) normalize() {
|
||||
const debug = false
|
||||
if debug {
|
||||
debugf("ranges start in=%v out=%v", s.in, s.out)
|
||||
}
|
||||
in, ok := mergeIPRanges(s.in)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
out, ok := mergeIPRanges(s.out)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if debug {
|
||||
debugf("ranges sort in=%v out=%v", in, out)
|
||||
}
|
||||
|
||||
// in and out are sorted in ascending range order, and have no
|
||||
// overlaps within each other. We can run a merge of the two lists
|
||||
// in one pass.
|
||||
|
||||
min := make([]IPRange, 0, len(in))
|
||||
for len(in) > 0 && len(out) > 0 {
|
||||
rin, rout := in[0], out[0]
|
||||
if debug {
|
||||
debugf("step in=%v out=%v", rin, rout)
|
||||
}
|
||||
|
||||
switch {
|
||||
case !rout.IsValid() || !rin.IsValid():
|
||||
// mergeIPRanges should have prevented invalid ranges from
|
||||
// sneaking in.
|
||||
panic("invalid IPRanges during Ranges merge")
|
||||
case rout.entirelyBefore(rin):
|
||||
// "out" is entirely before "in".
|
||||
//
|
||||
// out in
|
||||
// f-------t f-------t
|
||||
out = out[1:]
|
||||
if debug {
|
||||
debugf("out before in; drop out")
|
||||
}
|
||||
case rin.entirelyBefore(rout):
|
||||
// "in" is entirely before "out".
|
||||
//
|
||||
// in out
|
||||
// f------t f-------t
|
||||
min = append(min, rin)
|
||||
in = in[1:]
|
||||
if debug {
|
||||
debugf("in before out; append in")
|
||||
debugf("min=%v", min)
|
||||
}
|
||||
case rin.coveredBy(rout):
|
||||
// "out" entirely covers "in".
|
||||
//
|
||||
// out
|
||||
// f-------------t
|
||||
// f------t
|
||||
// in
|
||||
in = in[1:]
|
||||
if debug {
|
||||
debugf("in inside out; drop in")
|
||||
}
|
||||
case rout.inMiddleOf(rin):
|
||||
// "in" entirely covers "out".
|
||||
//
|
||||
// in
|
||||
// f-------------t
|
||||
// f------t
|
||||
// out
|
||||
min = append(min, IPRange{from: rin.from, to: AddrPrior(rout.from)})
|
||||
// Adjust in[0], not ir, because we want to consider the
|
||||
// mutated range on the next iteration.
|
||||
in[0].from = rout.to.Next()
|
||||
out = out[1:]
|
||||
if debug {
|
||||
debugf("out inside in; split in, append first in, drop out, adjust second in")
|
||||
debugf("min=%v", min)
|
||||
}
|
||||
case rout.overlapsStartOf(rin):
|
||||
// "out" overlaps start of "in".
|
||||
//
|
||||
// out
|
||||
// f------t
|
||||
// f------t
|
||||
// in
|
||||
in[0].from = rout.to.Next()
|
||||
// Can't move ir onto min yet, another later out might
|
||||
// trim it further. Just discard or and continue.
|
||||
out = out[1:]
|
||||
if debug {
|
||||
debugf("out cuts start of in; adjust in, drop out")
|
||||
}
|
||||
case rout.overlapsEndOf(rin):
|
||||
// "out" overlaps end of "in".
|
||||
//
|
||||
// out
|
||||
// f------t
|
||||
// f------t
|
||||
// in
|
||||
min = append(min, IPRange{from: rin.from, to: AddrPrior(rout.from)})
|
||||
in = in[1:]
|
||||
if debug {
|
||||
debugf("merge out cuts end of in; append shortened in")
|
||||
debugf("min=%v", min)
|
||||
}
|
||||
default:
|
||||
// The above should account for all combinations of in and
|
||||
// out overlapping, but insert a panic to be sure.
|
||||
panic("unexpected additional overlap scenario")
|
||||
}
|
||||
}
|
||||
if len(in) > 0 {
|
||||
// Ran out of removals before the end of in.
|
||||
min = append(min, in...)
|
||||
if debug {
|
||||
debugf("min=%v", min)
|
||||
}
|
||||
}
|
||||
|
||||
s.in = min
|
||||
s.out = nil
|
||||
}
|
||||
|
||||
// Clone returns a copy of s that shares no memory with s.
|
||||
func (s *IPSetBuilder) Clone() *IPSetBuilder {
|
||||
return &IPSetBuilder{
|
||||
in: append([]IPRange(nil), s.in...),
|
||||
out: append([]IPRange(nil), s.out...),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IPSetBuilder) addError(msg string, args ...interface{}) {
|
||||
se := new(stacktraceErr)
|
||||
// Skip three frames: runtime.Callers, addError, and the IPSetBuilder
|
||||
// method that called addError (such as IPSetBuilder.Add).
|
||||
// The resulting stack trace ends at the line in the user's
|
||||
// code where they called into netaddr.
|
||||
n := runtime.Callers(3, se.pcs[:])
|
||||
se.at = se.pcs[:n]
|
||||
se.err = fmt.Errorf(msg, args...)
|
||||
s.errs = append(s.errs, se)
|
||||
}
|
||||
|
||||
// Add adds ip to s.
|
||||
func (s *IPSetBuilder) Add(ip netip.Addr) {
|
||||
if !ip.IsValid() {
|
||||
s.addError("Add(IP{})")
|
||||
return
|
||||
}
|
||||
s.AddRange(IPRangeFrom(ip, ip))
|
||||
}
|
||||
|
||||
// AddPrefix adds all IPs in p to s.
|
||||
func (s *IPSetBuilder) AddPrefix(p netip.Prefix) {
|
||||
if r := RangeOfPrefix(p); r.IsValid() {
|
||||
s.AddRange(r)
|
||||
} else {
|
||||
s.addError("AddPrefix(%v/%v)", p.Addr(), p.Bits())
|
||||
}
|
||||
}
|
||||
|
||||
// AddRange adds r to s.
|
||||
// If r is not Valid, AddRange does nothing.
|
||||
func (s *IPSetBuilder) AddRange(r IPRange) {
|
||||
if !r.IsValid() {
|
||||
s.addError("AddRange(%v-%v)", r.From(), r.To())
|
||||
return
|
||||
}
|
||||
// If there are any removals (s.out), then we need to compact the set
|
||||
// first to get the order right.
|
||||
if len(s.out) > 0 {
|
||||
s.normalize()
|
||||
}
|
||||
s.in = append(s.in, r)
|
||||
}
|
||||
|
||||
// AddSet adds all IPs in b to s.
|
||||
func (s *IPSetBuilder) AddSet(b *IPSet) {
|
||||
if b == nil {
|
||||
return
|
||||
}
|
||||
for _, r := range b.rr {
|
||||
s.AddRange(r)
|
||||
}
|
||||
}
|
||||
|
||||
// Remove removes ip from s.
|
||||
func (s *IPSetBuilder) Remove(ip netip.Addr) {
|
||||
if !ip.IsValid() {
|
||||
s.addError("Remove(IP{})")
|
||||
} else {
|
||||
s.RemoveRange(IPRangeFrom(ip, ip))
|
||||
}
|
||||
}
|
||||
|
||||
// RemovePrefix removes all IPs in p from s.
|
||||
func (s *IPSetBuilder) RemovePrefix(p netip.Prefix) {
|
||||
if r := RangeOfPrefix(p); r.IsValid() {
|
||||
s.RemoveRange(r)
|
||||
} else {
|
||||
s.addError("RemovePrefix(%v/%v)", p.Addr(), p.Bits())
|
||||
}
|
||||
}
|
||||
|
||||
// RemoveRange removes all IPs in r from s.
|
||||
func (s *IPSetBuilder) RemoveRange(r IPRange) {
|
||||
if r.IsValid() {
|
||||
s.out = append(s.out, r)
|
||||
} else {
|
||||
s.addError("RemoveRange(%v-%v)", r.From(), r.To())
|
||||
}
|
||||
}
|
||||
|
||||
// RemoveSet removes all IPs in o from s.
|
||||
func (s *IPSetBuilder) RemoveSet(b *IPSet) {
|
||||
if b == nil {
|
||||
return
|
||||
}
|
||||
for _, r := range b.rr {
|
||||
s.RemoveRange(r)
|
||||
}
|
||||
}
|
||||
|
||||
// removeBuilder removes all IPs in b from s.
|
||||
func (s *IPSetBuilder) removeBuilder(b *IPSetBuilder) {
|
||||
b.normalize()
|
||||
for _, r := range b.in {
|
||||
s.RemoveRange(r)
|
||||
}
|
||||
}
|
||||
|
||||
// Complement updates s to contain the complement of its current
|
||||
// contents.
|
||||
func (s *IPSetBuilder) Complement() {
|
||||
s.normalize()
|
||||
s.out = s.in
|
||||
s.in = []IPRange{
|
||||
RangeOfPrefix(netip.PrefixFrom(netip.AddrFrom4([4]byte{}), 0)),
|
||||
RangeOfPrefix(netip.PrefixFrom(netip.IPv6Unspecified(), 0)),
|
||||
}
|
||||
}
|
||||
|
||||
// Intersect updates s to the set intersection of s and b.
|
||||
func (s *IPSetBuilder) Intersect(b *IPSet) {
|
||||
var o IPSetBuilder
|
||||
o.Complement()
|
||||
o.RemoveSet(b)
|
||||
s.removeBuilder(&o)
|
||||
}
|
||||
|
||||
func discardf(format string, args ...interface{}) {}
|
||||
|
||||
// debugf is reassigned by tests.
|
||||
var debugf = discardf
|
||||
|
||||
// IPSet returns an immutable IPSet representing the current state of s.
|
||||
//
|
||||
// Most IPSetBuilder methods do not return errors.
|
||||
// Rather, the builder ignores any invalid inputs (such as an invalid IPPrefix),
|
||||
// and accumulates a list of any such errors that it encountered.
|
||||
//
|
||||
// IPSet also reports any such accumulated errors.
|
||||
// Even if the returned error is non-nil, the returned IPSet is usable
|
||||
// and contains all modifications made with valid inputs.
|
||||
//
|
||||
// The builder remains usable after calling IPSet.
|
||||
// Calling IPSet clears any accumulated errors.
|
||||
func (s *IPSetBuilder) IPSet() (*IPSet, error) {
|
||||
s.normalize()
|
||||
ret := &IPSet{
|
||||
rr: append([]IPRange{}, s.in...),
|
||||
}
|
||||
if len(s.errs) == 0 {
|
||||
return ret, nil
|
||||
} else {
|
||||
errs := s.errs
|
||||
s.errs = nil
|
||||
return ret, errs
|
||||
}
|
||||
}
|
||||
|
||||
// IPSet represents a set of IP addresses.
|
||||
//
|
||||
// IPSet is safe for concurrent use.
|
||||
// The zero value is a valid value representing a set of no IPs.
|
||||
// Use IPSetBuilder to construct IPSets.
|
||||
type IPSet struct {
|
||||
// rr is the set of IPs that belong to this IPSet. The IPRanges
|
||||
// are normalized according to IPSetBuilder.normalize, meaning
|
||||
// they are a sorted, minimal representation (no overlapping
|
||||
// ranges, no contiguous ranges). The implementation of various
|
||||
// methods rely on this property.
|
||||
rr []IPRange
|
||||
}
|
||||
|
||||
// Ranges returns the minimum and sorted set of IP
|
||||
// ranges that covers s.
|
||||
func (s *IPSet) Ranges() []IPRange {
|
||||
return append([]IPRange{}, s.rr...)
|
||||
}
|
||||
|
||||
// Prefixes returns the minimum and sorted set of IP prefixes
|
||||
// that covers s.
|
||||
func (s *IPSet) Prefixes() []netip.Prefix {
|
||||
out := make([]netip.Prefix, 0, len(s.rr))
|
||||
for _, r := range s.rr {
|
||||
out = append(out, r.Prefixes()...)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// Equal reports whether s and o represent the same set of IP
|
||||
// addresses.
|
||||
func (s *IPSet) Equal(o *IPSet) bool {
|
||||
if len(s.rr) != len(o.rr) {
|
||||
return false
|
||||
}
|
||||
for i := range s.rr {
|
||||
if s.rr[i] != o.rr[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Contains reports whether ip is in s.
|
||||
// If ip has an IPv6 zone, Contains returns false,
|
||||
// because IPSets do not track zones.
|
||||
func (s *IPSet) Contains(ip netip.Addr) bool {
|
||||
if ip.Zone() != "" {
|
||||
return false
|
||||
}
|
||||
// TODO: data structure permitting more efficient lookups:
|
||||
// https://github.com/inetaf/netaddr/issues/139
|
||||
i := sort.Search(len(s.rr), func(i int) bool {
|
||||
return ip.Less(s.rr[i].from)
|
||||
})
|
||||
if i == 0 {
|
||||
return false
|
||||
}
|
||||
i--
|
||||
return s.rr[i].contains(ip)
|
||||
}
|
||||
|
||||
// ContainsRange reports whether all IPs in r are in s.
|
||||
func (s *IPSet) ContainsRange(r IPRange) bool {
|
||||
for _, x := range s.rr {
|
||||
if r.coveredBy(x) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ContainsPrefix reports whether all IPs in p are in s.
|
||||
func (s *IPSet) ContainsPrefix(p netip.Prefix) bool {
|
||||
return s.ContainsRange(RangeOfPrefix(p))
|
||||
}
|
||||
|
||||
// Overlaps reports whether any IP in b is also in s.
|
||||
func (s *IPSet) Overlaps(b *IPSet) bool {
|
||||
// TODO: sorted ranges lets us do this in O(n+m)
|
||||
for _, r := range s.rr {
|
||||
for _, or := range b.rr {
|
||||
if r.Overlaps(or) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// OverlapsRange reports whether any IP in r is also in s.
|
||||
func (s *IPSet) OverlapsRange(r IPRange) bool {
|
||||
// TODO: sorted ranges lets us do this more efficiently.
|
||||
for _, x := range s.rr {
|
||||
if x.Overlaps(r) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// OverlapsPrefix reports whether any IP in p is also in s.
|
||||
func (s *IPSet) OverlapsPrefix(p netip.Prefix) bool {
|
||||
return s.OverlapsRange(RangeOfPrefix(p))
|
||||
}
|
||||
|
||||
// RemoveFreePrefix splits s into a Prefix of length bitLen and a new
|
||||
// IPSet with that prefix removed.
|
||||
//
|
||||
// If no contiguous prefix of length bitLen exists in s,
|
||||
// RemoveFreePrefix returns ok=false.
|
||||
func (s *IPSet) RemoveFreePrefix(bitLen uint8) (p netip.Prefix, newSet *IPSet, ok bool) {
|
||||
var bestFit netip.Prefix
|
||||
for _, r := range s.rr {
|
||||
for _, prefix := range r.Prefixes() {
|
||||
if uint8(prefix.Bits()) > bitLen {
|
||||
continue
|
||||
}
|
||||
if !bestFit.Addr().IsValid() || prefix.Bits() > bestFit.Bits() {
|
||||
bestFit = prefix
|
||||
if uint8(bestFit.Bits()) == bitLen {
|
||||
// exact match, done.
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !bestFit.Addr().IsValid() {
|
||||
return netip.Prefix{}, s, false
|
||||
}
|
||||
|
||||
prefix := netip.PrefixFrom(bestFit.Addr(), int(bitLen))
|
||||
|
||||
var b IPSetBuilder
|
||||
b.AddSet(s)
|
||||
b.RemovePrefix(prefix)
|
||||
newSet, _ = b.IPSet()
|
||||
return prefix, newSet, true
|
||||
}
|
||||
|
||||
type multiErr []error
|
||||
|
||||
func (e multiErr) Error() string {
|
||||
var ret []string
|
||||
for _, err := range e {
|
||||
ret = append(ret, err.Error())
|
||||
}
|
||||
return strings.Join(ret, "; ")
|
||||
}
|
||||
|
||||
// A stacktraceErr combines an error with a stack trace.
|
||||
type stacktraceErr struct {
|
||||
pcs [16]uintptr // preallocated array of PCs
|
||||
at []uintptr // stack trace whence the error
|
||||
err error // underlying error
|
||||
}
|
||||
|
||||
func (e *stacktraceErr) Error() string {
|
||||
frames := runtime.CallersFrames(e.at)
|
||||
buf := new(strings.Builder)
|
||||
buf.WriteString(e.err.Error())
|
||||
buf.WriteString(" @ ")
|
||||
for {
|
||||
frame, more := frames.Next()
|
||||
if !more {
|
||||
break
|
||||
}
|
||||
fmt.Fprintf(buf, "%s:%d ", frame.File, frame.Line)
|
||||
}
|
||||
return strings.TrimSpace(buf.String())
|
||||
}
|
||||
|
||||
func (e *stacktraceErr) Unwrap() error {
|
||||
return e.err
|
||||
}
|
||||
141
vendor/go4.org/netipx/mask6.go
generated
vendored
Normal file
141
vendor/go4.org/netipx/mask6.go
generated
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
// Copyright 2021 The Inet.Af AUTHORS. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package netipx
|
||||
|
||||
// mask6 are bitmasks with the topmost n bits of a
|
||||
// 128-bit number, where n is the array index.
|
||||
//
|
||||
// generated with https://play.golang.org/p/64XKxaUSa_9
|
||||
var mask6 = [...]uint128{
|
||||
0: {0x0000000000000000, 0x0000000000000000},
|
||||
1: {0x8000000000000000, 0x0000000000000000},
|
||||
2: {0xc000000000000000, 0x0000000000000000},
|
||||
3: {0xe000000000000000, 0x0000000000000000},
|
||||
4: {0xf000000000000000, 0x0000000000000000},
|
||||
5: {0xf800000000000000, 0x0000000000000000},
|
||||
6: {0xfc00000000000000, 0x0000000000000000},
|
||||
7: {0xfe00000000000000, 0x0000000000000000},
|
||||
8: {0xff00000000000000, 0x0000000000000000},
|
||||
9: {0xff80000000000000, 0x0000000000000000},
|
||||
10: {0xffc0000000000000, 0x0000000000000000},
|
||||
11: {0xffe0000000000000, 0x0000000000000000},
|
||||
12: {0xfff0000000000000, 0x0000000000000000},
|
||||
13: {0xfff8000000000000, 0x0000000000000000},
|
||||
14: {0xfffc000000000000, 0x0000000000000000},
|
||||
15: {0xfffe000000000000, 0x0000000000000000},
|
||||
16: {0xffff000000000000, 0x0000000000000000},
|
||||
17: {0xffff800000000000, 0x0000000000000000},
|
||||
18: {0xffffc00000000000, 0x0000000000000000},
|
||||
19: {0xffffe00000000000, 0x0000000000000000},
|
||||
20: {0xfffff00000000000, 0x0000000000000000},
|
||||
21: {0xfffff80000000000, 0x0000000000000000},
|
||||
22: {0xfffffc0000000000, 0x0000000000000000},
|
||||
23: {0xfffffe0000000000, 0x0000000000000000},
|
||||
24: {0xffffff0000000000, 0x0000000000000000},
|
||||
25: {0xffffff8000000000, 0x0000000000000000},
|
||||
26: {0xffffffc000000000, 0x0000000000000000},
|
||||
27: {0xffffffe000000000, 0x0000000000000000},
|
||||
28: {0xfffffff000000000, 0x0000000000000000},
|
||||
29: {0xfffffff800000000, 0x0000000000000000},
|
||||
30: {0xfffffffc00000000, 0x0000000000000000},
|
||||
31: {0xfffffffe00000000, 0x0000000000000000},
|
||||
32: {0xffffffff00000000, 0x0000000000000000},
|
||||
33: {0xffffffff80000000, 0x0000000000000000},
|
||||
34: {0xffffffffc0000000, 0x0000000000000000},
|
||||
35: {0xffffffffe0000000, 0x0000000000000000},
|
||||
36: {0xfffffffff0000000, 0x0000000000000000},
|
||||
37: {0xfffffffff8000000, 0x0000000000000000},
|
||||
38: {0xfffffffffc000000, 0x0000000000000000},
|
||||
39: {0xfffffffffe000000, 0x0000000000000000},
|
||||
40: {0xffffffffff000000, 0x0000000000000000},
|
||||
41: {0xffffffffff800000, 0x0000000000000000},
|
||||
42: {0xffffffffffc00000, 0x0000000000000000},
|
||||
43: {0xffffffffffe00000, 0x0000000000000000},
|
||||
44: {0xfffffffffff00000, 0x0000000000000000},
|
||||
45: {0xfffffffffff80000, 0x0000000000000000},
|
||||
46: {0xfffffffffffc0000, 0x0000000000000000},
|
||||
47: {0xfffffffffffe0000, 0x0000000000000000},
|
||||
48: {0xffffffffffff0000, 0x0000000000000000},
|
||||
49: {0xffffffffffff8000, 0x0000000000000000},
|
||||
50: {0xffffffffffffc000, 0x0000000000000000},
|
||||
51: {0xffffffffffffe000, 0x0000000000000000},
|
||||
52: {0xfffffffffffff000, 0x0000000000000000},
|
||||
53: {0xfffffffffffff800, 0x0000000000000000},
|
||||
54: {0xfffffffffffffc00, 0x0000000000000000},
|
||||
55: {0xfffffffffffffe00, 0x0000000000000000},
|
||||
56: {0xffffffffffffff00, 0x0000000000000000},
|
||||
57: {0xffffffffffffff80, 0x0000000000000000},
|
||||
58: {0xffffffffffffffc0, 0x0000000000000000},
|
||||
59: {0xffffffffffffffe0, 0x0000000000000000},
|
||||
60: {0xfffffffffffffff0, 0x0000000000000000},
|
||||
61: {0xfffffffffffffff8, 0x0000000000000000},
|
||||
62: {0xfffffffffffffffc, 0x0000000000000000},
|
||||
63: {0xfffffffffffffffe, 0x0000000000000000},
|
||||
64: {0xffffffffffffffff, 0x0000000000000000},
|
||||
65: {0xffffffffffffffff, 0x8000000000000000},
|
||||
66: {0xffffffffffffffff, 0xc000000000000000},
|
||||
67: {0xffffffffffffffff, 0xe000000000000000},
|
||||
68: {0xffffffffffffffff, 0xf000000000000000},
|
||||
69: {0xffffffffffffffff, 0xf800000000000000},
|
||||
70: {0xffffffffffffffff, 0xfc00000000000000},
|
||||
71: {0xffffffffffffffff, 0xfe00000000000000},
|
||||
72: {0xffffffffffffffff, 0xff00000000000000},
|
||||
73: {0xffffffffffffffff, 0xff80000000000000},
|
||||
74: {0xffffffffffffffff, 0xffc0000000000000},
|
||||
75: {0xffffffffffffffff, 0xffe0000000000000},
|
||||
76: {0xffffffffffffffff, 0xfff0000000000000},
|
||||
77: {0xffffffffffffffff, 0xfff8000000000000},
|
||||
78: {0xffffffffffffffff, 0xfffc000000000000},
|
||||
79: {0xffffffffffffffff, 0xfffe000000000000},
|
||||
80: {0xffffffffffffffff, 0xffff000000000000},
|
||||
81: {0xffffffffffffffff, 0xffff800000000000},
|
||||
82: {0xffffffffffffffff, 0xffffc00000000000},
|
||||
83: {0xffffffffffffffff, 0xffffe00000000000},
|
||||
84: {0xffffffffffffffff, 0xfffff00000000000},
|
||||
85: {0xffffffffffffffff, 0xfffff80000000000},
|
||||
86: {0xffffffffffffffff, 0xfffffc0000000000},
|
||||
87: {0xffffffffffffffff, 0xfffffe0000000000},
|
||||
88: {0xffffffffffffffff, 0xffffff0000000000},
|
||||
89: {0xffffffffffffffff, 0xffffff8000000000},
|
||||
90: {0xffffffffffffffff, 0xffffffc000000000},
|
||||
91: {0xffffffffffffffff, 0xffffffe000000000},
|
||||
92: {0xffffffffffffffff, 0xfffffff000000000},
|
||||
93: {0xffffffffffffffff, 0xfffffff800000000},
|
||||
94: {0xffffffffffffffff, 0xfffffffc00000000},
|
||||
95: {0xffffffffffffffff, 0xfffffffe00000000},
|
||||
96: {0xffffffffffffffff, 0xffffffff00000000},
|
||||
97: {0xffffffffffffffff, 0xffffffff80000000},
|
||||
98: {0xffffffffffffffff, 0xffffffffc0000000},
|
||||
99: {0xffffffffffffffff, 0xffffffffe0000000},
|
||||
100: {0xffffffffffffffff, 0xfffffffff0000000},
|
||||
101: {0xffffffffffffffff, 0xfffffffff8000000},
|
||||
102: {0xffffffffffffffff, 0xfffffffffc000000},
|
||||
103: {0xffffffffffffffff, 0xfffffffffe000000},
|
||||
104: {0xffffffffffffffff, 0xffffffffff000000},
|
||||
105: {0xffffffffffffffff, 0xffffffffff800000},
|
||||
106: {0xffffffffffffffff, 0xffffffffffc00000},
|
||||
107: {0xffffffffffffffff, 0xffffffffffe00000},
|
||||
108: {0xffffffffffffffff, 0xfffffffffff00000},
|
||||
109: {0xffffffffffffffff, 0xfffffffffff80000},
|
||||
110: {0xffffffffffffffff, 0xfffffffffffc0000},
|
||||
111: {0xffffffffffffffff, 0xfffffffffffe0000},
|
||||
112: {0xffffffffffffffff, 0xffffffffffff0000},
|
||||
113: {0xffffffffffffffff, 0xffffffffffff8000},
|
||||
114: {0xffffffffffffffff, 0xffffffffffffc000},
|
||||
115: {0xffffffffffffffff, 0xffffffffffffe000},
|
||||
116: {0xffffffffffffffff, 0xfffffffffffff000},
|
||||
117: {0xffffffffffffffff, 0xfffffffffffff800},
|
||||
118: {0xffffffffffffffff, 0xfffffffffffffc00},
|
||||
119: {0xffffffffffffffff, 0xfffffffffffffe00},
|
||||
120: {0xffffffffffffffff, 0xffffffffffffff00},
|
||||
121: {0xffffffffffffffff, 0xffffffffffffff80},
|
||||
122: {0xffffffffffffffff, 0xffffffffffffffc0},
|
||||
123: {0xffffffffffffffff, 0xffffffffffffffe0},
|
||||
124: {0xffffffffffffffff, 0xfffffffffffffff0},
|
||||
125: {0xffffffffffffffff, 0xfffffffffffffff8},
|
||||
126: {0xffffffffffffffff, 0xfffffffffffffffc},
|
||||
127: {0xffffffffffffffff, 0xfffffffffffffffe},
|
||||
128: {0xffffffffffffffff, 0xffffffffffffffff},
|
||||
}
|
||||
584
vendor/go4.org/netipx/netipx.go
generated
vendored
Normal file
584
vendor/go4.org/netipx/netipx.go
generated
vendored
Normal file
@@ -0,0 +1,584 @@
|
||||
// Copyright 2020 The Inet.Af AUTHORS. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package netipx contains code and types that were left behind when
|
||||
// the old inet.af/netaddr package moved to the standard library in Go
|
||||
// 1.18 as net/netip.
|
||||
package netipx // import "go4.org/netipx"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"net"
|
||||
"net/netip"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// FromStdIP returns an IP from the standard library's IP type.
|
||||
//
|
||||
// If std is invalid, ok is false.
|
||||
//
|
||||
// FromStdIP implicitly unmaps IPv6-mapped IPv4 addresses. That is, if
|
||||
// len(std) == 16 and contains an IPv4 address, only the IPv4 part is
|
||||
// returned, without the IPv6 wrapper. This is the common form returned by
|
||||
// the standard library's ParseIP: https://play.golang.org/p/qdjylUkKWxl.
|
||||
// To convert a standard library IP without the implicit unmapping, use
|
||||
// netip.AddrFromSlice.
|
||||
func FromStdIP(std net.IP) (ip netip.Addr, ok bool) {
|
||||
ret, ok := netip.AddrFromSlice(std)
|
||||
return ret.Unmap(), ok
|
||||
}
|
||||
|
||||
// MustFromStdIP is like FromStdIP, but it panics if std is invalid.
|
||||
func MustFromStdIP(std net.IP) netip.Addr {
|
||||
ret, ok := netip.AddrFromSlice(std)
|
||||
if !ok {
|
||||
panic("not a valid IP address")
|
||||
}
|
||||
return ret.Unmap()
|
||||
}
|
||||
|
||||
// FromStdIPRaw returns an IP from the standard library's IP type.
|
||||
// If std is invalid, ok is false.
|
||||
// Unlike FromStdIP, FromStdIPRaw does not do an implicit Unmap if
|
||||
// len(std) == 16 and contains an IPv6-mapped IPv4 address.
|
||||
//
|
||||
// Deprecated: use netip.AddrFromSlice instead.
|
||||
func FromStdIPRaw(std net.IP) (ip netip.Addr, ok bool) {
|
||||
return netip.AddrFromSlice(std)
|
||||
}
|
||||
|
||||
// ParsePrefixOrAddr parses s as an IP address prefix or IP address. If s parses
|
||||
// as an IP address prefix, its [net/netip.Prefix.Addr] is returned. The string
|
||||
// s can be an IPv4 address ("192.0.2.1"), IPv6 address ("2001:db8::68"), IPv4
|
||||
// prefix ("192.0.2.1/32"), or IPv6 prefix ("2001:db:68/96").
|
||||
func ParsePrefixOrAddr(s string) (netip.Addr, error) {
|
||||
// Factored out of netip.ParsePrefix to avoid allocating an empty netip.Prefix in case it's
|
||||
// an address and not a prefix.
|
||||
i := strings.LastIndexByte(s, '/')
|
||||
if i < 0 {
|
||||
return netip.ParseAddr(s)
|
||||
}
|
||||
prefix, err := netip.ParsePrefix(s)
|
||||
return prefix.Addr(), err
|
||||
}
|
||||
|
||||
// AddrNext returns the IP following ip.
|
||||
// If there is none, it returns the IP zero value.
|
||||
//
|
||||
// Deprecated: use netip.Addr.Next instead.
|
||||
func AddrNext(ip netip.Addr) netip.Addr {
|
||||
addr := u128From16(ip.As16()).addOne()
|
||||
if ip.Is4() {
|
||||
if uint32(addr.lo) == 0 {
|
||||
// Overflowed.
|
||||
return netip.Addr{}
|
||||
}
|
||||
return addr.IP4()
|
||||
} else {
|
||||
if addr.isZero() {
|
||||
// Overflowed
|
||||
return netip.Addr{}
|
||||
}
|
||||
return addr.IP6().WithZone(ip.Zone())
|
||||
}
|
||||
}
|
||||
|
||||
// AddrPrior returns the IP before ip.
|
||||
// If there is none, it returns the IP zero value.
|
||||
//
|
||||
// Deprecated: use netip.Addr.Prev instead.
|
||||
func AddrPrior(ip netip.Addr) netip.Addr {
|
||||
addr := u128From16(ip.As16())
|
||||
if ip.Is4() {
|
||||
if uint32(addr.lo) == 0 {
|
||||
return netip.Addr{}
|
||||
}
|
||||
return addr.subOne().IP4()
|
||||
} else {
|
||||
if addr.isZero() {
|
||||
return netip.Addr{}
|
||||
}
|
||||
return addr.subOne().IP6().WithZone(ip.Zone())
|
||||
}
|
||||
}
|
||||
|
||||
// FromStdAddr maps the components of a standard library TCPAddr or
|
||||
// UDPAddr into an IPPort.
|
||||
func FromStdAddr(stdIP net.IP, port int, zone string) (_ netip.AddrPort, ok bool) {
|
||||
ip, ok := FromStdIP(stdIP)
|
||||
if !ok || port < 0 || port > math.MaxUint16 {
|
||||
return netip.AddrPort{}, false
|
||||
}
|
||||
ip = ip.Unmap()
|
||||
if zone != "" {
|
||||
if ip.Is4() {
|
||||
ok = false
|
||||
return
|
||||
}
|
||||
ip = ip.WithZone(zone)
|
||||
}
|
||||
return netip.AddrPortFrom(ip, uint16(port)), true
|
||||
}
|
||||
|
||||
// FromStdIPNet returns an netip.Prefix from the standard library's IPNet type.
|
||||
// If std is invalid, ok is false.
|
||||
func FromStdIPNet(std *net.IPNet) (prefix netip.Prefix, ok bool) {
|
||||
ip, ok := FromStdIP(std.IP)
|
||||
if !ok {
|
||||
return netip.Prefix{}, false
|
||||
}
|
||||
|
||||
if l := len(std.Mask); l != net.IPv4len && l != net.IPv6len {
|
||||
// Invalid mask.
|
||||
return netip.Prefix{}, false
|
||||
}
|
||||
|
||||
ones, bits := std.Mask.Size()
|
||||
if ones == 0 && bits == 0 {
|
||||
// IPPrefix does not support non-contiguous masks.
|
||||
return netip.Prefix{}, false
|
||||
}
|
||||
|
||||
return netip.PrefixFrom(ip, ones), true
|
||||
}
|
||||
|
||||
// RangeOfPrefix returns the inclusive range of IPs that p covers.
|
||||
//
|
||||
// If p is zero or otherwise invalid, Range returns the zero value.
|
||||
func RangeOfPrefix(p netip.Prefix) IPRange {
|
||||
p = p.Masked()
|
||||
if !p.IsValid() {
|
||||
return IPRange{}
|
||||
}
|
||||
return IPRangeFrom(p.Addr(), PrefixLastIP(p))
|
||||
}
|
||||
|
||||
// PrefixIPNet returns the net.IPNet representation of an netip.Prefix.
|
||||
// The returned value is always non-nil.
|
||||
// Any zone identifier is dropped in the conversion.
|
||||
func PrefixIPNet(p netip.Prefix) *net.IPNet {
|
||||
if !p.IsValid() {
|
||||
return &net.IPNet{}
|
||||
}
|
||||
return &net.IPNet{
|
||||
IP: p.Addr().AsSlice(),
|
||||
Mask: net.CIDRMask(p.Bits(), p.Addr().BitLen()),
|
||||
}
|
||||
}
|
||||
|
||||
// AddrIPNet returns the net.IPNet representation of an netip.Addr
|
||||
// with a mask corresponding to the addresses's bit length.
|
||||
// The returned value is always non-nil.
|
||||
// Any zone identifier is dropped in the conversion.
|
||||
func AddrIPNet(addr netip.Addr) *net.IPNet {
|
||||
if !addr.IsValid() {
|
||||
return &net.IPNet{}
|
||||
}
|
||||
return &net.IPNet{
|
||||
IP: addr.AsSlice(),
|
||||
Mask: net.CIDRMask(addr.BitLen(), addr.BitLen()),
|
||||
}
|
||||
}
|
||||
|
||||
// PrefixLastIP returns the last IP in the prefix.
|
||||
func PrefixLastIP(p netip.Prefix) netip.Addr {
|
||||
if !p.IsValid() {
|
||||
return netip.Addr{}
|
||||
}
|
||||
a16 := p.Addr().As16()
|
||||
var off uint8
|
||||
var bits uint8 = 128
|
||||
if p.Addr().Is4() {
|
||||
off = 12
|
||||
bits = 32
|
||||
}
|
||||
for b := uint8(p.Bits()); b < bits; b++ {
|
||||
byteNum, bitInByte := b/8, 7-(b%8)
|
||||
a16[off+byteNum] |= 1 << uint(bitInByte)
|
||||
}
|
||||
if p.Addr().Is4() {
|
||||
return netip.AddrFrom16(a16).Unmap()
|
||||
} else {
|
||||
return netip.AddrFrom16(a16) // doesn't unmap
|
||||
}
|
||||
}
|
||||
|
||||
// IPRange represents an inclusive range of IP addresses
|
||||
// from the same address family.
|
||||
//
|
||||
// The From and To IPs are inclusive bounds, with both included in the
|
||||
// range.
|
||||
//
|
||||
// To be valid, the From and To values must be non-zero, have matching
|
||||
// address families (IPv4 vs IPv6), and From must be less than or equal to To.
|
||||
// IPv6 zones are stripped out and ignored.
|
||||
// An invalid range may be ignored.
|
||||
type IPRange struct {
|
||||
// from is the initial IP address in the range.
|
||||
from netip.Addr
|
||||
|
||||
// to is the final IP address in the range.
|
||||
to netip.Addr
|
||||
}
|
||||
|
||||
// IPRangeFrom returns an IPRange from from to to.
|
||||
// It does not allocate.
|
||||
func IPRangeFrom(from, to netip.Addr) IPRange {
|
||||
return IPRange{
|
||||
from: from.WithZone(""),
|
||||
to: to.WithZone(""),
|
||||
}
|
||||
}
|
||||
|
||||
// From returns the lower bound of r.
|
||||
func (r IPRange) From() netip.Addr { return r.from }
|
||||
|
||||
// To returns the upper bound of r.
|
||||
func (r IPRange) To() netip.Addr { return r.to }
|
||||
|
||||
// ParseIPRange parses a range out of two IPs separated by a hyphen.
|
||||
//
|
||||
// It returns an error if the range is not valid.
|
||||
func ParseIPRange(s string) (IPRange, error) {
|
||||
var r IPRange
|
||||
h := strings.IndexByte(s, '-')
|
||||
if h == -1 {
|
||||
return r, fmt.Errorf("no hyphen in range %q", s)
|
||||
}
|
||||
from, to := s[:h], s[h+1:]
|
||||
var err error
|
||||
r.from, err = netip.ParseAddr(from)
|
||||
if err != nil {
|
||||
return r, fmt.Errorf("invalid From IP %q in range %q", from, s)
|
||||
}
|
||||
r.from = r.from.WithZone("")
|
||||
r.to, err = netip.ParseAddr(to)
|
||||
if err != nil {
|
||||
return r, fmt.Errorf("invalid To IP %q in range %q", to, s)
|
||||
}
|
||||
r.to = r.to.WithZone("")
|
||||
if !r.IsValid() {
|
||||
return r, fmt.Errorf("range %v to %v not valid", r.from, r.to)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// MustParseIPRange calls ParseIPRange(s) and panics on error.
|
||||
// It is intended for use in tests with hard-coded strings.
|
||||
func MustParseIPRange(s string) IPRange {
|
||||
r, err := ParseIPRange(s)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// String returns a string representation of the range.
|
||||
//
|
||||
// For a valid range, the form is "From-To" with a single hyphen
|
||||
// separating the IPs, the same format recognized by
|
||||
// ParseIPRange.
|
||||
func (r IPRange) String() string {
|
||||
if r.IsValid() {
|
||||
return fmt.Sprintf("%s-%s", r.from, r.to)
|
||||
}
|
||||
if !r.from.IsValid() || !r.to.IsValid() {
|
||||
return "zero IPRange"
|
||||
}
|
||||
return "invalid IPRange"
|
||||
}
|
||||
|
||||
// AppendTo appends a text encoding of r,
|
||||
// as generated by MarshalText,
|
||||
// to b and returns the extended buffer.
|
||||
func (r IPRange) AppendTo(b []byte) []byte {
|
||||
if r.IsZero() {
|
||||
return b
|
||||
}
|
||||
b = r.from.AppendTo(b)
|
||||
b = append(b, '-')
|
||||
b = r.to.AppendTo(b)
|
||||
return b
|
||||
}
|
||||
|
||||
// MarshalText implements the encoding.TextMarshaler interface,
|
||||
// The encoding is the same as returned by String, with one exception:
|
||||
// If ip is the zero value, the encoding is the empty string.
|
||||
func (r IPRange) MarshalText() ([]byte, error) {
|
||||
if r.IsZero() {
|
||||
return []byte(""), nil
|
||||
}
|
||||
var max int
|
||||
if r.from.Is4() {
|
||||
max = len("255.255.255.255-255.255.255.255")
|
||||
} else {
|
||||
max = len("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")
|
||||
}
|
||||
b := make([]byte, 0, max)
|
||||
return r.AppendTo(b), nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements the encoding.TextUnmarshaler interface.
|
||||
// The IP range is expected in a form accepted by ParseIPRange.
|
||||
// It returns an error if *r is not the IPRange zero value.
|
||||
func (r *IPRange) UnmarshalText(text []byte) error {
|
||||
if *r != (IPRange{}) {
|
||||
return errors.New("refusing to Unmarshal into non-zero IPRange")
|
||||
}
|
||||
if len(text) == 0 {
|
||||
return nil
|
||||
}
|
||||
var err error
|
||||
*r, err = ParseIPRange(string(text))
|
||||
return err
|
||||
}
|
||||
|
||||
// IsZero reports whether r is the zero value of the IPRange type.
|
||||
func (r IPRange) IsZero() bool {
|
||||
return r == IPRange{}
|
||||
}
|
||||
|
||||
// IsValid reports whether r.From() and r.To() are both non-zero and
|
||||
// obey the documented requirements: address families match, and From
|
||||
// is less than or equal to To.
|
||||
func (r IPRange) IsValid() bool {
|
||||
return r.from.IsValid() &&
|
||||
r.from.BitLen() == r.to.BitLen() &&
|
||||
r.from.Zone() == r.to.Zone() &&
|
||||
!r.to.Less(r.from)
|
||||
}
|
||||
|
||||
// Valid reports whether r.From() and r.To() are both non-zero and
|
||||
// obey the documented requirements: address families match, and From
|
||||
// is less than or equal to To.
|
||||
//
|
||||
// Deprecated: use the correctly named and identical IsValid method instead.
|
||||
func (r IPRange) Valid() bool { return r.IsValid() }
|
||||
|
||||
// Contains reports whether the range r includes addr.
|
||||
//
|
||||
// An invalid range always reports false.
|
||||
//
|
||||
// If ip has an IPv6 zone, Contains returns false,
|
||||
// because IPPrefixes strip zones.
|
||||
func (r IPRange) Contains(addr netip.Addr) bool {
|
||||
return r.IsValid() && addr.Zone() == "" && r.contains(addr)
|
||||
}
|
||||
|
||||
// contains is like Contains, but without the validity check.
|
||||
// addr must not have a zone.
|
||||
func (r IPRange) contains(addr netip.Addr) bool {
|
||||
return r.from.Compare(addr) <= 0 && r.to.Compare(addr) >= 0
|
||||
}
|
||||
|
||||
// less reports whether r is "before" other. It is before if r.From()
|
||||
// is before other.From(). If they're equal, then the larger range
|
||||
// (higher To()) comes first.
|
||||
func (r IPRange) less(other IPRange) bool {
|
||||
if cmp := r.from.Compare(other.from); cmp != 0 {
|
||||
return cmp < 0
|
||||
}
|
||||
return other.to.Less(r.to)
|
||||
}
|
||||
|
||||
// entirelyBefore returns whether r lies entirely before other in IP
|
||||
// space.
|
||||
func (r IPRange) entirelyBefore(other IPRange) bool {
|
||||
return r.to.Less(other.from)
|
||||
}
|
||||
|
||||
func lessOrEq(ip, ip2 netip.Addr) bool { return ip.Compare(ip2) <= 0 }
|
||||
|
||||
// entirelyWithin returns whether r is entirely contained within
|
||||
// other.
|
||||
func (r IPRange) coveredBy(other IPRange) bool {
|
||||
return lessOrEq(other.from, r.from) && lessOrEq(r.to, other.to)
|
||||
}
|
||||
|
||||
// inMiddleOf returns whether r is inside other, but not touching the
|
||||
// edges of other.
|
||||
func (r IPRange) inMiddleOf(other IPRange) bool {
|
||||
return other.from.Less(r.from) && r.to.Less(other.to)
|
||||
}
|
||||
|
||||
// overlapsStartOf returns whether r entirely overlaps the start of
|
||||
// other, but not all of other.
|
||||
func (r IPRange) overlapsStartOf(other IPRange) bool {
|
||||
return lessOrEq(r.from, other.from) && r.to.Less(other.to)
|
||||
}
|
||||
|
||||
// overlapsEndOf returns whether r entirely overlaps the end of
|
||||
// other, but not all of other.
|
||||
func (r IPRange) overlapsEndOf(other IPRange) bool {
|
||||
return other.from.Less(r.from) && lessOrEq(other.to, r.to)
|
||||
}
|
||||
|
||||
// mergeIPRanges returns the minimum and sorted set of IP ranges that
|
||||
// cover r.
|
||||
func mergeIPRanges(rr []IPRange) (out []IPRange, valid bool) {
|
||||
// Always return a copy of r, to avoid aliasing slice memory in
|
||||
// the caller.
|
||||
switch len(rr) {
|
||||
case 0:
|
||||
return nil, true
|
||||
case 1:
|
||||
return []IPRange{rr[0]}, true
|
||||
}
|
||||
|
||||
sort.Slice(rr, func(i, j int) bool { return rr[i].less(rr[j]) })
|
||||
out = make([]IPRange, 1, len(rr))
|
||||
out[0] = rr[0]
|
||||
for _, r := range rr[1:] {
|
||||
prev := &out[len(out)-1]
|
||||
switch {
|
||||
case !r.IsValid():
|
||||
// Invalid ranges make no sense to merge, refuse to
|
||||
// perform.
|
||||
return nil, false
|
||||
case prev.to.Next() == r.from:
|
||||
// prev and r touch, merge them.
|
||||
//
|
||||
// prev r
|
||||
// f------tf-----t
|
||||
prev.to = r.to
|
||||
case prev.to.Less(r.from):
|
||||
// No overlap and not adjacent (per previous case), no
|
||||
// merging possible.
|
||||
//
|
||||
// prev r
|
||||
// f------t f-----t
|
||||
out = append(out, r)
|
||||
case prev.to.Less(r.to):
|
||||
// Partial overlap, update prev
|
||||
//
|
||||
// prev
|
||||
// f------t
|
||||
// f-----t
|
||||
// r
|
||||
prev.to = r.to
|
||||
default:
|
||||
// r entirely contained in prev, nothing to do.
|
||||
//
|
||||
// prev
|
||||
// f--------t
|
||||
// f-----t
|
||||
// r
|
||||
}
|
||||
}
|
||||
return out, true
|
||||
}
|
||||
|
||||
// Overlaps reports whether p and o overlap at all.
|
||||
//
|
||||
// If p and o are of different address families or either are invalid,
|
||||
// it reports false.
|
||||
func (r IPRange) Overlaps(o IPRange) bool {
|
||||
return r.IsValid() &&
|
||||
o.IsValid() &&
|
||||
r.from.Compare(o.to) <= 0 &&
|
||||
o.from.Compare(r.to) <= 0
|
||||
}
|
||||
|
||||
// prefixMaker returns a address-family-corrected IPPrefix from a and bits,
|
||||
// where the input bits is always in the IPv6-mapped form for IPv4 addresses.
|
||||
type prefixMaker func(a uint128, bits uint8) netip.Prefix
|
||||
|
||||
// Prefixes returns the set of IPPrefix entries that covers r.
|
||||
//
|
||||
// If either of r's bounds are invalid, in the wrong order, or if
|
||||
// they're of different address families, then Prefixes returns nil.
|
||||
//
|
||||
// Prefixes necessarily allocates. See AppendPrefixes for a version that uses
|
||||
// memory you provide.
|
||||
func (r IPRange) Prefixes() []netip.Prefix {
|
||||
return r.AppendPrefixes(nil)
|
||||
}
|
||||
|
||||
// AppendPrefixes is an append version of IPRange.Prefixes. It appends
|
||||
// the netip.Prefix entries that cover r to dst.
|
||||
func (r IPRange) AppendPrefixes(dst []netip.Prefix) []netip.Prefix {
|
||||
if !r.IsValid() {
|
||||
return nil
|
||||
}
|
||||
return appendRangePrefixes(dst, r.prefixFrom128AndBits, u128From16(r.from.As16()), u128From16(r.to.As16()))
|
||||
}
|
||||
|
||||
func (r IPRange) prefixFrom128AndBits(a uint128, bits uint8) netip.Prefix {
|
||||
var ip netip.Addr
|
||||
if r.from.Is4() {
|
||||
bits -= 12 * 8
|
||||
ip = a.IP4()
|
||||
} else {
|
||||
ip = a.IP6()
|
||||
}
|
||||
return netip.PrefixFrom(ip, int(bits))
|
||||
}
|
||||
|
||||
// aZeroBSet is whether, after the common bits, a is all zero bits and
|
||||
// b is all set (one) bits.
|
||||
func comparePrefixes(a, b uint128) (common uint8, aZeroBSet bool) {
|
||||
common = a.commonPrefixLen(b)
|
||||
|
||||
// See whether a and b, after their common shared bits, end
|
||||
// in all zero bits or all one bits, respectively.
|
||||
if common == 128 {
|
||||
return common, true
|
||||
}
|
||||
|
||||
m := mask6[common]
|
||||
return common, (a.xor(a.and(m)).isZero() &&
|
||||
b.or(m) == uint128{^uint64(0), ^uint64(0)})
|
||||
}
|
||||
|
||||
// Prefix returns r as an IPPrefix, if it can be presented exactly as such.
|
||||
// If r is not valid or is not exactly equal to one prefix, ok is false.
|
||||
func (r IPRange) Prefix() (p netip.Prefix, ok bool) {
|
||||
if !r.IsValid() {
|
||||
return
|
||||
}
|
||||
from128 := u128From16(r.from.As16())
|
||||
to128 := u128From16(r.to.As16())
|
||||
if common, ok := comparePrefixes(from128, to128); ok {
|
||||
return r.prefixFrom128AndBits(from128, common), true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func appendRangePrefixes(dst []netip.Prefix, makePrefix prefixMaker, a, b uint128) []netip.Prefix {
|
||||
common, ok := comparePrefixes(a, b)
|
||||
if ok {
|
||||
// a to b represents a whole range, like 10.50.0.0/16.
|
||||
// (a being 10.50.0.0 and b being 10.50.255.255)
|
||||
return append(dst, makePrefix(a, common))
|
||||
}
|
||||
// Otherwise recursively do both halves.
|
||||
dst = appendRangePrefixes(dst, makePrefix, a, a.bitsSetFrom(common+1))
|
||||
dst = appendRangePrefixes(dst, makePrefix, b.bitsClearedFrom(common+1), b)
|
||||
return dst
|
||||
}
|
||||
|
||||
// ComparePrefix is a compare function (returning -1, 0 or 1)
|
||||
// sorting prefixes first by address family (IPv4 before IPv6),
|
||||
// then by prefix length (smaller prefixes first), then by
|
||||
// address.
|
||||
func ComparePrefix(a, b netip.Prefix) int {
|
||||
aa, ba := a.Addr(), b.Addr()
|
||||
if al, bl := aa.BitLen(), ba.BitLen(); al != bl {
|
||||
if al < bl {
|
||||
return -1
|
||||
}
|
||||
return 1
|
||||
}
|
||||
ab, bb := a.Bits(), b.Bits()
|
||||
if ab != bb {
|
||||
if ab < bb {
|
||||
return -1
|
||||
}
|
||||
return 1
|
||||
}
|
||||
return aa.Compare(ba)
|
||||
}
|
||||
106
vendor/go4.org/netipx/uint128.go
generated
vendored
Normal file
106
vendor/go4.org/netipx/uint128.go
generated
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
// Copyright 2020 The Inet.Af AUTHORS. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package netipx
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"math/bits"
|
||||
"net/netip"
|
||||
)
|
||||
|
||||
// uint128 represents a uint128 using two uint64s.
|
||||
//
|
||||
// When the methods below mention a bit number, bit 0 is the most
|
||||
// significant bit (in hi) and bit 127 is the lowest (lo&1).
|
||||
type uint128 struct {
|
||||
hi uint64
|
||||
lo uint64
|
||||
}
|
||||
|
||||
func u128From16(a [16]byte) uint128 {
|
||||
return uint128{
|
||||
binary.BigEndian.Uint64(a[:8]),
|
||||
binary.BigEndian.Uint64(a[8:]),
|
||||
}
|
||||
}
|
||||
|
||||
func (u uint128) IP6() netip.Addr {
|
||||
var a [16]byte
|
||||
binary.BigEndian.PutUint64(a[:8], u.hi)
|
||||
binary.BigEndian.PutUint64(a[8:], u.lo)
|
||||
return netip.AddrFrom16(a)
|
||||
}
|
||||
|
||||
func (u uint128) IP4() netip.Addr {
|
||||
var a [8]byte
|
||||
binary.BigEndian.PutUint64(a[:], u.lo)
|
||||
return netip.AddrFrom4([4]byte{a[4], a[5], a[6], a[7]})
|
||||
}
|
||||
|
||||
// isZero reports whether u == 0.
|
||||
//
|
||||
// It's faster than u == (uint128{}) because the compiler (as of Go
|
||||
// 1.15/1.16b1) doesn't do this trick and instead inserts a branch in
|
||||
// its eq alg's generated code.
|
||||
func (u uint128) isZero() bool { return u.hi|u.lo == 0 }
|
||||
|
||||
// and returns the bitwise AND of u and m (u&m).
|
||||
func (u uint128) and(m uint128) uint128 {
|
||||
return uint128{u.hi & m.hi, u.lo & m.lo}
|
||||
}
|
||||
|
||||
// xor returns the bitwise XOR of u and m (u^m).
|
||||
func (u uint128) xor(m uint128) uint128 {
|
||||
return uint128{u.hi ^ m.hi, u.lo ^ m.lo}
|
||||
}
|
||||
|
||||
// or returns the bitwise OR of u and m (u|m).
|
||||
func (u uint128) or(m uint128) uint128 {
|
||||
return uint128{u.hi | m.hi, u.lo | m.lo}
|
||||
}
|
||||
|
||||
// not returns the bitwise NOT of u.
|
||||
func (u uint128) not() uint128 {
|
||||
return uint128{^u.hi, ^u.lo}
|
||||
}
|
||||
|
||||
// subOne returns u - 1.
|
||||
func (u uint128) subOne() uint128 {
|
||||
lo, borrow := bits.Sub64(u.lo, 1, 0)
|
||||
return uint128{u.hi - borrow, lo}
|
||||
}
|
||||
|
||||
// addOne returns u + 1.
|
||||
func (u uint128) addOne() uint128 {
|
||||
lo, carry := bits.Add64(u.lo, 1, 0)
|
||||
return uint128{u.hi + carry, lo}
|
||||
}
|
||||
|
||||
func u64CommonPrefixLen(a, b uint64) uint8 {
|
||||
return uint8(bits.LeadingZeros64(a ^ b))
|
||||
}
|
||||
|
||||
func (u uint128) commonPrefixLen(v uint128) (n uint8) {
|
||||
if n = u64CommonPrefixLen(u.hi, v.hi); n == 64 {
|
||||
n += u64CommonPrefixLen(u.lo, v.lo)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// func (u *uint128) halves() [2]*uint64 {
|
||||
// return [2]*uint64{&u.hi, &u.lo}
|
||||
// }
|
||||
|
||||
// bitsSetFrom returns a copy of u with the given bit
|
||||
// and all subsequent ones set.
|
||||
func (u uint128) bitsSetFrom(bit uint8) uint128 {
|
||||
return u.or(mask6[bit].not())
|
||||
}
|
||||
|
||||
// bitsClearedFrom returns a copy of u with the given bit
|
||||
// and all subsequent ones cleared.
|
||||
func (u uint128) bitsClearedFrom(bit uint8) uint128 {
|
||||
return u.and(mask6[bit])
|
||||
}
|
||||
Reference in New Issue
Block a user