hostinfo, ipnlocal: flesh out Wake-on-LAN support, send MACs, add c2n sender

This optionally uploads MAC address(es) to control, then adds a
c2n handler so control can ask a node to send a WoL packet.

Updates #306

RELNOTE=now supports waking up peer nodes on your LAN via Wake-on-LAN packets

Change-Id: Ibea1275fcd2048dc61d7059039abfbaf1ad4f465
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick
2023-10-05 09:49:30 -07:00
committed by Brad Fitzpatrick
parent da1b917575
commit b4816e19b6
8 changed files with 183 additions and 9 deletions

View File

@@ -118,7 +118,8 @@ type CapabilityVersion int
// - 75: 2023-09-12: Client understands NodeAttrDNSForwarderDisableTCPRetries
// - 76: 2023-09-20: Client understands ExitNodeDNSResolvers for IsWireGuardOnly nodes
// - 77: 2023-10-03: Client understands Peers[].SelfNodeV6MasqAddrForThisPeer
const CurrentCapabilityVersion CapabilityVersion = 77
// - 78: 2023-10-05: can handle c2n Wake-on-LAN sending
const CurrentCapabilityVersion CapabilityVersion = 78
type StableID string
@@ -735,6 +736,7 @@ type Hostinfo struct {
GoVersion string `json:",omitempty"` // Go version binary was built with
RoutableIPs []netip.Prefix `json:",omitempty"` // set of IP ranges this client can route
RequestTags []string `json:",omitempty"` // set of ACL tags this node wants to claim
WoLMACs []string `json:",omitempty"` // MAC address(es) to send Wake-on-LAN packets to wake this node (lowercase hex w/ colons)
Services []Service `json:",omitempty"` // services advertised by this machine
NetInfo *NetInfo `json:",omitempty"`
SSH_HostKeys []string `json:"sshHostKeys,omitempty"` // if advertised

View File

@@ -131,6 +131,7 @@ func (src *Hostinfo) Clone() *Hostinfo {
*dst = *src
dst.RoutableIPs = append(src.RoutableIPs[:0:0], src.RoutableIPs...)
dst.RequestTags = append(src.RequestTags[:0:0], src.RequestTags...)
dst.WoLMACs = append(src.WoLMACs[:0:0], src.WoLMACs...)
dst.Services = append(src.Services[:0:0], src.Services...)
dst.NetInfo = src.NetInfo.Clone()
dst.SSH_HostKeys = append(src.SSH_HostKeys[:0:0], src.SSH_HostKeys...)
@@ -169,6 +170,7 @@ var _HostinfoCloneNeedsRegeneration = Hostinfo(struct {
GoVersion string
RoutableIPs []netip.Prefix
RequestTags []string
WoLMACs []string
Services []Service
NetInfo *NetInfo
SSH_HostKeys []string

View File

@@ -57,6 +57,7 @@ func TestHostinfoEqual(t *testing.T) {
"GoVersion",
"RoutableIPs",
"RequestTags",
"WoLMACs",
"Services",
"NetInfo",
"SSH_HostKeys",

View File

@@ -310,6 +310,7 @@ func (v HostinfoView) GoArchVar() string { return v.ж.GoAr
func (v HostinfoView) GoVersion() string { return v.ж.GoVersion }
func (v HostinfoView) RoutableIPs() views.Slice[netip.Prefix] { return views.SliceOf(v.ж.RoutableIPs) }
func (v HostinfoView) RequestTags() views.Slice[string] { return views.SliceOf(v.ж.RequestTags) }
func (v HostinfoView) WoLMACs() views.Slice[string] { return views.SliceOf(v.ж.WoLMACs) }
func (v HostinfoView) Services() views.Slice[Service] { return views.SliceOf(v.ж.Services) }
func (v HostinfoView) NetInfo() NetInfoView { return v.ж.NetInfo.View() }
func (v HostinfoView) SSH_HostKeys() views.Slice[string] { return views.SliceOf(v.ж.SSH_HostKeys) }
@@ -355,6 +356,7 @@ var _HostinfoViewNeedsRegeneration = Hostinfo(struct {
GoVersion string
RoutableIPs []netip.Prefix
RequestTags []string
WoLMACs []string
Services []Service
NetInfo *NetInfo
SSH_HostKeys []string