Skip to content

Commit 5608279

Browse files
committed
http2: avoid corruption in priority write scheduler
When removing a stream containing children in the priority tree, it was possible for some children to not be correctly moved to the parent of the removed stream. Fixes golang/go#66514 Change-Id: Ie8a8743a6213a6b1a2426e023111878afff78f9e Reviewed-on: https://go-review.googlesource.com/c/net/+/589255 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Jonathan Amsterdam <jba@google.com>
1 parent 0d515a5 commit 5608279

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

http2/writesched_priority.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -443,8 +443,8 @@ func (ws *priorityWriteScheduler) addClosedOrIdleNode(list *[]*priorityNode, max
443443
}
444444

445445
func (ws *priorityWriteScheduler) removeNode(n *priorityNode) {
446-
for k := n.kids; k != nil; k = k.next {
447-
k.setParent(n.parent)
446+
for n.kids != nil {
447+
n.kids.setParent(n.parent)
448448
}
449449
n.setParent(nil)
450450
delete(ws.nodes, n.id)

http2/writesched_priority_test.go

+34
Original file line numberDiff line numberDiff line change
@@ -562,3 +562,37 @@ func TestPriorityRstStreamOnNonOpenStreams(t *testing.T) {
562562
t.Error(err)
563563
}
564564
}
565+
566+
// https://go.dev/issue/66514
567+
func TestPriorityIssue66514(t *testing.T) {
568+
addDep := func(ws *priorityWriteScheduler, child uint32, parent uint32) {
569+
ws.AdjustStream(child, PriorityParam{
570+
StreamDep: parent,
571+
Exclusive: false,
572+
Weight: 16,
573+
})
574+
}
575+
576+
validateDepTree := func(ws *priorityWriteScheduler, id uint32, t *testing.T) {
577+
for n := ws.nodes[id]; n != nil; n = n.parent {
578+
if n.parent == nil {
579+
if n.id != uint32(0) {
580+
t.Errorf("detected nodes not parented to 0")
581+
}
582+
}
583+
}
584+
}
585+
586+
ws := NewPriorityWriteScheduler(nil).(*priorityWriteScheduler)
587+
588+
// Root entry
589+
addDep(ws, uint32(1), uint32(0))
590+
addDep(ws, uint32(3), uint32(1))
591+
addDep(ws, uint32(5), uint32(1))
592+
593+
for id := uint32(7); id < uint32(100); id += uint32(4) {
594+
addDep(ws, id, id-uint32(4))
595+
addDep(ws, id+uint32(2), id-uint32(4))
596+
validateDepTree(ws, id, t)
597+
}
598+
}

0 commit comments

Comments
 (0)