bradfitz/http2

serverConn.readFrames goroutine leak

dvyukov opened this issue · 2 comments

The following test leaks serverConn.readFrames goroutines:

package http2

import (
    "io"
    "net"
    "net/http"
    "testing"
    "time"
)

var data = "PRI * HTTP/2.0\r\n\r\nSM" +
    "\r\n\r\n\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x96\x01\x00nf" +
    "i\r\n\x00\x00\x00\t\ai\n\r\x01#-9---\n\x00" +
    "G\x01#?M\x0f\n\r\n\x00\x00\x00\t\x0f\n\n\r\x01#-" +
    "9---\n\x00G\x01#?M\x0f\n\x00G\x01#?M\x0f" +
    "\n\r\n\x00\x00\x00\t\x0f\n\n\r\x01#-9---\n\x00" +
    "G\x01#?\n\x00\x00\x00\x04\x00M\x0f\n\r\n\x00\x00\x01#-" +
    "----[\x00\x00\r\n\x00\x00\x01#-----[\x00" +
    "\x00\x01\xff\xffM\r\n\r\n\x00\x00\x01#-----\n\x00" +
    "\x00\r\n\x00\x00\x19\t\ai\n\r\n\x00\x00\x00\t\ai\n\r" +
    "\n\x00"

func TestFuzz(t *testing.T) {
    for i := 0; i < 10; i++ {
        s := &http.Server{}
        s2 := &Server{MaxReadFrameSize: 1 << 16, PermitProhibitedCipherSuites: true}
        c := &MyConn{[]byte(data), false, false}
        s2.handleConn(s, c, http.HandlerFunc(handler))
        if !c.closed {
            panic("connection is not closed")
        }
    }
    time.Sleep(time.Second)
    panic("кeady or not, here I come")
}

func handler(w http.ResponseWriter, req *http.Request) {
    w.Write([]byte("hello"))
}

type MyConn struct {
    data    []byte
    closed  bool
    written bool
}

func (c *MyConn) Read(b []byte) (n int, err error) {
    if len(c.data) == 0 {
        return 0, io.EOF
    }
    n = copy(b, c.data)
    c.data = c.data[n:]
    return
}

func (c *MyConn) Write(b []byte) (n int, err error) {
    c.written = true
    return len(b), nil
}

func (c *MyConn) Close() error {
    c.closed = true
    return nil
}

func (c *MyConn) LocalAddr() net.Addr {
    return &net.TCPAddr{net.IP{127, 0, 0, 1}, 49706, ""}
}

func (c *MyConn) RemoteAddr() net.Addr {
    return &net.TCPAddr{net.IP{127, 0, 0, 1}, 49706, ""}
}

func (c *MyConn) SetDeadline(t time.Time) error {
    return nil
}

func (c *MyConn) SetReadDeadline(t time.Time) error {
    return nil
}

func (c *MyConn) SetWriteDeadline(t time.Time) error {
    return nil
}
panic: кeady or not, here I come

goroutine 5 [running]:
testing.tRunner.func1(0xc20801a1b0)
    src/testing/testing.go:446 +0x174
github.com/bradfitz/http2.TestFuzz(0xc20801a1b0)
    src/github.com/bradfitz/http2/fuzz_test.go:34 +0x2ab
testing.tRunner(0xc20801a1b0, 0xa4c040)
    src/testing/testing.go:452 +0x9b
created by testing.RunTests
    src/testing/testing.go:560 +0xa2a

goroutine 1 [chan receive]:
testing.RunTests(0x90c700, 0xa4be60, 0x61, 0x61, 0xa4e601)
    src/testing/testing.go:561 +0xa6a
testing.(*M).Run(0xc20804ff38, 0x7f53aa89b368)
    src/testing/testing.go:490 +0x73
main.main()
    github.com/bradfitz/http2/_test/_testmain.go:250 +0x119

goroutine 9 [chan send]:
github.com/bradfitz/http2.(*serverConn).readFrames(0xc20808c280)
    src/github.com/bradfitz/http2/server.go:544 +0x117
created by github.com/bradfitz/http2.(*serverConn).serve
    src/github.com/bradfitz/http2/server.go:626 +0x69c

goroutine 14 [chan send]:
github.com/bradfitz/http2.(*serverConn).readFrames(0xc20808c500)
    src/github.com/bradfitz/http2/server.go:544 +0x117
created by github.com/bradfitz/http2.(*serverConn).serve
    src/github.com/bradfitz/http2/server.go:626 +0x69c

goroutine 18 [chan send]:
github.com/bradfitz/http2.(*serverConn).readFrames(0xc20808c780)
    src/github.com/bradfitz/http2/server.go:544 +0x117
created by github.com/bradfitz/http2.(*serverConn).serve
    src/github.com/bradfitz/http2/server.go:626 +0x69c

goroutine 21 [chan send]:
github.com/bradfitz/http2.(*serverConn).readFrames(0xc20808ca00)
    src/github.com/bradfitz/http2/server.go:544 +0x117
created by github.com/bradfitz/http2.(*serverConn).serve
    src/github.com/bradfitz/http2/server.go:626 +0x69c

goroutine 24 [chan send]:
github.com/bradfitz/http2.(*serverConn).readFrames(0xc20808cc80)
    src/github.com/bradfitz/http2/server.go:544 +0x117
created by github.com/bradfitz/http2.(*serverConn).serve
    src/github.com/bradfitz/http2/server.go:626 +0x69c

goroutine 27 [chan send]:
github.com/bradfitz/http2.(*serverConn).readFrames(0xc20808cf00)
    src/github.com/bradfitz/http2/server.go:544 +0x117
created by github.com/bradfitz/http2.(*serverConn).serve
    src/github.com/bradfitz/http2/server.go:626 +0x69c

goroutine 30 [chan send]:
github.com/bradfitz/http2.(*serverConn).readFrames(0xc20808d180)
    src/github.com/bradfitz/http2/server.go:544 +0x117
created by github.com/bradfitz/http2.(*serverConn).serve
    src/github.com/bradfitz/http2/server.go:626 +0x69c

goroutine 33 [chan send]:
github.com/bradfitz/http2.(*serverConn).readFrames(0xc20808d400)
    src/github.com/bradfitz/http2/server.go:544 +0x117
created by github.com/bradfitz/http2.(*serverConn).serve
    src/github.com/bradfitz/http2/server.go:626 +0x69c

goroutine 36 [chan send]:
github.com/bradfitz/http2.(*serverConn).readFrames(0xc20808d680)
    src/github.com/bradfitz/http2/server.go:544 +0x117
created by github.com/bradfitz/http2.(*serverConn).serve
    src/github.com/bradfitz/http2/server.go:626 +0x69c

goroutine 39 [chan send]:
github.com/bradfitz/http2.(*serverConn).readFrames(0xc20808d900)
    src/github.com/bradfitz/http2/server.go:544 +0x117
created by github.com/bradfitz/http2.(*serverConn).serve
    src/github.com/bradfitz/http2/server.go:626 +0x69c

on commit b625564

This and #46 are the same.