disco, wgengine/magicsock: send self node key in disco pings

This lets clients quickly (sub-millisecond within a local LAN) map
from an ambiguous disco key to a node key without waiting for a
CallMeMaybe (over relatively high latency DERP).

Updates #3088

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
(cherry picked from commit 75a7779b42)
This commit is contained in:
Brad Fitzpatrick
2021-10-16 14:55:26 -07:00
parent 76ad9d7a7a
commit ac4cda9303
3 changed files with 50 additions and 5 deletions

View File

@@ -26,6 +26,7 @@ import (
"net"
"inet.af/netaddr"
"tailscale.com/tailcfg"
)
// Magic is the 6 byte header of all discovery messages.
@@ -106,12 +107,28 @@ func appendMsgHeader(b []byte, t MessageType, ver uint8, dataLen int) (all, data
}
type Ping struct {
// TxID is a random client-generated per-ping transaction ID.
TxID [12]byte
// NodeKey is the ping sender's wireguard public key. Old
// clients (~1.16.0 and earlier) don't send this field. It
// shouldn't be trusted by itself. But if present and the
// netmap's peer for this NodeKey's DiscoKey matches the
// sender of this disco key, they it can be.
NodeKey tailcfg.NodeKey
}
func (m *Ping) AppendMarshal(b []byte) []byte {
ret, d := appendMsgHeader(b, TypePing, v0, 12)
copy(d, m.TxID[:])
dataLen := 12
hasKey := !m.NodeKey.IsZero()
if hasKey {
dataLen += len(m.NodeKey)
}
ret, d := appendMsgHeader(b, TypePing, v0, dataLen)
n := copy(d, m.TxID[:])
if hasKey {
copy(d[n:], m.NodeKey[:])
}
return ret
}
@@ -120,7 +137,10 @@ func parsePing(ver uint8, p []byte) (m *Ping, err error) {
return nil, errShort
}
m = new(Ping)
copy(m.TxID[:], p)
p = p[copy(m.TxID[:], p):]
if len(p) >= len(m.NodeKey) {
copy(m.NodeKey[:], p)
}
return m, nil
}

View File

@@ -11,6 +11,7 @@ import (
"testing"
"inet.af/netaddr"
"tailscale.com/tailcfg"
)
func TestMarshalAndParse(t *testing.T) {
@@ -26,6 +27,19 @@ func TestMarshalAndParse(t *testing.T) {
},
want: "01 00 01 02 03 04 05 06 07 08 09 0a 0b 0c",
},
{
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,
},
},
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",
},
{
name: "pong",
m: &Pong{