mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-11 21:27:31 +00:00
all: convert more code to use net/netip directly
perl -i -npe 's,netaddr.IPPrefixFrom,netip.PrefixFrom,' $(git grep -l -F netaddr.) perl -i -npe 's,netaddr.IPPortFrom,netip.AddrPortFrom,' $(git grep -l -F netaddr. ) perl -i -npe 's,netaddr.IPPrefix,netip.Prefix,g' $(git grep -l -F netaddr. ) perl -i -npe 's,netaddr.IPPort,netip.AddrPort,g' $(git grep -l -F netaddr. ) perl -i -npe 's,netaddr.IP\b,netip.Addr,g' $(git grep -l -F netaddr. ) perl -i -npe 's,netaddr.IPv6Raw\b,netip.AddrFrom16,g' $(git grep -l -F netaddr. ) goimports -w . Then delete some stuff from the net/netaddr shim package which is no longer neeed. Updates #5162 Change-Id: Ia7a86893fe21c7e3ee1ec823e8aba288d4566cd8 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:

committed by
Brad Fitzpatrick

parent
6a396731eb
commit
a12aad6b47
@@ -28,7 +28,7 @@ var LoginEndpointForProxyDetermination = "https://controlplane.tailscale.com/"
|
||||
// Tailscale returns the current machine's Tailscale interface, if any.
|
||||
// If none is found, all zero values are returned.
|
||||
// A non-nil error is only returned on a problem listing the system interfaces.
|
||||
func Tailscale() ([]netaddr.IP, *net.Interface, error) {
|
||||
func Tailscale() ([]netip.Addr, *net.Interface, error) {
|
||||
ifs, err := netInterfaces()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -41,7 +41,7 @@ func Tailscale() ([]netaddr.IP, *net.Interface, error) {
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
var tsIPs []netaddr.IP
|
||||
var tsIPs []netip.Addr
|
||||
for _, a := range addrs {
|
||||
if ipnet, ok := a.(*net.IPNet); ok {
|
||||
nip, ok := netaddr.FromStdIP(ipnet.IP)
|
||||
@@ -86,13 +86,13 @@ func isProblematicInterface(nif *net.Interface) bool {
|
||||
// whether they're loopback addresses. If there are no regular addresses
|
||||
// it will return any IPv4 linklocal or IPv6 unique local addresses because we
|
||||
// know of environments where these are used with NAT to provide connectivity.
|
||||
func LocalAddresses() (regular, loopback []netaddr.IP, err error) {
|
||||
func LocalAddresses() (regular, loopback []netip.Addr, err error) {
|
||||
// TODO(crawshaw): don't serve interface addresses that we are routing
|
||||
ifaces, err := netInterfaces()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
var regular4, regular6, linklocal4, ula6 []netaddr.IP
|
||||
var regular4, regular6, linklocal4, ula6 []netip.Addr
|
||||
for _, iface := range ifaces {
|
||||
stdIf := iface.Interface
|
||||
if !isUp(stdIf) || isProblematicInterface(stdIf) {
|
||||
@@ -165,7 +165,7 @@ func LocalAddresses() (regular, loopback []netaddr.IP, err error) {
|
||||
return regular, loopback, nil
|
||||
}
|
||||
|
||||
func sortIPs(s []netaddr.IP) {
|
||||
func sortIPs(s []netip.Addr) {
|
||||
sort.Slice(s, func(i, j int) bool { return s[i].Less(s[j]) })
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ func (i Interface) Addrs() ([]net.Addr, error) {
|
||||
|
||||
// ForeachInterfaceAddress is a wrapper for GetList, then
|
||||
// List.ForeachInterfaceAddress.
|
||||
func ForeachInterfaceAddress(fn func(Interface, netaddr.IPPrefix)) error {
|
||||
func ForeachInterfaceAddress(fn func(Interface, netip.Prefix)) error {
|
||||
ifaces, err := GetList()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -198,7 +198,7 @@ func ForeachInterfaceAddress(fn func(Interface, netaddr.IPPrefix)) error {
|
||||
// ForeachInterfaceAddress calls fn for each interface in ifaces, with
|
||||
// all its addresses. The IPPrefix's IP is the IP address assigned to
|
||||
// the interface, and Bits are the subnet mask.
|
||||
func (ifaces List) ForeachInterfaceAddress(fn func(Interface, netaddr.IPPrefix)) error {
|
||||
func (ifaces List) ForeachInterfaceAddress(fn func(Interface, netip.Prefix)) error {
|
||||
for _, iface := range ifaces {
|
||||
addrs, err := iface.Addrs()
|
||||
if err != nil {
|
||||
@@ -218,7 +218,7 @@ func (ifaces List) ForeachInterfaceAddress(fn func(Interface, netaddr.IPPrefix))
|
||||
|
||||
// ForeachInterface is a wrapper for GetList, then
|
||||
// List.ForeachInterface.
|
||||
func ForeachInterface(fn func(Interface, []netaddr.IPPrefix)) error {
|
||||
func ForeachInterface(fn func(Interface, []netip.Prefix)) error {
|
||||
ifaces, err := GetList()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -229,7 +229,7 @@ func ForeachInterface(fn func(Interface, []netaddr.IPPrefix)) error {
|
||||
// ForeachInterface calls fn for each interface in ifaces, with
|
||||
// all its addresses. The IPPrefix's IP is the IP address assigned to
|
||||
// the interface, and Bits are the subnet mask.
|
||||
func (ifaces List) ForeachInterface(fn func(Interface, []netaddr.IPPrefix)) error {
|
||||
func (ifaces List) ForeachInterface(fn func(Interface, []netip.Prefix)) error {
|
||||
ifaces, err := GetList()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -239,7 +239,7 @@ func (ifaces List) ForeachInterface(fn func(Interface, []netaddr.IPPrefix)) erro
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var pfxs []netaddr.IPPrefix
|
||||
var pfxs []netip.Prefix
|
||||
for _, a := range addrs {
|
||||
switch v := a.(type) {
|
||||
case *net.IPNet:
|
||||
@@ -264,7 +264,7 @@ type State struct {
|
||||
// configured on that interface. Each address is represented as an
|
||||
// IPPrefix, where the IP is the interface IP address and Bits is
|
||||
// the subnet mask.
|
||||
InterfaceIPs map[string][]netaddr.IPPrefix
|
||||
InterfaceIPs map[string][]netip.Prefix
|
||||
Interface map[string]Interface
|
||||
|
||||
// HaveV6 is whether this machine has an IPv6 Global or Unique Local Address
|
||||
@@ -358,11 +358,11 @@ func (s *State) String() string {
|
||||
|
||||
// An InterfaceFilter indicates whether EqualFiltered should use i when deciding whether two States are equal.
|
||||
// ips are all the IPPrefixes associated with i.
|
||||
type InterfaceFilter func(i Interface, ips []netaddr.IPPrefix) bool
|
||||
type InterfaceFilter func(i Interface, ips []netip.Prefix) bool
|
||||
|
||||
// An IPFilter indicates whether EqualFiltered should use ip when deciding whether two States are equal.
|
||||
// ip is an ip address associated with some interface under consideration.
|
||||
type IPFilter func(ip netaddr.IP) bool
|
||||
type IPFilter func(ip netip.Addr) bool
|
||||
|
||||
// EqualFiltered reports whether s and s2 are equal,
|
||||
// considering only interfaces in s for which filter returns true,
|
||||
@@ -410,9 +410,9 @@ func interfacesEqual(a, b Interface) bool {
|
||||
bytes.Equal([]byte(a.HardwareAddr), []byte(b.HardwareAddr))
|
||||
}
|
||||
|
||||
func filteredIPPs(ipps []netaddr.IPPrefix, useIP IPFilter) []netaddr.IPPrefix {
|
||||
func filteredIPPs(ipps []netip.Prefix, useIP IPFilter) []netip.Prefix {
|
||||
// TODO: rewrite prefixesEqualFiltered to avoid making copies
|
||||
x := make([]netaddr.IPPrefix, 0, len(ipps))
|
||||
x := make([]netip.Prefix, 0, len(ipps))
|
||||
for _, ipp := range ipps {
|
||||
if useIP(ipp.Addr()) {
|
||||
x = append(x, ipp)
|
||||
@@ -421,11 +421,11 @@ func filteredIPPs(ipps []netaddr.IPPrefix, useIP IPFilter) []netaddr.IPPrefix {
|
||||
return x
|
||||
}
|
||||
|
||||
func prefixesEqualFiltered(a, b []netaddr.IPPrefix, useIP IPFilter) bool {
|
||||
func prefixesEqualFiltered(a, b []netip.Prefix, useIP IPFilter) bool {
|
||||
return prefixesEqual(filteredIPPs(a, useIP), filteredIPPs(b, useIP))
|
||||
}
|
||||
|
||||
func prefixesEqual(a, b []netaddr.IPPrefix) bool {
|
||||
func prefixesEqual(a, b []netip.Prefix) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
@@ -440,21 +440,21 @@ func prefixesEqual(a, b []netaddr.IPPrefix) bool {
|
||||
// UseInterestingInterfaces is an InterfaceFilter that reports whether i is an interesting interface.
|
||||
// An interesting interface if it is (a) not owned by Tailscale and (b) routes interesting IP addresses.
|
||||
// See UseInterestingIPs for the defition of an interesting IP address.
|
||||
func UseInterestingInterfaces(i Interface, ips []netaddr.IPPrefix) bool {
|
||||
func UseInterestingInterfaces(i Interface, ips []netip.Prefix) bool {
|
||||
return !isTailscaleInterface(i.Name, ips) && anyInterestingIP(ips)
|
||||
}
|
||||
|
||||
// UseInterestingIPs is an IPFilter that reports whether ip is an interesting IP address.
|
||||
// An IP address is interesting if it is neither a lopback not a link local unicast IP address.
|
||||
func UseInterestingIPs(ip netaddr.IP) bool {
|
||||
func UseInterestingIPs(ip netip.Addr) bool {
|
||||
return isInterestingIP(ip)
|
||||
}
|
||||
|
||||
// UseAllInterfaces is an InterfaceFilter that includes all interfaces.
|
||||
func UseAllInterfaces(i Interface, ips []netaddr.IPPrefix) bool { return true }
|
||||
func UseAllInterfaces(i Interface, ips []netip.Prefix) bool { return true }
|
||||
|
||||
// UseAllIPs is an IPFilter that includes all all IPs.
|
||||
func UseAllIPs(ips netaddr.IP) bool { return true }
|
||||
func UseAllIPs(ips netip.Addr) bool { return true }
|
||||
|
||||
func (s *State) HasPAC() bool { return s != nil && s.PAC != "" }
|
||||
|
||||
@@ -466,7 +466,7 @@ func (s *State) AnyInterfaceUp() bool {
|
||||
return s != nil && (s.HaveV4 || s.HaveV6)
|
||||
}
|
||||
|
||||
func hasTailscaleIP(pfxs []netaddr.IPPrefix) bool {
|
||||
func hasTailscaleIP(pfxs []netip.Prefix) bool {
|
||||
for _, pfx := range pfxs {
|
||||
if tsaddr.IsTailscaleIP(pfx.Addr()) {
|
||||
return true
|
||||
@@ -475,7 +475,7 @@ func hasTailscaleIP(pfxs []netaddr.IPPrefix) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func isTailscaleInterface(name string, ips []netaddr.IPPrefix) bool {
|
||||
func isTailscaleInterface(name string, ips []netip.Prefix) bool {
|
||||
if runtime.GOOS == "darwin" && strings.HasPrefix(name, "utun") && hasTailscaleIP(ips) {
|
||||
// On macOS in the sandboxed app (at least as of
|
||||
// 2021-02-25), we often see two utun devices
|
||||
@@ -497,10 +497,10 @@ var getPAC func() string
|
||||
// It does not set the returned State.IsExpensive. The caller can populate that.
|
||||
func GetState() (*State, error) {
|
||||
s := &State{
|
||||
InterfaceIPs: make(map[string][]netaddr.IPPrefix),
|
||||
InterfaceIPs: make(map[string][]netip.Prefix),
|
||||
Interface: make(map[string]Interface),
|
||||
}
|
||||
if err := ForeachInterface(func(ni Interface, pfxs []netaddr.IPPrefix) {
|
||||
if err := ForeachInterface(func(ni Interface, pfxs []netip.Prefix) {
|
||||
ifUp := ni.IsUp()
|
||||
s.Interface[ni.Name] = ni
|
||||
s.InterfaceIPs[ni.Name] = append(s.InterfaceIPs[ni.Name], pfxs...)
|
||||
@@ -556,7 +556,7 @@ func HTTPOfListener(ln net.Listener) string {
|
||||
|
||||
var goodIP string
|
||||
var privateIP string
|
||||
ForeachInterfaceAddress(func(i Interface, pfx netaddr.IPPrefix) {
|
||||
ForeachInterfaceAddress(func(i Interface, pfx netip.Prefix) {
|
||||
ip := pfx.Addr()
|
||||
if ip.IsPrivate() {
|
||||
if privateIP == "" {
|
||||
@@ -576,14 +576,14 @@ func HTTPOfListener(ln net.Listener) string {
|
||||
|
||||
}
|
||||
|
||||
var likelyHomeRouterIP func() (netaddr.IP, bool)
|
||||
var likelyHomeRouterIP func() (netip.Addr, bool)
|
||||
|
||||
// LikelyHomeRouterIP returns the likely IP of the residential router,
|
||||
// which will always be an IPv4 private address, if found.
|
||||
// In addition, it returns the IP address of the current machine on
|
||||
// the LAN using that gateway.
|
||||
// This is used as the destination for UPnP, NAT-PMP, PCP, etc queries.
|
||||
func LikelyHomeRouterIP() (gateway, myIP netaddr.IP, ok bool) {
|
||||
func LikelyHomeRouterIP() (gateway, myIP netip.Addr, ok bool) {
|
||||
if likelyHomeRouterIP != nil {
|
||||
gateway, ok = likelyHomeRouterIP()
|
||||
if !ok {
|
||||
@@ -593,7 +593,7 @@ func LikelyHomeRouterIP() (gateway, myIP netaddr.IP, ok bool) {
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
ForeachInterfaceAddress(func(i Interface, pfx netaddr.IPPrefix) {
|
||||
ForeachInterfaceAddress(func(i Interface, pfx netip.Prefix) {
|
||||
ip := pfx.Addr()
|
||||
if !i.IsUp() || !ip.IsValid() || myIP.IsValid() {
|
||||
return
|
||||
@@ -611,7 +611,7 @@ func LikelyHomeRouterIP() (gateway, myIP netaddr.IP, ok bool) {
|
||||
// conceivably be used to get Internet connectivity. Globally routable and
|
||||
// private IPv4 addresses are always Usable, and link local 169.254.x.x
|
||||
// addresses are in some environments.
|
||||
func isUsableV4(ip netaddr.IP) bool {
|
||||
func isUsableV4(ip netip.Addr) bool {
|
||||
if !ip.Is4() || ip.IsLoopback() {
|
||||
return false
|
||||
}
|
||||
@@ -625,7 +625,7 @@ func isUsableV4(ip netaddr.IP) bool {
|
||||
// conceivably be used to get Internet connectivity. Globally routable
|
||||
// IPv6 addresses are always Usable, and Unique Local Addresses
|
||||
// (fc00::/7) are in some environments used with address translation.
|
||||
func isUsableV6(ip netaddr.IP) bool {
|
||||
func isUsableV6(ip netip.Addr) bool {
|
||||
return v6Global1.Contains(ip) ||
|
||||
(ip.Is6() && ip.IsPrivate() && !tsaddr.TailscaleULARange().Contains(ip))
|
||||
}
|
||||
@@ -636,7 +636,7 @@ var (
|
||||
|
||||
// anyInterestingIP reports whether pfxs contains any IP that matches
|
||||
// isInterestingIP.
|
||||
func anyInterestingIP(pfxs []netaddr.IPPrefix) bool {
|
||||
func anyInterestingIP(pfxs []netip.Prefix) bool {
|
||||
for _, pfx := range pfxs {
|
||||
if isInterestingIP(pfx.Addr()) {
|
||||
return true
|
||||
@@ -648,7 +648,7 @@ func anyInterestingIP(pfxs []netaddr.IPPrefix) bool {
|
||||
// isInterestingIP reports whether ip is an interesting IP that we
|
||||
// should log in interfaces.State logging. We don't need to show
|
||||
// localhost or link-local addresses.
|
||||
func isInterestingIP(ip netaddr.IP) bool {
|
||||
func isInterestingIP(ip netip.Addr) bool {
|
||||
return !ip.IsLoopback() && !ip.IsLinkLocalUnicast()
|
||||
}
|
||||
|
||||
@@ -727,7 +727,7 @@ func DefaultRoute() (DefaultRouteDetails, error) {
|
||||
func HasCGNATInterface() (bool, error) {
|
||||
hasCGNATInterface := false
|
||||
cgnatRange := tsaddr.CGNATRange()
|
||||
err := ForeachInterface(func(i Interface, pfxs []netaddr.IPPrefix) {
|
||||
err := ForeachInterface(func(i Interface, pfxs []netip.Prefix) {
|
||||
if hasCGNATInterface || !i.IsUp() || isTailscaleInterface(i.Name, pfxs) {
|
||||
return
|
||||
}
|
||||
|
@@ -15,6 +15,7 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"net/netip"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/net/route"
|
||||
@@ -95,7 +96,7 @@ func init() {
|
||||
likelyHomeRouterIP = likelyHomeRouterIPBSDFetchRIB
|
||||
}
|
||||
|
||||
func likelyHomeRouterIPBSDFetchRIB() (ret netaddr.IP, ok bool) {
|
||||
func likelyHomeRouterIPBSDFetchRIB() (ret netip.Addr, ok bool) {
|
||||
rib, err := fetchRoutingTable()
|
||||
if err != nil {
|
||||
log.Printf("routerIP/FetchRIB: %v", err)
|
||||
|
@@ -9,6 +9,7 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"net/netip"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/net/route"
|
||||
@@ -89,7 +90,7 @@ func init() {
|
||||
likelyHomeRouterIP = likelyHomeRouterIPDarwinFetchRIB
|
||||
}
|
||||
|
||||
func likelyHomeRouterIPDarwinFetchRIB() (ret netaddr.IP, ok bool) {
|
||||
func likelyHomeRouterIPDarwinFetchRIB() (ret netip.Addr, ok bool) {
|
||||
rib, err := fetchRoutingTable()
|
||||
if err != nil {
|
||||
log.Printf("routerIP/FetchRIB: %v", err)
|
||||
|
@@ -11,7 +11,6 @@ import (
|
||||
"testing"
|
||||
|
||||
"go4.org/mem"
|
||||
"tailscale.com/net/netaddr"
|
||||
"tailscale.com/util/lineread"
|
||||
"tailscale.com/version"
|
||||
)
|
||||
@@ -42,7 +41,7 @@ default link#14 UCSI utun2
|
||||
...
|
||||
|
||||
*/
|
||||
func likelyHomeRouterIPDarwinExec() (ret netaddr.IP, ok bool) {
|
||||
func likelyHomeRouterIPDarwinExec() (ret netip.Addr, ok bool) {
|
||||
if version.IsMobile() {
|
||||
// Don't try to do subprocesses on iOS. Ends up with log spam like:
|
||||
// kernel: "Sandbox: IPNExtension(86580) deny(1) process-fork"
|
||||
|
@@ -46,7 +46,7 @@ Iface Destination Gateway Flags RefCnt Use Metric Mask
|
||||
ens18 00000000 0100000A 0003 0 0 0 00000000 0 0 0
|
||||
ens18 0000000A 00000000 0001 0 0 0 0000FFFF 0 0 0
|
||||
*/
|
||||
func likelyHomeRouterIPLinux() (ret netaddr.IP, ok bool) {
|
||||
func likelyHomeRouterIPLinux() (ret netip.Addr, ok bool) {
|
||||
if procNetRouteErr.Get() {
|
||||
// If we failed to read /proc/net/route previously, don't keep trying.
|
||||
// But if we're on Android, go into the Android path.
|
||||
@@ -104,7 +104,7 @@ func likelyHomeRouterIPLinux() (ret netaddr.IP, ok bool) {
|
||||
|
||||
// Android apps don't have permission to read /proc/net/route, at
|
||||
// least on Google devices and the Android emulator.
|
||||
func likelyHomeRouterIPAndroid() (ret netaddr.IP, ok bool) {
|
||||
func likelyHomeRouterIPAndroid() (ret netip.Addr, ok bool) {
|
||||
cmd := exec.Command("/system/bin/ip", "route", "show", "table", "0")
|
||||
out, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
|
@@ -9,8 +9,6 @@ import (
|
||||
"net"
|
||||
"net/netip"
|
||||
"testing"
|
||||
|
||||
"tailscale.com/net/netaddr"
|
||||
)
|
||||
|
||||
func TestGetState(t *testing.T) {
|
||||
@@ -76,7 +74,7 @@ func TestStateEqualFilteredIPFilter(t *testing.T) {
|
||||
// has gained an "uninteresting" IP address.
|
||||
|
||||
s1 := &State{
|
||||
InterfaceIPs: map[string][]netaddr.IPPrefix{"x": {
|
||||
InterfaceIPs: map[string][]netip.Prefix{"x": {
|
||||
netip.MustParsePrefix("42.0.0.0/8"),
|
||||
netip.MustParsePrefix("169.254.0.0/16"), // link local unicast
|
||||
}},
|
||||
@@ -84,7 +82,7 @@ func TestStateEqualFilteredIPFilter(t *testing.T) {
|
||||
}
|
||||
|
||||
s2 := &State{
|
||||
InterfaceIPs: map[string][]netaddr.IPPrefix{"x": {
|
||||
InterfaceIPs: map[string][]netip.Prefix{"x": {
|
||||
netip.MustParsePrefix("42.0.0.0/8"),
|
||||
netip.MustParsePrefix("169.254.0.0/16"), // link local unicast
|
||||
netip.MustParsePrefix("127.0.0.0/8"), // loopback (added)
|
||||
@@ -126,8 +124,8 @@ func TestStateString(t *testing.T) {
|
||||
Interface: &net.Interface{},
|
||||
},
|
||||
},
|
||||
InterfaceIPs: map[string][]netaddr.IPPrefix{
|
||||
"eth0": []netaddr.IPPrefix{
|
||||
InterfaceIPs: map[string][]netip.Prefix{
|
||||
"eth0": []netip.Prefix{
|
||||
netip.MustParsePrefix("10.0.0.2/8"),
|
||||
},
|
||||
},
|
||||
|
@@ -7,6 +7,7 @@ package interfaces
|
||||
import (
|
||||
"log"
|
||||
"net"
|
||||
"net/netip"
|
||||
"net/url"
|
||||
"strings"
|
||||
"syscall"
|
||||
@@ -27,7 +28,7 @@ func init() {
|
||||
getPAC = getPACWindows
|
||||
}
|
||||
|
||||
func likelyHomeRouterIPWindows() (ret netaddr.IP, ok bool) {
|
||||
func likelyHomeRouterIPWindows() (ret netip.Addr, ok bool) {
|
||||
rs, err := winipcfg.GetIPForwardTable2(windows.AF_INET)
|
||||
if err != nil {
|
||||
log.Printf("routerIP/GetIPForwardTable2 error: %v", err)
|
||||
@@ -94,7 +95,7 @@ func likelyHomeRouterIPWindows() (ret netaddr.IP, ok bool) {
|
||||
|
||||
if ret.IsValid() && !ret.IsPrivate() {
|
||||
// Default route has a non-private gateway
|
||||
return netaddr.IP{}, false
|
||||
return netip.Addr{}, false
|
||||
}
|
||||
|
||||
return ret, ret.IsValid()
|
||||
|
Reference in New Issue
Block a user