net/tstun: don't return early from a partial tun.Read() (#6745)

Fixes #6730

Signed-off-by: Jordan Whited <jordan@tailscale.com>
pull/6748/head
Jordan Whited 2022-12-14 16:29:34 -08:00 committed by GitHub
parent 3a5fc233aa
commit 55b24009f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 5 additions and 4 deletions

View File

@ -187,8 +187,9 @@ type tunInjectedRead struct {
// tunVectorReadResult is the result of a tun.Read(), or an injected packet // tunVectorReadResult is the result of a tun.Read(), or an injected packet
// pretending to be a tun.Read(). // pretending to be a tun.Read().
type tunVectorReadResult struct { type tunVectorReadResult struct {
// Only one of err, data, or injected should be set, and are read in that // When err AND data are nil, injected will be set with meaningful data
// order of precedence. // (injected packet). If either err OR data is non-nil, injected should be
// ignored (a "real" tun.Read).
err error err error
data [][]byte data [][]byte
injected tunInjectedRead injected tunInjectedRead
@ -543,7 +544,7 @@ func (t *Wrapper) Read(buffs [][]byte, sizes []int, offset int) (int, error) {
if !ok { if !ok {
return 0, io.EOF return 0, io.EOF
} }
if res.err != nil { if res.err != nil && len(res.data) == 0 {
return 0, res.err return 0, res.err
} }
if res.data == nil { if res.data == nil {
@ -595,7 +596,7 @@ func (t *Wrapper) Read(buffs [][]byte, sizes []int, offset int) (int, error) {
} }
t.noteActivity() t.noteActivity()
return buffsPos, nil return buffsPos, res.err
} }
// injectedRead handles injected reads, which bypass filters. // injectedRead handles injected reads, which bypass filters.