-
Notifications
You must be signed in to change notification settings - Fork 291
/
net_utils.go
129 lines (109 loc) · 2.8 KB
/
net_utils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//
// (C) Copyright 2020-2021 Intel Corporation.
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
package common
import (
"fmt"
"net"
"strconv"
"strings"
"github.com/pkg/errors"
"github.com/daos-stack/daos/src/control/build"
"github.com/daos-stack/daos/src/control/lib/hostlist"
)
// HasPort checks if addr specifies a port. This only works with IPv4
// addresses at the moment.
func HasPort(addr string) bool {
return strings.Contains(addr, ":")
}
// SplitPort separates port from host in address and can apply default port if
// address doesn't contain one.
func SplitPort(addrPattern string, defaultPort int) (string, string, error) {
host, port, err := net.SplitHostPort(addrPattern)
if err != nil {
if !strings.Contains(err.Error(), "missing port in address") {
return "", "", err
}
return net.SplitHostPort(
fmt.Sprintf("%s:%d", addrPattern, defaultPort))
}
if _, err := strconv.Atoi(port); err != nil {
return "", "", errors.Errorf("invalid port %q", port)
}
return host, port, err
}
// CmpTCPAddr compares two *net.TCPAddr instances and returns
// true if they are equivalent, false otherwise.
func CmpTCPAddr(a, b *net.TCPAddr) bool {
if a == nil && b == nil {
return true
}
if a == nil || b == nil {
return false
}
if !a.IP.Equal(b.IP) {
return false
}
if a.Port != b.Port {
return false
}
return a.Zone == b.Zone
}
// IsLocalAddr returns true if the supplied net.TCPAddr
// matches one of the local IP addresses, false otherwise.
func IsLocalAddr(testAddr *net.TCPAddr) bool {
if testAddr == nil {
return false
}
ifaceAddrs, err := net.InterfaceAddrs()
if err != nil {
return false
}
for _, ia := range ifaceAddrs {
if in, ok := ia.(*net.IPNet); ok {
if in.IP.Equal(testAddr.IP) {
return true
}
}
}
return false
}
// LocalhostCtrlAddr returns a *net.TCPAddr representing
// the default control address on localhost.
func LocalhostCtrlAddr() *net.TCPAddr {
return &net.TCPAddr{
IP: net.IPv4(127, 0, 0, 1),
Port: build.DefaultControlPort,
}
}
// ParseHostList validates and deduplicates the given list of host
// strings. Any hosts missing a port will have one added according
// to the defaultPort parameter.
func ParseHostList(in []string, defaultPort int) (out []string, err error) {
if len(in) == 0 {
return
}
var set *hostlist.HostSet
set, err = hostlist.CreateSet(strings.Join(in, ","))
if err != nil {
return nil, err
}
out = strings.Split(set.DerangedString(), ",")
for i, host := range out {
hostPort := strings.Split(host, ":")
switch len(hostPort) {
case 1:
out[i] = fmt.Sprintf("%s:%d", host, defaultPort)
case 2:
_, err = strconv.Atoi(hostPort[1])
default:
err = errors.New("host should conform to hostname[:port]")
}
if err != nil {
return nil, errors.Wrapf(err, "invalid host %q", host)
}
}
return
}