Этот коммит содержится в:
Christopher Speller
2017-06-21 19:06:17 -07:00
коммит произвёл Corey Hulen
родитель 6b39c308d8
Коммит 42f28ab8e3
714 изменённых файлов: 54430 добавлений и 51180 удалений

Просмотреть файл

@@ -2,6 +2,8 @@ TOOLS= golang.org/x/tools/cover
GOCOVER_TMPFILE?= $(GOCOVER_FILE).tmp
GOCOVER_FILE?= .cover.out
GOCOVERHTML?= coverage.html
FIND=`/usr/bin/which 2> /dev/null gfind find | /usr/bin/grep -v ^no | /usr/bin/head -n 1`
XARGS=`/usr/bin/which 2> /dev/null gxargs xargs | /usr/bin/grep -v ^no | /usr/bin/head -n 1`
test:: $(GOCOVER_FILE)
@$(MAKE) -C cmd/sockaddr test
@@ -9,10 +11,10 @@ test:: $(GOCOVER_FILE)
cover:: coverage_report
$(GOCOVER_FILE)::
@find . -type d ! -path '*cmd*' ! -path '*.git*' -print0 | xargs -0 -I % sh -ec "cd % && rm -f $(GOCOVER_TMPFILE) && go test -coverprofile=$(GOCOVER_TMPFILE)"
@${FIND} . -type d ! -path '*cmd*' ! -path '*.git*' -print0 | ${XARGS} -0 -I % sh -ec "cd % && rm -f $(GOCOVER_TMPFILE) && go test -coverprofile=$(GOCOVER_TMPFILE)"
@echo 'mode: set' > $(GOCOVER_FILE)
@find . -type f ! -path '*cmd*' ! -path '*.git*' -name "$(GOCOVER_TMPFILE)" -print0 | xargs -0 -n1 cat $(GOCOVER_TMPFILE) | grep -v '^mode: ' >> ${PWD}/$(GOCOVER_FILE)
@${FIND} . -type f ! -path '*cmd*' ! -path '*.git*' -name "$(GOCOVER_TMPFILE)" -print0 | ${XARGS} -0 -n1 cat $(GOCOVER_TMPFILE) | grep -v '^mode: ' >> ${PWD}/$(GOCOVER_FILE)
$(GOCOVERHTML): $(GOCOVER_FILE)
go tool cover -html=$(GOCOVER_FILE) -o $(GOCOVERHTML)
@@ -41,15 +43,15 @@ clean::
dev::
@go build
@make -B -C cmd/sockaddr sockaddr
@$(MAKE) -B -C cmd/sockaddr sockaddr
install::
@go install
@make -C cmd/sockaddr install
@$(MAKE) -C cmd/sockaddr install
doc::
echo Visit: http://127.0.0.1:6060/pkg/github.com/hashicorp/go-sockaddr/
godoc -http=:6060 -goroot $GOROOT
@echo Visit: http://127.0.0.1:6161/pkg/github.com/hashicorp/go-sockaddr/
godoc -http=:6161 -goroot $GOROOT
world::
@set -e; \
@@ -60,4 +62,4 @@ world::
done; \
done
make -C cmd/sockaddr world
$(MAKE) -C cmd/sockaddr world

2
vendor/github.com/hashicorp/go-sockaddr/cmd/sockaddr/GNUmakefile сгенерированный поставляемый
Просмотреть файл

@@ -21,7 +21,7 @@ install:: $(BIN)
.PHONY: test
test:: $(BIN)
@make -C regression
@$(MAKE) -C regression
.PHONY: world
world::

9
vendor/github.com/hashicorp/go-sockaddr/cmd/sockaddr/README.md сгенерированный поставляемый
Просмотреть файл

@@ -119,7 +119,7 @@ Options:
Here are a few impractical examples to get you started:
```text
$ sockaddr eval 'GetDefaultInterfaces | sort "type,size" | include "RFC" "6890" | attr "address"'
$ sockaddr eval 'GetAllInterfaces | include "flags" "forwardable" | include "up" | sort "default,type,size" | include "RFC" "6890" | attr "address"'
172.14.6.167
$ sockaddr eval 'GetDefaultInterfaces | sort "type,size" | include "RFC" "6890" | limit 1 | join "address" " "'
172.14.6.167
@@ -133,7 +133,7 @@ $ sockaddr eval 'GetAllInterfaces | include "network" "172.14.6.0/24" | attr "ad
172.14.6.167
$ sockaddr eval 'GetPrivateInterfaces | join "type" " "'
IPv4 IPv6
$ sockaddr eval 'GetPublicInterfaces | include "flags" "up|forwardable" | join "address" " "'
$ sockaddr eval 'GetAllInterfaces | include "flags" "forwardable" | join "address" " "'
203.0.113.4 2001:0DB8::1
$ sockaddr eval 'GetAllInterfaces | include "name" "lo0" | include "type" "IPv6" | sort "address" | join "address" " "'
100:: fe80::1
@@ -147,6 +147,11 @@ $ cat <<'EOF' | sockaddr eval -
{{. | include "name" "lo0" | include "type" "IPv6" | sort "address" | join "address" " "}}
EOF
100:: fe80::1
$ sockaddr eval 'GetPrivateInterfaces | include "flags" "forwardable|up" | include "type" "IPv4" | math "network" "+2" | attr "address"'
172.14.6.2
$ cat <<'EOF' | sudo tee -a /etc/profile
export CONSUL_HTTP_ADDR="http://`sockaddr eval 'GetInterfaceIP \"eth0\"'`:8500"
EOF
```
## `sockaddr rfc`

2
vendor/github.com/hashicorp/go-sockaddr/cmd/sockaddr/regression/expected/sockaddr.out сгенерированный поставляемый
Просмотреть файл

@@ -1,4 +1,4 @@
usage: sockaddr [--version] [--help] <command> [<args>]
Usage: sockaddr [--version] [--help] <command> [<args>]
Available commands are:
dump Parses input as an IP or interface name(s) and dumps various information

Просмотреть файл

@@ -10,6 +10,4 @@ Options:
-s Silent, only return different exit codes
Subcommands:
list Lists all known RFCs

Просмотреть файл

@@ -8,3 +8,6 @@ Usage: sockaddr rfc [RFC Number] [IP Address]
Options:
-s Silent, only return different exit codes
Subcommands:
list Lists all known RFCs

4
vendor/github.com/hashicorp/go-sockaddr/cmd/sockaddr/regression/run_all.sh сгенерированный поставляемый
Просмотреть файл

@@ -1,11 +1,13 @@
#!/bin/sh --
FIND=`/usr/bin/which 2> /dev/null gfind find | /usr/bin/grep -v ^no | /usr/bin/head -n 1`
XARGS=`/usr/bin/which 2> /dev/null gxargs xargs | /usr/bin/grep -v ^no | /usr/bin/head -n 1`
set -e
set -u
num_cpus=$(getconf NPROCESSORS_ONLN)
set +e
find . -name 'test_*.sh' -depth 1 | xargs -n1 -P${num_cpus} ./run_one.sh
${FIND} . -maxdepth 1 -name 'test_*.sh' -print0 | ${XARGS} -0 -n1 -P${num_cpus} ./run_one.sh
set -e
# rune_one.sh generates the .diff files

Просмотреть файл

@@ -5,6 +5,7 @@ cli is the library that powers the CLI for
[Packer](https://github.com/mitchellh/packer),
[Serf](https://github.com/hashicorp/serf),
[Consul](https://github.com/hashicorp/consul),
[Vault](https://github.com/hashicorp/vault),
[Terraform](https://github.com/hashicorp/terraform), and
[Nomad](https://github.com/hashicorp/nomad).

16
vendor/github.com/hashicorp/go-sockaddr/cmd/sockaddr/vendor/github.com/mitchellh/cli/cli.go сгенерированный поставляемый
Просмотреть файл

@@ -120,7 +120,13 @@ func (c *CLI) Run() (int, error) {
// Just show the version and exit if instructed.
if c.IsVersion() && c.Version != "" {
c.HelpWriter.Write([]byte(c.Version + "\n"))
return 1, nil
return 0, nil
}
// Just print the help when only '-h' or '--help' is passed.
if c.IsHelp() && c.Subcommand() == "" {
c.HelpWriter.Write([]byte(c.HelpFunc(c.Commands) + "\n"))
return 0, nil
}
// Attempt to get the factory function for creating the command
@@ -133,13 +139,13 @@ func (c *CLI) Run() (int, error) {
command, err := raw.(CommandFactory)()
if err != nil {
return 0, err
return 1, err
}
// If we've been instructed to just print the help, then print it
if c.IsHelp() {
c.commandHelp(command)
return 1, nil
return 0, nil
}
// If there is an invalid flag, then error
@@ -454,7 +460,7 @@ const defaultHelpTemplate = `
{{.Help}}{{if gt (len .Subcommands) 0}}
Subcommands:
{{ range $value := .Subcommands }}
{{- range $value := .Subcommands }}
{{ $value.NameAligned }} {{ $value.Synopsis }}{{ end }}
{{ end }}
{{- end }}
`

6
vendor/github.com/hashicorp/go-sockaddr/cmd/sockaddr/vendor/vendor.json сгенерированный поставляемый
Просмотреть файл

@@ -27,10 +27,10 @@
"revisionTime": "2016-08-06T12:27:52Z"
},
{
"checksumSHA1": "W6WsJ7dtBT0coA3S5FpGR0k4IEU=",
"checksumSHA1": "UP+pXl+ic9y6qrpZA5MqDIAuGfw=",
"path": "github.com/mitchellh/cli",
"revision": "494eb006fe29e9dc75fea6da4df4818f7e046b73",
"revisionTime": "2017-02-08T07:23:55Z"
"revision": "ee8578a9c12a5bb9d55303b9665cc448772c81b8",
"revisionTime": "2017-03-28T05:23:52Z"
},
{
"checksumSHA1": "L3leymg2RT8hFl5uL+5KP/LpBkg=",

2
vendor/github.com/hashicorp/go-sockaddr/cmd/sockaddr/version.go сгенерированный поставляемый
Просмотреть файл

@@ -12,7 +12,7 @@ var (
)
// The main version number that is being run at the moment.
const Version = "0.1.0"
const Version = "0.2.0"
// A pre-release marker for the version. If this is "" (empty string)
// then it means that it is a final release. Otherwise, this is a pre-release

128
vendor/github.com/hashicorp/go-sockaddr/ifaddr.go сгенерированный поставляемый
Просмотреть файл

@@ -1,5 +1,7 @@
package sockaddr
import "strings"
// ifAddrAttrMap is a map of the IfAddr type-specific attributes.
var ifAddrAttrMap map[AttrName]func(IfAddr) string
var ifAddrAttrs []AttrName
@@ -30,6 +32,53 @@ func GetPrivateIP() (string, error) {
return ip.NetIP().String(), nil
}
// GetPrivateIPs returns a string with all IP addresses that are part of RFC
// 6890 (regardless of whether or not there is a default route, unlike
// GetPublicIP). If the system can't find any RFC 6890 IP addresses, an empty
// string will be returned instead. This function is the `eval` equivalent of:
//
// ```
// $ sockaddr eval -r '{{GetAllInterfaces | include "RFC" "6890" | join "address" " "}}'
/// ```
func GetPrivateIPs() (string, error) {
ifAddrs, err := GetAllInterfaces()
if err != nil {
return "", err
} else if len(ifAddrs) < 1 {
return "", nil
}
ifAddrs, _ = FilterIfByType(ifAddrs, TypeIP)
if len(ifAddrs) == 0 {
return "", nil
}
OrderedIfAddrBy(AscIfType, AscIfNetworkSize).Sort(ifAddrs)
ifAddrs, _, err = IfByRFC("6890", ifAddrs)
if err != nil {
return "", err
} else if len(ifAddrs) == 0 {
return "", nil
}
_, ifAddrs, err = IfByRFC(ForwardingBlacklistRFC, ifAddrs)
if err != nil {
return "", err
} else if len(ifAddrs) == 0 {
return "", nil
}
ips := make([]string, 0, len(ifAddrs))
for _, ifAddr := range ifAddrs {
ip := *ToIPAddr(ifAddr.SockAddr)
s := ip.NetIP().String()
ips = append(ips, s)
}
return strings.Join(ips, " "), nil
}
// GetPublicIP returns a string with a single IP address that is NOT part of RFC
// 6890 and has a default route. If the system can't determine its IP address
// or find a non RFC 6890 IP address, an empty string will be returned instead.
@@ -51,6 +100,47 @@ func GetPublicIP() (string, error) {
return ip.NetIP().String(), nil
}
// GetPublicIPs returns a string with all IP addresses that are NOT part of RFC
// 6890 (regardless of whether or not there is a default route, unlike
// GetPublicIP). If the system can't find any non RFC 6890 IP addresses, an
// empty string will be returned instead. This function is the `eval`
// equivalent of:
//
// ```
// $ sockaddr eval -r '{{GetAllInterfaces | exclude "RFC" "6890" | join "address" " "}}'
/// ```
func GetPublicIPs() (string, error) {
ifAddrs, err := GetAllInterfaces()
if err != nil {
return "", err
} else if len(ifAddrs) < 1 {
return "", nil
}
ifAddrs, _ = FilterIfByType(ifAddrs, TypeIP)
if len(ifAddrs) == 0 {
return "", nil
}
OrderedIfAddrBy(AscIfType, AscIfNetworkSize).Sort(ifAddrs)
_, ifAddrs, err = IfByRFC("6890", ifAddrs)
if err != nil {
return "", err
} else if len(ifAddrs) == 0 {
return "", nil
}
ips := make([]string, 0, len(ifAddrs))
for _, ifAddr := range ifAddrs {
ip := *ToIPAddr(ifAddr.SockAddr)
s := ip.NetIP().String()
ips = append(ips, s)
}
return strings.Join(ips, " "), nil
}
// GetInterfaceIP returns a string with a single IP address sorted by the size
// of the network (i.e. IP addresses with a smaller netmask, larger network
// size, are sorted first). This function is the `eval` equivalent of:
@@ -91,6 +181,44 @@ func GetInterfaceIP(namedIfRE string) (string, error) {
return IPAddrAttr(*ip, "address"), nil
}
// GetInterfaceIPs returns a string with all IPs, sorted by the size of the
// network (i.e. IP addresses with a smaller netmask, larger network size, are
// sorted first), on a named interface. This function is the `eval` equivalent
// of:
//
// ```
// $ sockaddr eval -r '{{GetAllInterfaces | include "name" <<ARG>> | sort "type,size" | join "address" " "}}'
/// ```
func GetInterfaceIPs(namedIfRE string) (string, error) {
ifAddrs, err := GetAllInterfaces()
if err != nil {
return "", err
}
ifAddrs, _, err = IfByName(namedIfRE, ifAddrs)
if err != nil {
return "", err
}
ifAddrs, err = SortIfBy("+type,+size", ifAddrs)
if err != nil {
return "", err
}
if len(ifAddrs) == 0 {
return "", err
}
ips := make([]string, 0, len(ifAddrs))
for _, ifAddr := range ifAddrs {
ip := *ToIPAddr(ifAddr.SockAddr)
s := ip.NetIP().String()
ips = append(ips, s)
}
return strings.Join(ips, " "), nil
}
// IfAddrAttrs returns a list of attributes supported by the IfAddr type
func IfAddrAttrs() []AttrName {
return ifAddrAttrs

371
vendor/github.com/hashicorp/go-sockaddr/ifaddr_test.go сгенерированный поставляемый
Просмотреть файл

@@ -45,6 +45,42 @@ func havePublicIP() bool {
return boolEnvVar("SOCKADDR_HAVE_PUBLIC_IP", false)
}
func TestGetPrivateIP(t *testing.T) {
reportOnPrivate := func(args ...interface{}) {
if havePrivateIP() {
t.Fatalf(args[0].(string), args[1:]...)
} else {
t.Skipf(args[0].(string), args[1:]...)
}
}
ip, err := sockaddr.GetPrivateIP()
if err != nil {
reportOnPrivate("unable to get a private IP: %v", err)
}
if ip == "" {
reportOnPrivate("it's hard to test this reliably")
}
}
func TestGetPrivateIPs(t *testing.T) {
reportOnPrivate := func(args ...interface{}) {
if havePrivateIP() {
t.Fatalf(args[0].(string), args[1:]...)
} else {
t.Skipf(args[0].(string), args[1:]...)
}
}
ips, err := sockaddr.GetPrivateIPs()
if err != nil {
reportOnPrivate("unable to get a private IPs: %v", err)
}
if ips == "" {
reportOnPrivate("it's hard to test this reliably")
}
}
func TestGetPublicIP(t *testing.T) {
reportOnPublic := func(args ...interface{}) {
if havePublicIP() {
@@ -63,6 +99,24 @@ func TestGetPublicIP(t *testing.T) {
}
}
func TestGetPublicIPs(t *testing.T) {
reportOnPublic := func(args ...interface{}) {
if havePublicIP() {
t.Fatalf(args[0].(string), args[1:]...)
} else {
t.Skipf(args[0].(string), args[1:]...)
}
}
ips, err := sockaddr.GetPublicIPs()
if err != nil {
reportOnPublic("unable to get a public IPs: %v", err)
}
if ips == "" {
reportOnPublic("it's hard to test this reliably")
}
}
func TestGetInterfaceIP(t *testing.T) {
ip, err := sockaddr.GetInterfaceIP(`^.*[\d]$`)
if err != nil {
@@ -98,7 +152,7 @@ func TestIfAddrAttr(t *testing.T) {
t.Fatalf("test %d must have a name", i)
}
result, err := sockaddr.IfAttr(test.attr, sockaddr.IfAddrs{test.ifAddr})
result, err := sockaddr.IfAttr(test.attr, test.ifAddr)
if err != nil {
t.Errorf("failed to get attr %q from %v", test.name, test.ifAddr)
}
@@ -107,14 +161,317 @@ func TestIfAddrAttr(t *testing.T) {
t.Errorf("unexpected result")
}
}
}
// Test an empty array
result, err := sockaddr.IfAttr("name", sockaddr.IfAddrs{})
if err != nil {
t.Error(`failed to get attr "name" from an empty array`)
func TestIfAddrMath(t *testing.T) {
tests := []struct {
name string
ifAddr sockaddr.IfAddr
operation string
value string
expected string
wantFail bool
}{
{
name: "ipv4 address +2",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv4Addr("127.0.0.1/8"),
},
operation: "address",
value: "+2",
expected: "127.0.0.3/8",
},
{
name: "ipv4 address -2",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv4Addr("127.0.0.1/8"),
},
operation: "address",
value: "-2",
expected: "126.255.255.255/8",
},
{
name: "ipv4 address + overflow 0xff00ff03",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv4Addr("127.0.0.1/8"),
},
operation: "address",
value: fmt.Sprintf("+%d", 0xff00ff03),
expected: "126.0.255.4/8",
},
{
name: "ipv4 address - underflow 0xff00ff04",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv4Addr("127.0.0.1/8"),
},
operation: "address",
value: fmt.Sprintf("-%d", 0xff00ff04),
expected: "127.255.0.253/8",
},
{
name: "ipv6 address +2",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv6Addr("::1/128"),
},
operation: "address",
value: "+2",
expected: "::3",
},
{
name: "ipv6 address -3",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv6Addr("::4/128"),
},
operation: "address",
value: "-3",
expected: "::1",
},
{
name: "ipv6 address + overflow",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv6Addr("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"),
},
operation: "address",
value: fmt.Sprintf("+%d", 0x03),
expected: "::2",
},
{
name: "ipv6 address + underflow",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv6Addr("::1/128"),
},
operation: "address",
value: fmt.Sprintf("-%d", 0x03),
expected: "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe",
},
{
name: "ipv4 network +2",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv4Addr("127.0.0.1/8"),
},
operation: "network",
value: "+2",
expected: "127.0.0.2/8",
},
{
name: "ipv4 network -2",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv4Addr("127.0.0.1/8"),
},
operation: "network",
value: "-2",
expected: "127.255.255.254/8",
},
{
// Value exceeds /8
name: "ipv4 network + overflow 0xff00ff03",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv4Addr("127.0.0.1/8"),
},
operation: "network",
value: fmt.Sprintf("+%d", 0xff00ff03),
expected: "127.0.255.3/8",
},
{
// Value exceeds /8
name: "ipv4 network - underflow+wrap 0xff00ff04",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv4Addr("127.0.0.1/8"),
},
operation: "network",
value: fmt.Sprintf("-%d", 0xff00ff04),
expected: "127.255.0.252/8",
},
{
name: "ipv6 network +6",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv6Addr("fe80::1/64"),
},
operation: "network",
value: "+6",
expected: "fe80::6/64",
},
{
name: "ipv6 network -6",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv6Addr("fe80::ff/64"),
},
operation: "network",
value: "-6",
expected: "fe80::ffff:ffff:ffff:fffa/64",
},
{
// Value exceeds /104 mask
name: "ipv6 network + overflow 0xff00ff03",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv6Addr("fe80::1/104"),
},
operation: "network",
value: fmt.Sprintf("+%d", 0xff00ff03),
expected: "fe80::ff03/104",
},
{
// Value exceeds /104
name: "ipv6 network - underflow+wrap 0xff00ff04",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv6Addr("fe80::1/104"),
},
operation: "network",
value: fmt.Sprintf("-%d", 0xff00ff04),
expected: "fe80::ff:fc/104",
},
{
name: "ipv4 address missing sign",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv4Addr("127.0.0.1/8"),
},
operation: "address",
value: "123",
wantFail: true,
},
{
name: "ipv4 network missing sign",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv4Addr("127.0.0.1/8"),
},
operation: "network",
value: "123",
wantFail: true,
},
{
name: "ipv6 address missing sign",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv6Addr("::1/128"),
},
operation: "address",
value: "123",
wantFail: true,
},
{
name: "ipv6 network missing sign",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv6Addr("::1/128"),
},
operation: "network",
value: "123",
wantFail: true,
},
{
name: "ipv4 address bad value",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv4Addr("127.0.0.1/8"),
},
operation: "address",
value: "+xyz",
wantFail: true,
},
{
name: "ipv4 network bad value",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv4Addr("127.0.0.1/8"),
},
operation: "network",
value: "-xyz",
wantFail: true,
},
{
name: "ipv6 address bad value",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv6Addr("::1/128"),
},
operation: "address",
value: "+xyz",
wantFail: true,
},
{
name: "ipv6 network bad value",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv6Addr("::1/128"),
},
operation: "network",
value: "-xyz",
wantFail: true,
},
{
name: "ipv4 bad operation",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv4Addr("127.0.0.1/8"),
},
operation: "gooz",
value: "+xyz",
wantFail: true,
},
{
name: "ipv6 bad operation",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv6Addr("::1/128"),
},
operation: "frabba",
value: "+xyz",
wantFail: true,
},
{
name: "unix unsupported operation",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustUnixSock("/tmp/bar"),
},
operation: "address",
value: "+123",
wantFail: true,
},
{
name: "unix unsupported operation",
ifAddr: sockaddr.IfAddr{
SockAddr: sockaddr.MustUnixSock("/tmp/foo"),
},
operation: "network",
value: "+123",
wantFail: true,
},
}
if result != "" {
t.Errorf("unexpected result")
for i, test := range tests {
if test.name == "" {
t.Fatalf("test %d must have a name", i)
}
results, err := sockaddr.IfAddrsMath(test.operation, test.value, sockaddr.IfAddrs{test.ifAddr})
if test.wantFail {
if err != nil {
continue
} else {
t.Fatalf("%s: failed to fail math operation %q with value %q on %v", test.name, test.operation, test.value, test.ifAddr)
}
} else if err != nil {
t.Fatalf("%s: failed to compute math operation %q with value %q on %v", test.name, test.operation, test.value, test.ifAddr)
}
if len(results) != 1 {
t.Fatalf("%s: bad", test.name)
}
result := results[0]
switch saType := result.Type(); saType {
case sockaddr.TypeIPv4:
ipv4 := sockaddr.ToIPv4Addr(result.SockAddr)
if ipv4 == nil {
t.Fatalf("bad: %T %+#v", result, result)
}
if got := ipv4.String(); got != test.expected {
t.Errorf("unexpected result %q: want %q got %q", test.name, test.expected, got)
}
case sockaddr.TypeIPv6:
ipv6 := sockaddr.ToIPv6Addr(result.SockAddr)
if ipv6 == nil {
t.Fatalf("bad: %T %+#v", result, result)
}
if got := ipv6.String(); got != test.expected {
t.Errorf("unexpected result %q: want %q got %q", test.name, test.expected, got)
}
default:
t.Fatalf("bad")
}
}
}

267
vendor/github.com/hashicorp/go-sockaddr/ifaddrs.go сгенерированный поставляемый
Просмотреть файл

@@ -3,6 +3,7 @@ package sockaddr
import (
"errors"
"fmt"
"math/big"
"net"
"regexp"
"sort"
@@ -10,6 +11,14 @@ import (
"strings"
)
var (
// Centralize all regexps and regexp.Copy() where necessary.
signRE *regexp.Regexp = regexp.MustCompile(`^[\s]*[+-]`)
whitespaceRE *regexp.Regexp = regexp.MustCompile(`[\s]+`)
ifNameRE *regexp.Regexp = regexp.MustCompile(`^Ethernet adapter ([^\s:]+):`)
ipAddrRE *regexp.Regexp = regexp.MustCompile(`^ IPv[46] Address\. \. \. \. \. \. \. \. \. \. \. : ([^\s]+)`)
)
// IfAddrs is a slice of IfAddr
type IfAddrs []IfAddr
@@ -91,6 +100,40 @@ func AscIfAddress(p1Ptr, p2Ptr *IfAddr) int {
return AscAddress(&p1Ptr.SockAddr, &p2Ptr.SockAddr)
}
// AscIfDefault is a sorting function to sort IfAddrs by whether or not they
// have a default route or not. Non-equal types are deferred in the sort.
//
// FIXME: This is a particularly expensive sorting operation because of the
// non-memoized calls to NewRouteInfo(). In an ideal world the routeInfo data
// once at the start of the sort and pass it along as a context or by wrapping
// the IfAddr type with this information (this would also solve the inability to
// return errors and the possibility of failing silently). Fortunately,
// N*log(N) where N = 3 is only ~6.2 invocations. Not ideal, but not worth
// optimizing today. The common case is this gets called once or twice.
// Patches welcome.
func AscIfDefault(p1Ptr, p2Ptr *IfAddr) int {
ri, err := NewRouteInfo()
if err != nil {
return sortDeferDecision
}
defaultIfName, err := ri.GetDefaultInterfaceName()
if err != nil {
return sortDeferDecision
}
switch {
case p1Ptr.Interface.Name == defaultIfName && p2Ptr.Interface.Name == defaultIfName:
return sortDeferDecision
case p1Ptr.Interface.Name == defaultIfName:
return sortReceiverBeforeArg
case p2Ptr.Interface.Name == defaultIfName:
return sortArgBeforeReceiver
default:
return sortDeferDecision
}
}
// AscIfName is a sorting function to sort IfAddrs by their interface names.
func AscIfName(p1Ptr, p2Ptr *IfAddr) int {
return strings.Compare(p1Ptr.Name, p2Ptr.Name)
@@ -127,6 +170,11 @@ func DescIfAddress(p1Ptr, p2Ptr *IfAddr) int {
return -1 * AscAddress(&p1Ptr.SockAddr, &p2Ptr.SockAddr)
}
// DescIfDefault is identical to AscIfDefault but reverse ordered.
func DescIfDefault(p1Ptr, p2Ptr *IfAddr) int {
return -1 * AscIfDefault(p1Ptr, p2Ptr)
}
// DescIfName is identical to AscIfName but reverse ordered.
func DescIfName(p1Ptr, p2Ptr *IfAddr) int {
return -1 * strings.Compare(p1Ptr.Name, p2Ptr.Name)
@@ -169,7 +217,15 @@ func FilterIfByType(ifAddrs IfAddrs, type_ SockAddrType) (matchedIfs, excludedIf
// IfAttr forwards the selector to IfAttr.Attr() for resolution. If there is
// more than one IfAddr, only the first IfAddr is used.
func IfAttr(selectorName string, ifAddrs IfAddrs) (string, error) {
func IfAttr(selectorName string, ifAddr IfAddr) (string, error) {
attrName := AttrName(strings.ToLower(selectorName))
attrVal, err := ifAddr.Attr(attrName)
return attrVal, err
}
// IfAttrs forwards the selector to IfAttrs.Attr() for resolution. If there is
// more than one IfAddr, only the first IfAddr is used.
func IfAttrs(selectorName string, ifAddrs IfAddrs) (string, error) {
if len(ifAddrs) == 0 {
return "", nil
}
@@ -243,10 +299,10 @@ func GetDefaultInterfaces() (IfAddrs, error) {
// the `eval` equivalent of:
//
// ```
// $ sockaddr eval -r '{{GetDefaultInterfaces | include "type" "ip" | include "flags" "forwardable|up" | sort "type,size" | include "RFC" "6890" }}'
// $ sockaddr eval -r '{{GetAllInterfaces | include "type" "ip" | include "flags" "forwardable" | include "flags" "up" | sort "default,type,size" | include "RFC" "6890" }}'
/// ```
func GetPrivateInterfaces() (IfAddrs, error) {
privateIfs, err := GetDefaultInterfaces()
privateIfs, err := GetAllInterfaces()
if err != nil {
return IfAddrs{}, err
}
@@ -259,15 +315,21 @@ func GetPrivateInterfaces() (IfAddrs, error) {
return IfAddrs{}, nil
}
privateIfs, _, err = IfByFlag("forwardable|up", privateIfs)
privateIfs, _, err = IfByFlag("forwardable", privateIfs)
if err != nil {
return IfAddrs{}, err
}
privateIfs, _, err = IfByFlag("up", privateIfs)
if err != nil {
return IfAddrs{}, err
}
if len(privateIfs) == 0 {
return IfAddrs{}, nil
}
OrderedIfAddrBy(AscIfType, AscIfNetworkSize).Sort(privateIfs)
OrderedIfAddrBy(AscIfDefault, AscIfType, AscIfNetworkSize).Sort(privateIfs)
privateIfs, _, err = IfByRFC("6890", privateIfs)
if err != nil {
@@ -285,10 +347,10 @@ func GetPrivateInterfaces() (IfAddrs, error) {
// function is the `eval` equivalent of:
//
// ```
// $ sockaddr eval -r '{{GetDefaultInterfaces | include "type" "ip" | include "flags" "forwardable|up" | sort "type,size" | exclude "RFC" "6890" }}'
// $ sockaddr eval -r '{{GetAllInterfaces | include "type" "ip" | include "flags" "forwardable" | include "flags" "up" | sort "default,type,size" | exclude "RFC" "6890" }}'
/// ```
func GetPublicInterfaces() (IfAddrs, error) {
publicIfs, err := GetDefaultInterfaces()
publicIfs, err := GetAllInterfaces()
if err != nil {
return IfAddrs{}, err
}
@@ -301,15 +363,21 @@ func GetPublicInterfaces() (IfAddrs, error) {
return IfAddrs{}, nil
}
publicIfs, _, err = IfByFlag("forwardable|up", publicIfs)
publicIfs, _, err = IfByFlag("forwardable", publicIfs)
if err != nil {
return IfAddrs{}, err
}
publicIfs, _, err = IfByFlag("up", publicIfs)
if err != nil {
return IfAddrs{}, err
}
if len(publicIfs) == 0 {
return IfAddrs{}, nil
}
OrderedIfAddrBy(AscIfType, AscIfNetworkSize).Sort(publicIfs)
OrderedIfAddrBy(AscIfDefault, AscIfType, AscIfNetworkSize).Sort(publicIfs)
_, publicIfs, err = IfByRFC("6890", publicIfs)
if err != nil {
@@ -652,6 +720,171 @@ func IfByNetwork(selectorParam string, inputIfAddrs IfAddrs) (IfAddrs, IfAddrs,
return includedIfs, excludedIfs, nil
}
// IfAddrMath will return a new IfAddr struct with a mutated value.
func IfAddrMath(operation, value string, inputIfAddr IfAddr) (IfAddr, error) {
// Regexp used to enforce the sign being a required part of the grammar for
// some values.
signRe := signRE.Copy()
switch strings.ToLower(operation) {
case "address":
// "address" operates on the IP address and is allowed to overflow or
// underflow networks, however it will wrap along the underlying address's
// underlying type.
if !signRe.MatchString(value) {
return IfAddr{}, fmt.Errorf("sign (+/-) is required for operation %q", operation)
}
switch sockType := inputIfAddr.SockAddr.Type(); sockType {
case TypeIPv4:
// 33 == Accept any uint32 value
// TODO(seanc@): Add the ability to parse hex
i, err := strconv.ParseInt(value, 10, 33)
if err != nil {
return IfAddr{}, fmt.Errorf("unable to convert %q to int for operation %q: %v", value, operation, err)
}
ipv4 := *ToIPv4Addr(inputIfAddr.SockAddr)
ipv4Uint32 := uint32(ipv4.Address)
ipv4Uint32 += uint32(i)
return IfAddr{
SockAddr: IPv4Addr{
Address: IPv4Address(ipv4Uint32),
Mask: ipv4.Mask,
},
Interface: inputIfAddr.Interface,
}, nil
case TypeIPv6:
// 64 == Accept any int32 value
// TODO(seanc@): Add the ability to parse hex. Also parse a bignum int.
i, err := strconv.ParseInt(value, 10, 64)
if err != nil {
return IfAddr{}, fmt.Errorf("unable to convert %q to int for operation %q: %v", value, operation, err)
}
ipv6 := *ToIPv6Addr(inputIfAddr.SockAddr)
ipv6BigIntA := new(big.Int)
ipv6BigIntA.Set(ipv6.Address)
ipv6BigIntB := big.NewInt(i)
ipv6Addr := ipv6BigIntA.Add(ipv6BigIntA, ipv6BigIntB)
ipv6Addr.And(ipv6Addr, ipv6HostMask)
return IfAddr{
SockAddr: IPv6Addr{
Address: IPv6Address(ipv6Addr),
Mask: ipv6.Mask,
},
Interface: inputIfAddr.Interface,
}, nil
default:
return IfAddr{}, fmt.Errorf("unsupported type for operation %q: %T", operation, sockType)
}
case "network":
// "network" operates on the network address. Positive values start at the
// network address and negative values wrap at the network address, which
// means a "-1" value on a network will be the broadcast address after
// wrapping is applied.
if !signRe.MatchString(value) {
return IfAddr{}, fmt.Errorf("sign (+/-) is required for operation %q", operation)
}
switch sockType := inputIfAddr.SockAddr.Type(); sockType {
case TypeIPv4:
// 33 == Accept any uint32 value
// TODO(seanc@): Add the ability to parse hex
i, err := strconv.ParseInt(value, 10, 33)
if err != nil {
return IfAddr{}, fmt.Errorf("unable to convert %q to int for operation %q: %v", value, operation, err)
}
ipv4 := *ToIPv4Addr(inputIfAddr.SockAddr)
ipv4Uint32 := uint32(ipv4.NetworkAddress())
// Wrap along network mask boundaries. EZ-mode wrapping made possible by
// use of int64 vs a uint.
var wrappedMask int64
if i >= 0 {
wrappedMask = i
} else {
wrappedMask = 1 + i + int64(^uint32(ipv4.Mask))
}
ipv4Uint32 = ipv4Uint32 + (uint32(wrappedMask) &^ uint32(ipv4.Mask))
return IfAddr{
SockAddr: IPv4Addr{
Address: IPv4Address(ipv4Uint32),
Mask: ipv4.Mask,
},
Interface: inputIfAddr.Interface,
}, nil
case TypeIPv6:
// 64 == Accept any int32 value
// TODO(seanc@): Add the ability to parse hex. Also parse a bignum int.
i, err := strconv.ParseInt(value, 10, 64)
if err != nil {
return IfAddr{}, fmt.Errorf("unable to convert %q to int for operation %q: %v", value, operation, err)
}
ipv6 := *ToIPv6Addr(inputIfAddr.SockAddr)
ipv6BigInt := new(big.Int)
ipv6BigInt.Set(ipv6.NetworkAddress())
mask := new(big.Int)
mask.Set(ipv6.Mask)
if i > 0 {
wrappedMask := new(big.Int)
wrappedMask.SetInt64(i)
wrappedMask.AndNot(wrappedMask, mask)
ipv6BigInt.Add(ipv6BigInt, wrappedMask)
} else {
// Mask off any bits that exceed the network size. Subtract the
// wrappedMask from the last usable - 1
wrappedMask := new(big.Int)
wrappedMask.SetInt64(-1 * i)
wrappedMask.Sub(wrappedMask, big.NewInt(1))
wrappedMask.AndNot(wrappedMask, mask)
lastUsable := new(big.Int)
lastUsable.Set(ipv6.LastUsable().(IPv6Addr).Address)
ipv6BigInt = lastUsable.Sub(lastUsable, wrappedMask)
}
return IfAddr{
SockAddr: IPv6Addr{
Address: IPv6Address(ipv6BigInt),
Mask: ipv6.Mask,
},
Interface: inputIfAddr.Interface,
}, nil
default:
return IfAddr{}, fmt.Errorf("unsupported type for operation %q: %T", operation, sockType)
}
default:
return IfAddr{}, fmt.Errorf("unsupported math operation: %q", operation)
}
}
// IfAddrsMath will apply an IfAddrMath operation each IfAddr struct. Any
// failure will result in zero results.
func IfAddrsMath(operation, value string, inputIfAddrs IfAddrs) (IfAddrs, error) {
outputAddrs := make(IfAddrs, 0, len(inputIfAddrs))
for _, ifAddr := range inputIfAddrs {
result, err := IfAddrMath(operation, value, ifAddr)
if err != nil {
return IfAddrs{}, fmt.Errorf("unable to perform an IPMath operation on %s: %v", ifAddr, err)
}
outputAddrs = append(outputAddrs, result)
}
return outputAddrs, nil
}
// IncludeIfs returns an IfAddrs based on the passed in selector.
func IncludeIfs(selectorName, selectorParam string, inputIfAddrs IfAddrs) (IfAddrs, error) {
var includedIfs IfAddrs
@@ -736,6 +969,10 @@ func SortIfBy(selectorParam string, inputIfAddrs IfAddrs) (IfAddrs, error) {
sortFuncs[i] = AscIfAddress
case "-address":
sortFuncs[i] = DescIfAddress
case "+default", "default":
sortFuncs[i] = AscIfDefault
case "-default":
sortFuncs[i] = DescIfDefault
case "+name", "name":
// The "name" selector returns an array of IfAddrs
// ordered by the interface name.
@@ -886,7 +1123,7 @@ func parseDefaultIfNameFromRoute(routeOut string) (string, error) {
// Linux.
func parseDefaultIfNameFromIPCmd(routeOut string) (string, error) {
lines := strings.Split(routeOut, "\n")
re := regexp.MustCompile(`[\s]+`)
re := whitespaceRE.Copy()
for _, line := range lines {
kvs := re.Split(line, -1)
if len(kvs) < 5 {
@@ -929,7 +1166,7 @@ func parseDefaultIfNameWindows(routeOut, ipconfigOut string) (string, error) {
// support added.
func parseDefaultIPAddrWindowsRoute(routeOut string) (string, error) {
lines := strings.Split(routeOut, "\n")
re := regexp.MustCompile(`[\s]+`)
re := whitespaceRE.Copy()
for _, line := range lines {
kvs := re.Split(strings.TrimSpace(line), -1)
if len(kvs) < 3 {
@@ -949,17 +1186,17 @@ func parseDefaultIPAddrWindowsRoute(routeOut string) (string, error) {
// interface name forwarding traffic to the default gateway.
func parseDefaultIfNameWindowsIPConfig(defaultIPAddr, routeOut string) (string, error) {
lines := strings.Split(routeOut, "\n")
ifNameRE := regexp.MustCompile(`^Ethernet adapter ([^\s:]+):`)
ipAddrRE := regexp.MustCompile(`^ IPv[46] Address\. \. \. \. \. \. \. \. \. \. \. : ([^\s]+)`)
ifNameRe := ifNameRE.Copy()
ipAddrRe := ipAddrRE.Copy()
var ifName string
for _, line := range lines {
switch ifNameMatches := ifNameRE.FindStringSubmatch(line); {
switch ifNameMatches := ifNameRe.FindStringSubmatch(line); {
case len(ifNameMatches) > 1:
ifName = ifNameMatches[1]
continue
}
switch ipAddrMatches := ipAddrRE.FindStringSubmatch(line); {
switch ipAddrMatches := ipAddrRe.FindStringSubmatch(line); {
case len(ipAddrMatches) > 1 && ipAddrMatches[1] == defaultIPAddr:
return ifName, nil
}

148
vendor/github.com/hashicorp/go-sockaddr/ifaddrs_test.go сгенерированный поставляемый
Просмотреть файл

@@ -9,6 +9,13 @@ import (
sockaddr "github.com/hashicorp/go-sockaddr"
)
const (
// NOTE(seanc@): Assume "en0" is the interface with a default route attached
// to it. When this is not the case, change this one constant and tests
// should pass (i.e. "net0").
ifNameWithDefault = "en0"
)
// NOTE: A number of these code paths are exercised in template/ and
// cmd/sockaddr/.
//
@@ -690,31 +697,55 @@ func TestGetDefaultInterface(t *testing.T) {
}
}
func TestGetPrivateIP(t *testing.T) {
reportOnPrivate := func(args ...interface{}) {
if havePrivateIP() {
t.Fatalf(args[0].(string), args[1:]...)
} else {
t.Skipf(args[0].(string), args[1:]...)
}
}
ip, err := sockaddr.GetPrivateIP()
if err != nil {
reportOnPrivate("private IP failed: %v", err)
}
if len(ip) == 0 {
reportOnPrivate("no private IP found", nil)
}
}
func TestIfAddrAttrs(t *testing.T) {
const expectedNumAttrs = 2
attrs := sockaddr.IfAddrAttrs()
if len(attrs) != expectedNumAttrs {
t.Fatalf("wrong number of attrs")
}
tests := []struct {
name string
ifAddr sockaddr.IfAddr
attr string
expected string
}{
{
name: "name",
ifAddr: sockaddr.IfAddr{
Interface: net.Interface{
Name: "abc0",
},
},
attr: "name",
expected: "abc0",
},
}
for i, test := range tests {
if test.name == "" {
t.Fatalf("test %d must have a name", i)
}
result, err := sockaddr.IfAttrs(test.attr, sockaddr.IfAddrs{test.ifAddr})
if err != nil {
t.Errorf("failed to get attr %q from %v", test.name, test.ifAddr)
}
if result != test.expected {
t.Errorf("unexpected result")
}
}
// Test an empty array
result, err := sockaddr.IfAttrs("name", sockaddr.IfAddrs{})
if err != nil {
t.Error(`failed to get attr "name" from an empty array`)
}
if result != "" {
t.Errorf("unexpected result")
}
}
func TestGetAllInterfaces(t *testing.T) {
@@ -788,7 +819,7 @@ func TestGetPrivateInterfaces(t *testing.T) {
}
if len(ifAddrs) == 0 {
reportOnPrivate("no public IPs found", nil)
reportOnPrivate("no public IPs found")
}
if len(ifAddrs[0].String()) == 0 {
@@ -1668,6 +1699,82 @@ func TestSortIfBy(t *testing.T) {
sockaddr.IfAddr{SockAddr: sockaddr.MustIPv4Addr("1.2.3.3")},
},
},
{
// NOTE(seanc@): This test requires macOS, or at least a computer where
// en0 has the default route.
name: "sort default",
sortStr: "default",
in: sockaddr.IfAddrs{
sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv4Addr("1.2.3.4"),
Interface: net.Interface{Name: ifNameWithDefault},
},
sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv4Addr("1.2.3.3"),
Interface: net.Interface{Name: "other0"},
},
},
out: sockaddr.IfAddrs{
sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv4Addr("1.2.3.4"),
Interface: net.Interface{Name: ifNameWithDefault},
},
sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv4Addr("1.2.3.3"),
Interface: net.Interface{Name: "other0"},
},
},
},
{
// NOTE(seanc@): This test requires macOS, or at least a computer where
// en0 has the default route.
name: "sort +default",
sortStr: "+default",
in: sockaddr.IfAddrs{
sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv4Addr("1.2.3.4"),
Interface: net.Interface{Name: "other0"},
},
sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv4Addr("1.2.3.3"),
Interface: net.Interface{Name: ifNameWithDefault},
},
},
out: sockaddr.IfAddrs{
sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv4Addr("1.2.3.3"),
Interface: net.Interface{Name: ifNameWithDefault},
},
sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv4Addr("1.2.3.4"),
Interface: net.Interface{Name: "other0"},
},
},
},
{
name: "sort -default",
sortStr: "-default",
in: sockaddr.IfAddrs{
sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv4Addr("1.2.3.3"),
Interface: net.Interface{Name: ifNameWithDefault},
},
sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv4Addr("1.2.3.4"),
Interface: net.Interface{Name: "other0"},
},
},
out: sockaddr.IfAddrs{
sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv4Addr("1.2.3.4"),
Interface: net.Interface{Name: "other0"},
},
sockaddr.IfAddr{
SockAddr: sockaddr.MustIPv4Addr("1.2.3.3"),
Interface: net.Interface{Name: ifNameWithDefault},
},
},
},
{
name: "sort name",
sortStr: "name",
@@ -1877,5 +1984,4 @@ func TestSortIfBy(t *testing.T) {
}
})
}
}

3
vendor/github.com/hashicorp/go-sockaddr/ipv4addr.go сгенерированный поставляемый
Просмотреть файл

@@ -58,7 +58,8 @@ func NewIPv4Addr(ipv4Str string) (IPv4Addr, error) {
// Strip off any bogus hex-encoded netmasks that will be mis-parsed by Go. In
// particular, clients with the Barracuda VPN client will see something like:
// `192.168.3.51/00ffffff` as their IP address.
if match := trailingHexNetmaskRE.FindStringIndex(ipv4Str); match != nil {
trailingHexNetmaskRe := trailingHexNetmaskRE.Copy()
if match := trailingHexNetmaskRe.FindStringIndex(ipv4Str); match != nil {
ipv4Str = ipv4Str[:match[0]]
}

1
vendor/github.com/hashicorp/go-sockaddr/rfc.go сгенерированный поставляемый
Просмотреть файл

@@ -3,6 +3,7 @@ package sockaddr
// ForwardingBlacklist is a faux RFC that includes a list of non-forwardable IP
// blocks.
const ForwardingBlacklist = 4294967295
const ForwardingBlacklistRFC = "4294967295"
// IsRFC tests to see if an SockAddr matches the specified RFC
func IsRFC(rfcNum uint, sa SockAddr) bool {

Просмотреть файл

96
vendor/github.com/hashicorp/go-sockaddr/template/doc.go сгенерированный поставляемый
Просмотреть файл

@@ -53,23 +53,22 @@ Example:
{{ GetDefaultInterfaces }}
`GetPrivateInterfaces` - Returns one IfAddr for every forwardable IP address
that is included in RFC 6890, is attached to the interface with the default
route, and whose interface is marked as up. NOTE: RFC 6890 is a more exhaustive
version of RFC1918 because it spans IPv4 and IPv6, however it does permit the
that is included in RFC 6890 and whose interface is marked as up. NOTE: RFC 6890 is a more exhaustive
version of RFC1918 because it spans IPv4 and IPv6, however, RFC6890 does permit the
inclusion of likely undesired addresses such as multicast, therefore our version
of "private" also filters out non-forwardable addresses.
Example:
{{ GetPrivateInterfaces | include "flags" "up" }}
{{ GetPrivateInterfaces | sort "default" | join "address" " " }}
`GetPublicInterfaces` - Returns a list of IfAddr that do not match RFC 6890, is
attached to the default route, and whose interface is marked as up.
`GetPublicInterfaces` - Returns a list of IfAddr structs whos IPs are
forwardable, do not match RFC 6890, and whose interface is marked up.
Example:
{{ GetPublicInterfaces | include "flags" "up" }}
{{ GetPublicInterfaces | sort "default" | join "name" " " }}
`GetPrivateIP` - Helper function that returns a string of the first IP address
@@ -80,6 +79,14 @@ Example:
{{ GetPrivateIP }}
`GetPrivateIPs` - Helper function that returns a string of the all private IP
addresses on the host.
Example:
{{ GetPrivateIPs }}
`GetPublicIP` - Helper function that returns a string of the first IP from
GetPublicInterfaces.
@@ -87,12 +94,29 @@ Example:
{{ GetPublicIP }}
`GetPublicIPs` - Helper function that returns a space-delimited string of the
all public IP addresses on the host.
Example:
{{ GetPrivateIPs }}
`GetInterfaceIP` - Helper function that returns a string of the first IP from
the named interface.
Example:
{{ GetInterfaceIP }}
{{ GetInterfaceIP "en0" }}
`GetInterfaceIPs` - Helper function that returns a space-delimited list of all
IPs on a given interface.
Example:
{{ GetInterfaceIPs "en0" }}
`sort` - Sorts the IfAddrs result based on its arguments. `sort` takes one
@@ -100,6 +124,8 @@ argument, a list of ways to sort its IfAddrs argument. The list of sort
criteria is comma separated (`,`):
- `address`, `+address`: Ascending sort of IfAddrs by Address
- `-address`: Descending sort of IfAddrs by Address
- `default`, `+default`: Ascending sort of IfAddrs, IfAddr with a default route first
- `-default`: Descending sort of IfAddrs, IfAttr with default route last
- `name`, `+name`: Ascending sort of IfAddrs by lexical ordering of interface name
- `-name`: Descending sort of IfAddrs by lexical ordering of interface name
- `port`, `+port`: Ascending sort of IfAddrs by port number
@@ -116,7 +142,7 @@ criteria is comma separated (`,`):
Example:
{{ GetPrivateInterfaces | sort "type,size,address" }}
{{ GetPrivateInterfaces | sort "default,-type,size,+address" }}
`exclude` and `include`: Filters IfAddrs based on the selector criteria and its
@@ -142,7 +168,7 @@ available filtering criteria is:
Example:
{{ GetPrivateInterfaces | exclude "type" "IPv6" | include "flag" "up|forwardable" }}
{{ GetPrivateInterfaces | exclude "type" "IPv6" }}
`unique`: Removes duplicate entries from the IfAddrs list, assuming the list has
@@ -152,14 +178,14 @@ already been sorted. `unique` only takes one argument:
Example:
{{ GetPrivateInterfaces | sort "type,address" | unique "name" }}
{{ GetAllInterfaces | sort "default,-type,address" | unique "name" }}
`limit`: Reduces the size of the list to the specified value.
Example:
{{ GetPrivateInterfaces | include "flags" "forwardable|up" | limit 1 }}
{{ GetPrivateInterfaces | limit 1 }}
`offset`: Seeks into the list by the specified value. A negative value can be
@@ -167,7 +193,33 @@ used to seek from the end of the list.
Example:
{{ GetPrivateInterfaces | include "flags" "forwardable|up" | offset "-2" | limit 1 }}
{{ GetPrivateInterfaces | offset "-2" | limit 1 }}
`math`: Perform a "math" operation on each member of the list and return new
values. `math` takes two arguments, the attribute to operate on and the
operation's value.
Supported operations include:
- `address`: Adds the value, a positive or negative value expressed as a
decimal string, to the address. The sign is required. This value is
allowed to over or underflow networks (e.g. 127.255.255.255 `"address" "+1"`
will return "128.0.0.0"). Addresses will wrap at IPv4 or IPv6 boundaries.
- `network`: Add the value, a positive or negative value expressed as a
decimal string, to the network address. The sign is required. Positive
values are added to the network address. Negative values are subtracted
from the network's broadcast address (e.g. 127.0.0.1 `"network" "-1"` will
return "127.255.255.255"). Values that overflow the network size will
safely wrap.
Example:
{{ GetPrivateInterfaces | include "type" "IP" | math "address" "+256" | attr "address" }}
{{ GetPrivateInterfaces | include "type" "IP" | math "address" "-256" | attr "address" }}
{{ GetPrivateInterfaces | include "type" "IP" | math "network" "+2" | attr "address" }}
{{ GetPrivateInterfaces | include "type" "IP" | math "network" "-2" | attr "address" }}
{{ GetPrivateInterfaces | include "flags" "forwardable|up" | include "type" "IPv4" | math "network" "+2" | attr "address" }}
`attr`: Extracts a single attribute of the first member of the list and returns
@@ -177,7 +229,19 @@ supported attributes.
Example:
{{ GetPrivateInterfaces | include "flags" "forwardable|up" | attr "address" }}
{{ GetAllInterfaces | exclude "flags" "up" | attr "address" }}
`Attr`: Extracts a single attribute from an `IfAttr` and in every other way
performs the same as the `attr`.
Example:
{{ with $ifAddrs := GetAllInterfaces | include "type" "IP" | sort "+type,+address" -}}
{{- range $ifAddrs -}}
{{- Attr "address" . }} -- {{ Attr "network" . }}/{{ Attr "size" . -}}
{{- end -}}
{{- end }}
`join`: Similar to `attr`, `join` extracts all matching attributes of the list
@@ -187,7 +251,7 @@ and returns them as a string joined by the separator, the second argument to
Example:
{{ GetPrivateInterfaces | include "flags" "forwardable|up" | join "address" " " }}
{{ GetAllInterfaces | include "flags" "forwardable" | join "address" " " }}
`exclude` and `include` flags:
@@ -205,7 +269,7 @@ Example:
- `up`: Is the interface up?
Attributes for `attr` and `join`:
Attributes for `attr`, `Attr`, and `join`:
SockAddr Type:
- `string`

32
vendor/github.com/hashicorp/go-sockaddr/template/template.go сгенерированный поставляемый
Просмотреть файл

@@ -64,23 +64,53 @@ func init() {
HelperFuncs = template.FuncMap{
// Misc functions that operate on IfAddrs inputs
"attr": sockaddr.IfAttr,
"attr": Attr,
"join": sockaddr.JoinIfAddrs,
"limit": sockaddr.LimitIfAddrs,
"offset": sockaddr.OffsetIfAddrs,
"unique": sockaddr.UniqueIfAddrsBy,
// Misc math functions that operate on a single IfAddr input
"math": sockaddr.IfAddrsMath,
// Return a Private RFC 6890 IP address string that is attached
// to the default route and a forwardable address.
"GetPrivateIP": sockaddr.GetPrivateIP,
// Return all Private RFC 6890 IP addresses as a space-delimited string of
// IP addresses. Addresses returned do not have to be on the interface with
// a default route.
"GetPrivateIPs": sockaddr.GetPrivateIPs,
// Return a Public RFC 6890 IP address string that is attached
// to the default route and a forwardable address.
"GetPublicIP": sockaddr.GetPublicIP,
// Return allPublic RFC 6890 IP addresses as a space-delimited string of IP
// addresses. Addresses returned do not have to be on the interface with a
// default route.
"GetPublicIPs": sockaddr.GetPublicIPs,
// Return the first IP address of the named interface, sorted by
// the largest network size.
"GetInterfaceIP": sockaddr.GetInterfaceIP,
// Return all IP addresses on the named interface, sorted by the largest
// network size.
"GetInterfaceIPs": sockaddr.GetInterfaceIPs,
}
}
// Attr returns the attribute from the ifAddrRaw argument. If the argument is
// an IfAddrs, only the first element will be evaluated for resolution.
func Attr(selectorName string, ifAddrsRaw interface{}) (string, error) {
switch v := ifAddrsRaw.(type) {
case sockaddr.IfAddr:
return sockaddr.IfAttr(selectorName, v)
case sockaddr.IfAddrs:
return sockaddr.IfAttrs(selectorName, v)
default:
return "", fmt.Errorf("unable to obtain attribute %s from type %T (%v)", selectorName, ifAddrsRaw, ifAddrsRaw)
}
}

75
vendor/github.com/hashicorp/go-sockaddr/template/template_test.go сгенерированный поставляемый
Просмотреть файл

@@ -181,6 +181,81 @@ func TestSockAddr_Parse(t *testing.T) {
{{- end -}}`,
output: `true`,
},
{
name: "math address +",
input: `{{GetAllInterfaces | include "name" "^lo0$" | include "type" "IP" | math "address" "+2" | sort "+type,+address" | join "address" " " }}`,
output: `127.0.0.3 ::3 fe80::3`,
},
{
name: "math address + overflow",
input: `|{{- with $ifAddrs := GetAllInterfaces | include "name" "^lo0$" | include "type" "IP" | math "address" "+16777217" | sort "+type,+address" -}}
{{- range $ifAddrs -}}
{{- attr "address" . }} -- {{ attr "network" . }}/{{ attr "size" . }}|{{ end -}}
{{- end -}}`,
output: `|128.0.0.2 -- 128.0.0.0/16777216|::100:2 -- ::100:2/1|fe80::100:2 -- fe80::/18446744073709551616|`,
},
{
name: "math address + overflow+wrap",
input: `{{GetAllInterfaces | include "name" "^lo0$" | include "type" "IP" | math "address" "+4294967294" | sort "+type,+address" | join "address" " " }}`,
output: `126.255.255.255 ::ffff:ffff fe80::ffff:ffff`,
},
{
name: "math address -",
input: `{{GetAllInterfaces | include "name" "^lo0$" | include "type" "IP" | math "address" "-256" | sort "+type,+address" | join "address" " " }}`,
output: `126.255.255.1 fe7f:ffff:ffff:ffff:ffff:ffff:ffff:ff01 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff01`,
},
{
name: "math address - underflow",
input: `{{GetAllInterfaces | include "name" "^lo0$" | include "type" "IP" | math "address" "-4278190082" | sort "+type,+address" | join "address" " " }}`,
output: `127.255.255.255 fe7f:ffff:ffff:ffff:ffff:ffff:ff:ffff ffff:ffff:ffff:ffff:ffff:ffff:ff:ffff`,
},
{
// Note to readers: lo0's link-local address (::1) address has a mask of
// /128 which means its value never changes and this is expected. lo0's
// site-local address has a /64 address and is expected to change.
name: "math network",
input: `{{GetAllInterfaces | include "name" "^lo0$" | include "type" "IP" | math "network" "+2" | sort "+type,+address" | join "address" " " }}`,
output: `127.0.0.2 ::1 fe80::2`,
},
{
// Assume an IPv4 input of 127.0.0.1. With a value of 0xff00ff01, we wrap once on purpose.
name: "math network + wrap",
input: `{{GetAllInterfaces | include "name" "^lo0$" | include "type" "IP" | math "network" "+4278255368" | sort "+type,+address" | join "address" " " }}`,
output: `127.0.255.8 ::1 fe80::ff00:ff08`,
},
{
name: "math network -",
input: `{{GetAllInterfaces | include "name" "^lo0$" | include "type" "IP" | math "network" "-2" | sort "+type,+address" | join "address" " " }}`,
output: `127.255.255.254 ::1 fe80::ffff:ffff:ffff:fffe`,
},
{
// Assume an IPv4 input of 127.0.0.1. With a value of 0xff000008 it
// should wrap and underflow by 8. Assume an IPv6 input of ::1. With a
// value of -0xff000008 the value underflows and wraps.
name: "math network - underflow+wrap",
input: `{{GetAllInterfaces | include "name" "^lo0$" | include "type" "IP" | sort "+type,+address" | math "network" "-4278190088" | join "address" " " }}`,
output: `127.255.255.248 ::1 fe80::ffff:ffff:ff:fff8`,
},
{
// Assume the private IPs available on the host are: 10.1.2.3
// fe80::1025:f732:1001:203
name: "GetPrivateIPs",
input: `{{GetPrivateIPs}}`,
output: `10.1.2.3 fe80::1025:f732:1001:203`,
},
{
// Assume the public IPs available on the host are: 1.2.3.4 6.7.8.9
name: "GetPublicIPs",
input: `{{GetPublicIPs}}`,
output: `1.2.3.4 6.7.8.9`,
},
{
// Assume the private IPs on this host are just the IPv4 addresses:
// 10.1.2.3 and 172.16.4.6
name: "GetInterfaceIPs",
input: `{{GetInterfaceIPs "en0"}}`,
output: `10.1.2.3 and 172.16.4.6`,
},
}
for i, test := range tests {

18
vendor/github.com/hashicorp/memberlist/config.go сгенерированный поставляемый
Просмотреть файл

@@ -141,6 +141,16 @@ type Config struct {
GossipNodes int
GossipToTheDeadTime time.Duration
// GossipVerifyIncoming controls whether to enforce encryption for incoming
// gossip. It is used for upshifting from unencrypted to encrypted gossip on
// a running cluster.
GossipVerifyIncoming bool
// GossipVerifyOutgoing controls whether to enforce encryption for outgoing
// gossip. It is used for upshifting from unencrypted to encrypted gossip on
// a running cluster.
GossipVerifyOutgoing bool
// EnableCompression is used to control message compression. This can
// be used to reduce bandwidth usage at the cost of slightly more CPU
// utilization. This is only available starting at protocol version 1.
@@ -233,9 +243,11 @@ func DefaultLANConfig() *Config {
DisableTcpPings: false, // TCP pings are safe, even with mixed versions
AwarenessMaxMultiplier: 8, // Probe interval backs off to 8 seconds
GossipNodes: 3, // Gossip to 3 nodes
GossipInterval: 200 * time.Millisecond, // Gossip more rapidly
GossipToTheDeadTime: 30 * time.Second, // Same as push/pull
GossipNodes: 3, // Gossip to 3 nodes
GossipInterval: 200 * time.Millisecond, // Gossip more rapidly
GossipToTheDeadTime: 30 * time.Second, // Same as push/pull
GossipVerifyIncoming: true,
GossipVerifyOutgoing: true,
EnableCompression: true, // Enable compression by default

129
vendor/github.com/hashicorp/memberlist/memberlist_test.go сгенерированный поставляемый
Просмотреть файл

@@ -326,6 +326,12 @@ func TestMemberList_ResolveAddr(t *testing.T) {
if _, err := m.resolveAddr("[2001:db8:a0b:12f0::1]:80"); err != nil {
t.Fatalf("Could not understand hostname port combo: %s", err)
}
if _, err := m.resolveAddr("127.0.0.1"); err != nil {
t.Fatalf("Could not understand IPv4 only %s", err)
}
if _, err := m.resolveAddr("[2001:db8:a0b:12f0::1]"); err != nil {
t.Fatalf("Could not understand IPv6 only %s", err)
}
}
type dnsHandler struct {
@@ -1315,6 +1321,129 @@ func TestMemberlist_PingDelegate(t *testing.T) {
}
}
func TestMemberlist_EncryptedGossipTransition(t *testing.T) {
m1 := GetMemberlist(t)
m1.setAlive()
m1.schedule()
defer m1.Shutdown()
// Create a second node with the first stage of gossip transition settings
conf2 := DefaultLANConfig()
addr2 := getBindAddr()
conf2.Name = addr2.String()
conf2.BindAddr = addr2.String()
conf2.BindPort = m1.config.BindPort
conf2.GossipInterval = time.Millisecond
conf2.SecretKey = []byte("Hi16ZXu2lNCRVwtr20khAg==")
conf2.GossipVerifyIncoming = false
conf2.GossipVerifyOutgoing = false
m2, err := Create(conf2)
if err != nil {
t.Fatalf("unexpected err: %s", err)
}
defer m2.Shutdown()
// Join the second node. m1 has no encryption while m2 has encryption configured and
// can receive encrypted gossip, but will not encrypt outgoing gossip.
num, err := m2.Join([]string{m1.config.BindAddr})
if num != 1 {
t.Fatalf("unexpected 1: %d", num)
}
if err != nil {
t.Fatalf("unexpected err: %s", err)
}
// Check the hosts
if len(m2.Members()) != 2 {
t.Fatalf("should have 2 nodes! %v", m2.Members())
}
if m2.estNumNodes() != 2 {
t.Fatalf("should have 2 nodes! %v", m2.Members())
}
// Leave with the first node
m1.Leave(time.Second)
// Wait for leave
time.Sleep(10 * time.Millisecond)
// Create a third node that has the second stage of gossip transition settings
conf3 := DefaultLANConfig()
addr3 := getBindAddr()
conf3.Name = addr3.String()
conf3.BindAddr = addr3.String()
conf3.BindPort = m1.config.BindPort
conf3.GossipInterval = time.Millisecond
conf3.SecretKey = conf2.SecretKey
conf3.GossipVerifyIncoming = false
m3, err := Create(conf3)
if err != nil {
t.Fatalf("unexpected err: %s", err)
}
defer m3.Shutdown()
// Join the third node to the second node. At this step, both nodes have encryption
// configured but only m3 is sending encrypted gossip.
num, err = m3.Join([]string{m2.config.BindAddr})
if num != 1 {
t.Fatalf("unexpected 1: %d", num)
}
if err != nil {
t.Fatalf("unexpected err: %s", err)
}
// Check the hosts
if len(m3.Members()) != 2 {
t.Fatalf("should have 2 nodes! %v", m3.Members())
}
if m3.estNumNodes() != 2 {
t.Fatalf("should have 2 nodes! %v", m3.Members())
}
// Leave with the second node
m2.Leave(time.Second)
// Wait for leave
time.Sleep(10 * time.Millisecond)
// Create a fourth node that has the second stage of gossip transition settings
conf4 := DefaultLANConfig()
addr4 := getBindAddr()
conf4.Name = addr4.String()
conf4.BindAddr = addr4.String()
conf4.BindPort = m3.config.BindPort
conf4.GossipInterval = time.Millisecond
conf4.SecretKey = conf2.SecretKey
m4, err := Create(conf4)
if err != nil {
t.Fatalf("unexpected err: %s", err)
}
defer m4.Shutdown()
// Join the fourth node to the third node. At this step, both m3 and m4 are speaking
// encrypted gossip and m3 is still accepting insecure gossip.
num, err = m4.Join([]string{m3.config.BindAddr})
if num != 1 {
t.Fatalf("unexpected 1: %d", num)
}
if err != nil {
t.Fatalf("unexpected err: %s", err)
}
// Check the hosts
if len(m4.Members()) != 2 {
t.Fatalf("should have 2 nodes! %v", m4.Members())
}
if m4.estNumNodes() != 2 {
t.Fatalf("should have 2 nodes! %v", m4.Members())
}
}
// Consul bug, rapid restart (before failure detection),
// with an updated meta data. Should be at incarnation 1 for
// both.

17
vendor/github.com/hashicorp/memberlist/net.go сгенерированный поставляемый
Просмотреть файл

@@ -283,8 +283,13 @@ func (m *Memberlist) ingestPacket(buf []byte, from net.Addr, timestamp time.Time
// Decrypt the payload
plain, err := decryptPayload(m.config.Keyring.GetKeys(), buf, nil)
if err != nil {
m.logger.Printf("[ERR] memberlist: Decrypt packet failed: %v %s", err, LogAddress(from))
return
if !m.config.GossipVerifyIncoming {
// Treat the message as plaintext
plain = buf
} else {
m.logger.Printf("[ERR] memberlist: Decrypt packet failed: %v %s", err, LogAddress(from))
return
}
}
// Continue processing the plaintext buffer
@@ -557,7 +562,7 @@ func (m *Memberlist) encodeAndSendMsg(addr string, msgType messageType, msg inte
func (m *Memberlist) sendMsg(addr string, msg []byte) error {
// Check if we can piggy back any messages
bytesAvail := m.config.UDPBufferSize - len(msg) - compoundHeaderOverhead
if m.config.EncryptionEnabled() {
if m.config.EncryptionEnabled() && m.config.GossipVerifyOutgoing {
bytesAvail -= encryptOverhead(m.encryptionVersion())
}
extra := m.getBroadcasts(compoundOverhead, bytesAvail)
@@ -621,7 +626,7 @@ func (m *Memberlist) rawSendMsgPacket(addr string, node *Node, msg []byte) error
}
// Check if we have encryption enabled
if m.config.EncryptionEnabled() {
if m.config.EncryptionEnabled() && m.config.GossipVerifyOutgoing {
// Encrypt the payload
var buf bytes.Buffer
primaryKey := m.config.Keyring.GetPrimaryKey()
@@ -652,7 +657,7 @@ func (m *Memberlist) rawSendMsgStream(conn net.Conn, sendBuf []byte) error {
}
// Check if encryption is enabled
if m.config.EncryptionEnabled() {
if m.config.EncryptionEnabled() && m.config.GossipVerifyOutgoing {
crypt, err := m.encryptLocalState(sendBuf)
if err != nil {
m.logger.Printf("[ERROR] memberlist: Failed to encrypt local state: %v", err)
@@ -876,7 +881,7 @@ func (m *Memberlist) readStream(conn net.Conn) (messageType, io.Reader, *codec.D
// Reset message type and bufConn
msgType = messageType(plain[0])
bufConn = bytes.NewReader(plain[1:])
} else if m.config.EncryptionEnabled() {
} else if m.config.EncryptionEnabled() && m.config.GossipVerifyIncoming {
return 0, nil, nil,
fmt.Errorf("Encryption is configured but remote state is not encrypted")
}

2
vendor/github.com/hashicorp/memberlist/state_test.go сгенерированный поставляемый
Просмотреть файл

@@ -669,7 +669,7 @@ func TestMemberList_ProbeNode_Awareness_MissedNack(t *testing.T) {
// We should have gotten dinged for the missed nack.
time.Sleep(probeTimeMax)
if score := m1.GetHealthScore(); score != 2 {
if score := m1.GetHealthScore(); score != 1 {
t.Fatalf("bad: %d", score)
}
}