forked from mailgun/gubernator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnet.go
106 lines (97 loc) · 2.6 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
package gubernator
import (
"net"
"os"
"github.com/mailgun/holster/v4/slice"
"github.com/pkg/errors"
)
// If the passed address is "0.0.0.0" or "::" attempts to discover the actual ip address of the host
func ResolveHostIP(addr string) (string, error) {
if slice.ContainsString(addr, []string{"0.0.0.0", "::", "0:0:0:0:0:0:0:0"}, nil) {
// Use the hostname as the advertise address as it's most likely to be the external interface
domainName, err := os.Hostname()
if err != nil {
addr, err = discoverIP()
if err != nil {
return "", errors.Wrapf(err, "while discovering ip for '%s'", addr)
}
return addr, nil
}
addrs, err := net.LookupHost(domainName)
if err != nil {
return "", errors.Wrapf(err, "while preforming host lookup for '%s'", domainName)
}
if len(addrs) == 0 {
return "", errors.Wrapf(err, "net.LookupHost() returned no addresses for '%s'", domainName)
}
return addrs[0], nil
}
return addr, nil
}
type netInfo struct {
IPAddresses []string
DNSNames []string
}
// Attempts to discover all the external ips and dns names associated with the current host.
func discoverNetwork() (netInfo, error) {
var result netInfo
var err error
result.IPAddresses, err = discoverNetworkAddresses()
if err != nil {
return result, err
}
for _, ip := range result.IPAddresses {
records, _ := net.LookupAddr(ip)
result.DNSNames = append(result.DNSNames, records...)
}
return result, nil
}
// Returns the first external ip address it finds
func discoverIP() (string, error) {
addrs, err := discoverNetworkAddresses()
if err != nil {
return "", errors.Wrap(err, "while detecting external ip address")
}
if len(addrs) == 0 {
return "", errors.New("No external ip address found; please set `GUBER_ADVERTISE_ADDRESS`")
}
return addrs[0], err
}
// Returns a list of net addresses by inspecting the network interfaces on the current host.
func discoverNetworkAddresses() ([]string, error) {
var results []string
ifaces, err := net.Interfaces()
if err != nil {
return nil, err
}
for _, iface := range ifaces {
if iface.Flags&net.FlagUp == 0 {
continue // interface down
}
if iface.Flags&net.FlagLoopback != 0 {
continue // loopback interface
}
addrs, err := iface.Addrs()
if err != nil {
return nil, err
}
for _, addr := range addrs {
var ip net.IP
switch v := addr.(type) {
case *net.IPNet:
ip = v.IP
case *net.IPAddr:
ip = v.IP
}
if ip == nil || ip.IsLoopback() {
continue
}
ip = ip.To4()
if ip == nil {
continue // not an ipv4 address
}
results = append(results, ip.String())
}
}
return results, nil
}