forked from quic-go/quic-go
Merge pull request #3041 from lucas-clemente/send-immediately-before-handshake-completion
only read multiple packets at a time after handshake completion
This commit is contained in:
32
session.go
32
session.go
@@ -596,24 +596,26 @@ runLoop:
|
|||||||
break runLoop
|
break runLoop
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
// Now process all packets in the receivedPackets channel.
|
if s.handshakeComplete {
|
||||||
// Limit the number of packets to the length of the receivedPackets channel,
|
// Now process all packets in the receivedPackets channel.
|
||||||
// so we eventually get a chance to send out an ACK when receiving a lot of packets.
|
// Limit the number of packets to the length of the receivedPackets channel,
|
||||||
numPackets := len(s.receivedPackets)
|
// so we eventually get a chance to send out an ACK when receiving a lot of packets.
|
||||||
receiveLoop:
|
numPackets := len(s.receivedPackets)
|
||||||
for i := 0; i < numPackets; i++ {
|
receiveLoop:
|
||||||
select {
|
for i := 0; i < numPackets; i++ {
|
||||||
case p := <-s.receivedPackets:
|
|
||||||
if processed := s.handlePacketImpl(p); processed {
|
|
||||||
wasProcessed = true
|
|
||||||
}
|
|
||||||
select {
|
select {
|
||||||
case closeErr = <-s.closeChan:
|
case p := <-s.receivedPackets:
|
||||||
break runLoop
|
if processed := s.handlePacketImpl(p); processed {
|
||||||
|
wasProcessed = true
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
case closeErr = <-s.closeChan:
|
||||||
|
break runLoop
|
||||||
|
default:
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
|
break receiveLoop
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
break receiveLoop
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Only reset the timers if this packet was actually processed.
|
// Only reset the timers if this packet was actually processed.
|
||||||
|
|||||||
@@ -902,6 +902,51 @@ var _ = Describe("Session", func() {
|
|||||||
Eventually(sess.Context().Done()).Should(BeClosed())
|
Eventually(sess.Context().Done()).Should(BeClosed())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("doesn't processes multiple received packets before sending one before handshake completion", func() {
|
||||||
|
sess.handshakeComplete = false
|
||||||
|
sess.sessionCreationTime = time.Now()
|
||||||
|
var pn protocol.PacketNumber
|
||||||
|
unpacker.EXPECT().Unpack(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(hdr *wire.Header, rcvTime time.Time, data []byte) (*unpackedPacket, error) {
|
||||||
|
pn++
|
||||||
|
return &unpackedPacket{
|
||||||
|
data: []byte{0}, // PADDING frame
|
||||||
|
encryptionLevel: protocol.Encryption1RTT,
|
||||||
|
packetNumber: pn,
|
||||||
|
hdr: &wire.ExtendedHeader{Header: *hdr},
|
||||||
|
}, nil
|
||||||
|
}).Times(3)
|
||||||
|
tracer.EXPECT().StartedConnection(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
|
||||||
|
tracer.EXPECT().ReceivedPacket(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(hdr *wire.ExtendedHeader, _ protocol.ByteCount, _ []logging.Frame) {
|
||||||
|
}).Times(3)
|
||||||
|
packer.EXPECT().PackCoalescedPacket().Times(3) // only expect a single call
|
||||||
|
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
sess.handlePacket(getPacket(&wire.ExtendedHeader{
|
||||||
|
Header: wire.Header{DestConnectionID: srcConnID},
|
||||||
|
PacketNumber: 0x1337,
|
||||||
|
PacketNumberLen: protocol.PacketNumberLen2,
|
||||||
|
}, []byte("foobar")))
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
defer GinkgoRecover()
|
||||||
|
cryptoSetup.EXPECT().RunHandshake().MaxTimes(1)
|
||||||
|
sess.run()
|
||||||
|
}()
|
||||||
|
Consistently(sess.Context().Done()).ShouldNot(BeClosed())
|
||||||
|
|
||||||
|
// make the go routine return
|
||||||
|
streamManager.EXPECT().CloseWithError(gomock.Any())
|
||||||
|
cryptoSetup.EXPECT().Close()
|
||||||
|
packer.EXPECT().PackConnectionClose(gomock.Any()).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil)
|
||||||
|
expectReplaceWithClosed()
|
||||||
|
tracer.EXPECT().ClosedConnection(gomock.Any())
|
||||||
|
tracer.EXPECT().Close()
|
||||||
|
mconn.EXPECT().Write(gomock.Any())
|
||||||
|
sess.closeLocal(errors.New("close"))
|
||||||
|
Eventually(sess.Context().Done()).Should(BeClosed())
|
||||||
|
})
|
||||||
|
|
||||||
It("closes the session when unpacking fails because the reserved bits were incorrect", func() {
|
It("closes the session when unpacking fails because the reserved bits were incorrect", func() {
|
||||||
unpacker.EXPECT().Unpack(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, wire.ErrInvalidReservedBits)
|
unpacker.EXPECT().Unpack(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, wire.ErrInvalidReservedBits)
|
||||||
streamManager.EXPECT().CloseWithError(gomock.Any())
|
streamManager.EXPECT().CloseWithError(gomock.Any())
|
||||||
|
|||||||
Reference in New Issue
Block a user