diff options
Diffstat (limited to 'conf/config.go')
-rw-r--r-- | conf/config.go | 170 |
1 files changed, 110 insertions, 60 deletions
diff --git a/conf/config.go b/conf/config.go index 5b3496b6..74ffacf6 100644 --- a/conf/config.go +++ b/conf/config.go @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: MIT * - * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. + * Copyright (C) 2019-2022 WireGuard LLC. All Rights Reserved. */ package conf @@ -9,30 +9,28 @@ import ( "crypto/rand" "crypto/subtle" "encoding/base64" - "encoding/hex" "fmt" - "net" + "net/netip" "strings" "time" "golang.org/x/crypto/curve25519" + + "golang.zx2c4.com/wireguard/windows/l18n" ) const KeyLength = 32 -type IPCidr struct { - IP net.IP - Cidr uint8 -} - type Endpoint struct { Host string Port uint16 } -type Key [KeyLength]byte -type HandshakeTime time.Duration -type Bytes uint64 +type ( + Key [KeyLength]byte + HandshakeTime time.Duration + Bytes uint64 +) type Config struct { Name string @@ -42,16 +40,22 @@ type Config struct { type Interface struct { PrivateKey Key - Addresses []IPCidr + Addresses []netip.Prefix ListenPort uint16 MTU uint16 - DNS []net.IP + DNS []netip.Addr + DNSSearch []string + PreUp string + PostUp string + PreDown string + PostDown string + TableOff bool } type Peer struct { PublicKey Key PresharedKey Key - AllowedIPs []IPCidr + AllowedIPs []netip.Prefix Endpoint Endpoint PersistentKeepalive uint16 @@ -60,26 +64,37 @@ type Peer struct { LastHandshakeTime HandshakeTime } -func (r *IPCidr) String() string { - return fmt.Sprintf("%s/%d", r.IP.String(), r.Cidr) -} - -func (r *IPCidr) Bits() uint8 { - if r.IP.To4() != nil { - return 32 +func (conf *Config) IntersectsWith(other *Config) bool { + allRoutes := make(map[netip.Prefix]bool, len(conf.Interface.Addresses)*2+len(conf.Peers)*3) + for _, a := range conf.Interface.Addresses { + allRoutes[netip.PrefixFrom(a.Addr(), a.Addr().BitLen())] = true + allRoutes[a.Masked()] = true } - return 128 -} - -func (r *IPCidr) IPNet() net.IPNet { - return net.IPNet{ - IP: r.IP, - Mask: net.CIDRMask(int(r.Cidr), int(r.Bits())), + for i := range conf.Peers { + for _, a := range conf.Peers[i].AllowedIPs { + allRoutes[a.Masked()] = true + } + } + for _, a := range other.Interface.Addresses { + if allRoutes[netip.PrefixFrom(a.Addr(), a.Addr().BitLen())] { + return true + } + if allRoutes[a.Masked()] { + return true + } } + for i := range other.Peers { + for _, a := range other.Peers[i].AllowedIPs { + if allRoutes[a.Masked()] { + return true + } + } + } + return false } func (e *Endpoint) String() string { - if strings.IndexByte(e.Host, ':') > 0 { + if strings.IndexByte(e.Host, ':') != -1 { return fmt.Sprintf("[%s]:%d", e.Host, e.Port) } return fmt.Sprintf("%s:%d", e.Host, e.Port) @@ -93,10 +108,6 @@ func (k *Key) String() string { return base64.StdEncoding.EncodeToString(k[:]) } -func (k *Key) HexString() string { - return hex.EncodeToString(k[:]) -} - func (k *Key) IsZero() bool { var zeros Key return subtle.ConstantTimeCompare(zeros[:], k[:]) == 1 @@ -131,18 +142,6 @@ func NewPrivateKeyFromString(b64 string) (*Key, error) { return parseKeyBase64(b64) } -func formatInterval(i int64, n string, l int) string { - r := "" - if l > 0 { - r += ", " - } - r += fmt.Sprintf("%d %s", i, n) - if i != 1 { - r += "s" - } - return r -} - func (t HandshakeTime) IsEmpty() bool { return t == HandshakeTime(0) } @@ -151,9 +150,9 @@ func (t HandshakeTime) String() string { u := time.Unix(0, 0).Add(time.Duration(t)).Unix() n := time.Now().Unix() if u == n { - return "Now" + return l18n.Sprintf("Now") } else if u > n { - return "System clock wound backward!" + return l18n.Sprintf("System clock wound backward!") } left := n - u years := left / (365 * 24 * 60 * 60) @@ -164,35 +163,86 @@ func (t HandshakeTime) String() string { left = left % (60 * 60) minutes := left / 60 seconds := left % 60 - s := "" + s := make([]string, 0, 5) if years > 0 { - s += formatInterval(years, "year", len(s)) + s = append(s, l18n.Sprintf("%d year(s)", years)) } if days > 0 { - s += formatInterval(days, "day", len(s)) + s = append(s, l18n.Sprintf("%d day(s)", days)) } if hours > 0 { - s += formatInterval(hours, "hour", len(s)) + s = append(s, l18n.Sprintf("%d hour(s)", hours)) } if minutes > 0 { - s += formatInterval(minutes, "minute", len(s)) + s = append(s, l18n.Sprintf("%d minute(s)", minutes)) } if seconds > 0 { - s += formatInterval(seconds, "second", len(s)) + s = append(s, l18n.Sprintf("%d second(s)", seconds)) } - s += " ago" - return s + timestamp := strings.Join(s, l18n.UnitSeparator()) + return l18n.Sprintf("%s ago", timestamp) } func (b Bytes) String() string { if b < 1024 { - return fmt.Sprintf("%d B", b) + return l18n.Sprintf("%d\u00a0B", b) } else if b < 1024*1024 { - return fmt.Sprintf("%.2f KiB", float64(b)/1024) + return l18n.Sprintf("%.2f\u00a0KiB", float64(b)/1024) } else if b < 1024*1024*1024 { - return fmt.Sprintf("%.2f MiB", float64(b)/(1024*1024)) + return l18n.Sprintf("%.2f\u00a0MiB", float64(b)/(1024*1024)) } else if b < 1024*1024*1024*1024 { - return fmt.Sprintf("%.2f GiB", float64(b)/(1024*1024*1024)) + return l18n.Sprintf("%.2f\u00a0GiB", float64(b)/(1024*1024*1024)) + } + return l18n.Sprintf("%.2f\u00a0TiB", float64(b)/(1024*1024*1024)/1024) +} + +func (conf *Config) DeduplicateNetworkEntries() { + m := make(map[string]bool, len(conf.Interface.Addresses)) + i := 0 + for _, addr := range conf.Interface.Addresses { + s := addr.String() + if m[s] { + continue + } + m[s] = true + conf.Interface.Addresses[i] = addr + i++ + } + conf.Interface.Addresses = conf.Interface.Addresses[:i] + + m = make(map[string]bool, len(conf.Interface.DNS)) + i = 0 + for _, addr := range conf.Interface.DNS { + s := addr.String() + if m[s] { + continue + } + m[s] = true + conf.Interface.DNS[i] = addr + i++ + } + conf.Interface.DNS = conf.Interface.DNS[:i] + + for _, peer := range conf.Peers { + m = make(map[string]bool, len(peer.AllowedIPs)) + i = 0 + for _, addr := range peer.AllowedIPs { + s := addr.String() + if m[s] { + continue + } + m[s] = true + peer.AllowedIPs[i] = addr + i++ + } + peer.AllowedIPs = peer.AllowedIPs[:i] + } +} + +func (conf *Config) Redact() { + conf.Interface.PrivateKey = Key{} + for i := range conf.Peers { + conf.Peers[i].PublicKey = Key{} + conf.Peers[i].PresharedKey = Key{} } - return fmt.Sprintf("%.2f TiB", float64(b)/(1024*1024*1024)/1024) } |