mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-04 04:37:36 +03:00
stop appending to a GSO batch when the ECN marking changes
This commit is contained in:
parent
f9cfa248da
commit
b6ce91bfe7
2 changed files with 50 additions and 7 deletions
|
@ -1911,9 +1911,9 @@ func (s *connection) sendPacketsWithGSO(now time.Time) error {
|
|||
buf := getLargePacketBuffer()
|
||||
maxSize := s.mtuDiscoverer.CurrentSize()
|
||||
|
||||
ecn := s.sentPacketHandler.ECNMode(true)
|
||||
for {
|
||||
var dontSendMore bool
|
||||
ecn := s.sentPacketHandler.ECNMode(true)
|
||||
size, err := s.appendOneShortHeaderPacket(buf, maxSize, ecn, now)
|
||||
if err != nil {
|
||||
if err != errNothingToPack {
|
||||
|
@ -1936,11 +1936,15 @@ func (s *connection) sendPacketsWithGSO(now time.Time) error {
|
|||
}
|
||||
}
|
||||
|
||||
// Don't send more packets in this batch if they require a different ECN marking than the previous ones.
|
||||
nextECN := s.sentPacketHandler.ECNMode(true)
|
||||
|
||||
// Append another packet if
|
||||
// 1. The congestion controller and pacer allow sending more
|
||||
// 2. The last packet appended was a full-size packet
|
||||
// 3. We still have enough space for another full-size packet in the buffer
|
||||
if !dontSendMore && size == maxSize && buf.Len()+maxSize <= buf.Cap() {
|
||||
// 3. The next packet will have the same ECN marking
|
||||
// 4. We still have enough space for another full-size packet in the buffer
|
||||
if !dontSendMore && size == maxSize && nextECN == ecn && buf.Len()+maxSize <= buf.Cap() {
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
|
@ -1451,7 +1451,7 @@ var _ = Describe("Connection", func() {
|
|||
It("sends multiple packets one by one immediately, with GSO", func() {
|
||||
enableGSO()
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(2)
|
||||
sph.EXPECT().ECNMode(true).Times(3)
|
||||
sph.EXPECT().ECNMode(true).Return(protocol.ECT1).Times(4)
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).Times(3)
|
||||
payload1 := make([]byte, conn.mtuDiscoverer.CurrentSize())
|
||||
rand.Read(payload1)
|
||||
|
@ -1476,20 +1476,59 @@ var _ = Describe("Connection", func() {
|
|||
|
||||
It("stops appending packets when a smaller packet is packed, with GSO", func() {
|
||||
enableGSO()
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(2)
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).Times(2)
|
||||
sph.EXPECT().ECNMode(true).Times(2)
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(3)
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).Times(3)
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendNone)
|
||||
sph.EXPECT().ECNMode(true).Times(4)
|
||||
payload1 := make([]byte, conn.mtuDiscoverer.CurrentSize())
|
||||
rand.Read(payload1)
|
||||
payload2 := make([]byte, conn.mtuDiscoverer.CurrentSize()-1)
|
||||
rand.Read(payload2)
|
||||
payload3 := make([]byte, conn.mtuDiscoverer.CurrentSize())
|
||||
rand.Read(payload3)
|
||||
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 10}, payload1)
|
||||
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 11}, payload2)
|
||||
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 12}, payload3)
|
||||
sender.EXPECT().WouldBlock().AnyTimes()
|
||||
sender.EXPECT().Send(gomock.Any(), uint16(conn.mtuDiscoverer.CurrentSize()), gomock.Any()).Do(func(b *packetBuffer, _ uint16, _ protocol.ECN) {
|
||||
Expect(b.Data).To(Equal(append(payload1, payload2...)))
|
||||
})
|
||||
sender.EXPECT().Send(gomock.Any(), uint16(conn.mtuDiscoverer.CurrentSize()), gomock.Any()).Do(func(b *packetBuffer, _ uint16, _ protocol.ECN) {
|
||||
Expect(b.Data).To(Equal(payload3))
|
||||
})
|
||||
go func() {
|
||||
defer GinkgoRecover()
|
||||
cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
|
||||
cryptoSetup.EXPECT().NextEvent().Return(handshake.Event{Kind: handshake.EventNoEvent})
|
||||
conn.run()
|
||||
}()
|
||||
conn.scheduleSending()
|
||||
time.Sleep(50 * time.Millisecond) // make sure that only 2 packets are sent
|
||||
})
|
||||
|
||||
It("stops appending packets when the ECN marking changes, with GSO", func() {
|
||||
enableGSO()
|
||||
sph.EXPECT().SentPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(3)
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).Times(3)
|
||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendNone)
|
||||
sph.EXPECT().ECNMode(true).Return(protocol.ECT1).Times(2)
|
||||
sph.EXPECT().ECNMode(true).Return(protocol.ECT0).Times(2)
|
||||
payload1 := make([]byte, conn.mtuDiscoverer.CurrentSize())
|
||||
rand.Read(payload1)
|
||||
payload2 := make([]byte, conn.mtuDiscoverer.CurrentSize())
|
||||
rand.Read(payload2)
|
||||
payload3 := make([]byte, conn.mtuDiscoverer.CurrentSize())
|
||||
rand.Read(payload3)
|
||||
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 10}, payload1)
|
||||
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 11}, payload2)
|
||||
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 11}, payload3)
|
||||
sender.EXPECT().WouldBlock().AnyTimes()
|
||||
sender.EXPECT().Send(gomock.Any(), uint16(conn.mtuDiscoverer.CurrentSize()), gomock.Any()).Do(func(b *packetBuffer, _ uint16, _ protocol.ECN) {
|
||||
Expect(b.Data).To(Equal(append(payload1, payload2...)))
|
||||
})
|
||||
sender.EXPECT().Send(gomock.Any(), uint16(conn.mtuDiscoverer.CurrentSize()), gomock.Any()).Do(func(b *packetBuffer, _ uint16, _ protocol.ECN) {
|
||||
Expect(b.Data).To(Equal(payload3))
|
||||
})
|
||||
go func() {
|
||||
defer GinkgoRecover()
|
||||
cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue