mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-03 20:27:35 +03:00
report retransmissions separately to the sent packet handler
This commit is contained in:
parent
dc4a9b1d86
commit
56720edc34
6 changed files with 69 additions and 26 deletions
|
@ -11,6 +11,7 @@ import (
|
|||
type SentPacketHandler interface {
|
||||
// SentPacket may modify the packet
|
||||
SentPacket(packet *Packet)
|
||||
SentPacketsAsRetransmission(packets []*Packet, retransmissionOf protocol.PacketNumber)
|
||||
ReceivedAck(ackFrame *wire.AckFrame, withPacketNumber protocol.PacketNumber, encLevel protocol.EncryptionLevel, recvTime time.Time) error
|
||||
SetHandshakeComplete()
|
||||
|
||||
|
|
|
@ -150,6 +150,12 @@ func (h *sentPacketHandler) SentPacket(packet *Packet) {
|
|||
h.updateLossDetectionAlarm(now)
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) SentPacketsAsRetransmission(packets []*Packet, retransmissionOf protocol.PacketNumber) {
|
||||
for _, packet := range packets {
|
||||
h.SentPacket(packet)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) ReceivedAck(ackFrame *wire.AckFrame, withPacketNumber protocol.PacketNumber, encLevel protocol.EncryptionLevel, rcvTime time.Time) error {
|
||||
if ackFrame.LargestAcked > h.lastSentPacketNumber {
|
||||
return qerr.Error(qerr.InvalidAckData, "Received ACK for an unsent package")
|
||||
|
|
|
@ -141,6 +141,16 @@ func (mr *MockSentPacketHandlerMockRecorder) SentPacket(arg0 interface{}) *gomoc
|
|||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentPacket", reflect.TypeOf((*MockSentPacketHandler)(nil).SentPacket), arg0)
|
||||
}
|
||||
|
||||
// SentPacketsAsRetransmission mocks base method
|
||||
func (m *MockSentPacketHandler) SentPacketsAsRetransmission(arg0 []*ackhandler.Packet, arg1 protocol.PacketNumber) {
|
||||
m.ctrl.Call(m, "SentPacketsAsRetransmission", arg0, arg1)
|
||||
}
|
||||
|
||||
// SentPacketsAsRetransmission indicates an expected call of SentPacketsAsRetransmission
|
||||
func (mr *MockSentPacketHandlerMockRecorder) SentPacketsAsRetransmission(arg0, arg1 interface{}) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SentPacketsAsRetransmission", reflect.TypeOf((*MockSentPacketHandler)(nil).SentPacketsAsRetransmission), arg0, arg1)
|
||||
}
|
||||
|
||||
// SetHandshakeComplete mocks base method
|
||||
func (m *MockSentPacketHandler) SetHandshakeComplete() {
|
||||
m.ctrl.Call(m, "SetHandshakeComplete")
|
||||
|
|
|
@ -21,6 +21,16 @@ type packedPacket struct {
|
|||
encryptionLevel protocol.EncryptionLevel
|
||||
}
|
||||
|
||||
func (p *packedPacket) ToAckHandlerPacket() *ackhandler.Packet {
|
||||
return &ackhandler.Packet{
|
||||
PacketNumber: p.header.PacketNumber,
|
||||
PacketType: p.header.Type,
|
||||
Frames: p.frames,
|
||||
Length: protocol.ByteCount(len(p.raw)),
|
||||
EncryptionLevel: p.encryptionLevel,
|
||||
}
|
||||
}
|
||||
|
||||
type streamFrameSource interface {
|
||||
HasCryptoStreamData() bool
|
||||
PopCryptoStreamFrame(protocol.ByteCount) *wire.StreamFrame
|
||||
|
|
14
session.go
14
session.go
|
@ -838,6 +838,7 @@ func (s *session) maybeSendAckOnlyPacket() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.sentPacketHandler.SentPacket(packet.ToAckHandlerPacket())
|
||||
return s.sendPackedPacket(packet)
|
||||
}
|
||||
|
||||
|
@ -874,6 +875,11 @@ func (s *session) maybeSendRetransmission() (bool, error) {
|
|||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
ackhandlerPackets := make([]*ackhandler.Packet, len(packets))
|
||||
for i, packet := range packets {
|
||||
ackhandlerPackets[i] = packet.ToAckHandlerPacket()
|
||||
}
|
||||
s.sentPacketHandler.SentPacketsAsRetransmission(ackhandlerPackets, retransmitPacket.PacketNumber)
|
||||
for _, packet := range packets {
|
||||
if err := s.sendPackedPacket(packet); err != nil {
|
||||
return false, err
|
||||
|
@ -904,6 +910,7 @@ func (s *session) sendPacket() (bool, error) {
|
|||
if err != nil || packet == nil {
|
||||
return false, err
|
||||
}
|
||||
s.sentPacketHandler.SentPacket(packet.ToAckHandlerPacket())
|
||||
if err := s.sendPackedPacket(packet); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@ -912,13 +919,6 @@ func (s *session) sendPacket() (bool, error) {
|
|||
|
||||
func (s *session) sendPackedPacket(packet *packedPacket) error {
|
||||
defer putPacketBuffer(&packet.raw)
|
||||
s.sentPacketHandler.SentPacket(&ackhandler.Packet{
|
||||
PacketNumber: packet.header.PacketNumber,
|
||||
PacketType: packet.header.Type,
|
||||
Frames: packet.frames,
|
||||
Length: protocol.ByteCount(len(packet.raw)),
|
||||
EncryptionLevel: packet.encryptionLevel,
|
||||
})
|
||||
s.logPacket(packet)
|
||||
return s.conn.Write(packet.raw)
|
||||
}
|
||||
|
|
|
@ -759,16 +759,17 @@ var _ = Describe("Session", func() {
|
|||
sph.EXPECT().ShouldSendNumPackets().Return(2)
|
||||
sph.EXPECT().TimeUntilSend()
|
||||
sph.EXPECT().GetStopWaitingFrame(gomock.Any()).Return(&wire.StopWaitingFrame{})
|
||||
sph.EXPECT().SentPacket(gomock.Any()).Do(func(p *ackhandler.Packet) {
|
||||
// retransmitted packet
|
||||
Expect(len(p.Frames)).To(BeNumerically(">", 0))
|
||||
Expect(p.Frames[0]).To(BeAssignableToTypeOf(&wire.StopWaitingFrame{}))
|
||||
})
|
||||
sph.EXPECT().SentPacket(gomock.Any()).Do(func(p *ackhandler.Packet) {
|
||||
// regular packet
|
||||
Expect(p.Frames).To(HaveLen(1))
|
||||
Expect(p.Frames[0]).To(BeAssignableToTypeOf(&wire.MaxDataFrame{}))
|
||||
})
|
||||
gomock.InOrder(
|
||||
sph.EXPECT().SentPacketsAsRetransmission(gomock.Any(), protocol.PacketNumber(10)).Do(func(packets []*ackhandler.Packet, _ protocol.PacketNumber) {
|
||||
Expect(packets).To(HaveLen(1))
|
||||
Expect(len(packets[0].Frames)).To(BeNumerically(">", 0))
|
||||
Expect(packets[0].Frames[0]).To(BeAssignableToTypeOf(&wire.StopWaitingFrame{}))
|
||||
}),
|
||||
sph.EXPECT().SentPacket(gomock.Any()).Do(func(p *ackhandler.Packet) {
|
||||
Expect(p.Frames).To(HaveLen(1))
|
||||
Expect(p.Frames[0]).To(BeAssignableToTypeOf(&wire.MaxDataFrame{}))
|
||||
}),
|
||||
)
|
||||
sess.sentPacketHandler = sph
|
||||
err := sess.sendPackets()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -1000,10 +1001,13 @@ var _ = Describe("Session", func() {
|
|||
swf := &wire.StopWaitingFrame{LeastUnacked: 0x1337}
|
||||
sph.EXPECT().GetStopWaitingFrame(true).Return(swf)
|
||||
sph.EXPECT().DequeuePacketForRetransmission().Return(&ackhandler.Packet{
|
||||
PacketNumber: 42,
|
||||
Frames: []wire.Frame{sf},
|
||||
EncryptionLevel: protocol.EncryptionUnencrypted,
|
||||
})
|
||||
sph.EXPECT().SentPacket(gomock.Any()).Do(func(p *ackhandler.Packet) {
|
||||
sph.EXPECT().SentPacketsAsRetransmission(gomock.Any(), protocol.PacketNumber(42)).Do(func(packets []*ackhandler.Packet, _ protocol.PacketNumber) {
|
||||
Expect(packets).To(HaveLen(1))
|
||||
p := packets[0]
|
||||
Expect(p.EncryptionLevel).To(Equal(protocol.EncryptionUnencrypted))
|
||||
Expect(p.Frames).To(Equal([]wire.Frame{swf, sf}))
|
||||
})
|
||||
|
@ -1018,10 +1022,13 @@ var _ = Describe("Session", func() {
|
|||
sess.packer.version = versionIETFFrames
|
||||
sf := &wire.StreamFrame{StreamID: 1, Data: []byte("foobar")}
|
||||
sph.EXPECT().DequeuePacketForRetransmission().Return(&ackhandler.Packet{
|
||||
PacketNumber: 1337,
|
||||
Frames: []wire.Frame{sf},
|
||||
EncryptionLevel: protocol.EncryptionUnencrypted,
|
||||
})
|
||||
sph.EXPECT().SentPacket(gomock.Any()).Do(func(p *ackhandler.Packet) {
|
||||
sph.EXPECT().SentPacketsAsRetransmission(gomock.Any(), protocol.PacketNumber(1337)).Do(func(packets []*ackhandler.Packet, _ protocol.PacketNumber) {
|
||||
Expect(packets).To(HaveLen(1))
|
||||
p := packets[0]
|
||||
Expect(p.EncryptionLevel).To(Equal(protocol.EncryptionUnencrypted))
|
||||
Expect(p.Frames).To(Equal([]wire.Frame{sf}))
|
||||
})
|
||||
|
@ -1045,7 +1052,9 @@ var _ = Describe("Session", func() {
|
|||
Frames: []wire.Frame{f},
|
||||
EncryptionLevel: protocol.EncryptionForwardSecure,
|
||||
})
|
||||
sph.EXPECT().SentPacket(gomock.Any()).Do(func(p *ackhandler.Packet) {
|
||||
sph.EXPECT().SentPacketsAsRetransmission(gomock.Any(), protocol.PacketNumber(0x1337)).Do(func(packets []*ackhandler.Packet, _ protocol.PacketNumber) {
|
||||
Expect(packets).To(HaveLen(1))
|
||||
p := packets[0]
|
||||
Expect(p.Frames).To(HaveLen(2))
|
||||
Expect(p.Frames[0]).To(BeAssignableToTypeOf(&wire.StopWaitingFrame{}))
|
||||
Expect(p.Frames[1]).To(Equal(f))
|
||||
|
@ -1065,10 +1074,13 @@ var _ = Describe("Session", func() {
|
|||
Data: []byte("foobar"),
|
||||
}
|
||||
sph.EXPECT().DequeuePacketForRetransmission().Return(&ackhandler.Packet{
|
||||
PacketNumber: 42,
|
||||
Frames: []wire.Frame{f},
|
||||
EncryptionLevel: protocol.EncryptionForwardSecure,
|
||||
})
|
||||
sph.EXPECT().SentPacket(gomock.Any()).Do(func(p *ackhandler.Packet) {
|
||||
sph.EXPECT().SentPacketsAsRetransmission(gomock.Any(), protocol.PacketNumber(42)).Do(func(packets []*ackhandler.Packet, _ protocol.PacketNumber) {
|
||||
Expect(packets).To(HaveLen(1))
|
||||
p := packets[0]
|
||||
Expect(p.Frames).To(Equal([]wire.Frame{f}))
|
||||
Expect(p.EncryptionLevel).To(Equal(protocol.EncryptionForwardSecure))
|
||||
})
|
||||
|
@ -1086,14 +1098,18 @@ var _ = Describe("Session", func() {
|
|||
Data: bytes.Repeat([]byte{'b'}, int(protocol.MaxPacketSizeIPv4)*3/2),
|
||||
}
|
||||
sph.EXPECT().DequeuePacketForRetransmission().Return(&ackhandler.Packet{
|
||||
PacketNumber: 42,
|
||||
Frames: []wire.Frame{f},
|
||||
EncryptionLevel: protocol.EncryptionForwardSecure,
|
||||
})
|
||||
sph.EXPECT().SentPacket(gomock.Any()).Do(func(p *ackhandler.Packet) {
|
||||
Expect(p.Frames).To(HaveLen(1))
|
||||
Expect(p.Frames[0]).To(BeAssignableToTypeOf(&wire.StreamFrame{}))
|
||||
Expect(p.EncryptionLevel).To(Equal(protocol.EncryptionForwardSecure))
|
||||
}).Times(2)
|
||||
sph.EXPECT().SentPacketsAsRetransmission(gomock.Any(), protocol.PacketNumber(42)).Do(func(packets []*ackhandler.Packet, _ protocol.PacketNumber) {
|
||||
Expect(packets).To(HaveLen(2))
|
||||
for _, p := range packets {
|
||||
Expect(p.Frames).To(HaveLen(1))
|
||||
Expect(p.Frames[0]).To(BeAssignableToTypeOf(&wire.StreamFrame{}))
|
||||
Expect(p.EncryptionLevel).To(Equal(protocol.EncryptionForwardSecure))
|
||||
}
|
||||
})
|
||||
sent, err := sess.maybeSendRetransmission()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(sent).To(BeTrue())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue