diff --git a/disco/disco.go b/disco/disco.go index e7a629492..552684e73 100644 --- a/disco/disco.go +++ b/disco/disco.go @@ -25,8 +25,9 @@ import ( "fmt" "net" + "go4.org/mem" "inet.af/netaddr" - "tailscale.com/tailcfg" + "tailscale.com/types/key" ) // Magic is the 6 byte header of all discovery messages. @@ -115,19 +116,19 @@ type Ping struct { // It shouldn't be trusted by itself, but can be combined with // netmap data to reduce the discokey:nodekey relation from 1:N to // 1:1. - NodeKey tailcfg.NodeKey + NodeKey key.NodePublic } func (m *Ping) AppendMarshal(b []byte) []byte { dataLen := 12 hasKey := !m.NodeKey.IsZero() if hasKey { - dataLen += len(m.NodeKey) + dataLen += m.NodeKey.RawLen() } ret, d := appendMsgHeader(b, TypePing, v0, dataLen) n := copy(d, m.TxID[:]) if hasKey { - copy(d[n:], m.NodeKey[:]) + m.NodeKey.AppendTo(d[:n]) } return ret } @@ -138,8 +139,10 @@ func parsePing(ver uint8, p []byte) (m *Ping, err error) { } m = new(Ping) p = p[copy(m.TxID[:], p):] - if len(p) >= len(m.NodeKey) { - copy(m.NodeKey[:], p) + // Deliberately lax on longer-than-expected messages, for future + // compatibility. + if len(p) >= m.NodeKey.RawLen() { + m.NodeKey = key.NodePublicFromRaw32(mem.B(p[:m.NodeKey.RawLen()])) } return m, nil } diff --git a/disco/disco_test.go b/disco/disco_test.go index a02622d79..c1ec48af4 100644 --- a/disco/disco_test.go +++ b/disco/disco_test.go @@ -10,8 +10,9 @@ import ( "strings" "testing" + "go4.org/mem" "inet.af/netaddr" - "tailscale.com/tailcfg" + "tailscale.com/types/key" ) func TestMarshalAndParse(t *testing.T) { @@ -30,13 +31,8 @@ func TestMarshalAndParse(t *testing.T) { { name: "ping_with_nodekey_src", m: &Ping{ - TxID: [12]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, - NodeKey: tailcfg.NodeKey{ - 1: 1, - 2: 2, - 30: 30, - 31: 31, - }, + TxID: [12]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, + NodeKey: key.NodePublicFromRaw32(mem.B([]byte{1: 1, 2: 2, 30: 30, 31: 31})), }, want: "01 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 00 01 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1e 1f", }, diff --git a/wgengine/magicsock/magicsock.go b/wgengine/magicsock/magicsock.go index cf7eb122e..986603cf4 100644 --- a/wgengine/magicsock/magicsock.go +++ b/wgengine/magicsock/magicsock.go @@ -1936,8 +1936,8 @@ func (c *Conn) unambiguousNodeKeyOfPingLocked(dm *disco.Ping, dk key.DiscoPublic // Pings after 1.16.0 contains its node source. See if it maps back. if !dm.NodeKey.IsZero() { - if ep, ok := c.peerMap.endpointForNodeKey(dm.NodeKey); ok && ep.discoKey == dk { - return dm.NodeKey, true + if ep, ok := c.peerMap.endpointForNodeKey(dm.NodeKey.AsNodeKey()); ok && ep.discoKey == dk { + return dm.NodeKey.AsNodeKey(), true } } @@ -3507,7 +3507,7 @@ func (de *endpoint) sendDiscoPing(ep netaddr.IPPort, txid stun.TxID, logLevel di selfPubKey, _ := de.c.publicKeyAtomic.Load().(tailcfg.NodeKey) sent, _ := de.sendDiscoMessage(ep, &disco.Ping{ TxID: [12]byte(txid), - NodeKey: selfPubKey, + NodeKey: selfPubKey.AsNodePublic(), }, logLevel) if !sent { de.forgetPing(txid)