mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-18 02:48:40 +00:00
wgengine/magicsock: don't block in Send waiting for derphttp.Send
Fixes #137 Updates #109 Updates #162 Updates #163 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
8807913be9
commit
bc73dcf204
@ -666,17 +666,20 @@ func (c *Conn) sendAddr(addr *net.UDPAddr, pubKey key.Public, b []byte) error {
|
|||||||
if ch == nil {
|
if ch == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
errc := make(chan error, 1)
|
|
||||||
|
// TODO(bradfitz): this makes garbage for now; we could use a
|
||||||
|
// buffer pool later. Previously we passed ownership of this
|
||||||
|
// to derpWriteRequest and waited for derphttp.Client.Send to
|
||||||
|
// complete, but that's too slow while holding wireguard-go
|
||||||
|
// internal locks.
|
||||||
|
pkt := make([]byte, len(b))
|
||||||
|
copy(pkt, b)
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-c.donec():
|
case <-c.donec():
|
||||||
return errConnClosed
|
return errConnClosed
|
||||||
case ch <- derpWriteRequest{addr, pubKey, b, errc}:
|
case ch <- derpWriteRequest{addr, pubKey, pkt}:
|
||||||
select {
|
return nil
|
||||||
case <-c.donec():
|
|
||||||
return errConnClosed
|
|
||||||
case err := <-errc:
|
|
||||||
return err // usually nil
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
// Too many writes queued. Drop packet.
|
// Too many writes queued. Drop packet.
|
||||||
return errDropDerpPacket
|
return errDropDerpPacket
|
||||||
@ -838,8 +841,7 @@ func (c *Conn) runDerpReader(ctx context.Context, derpFakeAddr *net.UDPAddr, dc
|
|||||||
type derpWriteRequest struct {
|
type derpWriteRequest struct {
|
||||||
addr *net.UDPAddr
|
addr *net.UDPAddr
|
||||||
pubKey key.Public
|
pubKey key.Public
|
||||||
b []byte
|
b []byte // copied; ownership passed to receiver
|
||||||
errc chan<- error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// runDerpWriter runs in a goroutine for the life of a DERP
|
// runDerpWriter runs in a goroutine for the life of a DERP
|
||||||
@ -861,11 +863,6 @@ func (c *Conn) runDerpWriter(ctx context.Context, derpFakeAddr *net.UDPAddr, dc
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
c.logf("magicsock: derp.Send(%v): %v", wr.addr, err)
|
c.logf("magicsock: derp.Send(%v): %v", wr.addr, err)
|
||||||
}
|
}
|
||||||
select {
|
|
||||||
case wr.errc <- err:
|
|
||||||
case <-c.donec(): // Note: not ctx.Done: sendAddr (receiver) has different lifetime than ctx.
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user