wgengine/magicsock: add a reSTUN method

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
pull/75/head
Brad Fitzpatrick 5 years ago
parent 619697063e
commit fd1aa4f7f6

@ -29,14 +29,16 @@ import (
// A Conn routes UDP packets and actively manages a list of its endpoints. // A Conn routes UDP packets and actively manages a list of its endpoints.
// It implements wireguard/device.Bind. // It implements wireguard/device.Bind.
type Conn struct { type Conn struct {
pconn *RebindingUDPConn pconn *RebindingUDPConn
pconnPort uint16 pconnPort uint16
stunServers []string stunServers []string
derpServer string derpServer string
startEpUpdate chan struct{} // send to trigger endpoint update startEpUpdate chan struct{} // send to trigger endpoint update
epUpdateCancel func() epFunc func(endpoints []string)
epFunc func(endpoints []string) logf func(format string, args ...interface{})
logf func(format string, args ...interface{})
epUpdateCtx context.Context // endpoint updater context
epUpdateCancel func() // the func to cancel epUpdateCtx
// indexedAddrs is a map of every remote ip:port to a priority // indexedAddrs is a map of every remote ip:port to a priority
// list of endpoint addresses for a peer. // list of endpoint addresses for a peer.
@ -137,6 +139,7 @@ func Listen(opts Options) (*Conn, error) {
stunServers: append([]string{}, opts.STUN...), stunServers: append([]string{}, opts.STUN...),
derpServer: opts.DERP, derpServer: opts.DERP,
startEpUpdate: make(chan struct{}, 1), startEpUpdate: make(chan struct{}, 1),
epUpdateCtx: epUpdateCtx,
epUpdateCancel: epUpdateCancel, epUpdateCancel: epUpdateCancel,
epFunc: opts.endpointsFunc(), epFunc: opts.endpointsFunc(),
logf: log.Printf, logf: log.Printf,
@ -144,7 +147,7 @@ func Listen(opts Options) (*Conn, error) {
} }
c.ignoreSTUNPackets() c.ignoreSTUNPackets()
c.pconn.Reset(packetConn.(*net.UDPConn)) c.pconn.Reset(packetConn.(*net.UDPConn))
c.startEpUpdate <- struct{}{} // STUN immediately on start c.reSTUN()
go c.epUpdate(epUpdateCtx) go c.epUpdate(epUpdateCtx)
return c, nil return c, nil
} }
@ -472,8 +475,7 @@ func (c *Conn) SetPrivateKey(privateKey wgcfg.PrivateKey) error {
time.Sleep(250 * time.Millisecond) time.Sleep(250 * time.Millisecond)
} }
// Trigger re-STUN. c.reSTUN()
c.startEpUpdate <- struct{}{}
addr := c.pconn.LocalAddr() addr := c.pconn.LocalAddr()
if _, err := c.pconn.WriteToUDP(b[:n], addr); err != nil { if _, err := c.pconn.WriteToUDP(b[:n], addr); err != nil {
@ -501,10 +503,15 @@ func (c *Conn) Close() error {
return c.pconn.Close() return c.pconn.Close()
} }
func (c *Conn) reSTUN() {
select {
case c.startEpUpdate <- struct{}{}:
case <-c.epUpdateCtx.Done():
}
}
func (c *Conn) LinkChange() { func (c *Conn) LinkChange() {
defer func() { defer c.reSTUN()
c.startEpUpdate <- struct{}{} // re-STUN
}()
if c.pconnPort != 0 { if c.pconnPort != 0 {
c.pconn.mu.Lock() c.pconn.mu.Lock()

Loading…
Cancel
Save