mirror of
https://github.com/tailscale/tailscale.git
synced 2025-12-01 09:32:08 +00:00
wgengine/wgcfg: convert to use new node key type.
Updates #3206 Signed-off-by: David Anderson <danderson@tailscale.com>
This commit is contained in:
committed by
Dave Anderson
parent
a47158e14d
commit
a9c78910bd
@@ -10,7 +10,7 @@ package wgcfg
|
||||
import (
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/wgkey"
|
||||
"tailscale.com/types/key"
|
||||
)
|
||||
|
||||
// Clone makes a deep copy of Config.
|
||||
@@ -33,7 +33,7 @@ func (src *Config) Clone() *Config {
|
||||
// A compilation failure here means this code must be regenerated, with the command at the top of this file.
|
||||
var _ConfigCloneNeedsRegeneration = Config(struct {
|
||||
Name string
|
||||
PrivateKey wgkey.Private
|
||||
PrivateKey key.NodePrivate
|
||||
Addresses []netaddr.IPPrefix
|
||||
MTU uint16
|
||||
DNS []netaddr.IP
|
||||
@@ -54,7 +54,7 @@ func (src *Peer) Clone() *Peer {
|
||||
|
||||
// A compilation failure here means this code must be regenerated, with the command at the top of this file.
|
||||
var _PeerCloneNeedsRegeneration = Peer(struct {
|
||||
PublicKey wgkey.Key
|
||||
PublicKey key.NodePublic
|
||||
DiscoKey tailcfg.DiscoKey
|
||||
AllowedIPs []netaddr.IPPrefix
|
||||
PersistentKeepalive uint16
|
||||
|
||||
@@ -8,7 +8,7 @@ package wgcfg
|
||||
import (
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/wgkey"
|
||||
"tailscale.com/types/key"
|
||||
)
|
||||
|
||||
//go:generate go run tailscale.com/cmd/cloner -type=Config,Peer -output=clone.go
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
// It only supports the set of things Tailscale uses.
|
||||
type Config struct {
|
||||
Name string
|
||||
PrivateKey wgkey.Private
|
||||
PrivateKey key.NodePrivate
|
||||
Addresses []netaddr.IPPrefix
|
||||
MTU uint16
|
||||
DNS []netaddr.IP
|
||||
@@ -25,14 +25,14 @@ type Config struct {
|
||||
}
|
||||
|
||||
type Peer struct {
|
||||
PublicKey wgkey.Key
|
||||
PublicKey key.NodePublic
|
||||
DiscoKey tailcfg.DiscoKey // present only so we can handle restarts within wgengine, not passed to WireGuard
|
||||
AllowedIPs []netaddr.IPPrefix
|
||||
PersistentKeepalive uint16
|
||||
}
|
||||
|
||||
// PeerWithKey returns the Peer with key k and reports whether it was found.
|
||||
func (config Config) PeerWithKey(k wgkey.Key) (Peer, bool) {
|
||||
func (config Config) PeerWithKey(k key.NodePublic) (Peer, bool) {
|
||||
for _, p := range config.Peers {
|
||||
if p.PublicKey == k {
|
||||
return p, true
|
||||
|
||||
@@ -29,7 +29,7 @@ func DeviceConfig(d *device.Device) (*Config, error) {
|
||||
return nil, err
|
||||
}
|
||||
sort.Slice(cfg.Peers, func(i, j int) bool {
|
||||
return cfg.Peers[i].PublicKey.LessThan(&cfg.Peers[j].PublicKey)
|
||||
return cfg.Peers[i].PublicKey.Less(cfg.Peers[j].PublicKey)
|
||||
})
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
@@ -20,29 +20,26 @@ import (
|
||||
"golang.zx2c4.com/wireguard/tun"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/wgkey"
|
||||
"tailscale.com/types/key"
|
||||
)
|
||||
|
||||
func TestDeviceConfig(t *testing.T) {
|
||||
newPrivateKey := func() (wgkey.Key, wgkey.Private) {
|
||||
newK := func() (key.NodePublic, key.NodePrivate) {
|
||||
t.Helper()
|
||||
pk, err := wgkey.NewPrivate()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return wgkey.Key(pk.Public()), wgkey.Private(pk)
|
||||
k := key.NewNode()
|
||||
return k.Public(), k
|
||||
}
|
||||
k1, pk1 := newPrivateKey()
|
||||
k1, pk1 := newK()
|
||||
ip1 := netaddr.MustParseIPPrefix("10.0.0.1/32")
|
||||
|
||||
k2, pk2 := newPrivateKey()
|
||||
k2, pk2 := newK()
|
||||
ip2 := netaddr.MustParseIPPrefix("10.0.0.2/32")
|
||||
|
||||
k3, _ := newPrivateKey()
|
||||
k3, _ := newK()
|
||||
ip3 := netaddr.MustParseIPPrefix("10.0.0.3/32")
|
||||
|
||||
cfg1 := &Config{
|
||||
PrivateKey: wgkey.Private(pk1),
|
||||
PrivateKey: pk1,
|
||||
Peers: []Peer{{
|
||||
PublicKey: k2,
|
||||
AllowedIPs: []netaddr.IPPrefix{ip2},
|
||||
@@ -50,7 +47,7 @@ func TestDeviceConfig(t *testing.T) {
|
||||
}
|
||||
|
||||
cfg2 := &Config{
|
||||
PrivateKey: wgkey.Private(pk2),
|
||||
PrivateKey: pk2,
|
||||
Peers: []Peer{{
|
||||
PublicKey: k1,
|
||||
AllowedIPs: []netaddr.IPPrefix{ip1},
|
||||
@@ -149,7 +146,7 @@ func TestDeviceConfig(t *testing.T) {
|
||||
AllowedIPs: []netaddr.IPPrefix{ip3},
|
||||
})
|
||||
sort.Slice(cfg1.Peers, func(i, j int) bool {
|
||||
return cfg1.Peers[i].PublicKey.LessThan(&cfg1.Peers[j].PublicKey)
|
||||
return cfg1.Peers[i].PublicKey.Less(cfg1.Peers[j].PublicKey)
|
||||
})
|
||||
|
||||
origCfg, err := DeviceConfig(device1)
|
||||
|
||||
@@ -10,12 +10,13 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"go4.org/mem"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/key"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/types/netmap"
|
||||
"tailscale.com/types/wgkey"
|
||||
"tailscale.com/wgengine/wgcfg"
|
||||
)
|
||||
|
||||
@@ -54,7 +55,7 @@ func cidrIsSubnet(node *tailcfg.Node, cidr netaddr.IPPrefix) bool {
|
||||
func WGCfg(nm *netmap.NetworkMap, logf logger.Logf, flags netmap.WGConfigFlags, exitNode tailcfg.StableNodeID) (*wgcfg.Config, error) {
|
||||
cfg := &wgcfg.Config{
|
||||
Name: "tailscale",
|
||||
PrivateKey: wgkey.Private(nm.PrivateKey),
|
||||
PrivateKey: key.NodePrivateFromRaw32(mem.B(nm.PrivateKey[:])),
|
||||
Addresses: nm.Addresses,
|
||||
Peers: make([]wgcfg.Peer, 0, len(nm.Peers)),
|
||||
}
|
||||
@@ -72,7 +73,7 @@ func WGCfg(nm *netmap.NetworkMap, logf logger.Logf, flags netmap.WGConfigFlags,
|
||||
continue
|
||||
}
|
||||
cfg.Peers = append(cfg.Peers, wgcfg.Peer{
|
||||
PublicKey: wgkey.Key(peer.Key),
|
||||
PublicKey: key.NodePublicFromRaw32(mem.B(peer.Key[:])),
|
||||
DiscoKey: peer.DiscoKey,
|
||||
})
|
||||
cpeer := &cfg.Peers[len(cfg.Peers)-1]
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
|
||||
"go4.org/mem"
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/types/key"
|
||||
"tailscale.com/types/wgkey"
|
||||
)
|
||||
|
||||
@@ -128,71 +129,70 @@ func parseKeyHex(s []byte, dst []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cfg *Config) handleDeviceLine(key, value mem.RO, valueBytes []byte) error {
|
||||
func (cfg *Config) handleDeviceLine(k, value mem.RO, valueBytes []byte) error {
|
||||
switch {
|
||||
case key.EqualString("private_key"):
|
||||
case k.EqualString("private_key"):
|
||||
// wireguard-go guarantees not to send zero value; private keys are already clamped.
|
||||
if err := parseKeyHex(valueBytes, cfg.PrivateKey[:]); err != nil {
|
||||
var err error
|
||||
cfg.PrivateKey, err = key.ParseNodePrivateUntyped(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case key.EqualString("listen_port") || key.EqualString("fwmark"):
|
||||
case k.EqualString("listen_port") || k.EqualString("fwmark"):
|
||||
// ignore
|
||||
default:
|
||||
return fmt.Errorf("unexpected IpcGetOperation key: %q", key.StringCopy())
|
||||
return fmt.Errorf("unexpected IpcGetOperation key: %q", k.StringCopy())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cfg *Config) handlePublicKeyLine(valueBytes []byte) (*Peer, error) {
|
||||
p := Peer{}
|
||||
if err := parseKeyHex(valueBytes, p.PublicKey[:]); err != nil {
|
||||
var err error
|
||||
p.PublicKey, err = key.ParseNodePublicUntyped(mem.B(valueBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cfg.Peers = append(cfg.Peers, p)
|
||||
return &cfg.Peers[len(cfg.Peers)-1], nil
|
||||
}
|
||||
|
||||
func (cfg *Config) handlePeerLine(peer *Peer, key, value mem.RO, valueBytes []byte) error {
|
||||
func (cfg *Config) handlePeerLine(peer *Peer, k, value mem.RO, valueBytes []byte) error {
|
||||
switch {
|
||||
case key.EqualString("endpoint"):
|
||||
// TODO: our key types are all over the place, and this
|
||||
// particular one can't parse a mem.RO or a []byte without
|
||||
// allocating. We don't reconfigure wireguard often though, so
|
||||
// this is okay.
|
||||
s := value.StringCopy()
|
||||
k, err := wgkey.ParseHex(s)
|
||||
case k.EqualString("endpoint"):
|
||||
nk, err := key.ParseNodePublicUntyped(value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid endpoint %q for peer %q, expected a hex public key", s, peer.PublicKey.ShortString())
|
||||
return fmt.Errorf("invalid endpoint %q for peer %q, expected a hex public key", value.StringCopy(), peer.PublicKey.ShortString())
|
||||
}
|
||||
if k != peer.PublicKey {
|
||||
return fmt.Errorf("unexpected endpoint %q for peer %q, expected the peer's public key", s, peer.PublicKey.ShortString())
|
||||
if nk != peer.PublicKey {
|
||||
return fmt.Errorf("unexpected endpoint %q for peer %q, expected the peer's public key", value.StringCopy(), peer.PublicKey.ShortString())
|
||||
}
|
||||
case key.EqualString("persistent_keepalive_interval"):
|
||||
case k.EqualString("persistent_keepalive_interval"):
|
||||
n, err := mem.ParseUint(value, 10, 16)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
peer.PersistentKeepalive = uint16(n)
|
||||
case key.EqualString("allowed_ip"):
|
||||
case k.EqualString("allowed_ip"):
|
||||
ipp := netaddr.IPPrefix{}
|
||||
err := ipp.UnmarshalText(valueBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
peer.AllowedIPs = append(peer.AllowedIPs, ipp)
|
||||
case key.EqualString("protocol_version"):
|
||||
case k.EqualString("protocol_version"):
|
||||
if !value.EqualString("1") {
|
||||
return fmt.Errorf("invalid protocol version: %q", value.StringCopy())
|
||||
}
|
||||
case key.EqualString("replace_allowed_ips") ||
|
||||
key.EqualString("preshared_key") ||
|
||||
key.EqualString("last_handshake_time_sec") ||
|
||||
key.EqualString("last_handshake_time_nsec") ||
|
||||
key.EqualString("tx_bytes") ||
|
||||
key.EqualString("rx_bytes"):
|
||||
case k.EqualString("replace_allowed_ips") ||
|
||||
k.EqualString("preshared_key") ||
|
||||
k.EqualString("last_handshake_time_sec") ||
|
||||
k.EqualString("last_handshake_time_nsec") ||
|
||||
k.EqualString("tx_bytes") ||
|
||||
k.EqualString("rx_bytes"):
|
||||
// ignore
|
||||
default:
|
||||
return fmt.Errorf("unexpected IpcGetOperation key: %q", key.StringCopy())
|
||||
return fmt.Errorf("unexpected IpcGetOperation key: %q", k.StringCopy())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/types/wgkey"
|
||||
"tailscale.com/types/key"
|
||||
)
|
||||
|
||||
func noError(t *testing.T, err error) bool {
|
||||
@@ -61,15 +61,12 @@ func TestParseEndpoint(t *testing.T) {
|
||||
}
|
||||
|
||||
func BenchmarkFromUAPI(b *testing.B) {
|
||||
newPrivateKey := func() (wgkey.Key, wgkey.Private) {
|
||||
newK := func() (key.NodePublic, key.NodePrivate) {
|
||||
b.Helper()
|
||||
pk, err := wgkey.NewPrivate()
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
return wgkey.Key(pk.Public()), wgkey.Private(pk)
|
||||
k := key.NewNode()
|
||||
return k.Public(), k
|
||||
}
|
||||
k1, pk1 := newPrivateKey()
|
||||
k1, pk1 := newK()
|
||||
ip1 := netaddr.MustParseIPPrefix("10.0.0.1/32")
|
||||
|
||||
peer := Peer{
|
||||
@@ -77,7 +74,7 @@ func BenchmarkFromUAPI(b *testing.B) {
|
||||
AllowedIPs: []netaddr.IPPrefix{ip1},
|
||||
}
|
||||
cfg1 := &Config{
|
||||
PrivateKey: wgkey.Private(pk1),
|
||||
PrivateKey: pk1,
|
||||
Peers: []Peer{peer, peer, peer, peer},
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"strconv"
|
||||
|
||||
"inet.af/netaddr"
|
||||
"tailscale.com/types/wgkey"
|
||||
"tailscale.com/types/key"
|
||||
)
|
||||
|
||||
// ToUAPI writes cfg in UAPI format to w.
|
||||
@@ -32,15 +32,15 @@ func (cfg *Config) ToUAPI(w io.Writer, prev *Config) error {
|
||||
set(key, strconv.FormatUint(uint64(value), 10))
|
||||
}
|
||||
setPeer := func(peer Peer) {
|
||||
set("public_key", peer.PublicKey.HexString())
|
||||
set("public_key", peer.PublicKey.UntypedHexString())
|
||||
}
|
||||
|
||||
// Device config.
|
||||
if prev.PrivateKey != cfg.PrivateKey {
|
||||
set("private_key", cfg.PrivateKey.HexString())
|
||||
if !prev.PrivateKey.Equal(cfg.PrivateKey) {
|
||||
set("private_key", cfg.PrivateKey.UntypedHexString())
|
||||
}
|
||||
|
||||
old := make(map[wgkey.Key]Peer)
|
||||
old := make(map[key.NodePublic]Peer)
|
||||
for _, p := range prev.Peers {
|
||||
old[p.PublicKey] = p
|
||||
}
|
||||
@@ -55,7 +55,7 @@ func (cfg *Config) ToUAPI(w io.Writer, prev *Config) error {
|
||||
// to WireGuard, because doing so generates a bit more work in
|
||||
// calling magicsock's ParseEndpoint for effectively a no-op.
|
||||
if !wasPresent {
|
||||
set("endpoint", p.PublicKey.HexString())
|
||||
set("endpoint", p.PublicKey.UntypedHexString())
|
||||
}
|
||||
|
||||
// TODO: replace_allowed_ips is expensive.
|
||||
|
||||
Reference in New Issue
Block a user