WIP: encode peer public key in endpoint
incomplete new idea is to make a new type in wgcfg an Endpoints type that can be serialized/deserialized nicely at the edges and be easy to deal with other places.josh/wip/create-endpoint-no-public-key
parent
4954fbfda6
commit
969a8540e2
|
@ -6,6 +6,7 @@ package deepprint
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"inet.af/netaddr"
|
||||
|
@ -33,6 +34,8 @@ func TestDeepPrint(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
var dummyHeyKey = strings.Repeat("0", wgcfg.HexKeyLen)
|
||||
|
||||
func getVal() []interface{} {
|
||||
return []interface{}{
|
||||
&wgcfg.Config{
|
||||
|
@ -41,7 +44,7 @@ func getVal() []interface{} {
|
|||
ListenPort: 5,
|
||||
Peers: []wgcfg.Peer{
|
||||
{
|
||||
Endpoints: "foo:5",
|
||||
Endpoints2: dummyHeyKey + "@foo:5",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -2745,7 +2745,6 @@ func (c *Conn) CreateBind(uint16) (conn.Bind, uint16, error) {
|
|||
// is running code that supports active discovery, so CreateEndpoint returns
|
||||
// a discoEndpoint.
|
||||
//
|
||||
|
||||
func (c *Conn) CreateEndpoint(pubKey [32]byte, addrs string) (conn.Endpoint, error) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
|
|
@ -639,11 +639,11 @@ func isTrimmablePeer(p *wgcfg.Peer, numPeers int) bool {
|
|||
if forceFullWireguardConfig(numPeers) {
|
||||
return false
|
||||
}
|
||||
if !isSingleEndpoint(p.Endpoints) {
|
||||
if !isSingleEndpoint(p.Endpoints2) {
|
||||
return false
|
||||
}
|
||||
|
||||
host, _, err := net.SplitHostPort(p.Endpoints)
|
||||
host, _, err := splitEndpointHostPort(p.Endpoints2)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
@ -986,7 +986,13 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config)
|
|||
|
||||
// isSingleEndpoint reports whether endpoints contains exactly one host:port pair.
|
||||
func isSingleEndpoint(s string) bool {
|
||||
return s != "" && !strings.Contains(s, ",")
|
||||
return len(s) > wgcfg.HexKeyPrefixLen && !strings.Contains(s, ",")
|
||||
}
|
||||
|
||||
// splitEndpointHostPort returns net.SplitHostPort of the sole endpoint in s.
|
||||
func splitEndpointHostPort(s string) (host, port string, err error) {
|
||||
ep := s[wgcfg.HexKeyPrefixLen:]
|
||||
return net.SplitHostPort(ep)
|
||||
}
|
||||
|
||||
func (e *userspaceEngine) GetFilter() *filter.Filter {
|
||||
|
|
|
@ -27,12 +27,21 @@ type Config struct {
|
|||
}
|
||||
|
||||
type Peer struct {
|
||||
PublicKey Key
|
||||
AllowedIPs []netaddr.IPPrefix
|
||||
Endpoints string // comma-separated host/port pairs: "1.2.3.4:56,[::]:80"
|
||||
PublicKey Key
|
||||
AllowedIPs []netaddr.IPPrefix
|
||||
// Endpoints encodes information about the Peer.
|
||||
// It has the form: "<HEXKEY>@1.2.3.4:56,[::]:80".
|
||||
// The first 65 bytes are a hex-encoded public key, then '@'.
|
||||
// The remainder is a comma-separated list of host/port pairs.
|
||||
Endpoints2 string
|
||||
PersistentKeepalive uint16
|
||||
}
|
||||
|
||||
const (
|
||||
HexKeyLength = KeySize * 2 // KeySize when encoded as hex bytes
|
||||
HexKeyPrefixLen = HexKeyLength + len("@")
|
||||
)
|
||||
|
||||
// Copy makes a deep copy of Config.
|
||||
// The result aliases no memory with the original.
|
||||
func (cfg Config) Copy() Config {
|
||||
|
|
|
@ -51,7 +51,7 @@ func cidrIsSubnet(node *tailcfg.Node, cidr netaddr.IPPrefix) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// WGCfg returns the NetworkMaps's Wireguard configuration.
|
||||
// WGCfg returns the NetworkMaps's WireGuard configuration.
|
||||
func WGCfg(nm *netmap.NetworkMap, logf logger.Logf, flags netmap.WGConfigFlags, exitNode tailcfg.StableNodeID) (*wgcfg.Config, error) {
|
||||
cfg := &wgcfg.Config{
|
||||
Name: "tailscale",
|
||||
|
@ -77,7 +77,7 @@ func WGCfg(nm *netmap.NetworkMap, logf logger.Logf, flags netmap.WGConfigFlags,
|
|||
if err := appendEndpoint(cpeer, fmt.Sprintf("%x%s", peer.DiscoKey[:], wgcfg.EndpointDiscoSuffix)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cpeer.Endpoints = fmt.Sprintf("%x.disco.tailscale:12345", peer.DiscoKey[:])
|
||||
cpeer.Endpoints2 = fmt.Sprintf("%x@%x.disco.tailscale:12345", peer.Key, peer.DiscoKey[:])
|
||||
} else {
|
||||
if err := appendEndpoint(cpeer, peer.DERP); err != nil {
|
||||
return nil, err
|
||||
|
@ -122,9 +122,11 @@ func appendEndpoint(peer *wgcfg.Peer, epStr string) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("invalid port in endpoint %q for peer %v", epStr, peer.PublicKey.ShortString())
|
||||
}
|
||||
if peer.Endpoints != "" {
|
||||
peer.Endpoints += ","
|
||||
if peer.Endpoints2 == "" {
|
||||
peer.Endpoints2 = peer.PublicKey.HexString() + "@"
|
||||
} else {
|
||||
peer.Endpoints2 += ","
|
||||
}
|
||||
peer.Endpoints += epStr
|
||||
peer.Endpoints2 += epStr
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -175,7 +175,7 @@ func (cfg *Config) handlePeerLine(peer *Peer, key, value string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
peer.Endpoints = value
|
||||
peer.Endpoints2 = peer.PublicKey.HexString() + "@" + value
|
||||
case "persistent_keepalive_interval":
|
||||
n, err := strconv.ParseUint(value, 10, 16)
|
||||
if err != nil {
|
||||
|
|
|
@ -55,8 +55,8 @@ func (cfg *Config) ToUAPI(w io.Writer, prev *Config) error {
|
|||
setPeer(p)
|
||||
set("protocol_version", "1")
|
||||
|
||||
if !endpointsEqual(oldPeer.Endpoints, p.Endpoints) {
|
||||
set("endpoint", p.Endpoints)
|
||||
if !endpointsEqual(oldPeer.Endpoints2, p.Endpoints2) {
|
||||
set("endpoint", p.Endpoints2)
|
||||
}
|
||||
|
||||
// TODO: replace_allowed_ips is expensive.
|
||||
|
@ -97,12 +97,18 @@ func endpointsEqual(x, y string) bool {
|
|||
if x == y {
|
||||
return true
|
||||
}
|
||||
// Public keys must match.
|
||||
if x[:HexKeyPrefixLen] != y[:HexKeyPrefixLen] {
|
||||
return false
|
||||
}
|
||||
// See whether the addresses are the same, but out of order.
|
||||
x = x[HexKeyPrefixLen:]
|
||||
y = y[HexKeyPrefixLen:]
|
||||
xs := strings.Split(x, ",")
|
||||
ys := strings.Split(y, ",")
|
||||
if len(xs) != len(ys) {
|
||||
return false
|
||||
}
|
||||
// Otherwise, see if they're the same, but out of order.
|
||||
sort.Strings(xs)
|
||||
sort.Strings(ys)
|
||||
x = strings.Join(xs, ",")
|
||||
|
|
Loading…
Reference in New Issue