read packets with the maximum packet size

fixes #467
This commit is contained in:
Marten Seemann
2017-03-06 13:02:46 +07:00
parent eff9c6f906
commit 1f01904270
8 changed files with 24 additions and 20 deletions

View File

@@ -13,7 +13,7 @@ func getPacketBuffer() []byte {
} }
func putPacketBuffer(buf []byte) { func putPacketBuffer(buf []byte) {
if cap(buf) != int(protocol.MaxPacketSize) { if cap(buf) != int(protocol.MaxReceivePacketSize) {
panic("putPacketBuffer called with packet of wrong size!") panic("putPacketBuffer called with packet of wrong size!")
} }
bufferPool.Put(buf[:0]) bufferPool.Put(buf[:0])
@@ -21,6 +21,6 @@ func putPacketBuffer(buf []byte) {
func init() { func init() {
bufferPool.New = func() interface{} { bufferPool.New = func() interface{} {
return make([]byte, 0, protocol.MaxPacketSize) return make([]byte, 0, protocol.MaxReceivePacketSize)
} }
} }

View File

@@ -11,7 +11,7 @@ var _ = Describe("Buffer Pool", func() {
It("returns buffers of correct len and cap", func() { It("returns buffers of correct len and cap", func() {
buf := getPacketBuffer() buf := getPacketBuffer()
Expect(buf).To(HaveLen(0)) Expect(buf).To(HaveLen(0))
Expect(buf).To(HaveCap(int(protocol.MaxPacketSize))) Expect(buf).To(HaveCap(int(protocol.MaxReceivePacketSize)))
}) })
It("zeroes put buffers' length", func() { It("zeroes put buffers' length", func() {
@@ -20,7 +20,7 @@ var _ = Describe("Buffer Pool", func() {
putPacketBuffer(buf[0:10]) putPacketBuffer(buf[0:10])
buf = getPacketBuffer() buf = getPacketBuffer()
Expect(buf).To(HaveLen(0)) Expect(buf).To(HaveLen(0))
Expect(buf).To(HaveCap(int(protocol.MaxPacketSize))) Expect(buf).To(HaveCap(int(protocol.MaxReceivePacketSize)))
} }
}) })

View File

@@ -115,7 +115,7 @@ func (c *client) listen() {
var n int var n int
var addr net.Addr var addr net.Addr
data := getPacketBuffer() data := getPacketBuffer()
data = data[:protocol.MaxPacketSize] data = data[:protocol.MaxReceivePacketSize]
n, addr, err = c.conn.Read(data) n, addr, err = c.conn.Read(data)
if err != nil { if err != nil {
@@ -141,7 +141,7 @@ func (c *client) listen() {
} }
func (c *client) handlePacket(remoteAddr net.Addr, packet []byte) error { func (c *client) handlePacket(remoteAddr net.Addr, packet []byte) error {
if protocol.ByteCount(len(packet)) > protocol.MaxPacketSize { if protocol.ByteCount(len(packet)) > protocol.MaxReceivePacketSize {
return qerr.PacketTooLarge return qerr.PacketTooLarge
} }

View File

@@ -112,11 +112,6 @@ var _ = Describe("Client", func() {
Expect(err.(*qerr.QuicError).ErrorCode).To(Equal(qerr.InvalidPacketHeader)) Expect(err.(*qerr.QuicError).ErrorCode).To(Equal(qerr.InvalidPacketHeader))
}) })
It("errors on large packets", func() {
err := cl.handlePacket(nil, bytes.Repeat([]byte{'a'}, int(protocol.MaxPacketSize)+1))
Expect(err).To(MatchError(qerr.PacketTooLarge))
})
// this test requires a real session (because it calls the close callback) and a real UDP conn (because it unblocks and errors when it is closed) // this test requires a real session (because it calls the close callback) and a real UDP conn (because it unblocks and errors when it is closed)
It("properly closes", func(done Done) { It("properly closes", func(done Done) {
udpConn, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)}) udpConn, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)})
@@ -152,7 +147,7 @@ var _ = Describe("Client", func() {
Context("handling packets", func() { Context("handling packets", func() {
It("errors on too large packets", func() { It("errors on too large packets", func() {
err := cl.handlePacket(nil, bytes.Repeat([]byte{'f'}, int(protocol.MaxPacketSize+1))) err := cl.handlePacket(nil, bytes.Repeat([]byte{'f'}, int(protocol.MaxReceivePacketSize+1)))
Expect(err).To(MatchError(qerr.PacketTooLarge)) Expect(err).To(MatchError(qerr.PacketTooLarge))
}) })

View File

@@ -36,12 +36,14 @@ type ByteCount uint64
// MaxByteCount is the maximum value of a ByteCount // MaxByteCount is the maximum value of a ByteCount
const MaxByteCount = math.MaxUint64 const MaxByteCount = math.MaxUint64
// MaxPacketSize is the maximum packet size, including the public header // CryptoStreamID is the ID of the crypto stream
// This is the value used by Chromium for a QUIC packet sent using IPv6 (for IPv4 it would be 1370) const CryptoStreamID StreamID = 1
const MaxPacketSize ByteCount = 1350
// MaxFrameAndPublicHeaderSize is the maximum size of a QUIC frame plus PublicHeader // MaxReceivePacketSize maximum packet size of any QUIC packet, based on
const MaxFrameAndPublicHeaderSize = MaxPacketSize - 12 /*crypto signature*/ // ethernet's max size, minus the IP and UDP headers. IPv6 has a 40 byte header,
// UDP adds an additional 8 bytes. This is a total overhead of 48 bytes.
// Ethernet's max packet size is 1500 bytes, 1500 - 48 = 1452.
const MaxReceivePacketSize ByteCount = 1452
// DefaultTCPMSS is the default maximum packet size used in the Linux TCP implementation. // DefaultTCPMSS is the default maximum packet size used in the Linux TCP implementation.
// Used in QUIC for congestion window computations in bytes. // Used in QUIC for congestion window computations in bytes.

View File

@@ -2,6 +2,13 @@ package protocol
import "time" import "time"
// MaxPacketSize is the maximum packet size, including the public header, that we use for sending packets
// This is the value used by Chromium for a QUIC packet sent using IPv6 (for IPv4 it would be 1370)
const MaxPacketSize ByteCount = 1350
// MaxFrameAndPublicHeaderSize is the maximum size of a QUIC frame plus PublicHeader
const MaxFrameAndPublicHeaderSize = MaxPacketSize - 12 /*crypto signature*/
// NonForwardSecurePacketSizeReduction is the number of bytes a non forward-secure packet has to be smaller than a forward-secure packet // NonForwardSecurePacketSizeReduction is the number of bytes a non forward-secure packet has to be smaller than a forward-secure packet
// This makes sure that those packets can always be retransmitted without splitting the contained StreamFrames // This makes sure that those packets can always be retransmitted without splitting the contained StreamFrames
const NonForwardSecurePacketSizeReduction = 50 const NonForwardSecurePacketSizeReduction = 50

View File

@@ -83,7 +83,7 @@ func Listen(conn net.PacketConn, config *Config) (Listener, error) {
func (s *server) Serve() error { func (s *server) Serve() error {
for { for {
data := getPacketBuffer() data := getPacketBuffer()
data = data[:protocol.MaxPacketSize] data = data[:protocol.MaxReceivePacketSize]
n, remoteAddr, err := s.conn.ReadFrom(data) n, remoteAddr, err := s.conn.ReadFrom(data)
if err != nil { if err != nil {
if strings.HasSuffix(err.Error(), "use of closed network connection") { if strings.HasSuffix(err.Error(), "use of closed network connection") {
@@ -122,7 +122,7 @@ func (s *server) Addr() net.Addr {
} }
func (s *server) handlePacket(pconn net.PacketConn, remoteAddr net.Addr, packet []byte) error { func (s *server) handlePacket(pconn net.PacketConn, remoteAddr net.Addr, packet []byte) error {
if protocol.ByteCount(len(packet)) > protocol.MaxPacketSize { if protocol.ByteCount(len(packet)) > protocol.MaxReceivePacketSize {
return qerr.PacketTooLarge return qerr.PacketTooLarge
} }

View File

@@ -253,7 +253,7 @@ var _ = Describe("Server", func() {
}) })
It("errors on large packets", func() { It("errors on large packets", func() {
err := serv.handlePacket(nil, nil, bytes.Repeat([]byte{'a'}, int(protocol.MaxPacketSize)+1)) err := serv.handlePacket(nil, nil, bytes.Repeat([]byte{'a'}, int(protocol.MaxReceivePacketSize)+1))
Expect(err).To(MatchError(qerr.PacketTooLarge)) Expect(err).To(MatchError(qerr.PacketTooLarge))
}) })