reject new connection attempts if the server's accept queue is full

This commit is contained in:
Marten Seemann
2019-01-06 13:36:52 +07:00
parent 1301610a54
commit 90514d53d1
7 changed files with 186 additions and 13 deletions

View File

@@ -4,9 +4,11 @@ import (
"crypto/tls"
"fmt"
"net"
"time"
quic "github.com/lucas-clemente/quic-go"
"github.com/lucas-clemente/quic-go/internal/protocol"
"github.com/lucas-clemente/quic-go/internal/qerr"
"github.com/lucas-clemente/quic-go/internal/testdata"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
@@ -143,4 +145,50 @@ var _ = Describe("Handshake tests", func() {
})
}
})
Context("rate limiting", func() {
It("rejects new connection attempts if connections don't get accepted", func() {
// start the server, but don't call Accept
serverConfig.AcceptCookie = func(net.Addr, *quic.Cookie) bool {
return true
}
server, err := quic.ListenAddr("localhost:0", testdata.GetTLSConfig(), serverConfig)
Expect(err).ToNot(HaveOccurred())
defer server.Close()
dial := func() (quic.Session, error) {
return quic.DialAddr(
fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port),
&tls.Config{RootCAs: testdata.GetRootCA()},
nil,
)
}
for i := 0; i < protocol.MaxAcceptQueueSize; i++ {
sess, err := dial()
Expect(err).ToNot(HaveOccurred())
defer sess.Close()
}
time.Sleep(25 * time.Millisecond) // wait a bit for the sessions to be queued
_, err = dial()
Expect(err).To(HaveOccurred())
// TODO(#1567): use the SERVER_BUSY error code
Expect(err.(*qerr.QuicError).ErrorCode).To(Equal(qerr.PeerGoingAway))
// now accept one session, freeing one spot in the queue
_, err = server.Accept()
Expect(err).ToNot(HaveOccurred())
// dial again, and expect that this dial succeeds
sess, err := dial()
Expect(err).ToNot(HaveOccurred())
defer sess.Close()
time.Sleep(25 * time.Millisecond) // wait a bit for the session to be queued
_, err = dial()
Expect(err).To(HaveOccurred())
// TODO(#1567): use the SERVER_BUSY error code
Expect(err.(*qerr.QuicError).ErrorCode).To(Equal(qerr.PeerGoingAway))
})
})
})