mirror of
https://github.com/tailscale/tailscale.git
synced 2025-04-16 03:31:39 +00:00
wgengine/userspace: delete HandshakeDone
It is unused, and has been since early Feb 2021 (Tailscale 1.6). We can't get delete the DeviceOptions entirely yet; first #1831 and #1839 need to go in, along with some wireguard-go changes. Deleting this chunk of code now will make the later commits more clearly correct. Pingers can now go too. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
This commit is contained in:
parent
4b14f72f1f
commit
ed63a041bf
@ -7,7 +7,6 @@ package wgengine
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
|
||||||
crand "crypto/rand"
|
crand "crypto/rand"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -120,7 +119,6 @@ type userspaceEngine struct {
|
|||||||
statusCallback StatusCallback
|
statusCallback StatusCallback
|
||||||
peerSequence []wgkey.Key
|
peerSequence []wgkey.Key
|
||||||
endpoints []tailcfg.Endpoint
|
endpoints []tailcfg.Endpoint
|
||||||
pingers map[wgkey.Key]*pinger // legacy pingers for pre-discovery peers
|
|
||||||
pendOpen map[flowtrack.Tuple]*pendingOpenFlow // see pendopen.go
|
pendOpen map[flowtrack.Tuple]*pendingOpenFlow // see pendopen.go
|
||||||
networkMapCallbacks map[*someHandle]NetworkMapCallback
|
networkMapCallbacks map[*someHandle]NetworkMapCallback
|
||||||
tsIPByIPPort map[netaddr.IPPort]netaddr.IP // allows registration of IP:ports as belonging to a certain Tailscale IP for whois lookups
|
tsIPByIPPort map[netaddr.IPPort]netaddr.IP // allows registration of IP:ports as belonging to a certain Tailscale IP for whois lookups
|
||||||
@ -241,7 +239,6 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error)
|
|||||||
waitCh: make(chan struct{}),
|
waitCh: make(chan struct{}),
|
||||||
tundev: tsTUNDev,
|
tundev: tsTUNDev,
|
||||||
router: conf.Router,
|
router: conf.Router,
|
||||||
pingers: make(map[wgkey.Key]*pinger),
|
|
||||||
}
|
}
|
||||||
e.isLocalAddr.Store(tsaddr.NewContainsIPFunc(nil))
|
e.isLocalAddr.Store(tsaddr.NewContainsIPFunc(nil))
|
||||||
|
|
||||||
@ -310,51 +307,7 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
e.wgLogger = wglog.NewLogger(logf)
|
e.wgLogger = wglog.NewLogger(logf)
|
||||||
opts := &device.DeviceOptions{
|
opts := &device.DeviceOptions{}
|
||||||
HandshakeDone: func(peerKey device.NoisePublicKey, peer *device.Peer, deviceAllowedIPs *device.AllowedIPs) {
|
|
||||||
// Send an unsolicited status event every time a
|
|
||||||
// handshake completes. This makes sure our UI can
|
|
||||||
// update quickly as soon as it connects to a peer.
|
|
||||||
//
|
|
||||||
// We use a goroutine here to avoid deadlocking
|
|
||||||
// wireguard, since RequestStatus() will call back
|
|
||||||
// into it, and wireguard is what called us to get
|
|
||||||
// here.
|
|
||||||
go e.RequestStatus()
|
|
||||||
|
|
||||||
peerWGKey := wgkey.Key(peerKey)
|
|
||||||
if e.magicConn.PeerHasDiscoKey(tailcfg.NodeKey(peerKey)) {
|
|
||||||
e.logf("wireguard handshake complete for %v", peerWGKey.ShortString())
|
|
||||||
// This is a modern peer with discovery support. No need to send pings.
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
e.logf("wireguard handshake complete for %v; sending legacy pings", peerWGKey.ShortString())
|
|
||||||
|
|
||||||
// Ping every single-IP that peer routes.
|
|
||||||
// These synthetic packets are used to traverse NATs.
|
|
||||||
var ips []netaddr.IP
|
|
||||||
var allowedIPs []netaddr.IPPrefix
|
|
||||||
deviceAllowedIPs.EntriesForPeer(peer, func(stdIP net.IP, cidr uint) bool {
|
|
||||||
ip, ok := netaddr.FromStdIP(stdIP)
|
|
||||||
if !ok {
|
|
||||||
logf("[unexpected] bad IP from deviceAllowedIPs.EntriesForPeer: %v", stdIP)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
ipp := netaddr.IPPrefix{IP: ip, Bits: uint8(cidr)}
|
|
||||||
allowedIPs = append(allowedIPs, ipp)
|
|
||||||
if ipp.IsSingleIP() {
|
|
||||||
ips = append(ips, ip)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
if len(ips) > 0 {
|
|
||||||
go e.pinger(peerWGKey, ips)
|
|
||||||
} else {
|
|
||||||
logf("[unexpected] peer %s has no single-IP routes: %v", peerWGKey.ShortString(), allowedIPs)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
e.tundev.OnTSMPPongReceived = func(pong packet.TSMPPongReply) {
|
e.tundev.OnTSMPPongReceived = func(pong packet.TSMPPongReply) {
|
||||||
e.mu.Lock()
|
e.mu.Lock()
|
||||||
@ -507,132 +460,6 @@ func (e *userspaceEngine) pollResolver() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// pinger sends ping packets for a few seconds.
|
|
||||||
//
|
|
||||||
// These generated packets are used to ensure we trigger the spray logic in
|
|
||||||
// the magicsock package for NAT traversal.
|
|
||||||
//
|
|
||||||
// These are only used with legacy peers (before 0.100.0) that don't
|
|
||||||
// have advertised discovery keys.
|
|
||||||
type pinger struct {
|
|
||||||
e *userspaceEngine
|
|
||||||
done chan struct{} // closed after shutdown (not the ctx.Done() chan)
|
|
||||||
cancel context.CancelFunc
|
|
||||||
}
|
|
||||||
|
|
||||||
// close cleans up pinger and removes it from the userspaceEngine.pingers map.
|
|
||||||
// It cannot be called while p.e.mu is held.
|
|
||||||
func (p *pinger) close() {
|
|
||||||
p.cancel()
|
|
||||||
<-p.done
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *pinger) run(ctx context.Context, peerKey wgkey.Key, ips []netaddr.IP, srcIP netaddr.IP) {
|
|
||||||
defer func() {
|
|
||||||
p.e.mu.Lock()
|
|
||||||
if p.e.pingers[peerKey] == p {
|
|
||||||
delete(p.e.pingers, peerKey)
|
|
||||||
}
|
|
||||||
p.e.mu.Unlock()
|
|
||||||
|
|
||||||
close(p.done)
|
|
||||||
}()
|
|
||||||
|
|
||||||
header := packet.ICMP4Header{
|
|
||||||
IP4Header: packet.IP4Header{
|
|
||||||
Src: srcIP,
|
|
||||||
},
|
|
||||||
Type: packet.ICMP4EchoRequest,
|
|
||||||
Code: packet.ICMP4NoCode,
|
|
||||||
}
|
|
||||||
|
|
||||||
// sendFreq is slightly longer than sprayFreq in magicsock to ensure
|
|
||||||
// that if these ping packets are the only source of early packets
|
|
||||||
// sent to the peer, that each one will be sprayed.
|
|
||||||
const sendFreq = 300 * time.Millisecond
|
|
||||||
const stopAfter = 3 * time.Second
|
|
||||||
|
|
||||||
start := time.Now()
|
|
||||||
var dstIPs []netaddr.IP
|
|
||||||
for _, ip := range ips {
|
|
||||||
if ip.Is6() {
|
|
||||||
// This code is only used for legacy (pre-discovery)
|
|
||||||
// peers. They're not going to work right with IPv6 on the
|
|
||||||
// overlay anyway, so don't bother trying to make ping
|
|
||||||
// work.
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
dstIPs = append(dstIPs, ip)
|
|
||||||
}
|
|
||||||
|
|
||||||
payload := []byte("magicsock_spray") // no meaning
|
|
||||||
|
|
||||||
header.IPID = 1
|
|
||||||
t := time.NewTicker(sendFreq)
|
|
||||||
defer t.Stop()
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
return
|
|
||||||
case <-t.C:
|
|
||||||
}
|
|
||||||
if time.Since(start) > stopAfter {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for _, dstIP := range dstIPs {
|
|
||||||
header.Dst = dstIP
|
|
||||||
// InjectOutbound take ownership of the packet, so we allocate.
|
|
||||||
b := packet.Generate(&header, payload)
|
|
||||||
p.e.tundev.InjectOutbound(b)
|
|
||||||
}
|
|
||||||
header.IPID++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// pinger sends ping packets for a few seconds.
|
|
||||||
//
|
|
||||||
// These generated packets are used to ensure we trigger the spray logic in
|
|
||||||
// the magicsock package for NAT traversal.
|
|
||||||
//
|
|
||||||
// This is only used with legacy peers (before 0.100.0) that don't
|
|
||||||
// have advertised discovery keys.
|
|
||||||
func (e *userspaceEngine) pinger(peerKey wgkey.Key, ips []netaddr.IP) {
|
|
||||||
e.logf("[v1] generating initial ping traffic to %s (%v)", peerKey.ShortString(), ips)
|
|
||||||
var srcIP netaddr.IP
|
|
||||||
|
|
||||||
e.wgLock.Lock()
|
|
||||||
if len(e.lastCfgFull.Addresses) > 0 {
|
|
||||||
srcIP = e.lastCfgFull.Addresses[0].IP
|
|
||||||
}
|
|
||||||
e.wgLock.Unlock()
|
|
||||||
|
|
||||||
if srcIP.IsZero() {
|
|
||||||
e.logf("generating initial ping traffic: no source IP")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
|
||||||
p := &pinger{
|
|
||||||
e: e,
|
|
||||||
done: make(chan struct{}),
|
|
||||||
cancel: cancel,
|
|
||||||
}
|
|
||||||
|
|
||||||
e.mu.Lock()
|
|
||||||
if e.closing {
|
|
||||||
e.mu.Unlock()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
oldPinger := e.pingers[peerKey]
|
|
||||||
e.pingers[peerKey] = p
|
|
||||||
e.mu.Unlock()
|
|
||||||
|
|
||||||
if oldPinger != nil {
|
|
||||||
oldPinger.close()
|
|
||||||
}
|
|
||||||
p.run(ctx, peerKey, ips, srcIP)
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
debugTrimWireguardEnv = os.Getenv("TS_DEBUG_TRIM_WIREGUARD")
|
debugTrimWireguardEnv = os.Getenv("TS_DEBUG_TRIM_WIREGUARD")
|
||||||
debugTrimWireguard, _ = strconv.ParseBool(debugTrimWireguardEnv)
|
debugTrimWireguard, _ = strconv.ParseBool(debugTrimWireguardEnv)
|
||||||
@ -1213,17 +1040,12 @@ func (e *userspaceEngine) RequestStatus() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e *userspaceEngine) Close() {
|
func (e *userspaceEngine) Close() {
|
||||||
var pingers []*pinger
|
|
||||||
|
|
||||||
e.mu.Lock()
|
e.mu.Lock()
|
||||||
if e.closing {
|
if e.closing {
|
||||||
e.mu.Unlock()
|
e.mu.Unlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
e.closing = true
|
e.closing = true
|
||||||
for _, pinger := range e.pingers {
|
|
||||||
pingers = append(pingers, pinger)
|
|
||||||
}
|
|
||||||
e.mu.Unlock()
|
e.mu.Unlock()
|
||||||
|
|
||||||
r := bufio.NewReader(strings.NewReader(""))
|
r := bufio.NewReader(strings.NewReader(""))
|
||||||
@ -1237,13 +1059,6 @@ func (e *userspaceEngine) Close() {
|
|||||||
e.router.Close()
|
e.router.Close()
|
||||||
e.wgdev.Close()
|
e.wgdev.Close()
|
||||||
e.tundev.Close()
|
e.tundev.Close()
|
||||||
|
|
||||||
// Shut down pingers after tundev is closed (by e.wgdev.Close) so the
|
|
||||||
// synchronous close does not get stuck on InjectOutbound.
|
|
||||||
for _, pinger := range pingers {
|
|
||||||
pinger.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
close(e.waitCh)
|
close(e.waitCh)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user