-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathdns.go
73 lines (62 loc) · 1.89 KB
/
dns.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
// Copyright (c) Roman Atachiants and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
package address
import (
"errors"
"fmt"
"net"
"net/url"
"strconv"
"strings"
)
// Resolve resolves the addresses behind a hostname or a URL. This supports
// only TCP (as pretty much everything in the package) but can handle a URL
// passed instead of the name (e.g. https://example.com).
func Resolve(name string, defaultPort int) ([]net.TCPAddr, error) {
if name == "" {
return nil, errors.New("unable to resolve an empty name or url")
}
// First we need to check whether the address is a valid IPv4 or IPv6 address
if ip := net.ParseIP(name); ip != nil {
return []net.TCPAddr{{IP: ip, Port: defaultPort}}, nil
}
// If this is not a url, add a scheme to make it a URL.
if !strings.Contains(name, "://") {
name = "tcp://" + name
}
// Check if this is a valid url, then adjust port and hostname
port := defaultPort
url, err := url.Parse(name)
if err != nil {
return nil, err
}
// The hostname might not be there (if it's an address)
if url.Hostname() != "" && url.Hostname() != "::" {
name = url.Hostname()
}
// If we have a port on the url, use that as well
if url.Port() != "" {
urlPort, err := strconv.Atoi(url.Port())
if err != nil {
return nil, err
}
port = urlPort
}
// If we can parse the address, we can just return ip/port combination
if ip := net.ParseIP(name); ip != nil {
return []net.TCPAddr{{IP: ip, Port: port}}, nil
}
// Get the addresses by performing a DNS lookup, this should not fail
addr, err := net.LookupHost(name)
if err != nil {
return nil, err
}
// Add port to each address
var addrs []net.TCPAddr
for _, a := range addr {
if resolved, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", a, port)); err == nil {
addrs = append(addrs, *resolved)
}
}
return addrs, nil
}