mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 04:55:31 +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 @@
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
crand "crypto/rand"
|
||||
"errors"
|
||||
"fmt"
|
||||
@ -120,7 +119,6 @@ type userspaceEngine struct {
|
||||
statusCallback StatusCallback
|
||||
peerSequence []wgkey.Key
|
||||
endpoints []tailcfg.Endpoint
|
||||
pingers map[wgkey.Key]*pinger // legacy pingers for pre-discovery peers
|
||||
pendOpen map[flowtrack.Tuple]*pendingOpenFlow // see pendopen.go
|
||||
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
|
||||
@ -241,7 +239,6 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error)
|
||||
waitCh: make(chan struct{}),
|
||||
tundev: tsTUNDev,
|
||||
router: conf.Router,
|
||||
pingers: make(map[wgkey.Key]*pinger),
|
||||
}
|
||||
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)
|
||||
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)
|
||||
}
|
||||
},
|
||||
}
|
||||
opts := &device.DeviceOptions{}
|
||||
|
||||
e.tundev.OnTSMPPongReceived = func(pong packet.TSMPPongReply) {
|
||||
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 (
|
||||
debugTrimWireguardEnv = os.Getenv("TS_DEBUG_TRIM_WIREGUARD")
|
||||
debugTrimWireguard, _ = strconv.ParseBool(debugTrimWireguardEnv)
|
||||
@ -1213,17 +1040,12 @@ func (e *userspaceEngine) RequestStatus() {
|
||||
}
|
||||
|
||||
func (e *userspaceEngine) Close() {
|
||||
var pingers []*pinger
|
||||
|
||||
e.mu.Lock()
|
||||
if e.closing {
|
||||
e.mu.Unlock()
|
||||
return
|
||||
}
|
||||
e.closing = true
|
||||
for _, pinger := range e.pingers {
|
||||
pingers = append(pingers, pinger)
|
||||
}
|
||||
e.mu.Unlock()
|
||||
|
||||
r := bufio.NewReader(strings.NewReader(""))
|
||||
@ -1237,13 +1059,6 @@ func (e *userspaceEngine) Close() {
|
||||
e.router.Close()
|
||||
e.wgdev.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)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user