mirror of
https://github.com/slackhq/nebula.git
synced 2026-08-15 15:57:01 +02:00
udp: test the partial-sendmmsg rewind
The rewind (resume after the kernel accepts fewer entries than submitted) was the hairiest untested logic in the write path; a bug there silently duplicates or loses packets under backpressure. Give batchWriter an injectable sendFn and drive WriteBatch through scripted partial-acceptance sequences over a mixed GSO-run/plain batch, decoding what "reached the wire" straight from the prepared iovecs rather than the entryEnd bookkeeping under test. Also pins the zero-progress abort and the EIO runtime GSO-disable replay. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -55,10 +55,16 @@ type batchWriter struct {
|
||||
// entryEnd[e] is the bufs index *after* the last packet packed into
|
||||
// mmsghdr entry e. Used to rewind `i` on partial sendmmsg success.
|
||||
entryEnd []int
|
||||
|
||||
// sendFn issues the sendmmsg for the first n prepared entries. Points
|
||||
// at the real syscall in production; tests inject partial-success and
|
||||
// error scripts to exercise the rewind logic without a socket.
|
||||
sendFn func(n int) (int, error)
|
||||
}
|
||||
|
||||
func newBatchWriter(fd int, isV4 bool, l *slog.Logger) *batchWriter {
|
||||
w := &batchWriter{fd: fd, isV4: isV4, l: l}
|
||||
w.sendFn = w.sendmmsg
|
||||
w.prepareWriteMessages(MaxWriteBatch)
|
||||
w.prepareGSO()
|
||||
return w
|
||||
@@ -294,7 +300,7 @@ sendChunks:
|
||||
return written, fmt.Errorf("sendmmsg: no progress")
|
||||
}
|
||||
|
||||
sent, serr := w.sendmmsg(entry)
|
||||
sent, serr := w.sendFn(entry)
|
||||
if serr != nil && sent <= 0 {
|
||||
// sent<=0 means message 0 itself failed. If that entry was a GSO
|
||||
// superpacket and the errno is the kernel's "device can't do this"
|
||||
|
||||
Reference in New Issue
Block a user