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 (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
|
@ -33,6 +34,8 @@ func TestDeepPrint(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var dummyHeyKey = strings.Repeat("0", wgcfg.HexKeyLen)
|
||||||
|
|
||||||
func getVal() []interface{} {
|
func getVal() []interface{} {
|
||||||
return []interface{}{
|
return []interface{}{
|
||||||
&wgcfg.Config{
|
&wgcfg.Config{
|
||||||
|
@ -41,7 +44,7 @@ func getVal() []interface{} {
|
||||||
ListenPort: 5,
|
ListenPort: 5,
|
||||||
Peers: []wgcfg.Peer{
|
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
|
// is running code that supports active discovery, so CreateEndpoint returns
|
||||||
// a discoEndpoint.
|
// a discoEndpoint.
|
||||||
//
|
//
|
||||||
|
|
||||||
func (c *Conn) CreateEndpoint(pubKey [32]byte, addrs string) (conn.Endpoint, error) {
|
func (c *Conn) CreateEndpoint(pubKey [32]byte, addrs string) (conn.Endpoint, error) {
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
|
|
|
@ -639,11 +639,11 @@ func isTrimmablePeer(p *wgcfg.Peer, numPeers int) bool {
|
||||||
if forceFullWireguardConfig(numPeers) {
|
if forceFullWireguardConfig(numPeers) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if !isSingleEndpoint(p.Endpoints) {
|
if !isSingleEndpoint(p.Endpoints2) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
host, _, err := net.SplitHostPort(p.Endpoints)
|
host, _, err := splitEndpointHostPort(p.Endpoints2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
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.
|
// isSingleEndpoint reports whether endpoints contains exactly one host:port pair.
|
||||||
func isSingleEndpoint(s string) bool {
|
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 {
|
func (e *userspaceEngine) GetFilter() *filter.Filter {
|
||||||
|
|
|
@ -27,12 +27,21 @@ type Config struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Peer struct {
|
type Peer struct {
|
||||||
PublicKey Key
|
PublicKey Key
|
||||||
AllowedIPs []netaddr.IPPrefix
|
AllowedIPs []netaddr.IPPrefix
|
||||||
Endpoints string // comma-separated host/port pairs: "1.2.3.4:56,[::]:80"
|
// 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
|
PersistentKeepalive uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
HexKeyLength = KeySize * 2 // KeySize when encoded as hex bytes
|
||||||
|
HexKeyPrefixLen = HexKeyLength + len("@")
|
||||||
|
)
|
||||||
|
|
||||||
// Copy makes a deep copy of Config.
|
// Copy makes a deep copy of Config.
|
||||||
// The result aliases no memory with the original.
|
// The result aliases no memory with the original.
|
||||||
func (cfg Config) Copy() Config {
|
func (cfg Config) Copy() Config {
|
||||||
|
|
|
@ -51,7 +51,7 @@ func cidrIsSubnet(node *tailcfg.Node, cidr netaddr.IPPrefix) bool {
|
||||||
return true
|
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) {
|
func WGCfg(nm *netmap.NetworkMap, logf logger.Logf, flags netmap.WGConfigFlags, exitNode tailcfg.StableNodeID) (*wgcfg.Config, error) {
|
||||||
cfg := &wgcfg.Config{
|
cfg := &wgcfg.Config{
|
||||||
Name: "tailscale",
|
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 {
|
if err := appendEndpoint(cpeer, fmt.Sprintf("%x%s", peer.DiscoKey[:], wgcfg.EndpointDiscoSuffix)); err != nil {
|
||||||
return nil, err
|
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 {
|
} else {
|
||||||
if err := appendEndpoint(cpeer, peer.DERP); err != nil {
|
if err := appendEndpoint(cpeer, peer.DERP); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -122,9 +122,11 @@ func appendEndpoint(peer *wgcfg.Peer, epStr string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid port in endpoint %q for peer %v", epStr, peer.PublicKey.ShortString())
|
return fmt.Errorf("invalid port in endpoint %q for peer %v", epStr, peer.PublicKey.ShortString())
|
||||||
}
|
}
|
||||||
if peer.Endpoints != "" {
|
if peer.Endpoints2 == "" {
|
||||||
peer.Endpoints += ","
|
peer.Endpoints2 = peer.PublicKey.HexString() + "@"
|
||||||
|
} else {
|
||||||
|
peer.Endpoints2 += ","
|
||||||
}
|
}
|
||||||
peer.Endpoints += epStr
|
peer.Endpoints2 += epStr
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -175,7 +175,7 @@ func (cfg *Config) handlePeerLine(peer *Peer, key, value string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
peer.Endpoints = value
|
peer.Endpoints2 = peer.PublicKey.HexString() + "@" + value
|
||||||
case "persistent_keepalive_interval":
|
case "persistent_keepalive_interval":
|
||||||
n, err := strconv.ParseUint(value, 10, 16)
|
n, err := strconv.ParseUint(value, 10, 16)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -55,8 +55,8 @@ func (cfg *Config) ToUAPI(w io.Writer, prev *Config) error {
|
||||||
setPeer(p)
|
setPeer(p)
|
||||||
set("protocol_version", "1")
|
set("protocol_version", "1")
|
||||||
|
|
||||||
if !endpointsEqual(oldPeer.Endpoints, p.Endpoints) {
|
if !endpointsEqual(oldPeer.Endpoints2, p.Endpoints2) {
|
||||||
set("endpoint", p.Endpoints)
|
set("endpoint", p.Endpoints2)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: replace_allowed_ips is expensive.
|
// TODO: replace_allowed_ips is expensive.
|
||||||
|
@ -97,12 +97,18 @@ func endpointsEqual(x, y string) bool {
|
||||||
if x == y {
|
if x == y {
|
||||||
return true
|
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, ",")
|
xs := strings.Split(x, ",")
|
||||||
ys := strings.Split(y, ",")
|
ys := strings.Split(y, ",")
|
||||||
if len(xs) != len(ys) {
|
if len(xs) != len(ys) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// Otherwise, see if they're the same, but out of order.
|
|
||||||
sort.Strings(xs)
|
sort.Strings(xs)
|
||||||
sort.Strings(ys)
|
sort.Strings(ys)
|
||||||
x = strings.Join(xs, ",")
|
x = strings.Join(xs, ",")
|
||||||
|
|
Loading…
Reference in New Issue