-
Notifications
You must be signed in to change notification settings - Fork 1
/
routeable.go
185 lines (172 loc) · 4.73 KB
/
routeable.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
package routeable
import (
"errors"
"net"
"strings"
"github.com/jackpal/gateway"
)
// TODO: android and ios need equivalent functions as gateway.DiscoverGateway
// Gateway stores the current network default gateway as discovered by
// github.com/jackpal/gateway
var Gateway net.IP
// Address is the network address that routes to the gateway and thus the
// internet
var Address net.IP
// IPNet is the subnet of the Gateway's LAN
var IPNet *net.IPNet
// Interface is the net.Interface of the Address above
var Interface *net.Interface
//
// // SecondaryAddresses are all the other addresses that can be reached from
// // somewhere (including localhost) but not necessarily the internet
// var SecondaryAddresses []net.IP
//
// // SecondaryInterfaces is the interfaces of the SecondaryAddresses stored in the
// // corresponding slice index
// var SecondaryInterfaces []*net.Interface
// GetAddressesAndInterfaces returns all of the addresses and interfaces that
// would be resolved from an automatic addresses that can connect two processes at all
func GetAddressesAndInterfaces() (
Interfaces []*net.Interface,
Addresses map[string]struct{},
) {
if Address == nil || Interface == nil {
if Discover() != nil {
E.Ln("no routeable address found")
}
}
Interfaces = append(Interfaces, Interface)
// Interfaces = append(Interfaces, SecondaryInterfaces...)
Addresses = make(map[string]struct{})
Addresses[Address.String()] = struct{}{}
// for i := range SecondaryAddresses {
// Addresses[SecondaryAddresses[i].String()] = struct{}{}
// }
// D.S(Interfaces)
// D.S(Addresses)
return
}
// Discover enumerates and evaluates all known network interfaces and addresses
// and filters it down to the ones that reach both a LAN and the internet
//
// We are only interested in IPv4 addresses because for the most part, domestic
// ISPs do not issue their customers with IPv6 routing, it's still a pain in the
// ass outside of large data centre connections
func Discover() (e error) {
D.Ln("discovering routeable interfaces and addresses...")
var nif []net.Interface
if nif, e = net.Interfaces(); E.Chk(e) {
return
}
// D.Ln("number of available network interfaces:", len(nif))
// D.S(nif)
var secondaryInterfaces []*net.Interface
var secondaryAddresses []net.IP
if Gateway, e = gateway.DiscoverGateway(); E.Chk(e) {
// todo: this error condition always happens on iOS and Android
// return
for i := range nif {
T.Ln(nif[i])
}
} else {
var gw net.IP
if Gateway != nil {
gws := Gateway.String()
gw = net.ParseIP(gws)
}
for i := range nif {
var addrs []net.Addr
if addrs, e = nif[i].Addrs(); E.Chk(e) || addrs == nil {
continue
}
for j := range addrs {
var in *net.IPNet
if _, in, e = net.ParseCIDR(addrs[j].String()); E.Chk(e) {
continue
}
if Gateway != nil && in.Contains(gw) {
Address = net.ParseIP(
strings.Split(
addrs[j].String(),
"/",
)[0],
)
Interface = &nif[i]
IPNet = in
continue
}
ip, _, _ := net.ParseCIDR(addrs[j].String())
if strings.HasPrefix(
ip.String(),
"169.",
) || strings.HasPrefix(ip.String(), "fe80:") {
continue
}
if strings.HasPrefix(
ip.String(),
"127.",
) || strings.HasPrefix(ip.String(), "::1") {
continue
}
secondaryAddresses = append(secondaryAddresses, ip)
secondaryInterfaces = append(secondaryInterfaces, &nif[i])
}
}
}
// SecondaryAddresses = secondaryAddresses
// SecondaryInterfaces = secondaryInterfaces
T.Ln("Gateway", Gateway)
T.Ln("Address", Address)
T.Ln("Interface", Interface.Name)
// T.Ln("SecondaryAddresses")
// for i := range SecondaryInterfaces {
// T.Ln(SecondaryInterfaces[i].Name, SecondaryAddresses[i].String())
// }
return
}
// GetInterface returns the address and interface of multicast-and-internet capable interfaces
func GetInterface() (ifc *net.Interface, address string, e error) {
if Address == nil || Interface == nil {
if Discover() != nil {
e = errors.New("no routeable address found")
return
}
}
address = Address.String()
ifc = Interface
return
}
func GetListenable() net.IP {
if Address == nil {
if Discover() != nil {
E.Ln("no routeable address found")
}
}
return Address
}
func GetAllInterfacesAndAddresses() (
interfaces []*net.Interface,
udpAddrs []*net.UDPAddr,
) {
if Discover() != nil {
E.Ln("no routeable address found")
return
}
interfaces = []*net.Interface{Interface}
naddrs := []net.IP{Address}
var addrs []*net.IP
for i := range naddrs {
addrs = append(addrs, &naddrs[i])
}
var e error
for i := range addrs {
var udpAddr *net.UDPAddr
if udpAddr, e = net.ResolveUDPAddr(
"udp",
addrs[i].String()+":0",
); !E.Chk(e) {
udpAddrs = append(udpAddrs, udpAddr)
}
}
return
}