|
@@ -6,6 +6,7 @@ package utils
|
6
|
6
|
|
7
|
7
|
import (
|
8
|
8
|
"net"
|
|
9
|
+ "regexp"
|
9
|
10
|
"strings"
|
10
|
11
|
)
|
11
|
12
|
|
|
@@ -13,6 +14,8 @@ var (
|
13
|
14
|
// subnet mask for an ipv6 /128:
|
14
|
15
|
mask128 = net.CIDRMask(128, 128)
|
15
|
16
|
IPv4LoopbackAddress = net.ParseIP("127.0.0.1").To16()
|
|
17
|
+
|
|
18
|
+ validHostnameLabelRegexp = regexp.MustCompile(`^[0-9A-Za-z.\-]+$`)
|
16
|
19
|
)
|
17
|
20
|
|
18
|
21
|
// AddrIsLocal returns whether the address is from a trusted local connection (loopback or unix).
|
|
@@ -49,12 +52,10 @@ func IPStringToHostname(ipStr string) string {
|
49
|
52
|
return ipStr
|
50
|
53
|
}
|
51
|
54
|
|
52
|
|
-var allowedHostnameChars = "abcdefghijklmnopqrstuvwxyz1234567890-."
|
53
|
|
-
|
54
|
55
|
// IsHostname returns whether we consider `name` a valid hostname.
|
55
|
56
|
func IsHostname(name string) bool {
|
56
|
|
- // IRC hostnames specifically require a period
|
57
|
|
- if !strings.Contains(name, ".") || len(name) < 1 || len(name) > 253 {
|
|
57
|
+ name = strings.TrimSuffix(name, ".")
|
|
58
|
+ if len(name) < 1 || len(name) > 253 {
|
58
|
59
|
return false
|
59
|
60
|
}
|
60
|
61
|
|
|
@@ -63,11 +64,7 @@ func IsHostname(name string) bool {
|
63
|
64
|
if len(part) < 1 || len(part) > 63 || strings.HasPrefix(part, "-") || strings.HasSuffix(part, "-") {
|
64
|
65
|
return false
|
65
|
66
|
}
|
66
|
|
- }
|
67
|
|
-
|
68
|
|
- // ensure all chars of hostname are valid
|
69
|
|
- for _, char := range strings.Split(strings.ToLower(name), "") {
|
70
|
|
- if !strings.Contains(allowedHostnameChars, char) {
|
|
67
|
+ if !validHostnameLabelRegexp.MatchString(part) {
|
71
|
68
|
return false
|
72
|
69
|
}
|
73
|
70
|
}
|
|
@@ -75,6 +72,12 @@ func IsHostname(name string) bool {
|
75
|
72
|
return true
|
76
|
73
|
}
|
77
|
74
|
|
|
75
|
+// IsServerName returns whether we consider `name` a valid IRC server name.
|
|
76
|
+func IsServerName(name string) bool {
|
|
77
|
+ // IRC server names specifically require a period
|
|
78
|
+ return IsHostname(name) && strings.IndexByte(name, '.') != -1
|
|
79
|
+}
|
|
80
|
+
|
78
|
81
|
// Convenience to test whether `ip` is contained in any of `nets`.
|
79
|
82
|
func IPInNets(ip net.IP, nets []net.IPNet) bool {
|
80
|
83
|
for _, network := range nets {
|