mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-22 12:58:37 +00:00
net/tstun: add inner loop to poll
This avoids re-enqueuing to t.bufferConsumed, which makes the code a bit clearer. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
This commit is contained in:
parent
a4cc7b6d54
commit
c35a832de6
@ -181,6 +181,16 @@ func (t *Wrapper) Close() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isClosed reports whether t is closed.
|
||||||
|
func (t *Wrapper) isClosed() bool {
|
||||||
|
select {
|
||||||
|
case <-t.closed:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// pumpEvents copies events from t.tdev to t.eventsUpDown and t.eventsOther.
|
// pumpEvents copies events from t.tdev to t.eventsUpDown and t.eventsOther.
|
||||||
// pumpEvents exits when t.tdev.events or t.closed is closed.
|
// pumpEvents exits when t.tdev.events or t.closed is closed.
|
||||||
// pumpEvents closes t.eventsUpDown and t.eventsOther when it exits.
|
// pumpEvents closes t.eventsUpDown and t.eventsOther when it exits.
|
||||||
@ -266,28 +276,24 @@ func allowSendOnClosedChannel() {
|
|||||||
// so packets may be stuck in t.outbound if t.Read called t.tdev.Read directly.
|
// so packets may be stuck in t.outbound if t.Read called t.tdev.Read directly.
|
||||||
func (t *Wrapper) poll() {
|
func (t *Wrapper) poll() {
|
||||||
defer allowSendOnClosedChannel() // for send to t.outbound
|
defer allowSendOnClosedChannel() // for send to t.outbound
|
||||||
for {
|
for range t.bufferConsumed {
|
||||||
<-t.bufferConsumed
|
var n int
|
||||||
|
var err error
|
||||||
// Read may use memory in t.buffer before PacketStartOffset for mandatory headers.
|
// Read may use memory in t.buffer before PacketStartOffset for mandatory headers.
|
||||||
// This is the rationale behind the tun.Wrapper.{Read,Write} interfaces
|
// This is the rationale behind the tun.Wrapper.{Read,Write} interfaces
|
||||||
// and the reason t.buffer has size MaxMessageSize and not MaxContentSize.
|
// and the reason t.buffer has size MaxMessageSize and not MaxContentSize.
|
||||||
n, err := t.tdev.Read(t.buffer[:], PacketStartOffset)
|
// In principle, read errors are not fatal (but wireguard-go disagrees).
|
||||||
if err != nil {
|
// We loop here until we get a non-empty (or failed) read.
|
||||||
t.outbound <- tunReadResult{err: err}
|
// We don't need this loop for correctness,
|
||||||
// In principle, read errors are not fatal (but wireguard-go disagrees).
|
// but wireguard-go will skip an empty read,
|
||||||
t.bufferConsumed <- struct{}{}
|
// so we might as well avoid the send through t.outbound.
|
||||||
continue
|
for n == 0 && err == nil {
|
||||||
|
if t.isClosed() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
n, err = t.tdev.Read(t.buffer[:], PacketStartOffset)
|
||||||
}
|
}
|
||||||
|
t.outbound <- tunReadResult{data: t.buffer[PacketStartOffset : PacketStartOffset+n], err: err}
|
||||||
// Wireguard will skip an empty read,
|
|
||||||
// so we might as well do it here to avoid the send through t.outbound.
|
|
||||||
if n == 0 {
|
|
||||||
t.bufferConsumed <- struct{}{}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
t.outbound <- tunReadResult{data: t.buffer[PacketStartOffset : PacketStartOffset+n]}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user