diff --git a/wgengine/magicsock/legacy.go b/wgengine/magicsock/legacy.go index e84f81e38..aafa4a82a 100644 --- a/wgengine/magicsock/legacy.go +++ b/wgengine/magicsock/legacy.go @@ -6,6 +6,7 @@ package magicsock import ( "encoding/binary" + "errors" "fmt" "net" "strings" @@ -20,6 +21,47 @@ import ( "tailscale.com/types/logger" ) +var errNoDestinations = errors.New("magicsock: no destinations") + +func (c *Conn) sendSingleEndpoint(b []byte, se *singleEndpoint) error { + addr := (*net.UDPAddr)(se) + if addr.IP.Equal(derpMagicIP) { + c.logf("magicsock: [unexpected] DERP BUG: attempting to send packet to DERP address %v", addr) + return nil + } + _, err := c.sendUDPStd(addr, b) + return err +} + +func (c *Conn) sendAddrSet(b []byte, as *addrSet) error { + var addrBuf [8]netaddr.IPPort + dsts, roamAddr := as.appendDests(addrBuf[:0], b) + + if len(dsts) == 0 { + return errNoDestinations + } + + var success bool + var ret error + for _, addr := range dsts { + sent, err := c.sendAddr(addr, as.publicKey, b) + if sent { + success = true + } else if ret == nil { + ret = err + } + if err != nil && addr != roamAddr && c.sendLogLimit.Allow() { + if c.connCtx.Err() == nil { // don't log if we're closed + c.logf("magicsock: Conn.Send(%v): %v", addr, err) + } + } + } + if success { + return nil + } + return ret +} + func shouldSprayPacket(b []byte) bool { if len(b) < 4 { return false diff --git a/wgengine/magicsock/magicsock.go b/wgengine/magicsock/magicsock.go index d6feee522..95b0e20a0 100644 --- a/wgengine/magicsock/magicsock.go +++ b/wgengine/magicsock/magicsock.go @@ -963,7 +963,6 @@ func (c *Conn) LocalPort() uint16 { return uint16(laddr.Port) } -var errNoDestinations = errors.New("magicsock: no destinations") var errNetworkDown = errors.New("magicsock: network down") func (c *Conn) networkDown() bool { return !c.networkUp.Get() } @@ -973,50 +972,16 @@ func (c *Conn) Send(b []byte, ep conn.Endpoint) error { return errNetworkDown } - var as *addrSet switch v := ep.(type) { default: panic(fmt.Sprintf("[unexpected] Endpoint type %T", v)) case *discoEndpoint: return v.send(b) case *singleEndpoint: - addr := (*net.UDPAddr)(v) - if addr.IP.Equal(derpMagicIP) { - c.logf("magicsock: [unexpected] DERP BUG: attempting to send packet to DERP address %v", addr) - return nil - } - _, err := c.sendUDPStd(addr, b) - return err + return c.sendSingleEndpoint(b, v) case *addrSet: - as = v + return c.sendAddrSet(b, v) } - - var addrBuf [8]netaddr.IPPort - dsts, roamAddr := as.appendDests(addrBuf[:0], b) - - if len(dsts) == 0 { - return errNoDestinations - } - - var success bool - var ret error - for _, addr := range dsts { - sent, err := c.sendAddr(addr, as.publicKey, b) - if sent { - success = true - } else if ret == nil { - ret = err - } - if err != nil && addr != roamAddr && c.sendLogLimit.Allow() { - if c.connCtx.Err() == nil { // don't log if we're closed - c.logf("magicsock: Conn.Send(%v): %v", addr, err) - } - } - } - if success { - return nil - } - return ret } var errConnClosed = errors.New("Conn closed")