mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-05 05:07: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()
|
buf := getLargePacketBuffer()
|
||||||
maxSize := s.mtuDiscoverer.CurrentSize()
|
maxSize := s.mtuDiscoverer.CurrentSize()
|
||||||
|
|
||||||
|
ecn := s.sentPacketHandler.ECNMode(true)
|
||||||
for {
|
for {
|
||||||
var dontSendMore bool
|
var dontSendMore bool
|
||||||
ecn := s.sentPacketHandler.ECNMode(true)
|
|
||||||
size, err := s.appendOneShortHeaderPacket(buf, maxSize, ecn, now)
|
size, err := s.appendOneShortHeaderPacket(buf, maxSize, ecn, now)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err != errNothingToPack {
|
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
|
// Append another packet if
|
||||||
// 1. The congestion controller and pacer allow sending more
|
// 1. The congestion controller and pacer allow sending more
|
||||||
// 2. The last packet appended was a full-size packet
|
// 2. The last packet appended was a full-size packet
|
||||||
// 3. We still have enough space for another full-size packet in the buffer
|
// 3. The next packet will have the same ECN marking
|
||||||
if !dontSendMore && size == maxSize && buf.Len()+maxSize <= buf.Cap() {
|
// 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
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1451,7 +1451,7 @@ var _ = Describe("Connection", func() {
|
||||||
It("sends multiple packets one by one immediately, with GSO", func() {
|
It("sends multiple packets one by one immediately, with GSO", func() {
|
||||||
enableGSO()
|
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().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)
|
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).Times(3)
|
||||||
payload1 := make([]byte, conn.mtuDiscoverer.CurrentSize())
|
payload1 := make([]byte, conn.mtuDiscoverer.CurrentSize())
|
||||||
rand.Read(payload1)
|
rand.Read(payload1)
|
||||||
|
@ -1476,20 +1476,59 @@ var _ = Describe("Connection", func() {
|
||||||
|
|
||||||
It("stops appending packets when a smaller packet is packed, with GSO", func() {
|
It("stops appending packets when a smaller packet is packed, with GSO", func() {
|
||||||
enableGSO()
|
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().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(2)
|
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendAny).Times(3)
|
||||||
sph.EXPECT().ECNMode(true).Times(2)
|
|
||||||
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendNone)
|
sph.EXPECT().SendMode(gomock.Any()).Return(ackhandler.SendNone)
|
||||||
|
sph.EXPECT().ECNMode(true).Times(4)
|
||||||
payload1 := make([]byte, conn.mtuDiscoverer.CurrentSize())
|
payload1 := make([]byte, conn.mtuDiscoverer.CurrentSize())
|
||||||
rand.Read(payload1)
|
rand.Read(payload1)
|
||||||
payload2 := make([]byte, conn.mtuDiscoverer.CurrentSize()-1)
|
payload2 := make([]byte, conn.mtuDiscoverer.CurrentSize()-1)
|
||||||
rand.Read(payload2)
|
rand.Read(payload2)
|
||||||
|
payload3 := make([]byte, conn.mtuDiscoverer.CurrentSize())
|
||||||
|
rand.Read(payload3)
|
||||||
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 10}, payload1)
|
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 10}, payload1)
|
||||||
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 11}, payload2)
|
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 11}, payload2)
|
||||||
|
expectAppendPacket(packer, shortHeaderPacket{PacketNumber: 12}, payload3)
|
||||||
sender.EXPECT().WouldBlock().AnyTimes()
|
sender.EXPECT().WouldBlock().AnyTimes()
|
||||||
sender.EXPECT().Send(gomock.Any(), uint16(conn.mtuDiscoverer.CurrentSize()), gomock.Any()).Do(func(b *packetBuffer, _ uint16, _ protocol.ECN) {
|
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...)))
|
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() {
|
go func() {
|
||||||
defer GinkgoRecover()
|
defer GinkgoRecover()
|
||||||
cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
|
cryptoSetup.EXPECT().StartHandshake().MaxTimes(1)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue