-
Notifications
You must be signed in to change notification settings - Fork 23
/
net.go
123 lines (105 loc) · 2.72 KB
/
net.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
package irtt
import (
"encoding/json"
"fmt"
"net"
)
// IPVersion is an IP version, or dual stack for IPv4 and IPv6.
type IPVersion int
// IPVersion constants.
const (
IPv4 IPVersion = 1 << iota
IPv6
DualStack = IPv4 | IPv6
)
// IPVersionFromBooleans returns an IPVersion from booleans. If both ipv4 and
// ipv6 are true, DualStack is returned. If neither are true, the value of dfl
// is returned.
func IPVersionFromBooleans(ipv4 bool, ipv6 bool, dfl IPVersion) IPVersion {
if ipv4 {
if ipv6 {
return DualStack
}
return IPv4
}
if ipv6 {
return IPv6
}
return dfl
}
// IPVersionFromIP returns an IPVersion from a net.IP.
func IPVersionFromIP(ip net.IP) IPVersion {
if ip.To4() != nil {
return IPv4
}
return IPv6
}
// IPVersionFromUDPAddr returns an IPVersion from a net.UDPAddr.
func IPVersionFromUDPAddr(addr *net.UDPAddr) IPVersion {
return IPVersionFromIP(addr.IP)
}
var udpNets = [...]string{"udp4", "udp6", "udp"}
func (v IPVersion) udpNetwork() string {
if int(v-1) < 0 || int(v-1) > len(udpNets) {
return fmt.Sprintf("IPVersion.udpNetwork:%d", v)
}
return udpNets[v-1]
}
// 28 == 20 (min IPv4 header) + 8 (UDP header)
// 48 == 40 (min IPv4 header) + 8 (UDP header)
var muhs = [...]int{28, 48, 28}
func (v IPVersion) minUDPHeaderSize() int {
return muhs[v-1]
}
var ipvs = [...]string{"IPv4", "IPv6", "IPv4+6"}
func (v IPVersion) String() string {
if int(v-1) < 0 || int(v-1) > len(ipvs) {
return fmt.Sprintf("IPVersion:%d", v)
}
return ipvs[v-1]
}
var ipvi = [...]int{4, 6, 46}
// Separate returns a slice of IPVersions, separating DualStack into IPv4 and
// IPv6 if necessary.
func (v IPVersion) Separate() []IPVersion {
if v == IPv4 {
return []IPVersion{IPv4}
}
if v == IPv6 {
return []IPVersion{IPv6}
}
return []IPVersion{IPv4, IPv6}
}
// ZeroIP returns the zero IP for the IPVersion (net.IPv4zero for IPv4 and
// otherwise net.IPv6zero).
func (v IPVersion) ZeroIP() net.IP {
if v == IPv4 {
return net.IPv4zero
}
return net.IPv6zero
}
// MarshalJSON implements the json.Marshaler interface.
func (v IPVersion) MarshalJSON() ([]byte, error) {
return json.Marshal(v.String())
}
// addPort adds the default port to a string, if the string does not
// already contain a port.
func addPort(hostport, port string) string {
if _, _, err := net.SplitHostPort(hostport); err != nil {
// JoinHostPort doesn't seem to work with IPv6 addresses with [], so I
// join manually.
return fmt.Sprintf("%s:%s", hostport, port)
}
return hostport
}
// udpAddrsEqual returns true if all fields of the passed in UDP addresses are
// equal.
func udpAddrsEqual(a1 *net.UDPAddr, a2 *net.UDPAddr) bool {
if !a1.IP.Equal(a2.IP) {
return false
}
if a1.Port != a2.Port {
return false
}
return a1.Zone == a2.Zone
}