github.com/quic-go/quic-go@v0.44.0/retransmission_queue_test.go (about) 1 package quic 2 3 import ( 4 "github.com/quic-go/quic-go/internal/protocol" 5 "github.com/quic-go/quic-go/internal/wire" 6 7 . "github.com/onsi/ginkgo/v2" 8 . "github.com/onsi/gomega" 9 ) 10 11 var _ = Describe("Retransmission queue", func() { 12 var q *retransmissionQueue 13 14 BeforeEach(func() { 15 q = newRetransmissionQueue() 16 }) 17 18 Context("Initial data", func() { 19 It("doesn't dequeue anything when it's empty", func() { 20 Expect(q.HasInitialData()).To(BeFalse()) 21 Expect(q.GetInitialFrame(protocol.MaxByteCount, protocol.Version1)).To(BeNil()) 22 }) 23 24 It("queues and retrieves a control frame", func() { 25 f := &wire.MaxDataFrame{MaximumData: 0x42} 26 q.addInitial(f) 27 Expect(q.HasInitialData()).To(BeTrue()) 28 Expect(q.GetInitialFrame(f.Length(protocol.Version1)-1, protocol.Version1)).To(BeNil()) 29 Expect(q.GetInitialFrame(f.Length(protocol.Version1), protocol.Version1)).To(Equal(f)) 30 Expect(q.HasInitialData()).To(BeFalse()) 31 }) 32 33 It("queues and retrieves a CRYPTO frame", func() { 34 f := &wire.CryptoFrame{Data: []byte("foobar")} 35 q.addInitial(f) 36 Expect(q.HasInitialData()).To(BeTrue()) 37 Expect(q.GetInitialFrame(f.Length(protocol.Version1), protocol.Version1)).To(Equal(f)) 38 Expect(q.HasInitialData()).To(BeFalse()) 39 }) 40 41 It("returns split CRYPTO frames", func() { 42 f := &wire.CryptoFrame{ 43 Offset: 100, 44 Data: []byte("foobar"), 45 } 46 q.addInitial(f) 47 Expect(q.HasInitialData()).To(BeTrue()) 48 f1 := q.GetInitialFrame(f.Length(protocol.Version1)-3, protocol.Version1) 49 Expect(f1).ToNot(BeNil()) 50 Expect(f1).To(BeAssignableToTypeOf(&wire.CryptoFrame{})) 51 Expect(f1.(*wire.CryptoFrame).Data).To(Equal([]byte("foo"))) 52 Expect(f1.(*wire.CryptoFrame).Offset).To(Equal(protocol.ByteCount(100))) 53 Expect(q.HasInitialData()).To(BeTrue()) 54 f2 := q.GetInitialFrame(protocol.MaxByteCount, protocol.Version1) 55 Expect(f2).ToNot(BeNil()) 56 Expect(f2).To(BeAssignableToTypeOf(&wire.CryptoFrame{})) 57 Expect(f2.(*wire.CryptoFrame).Data).To(Equal([]byte("bar"))) 58 Expect(f2.(*wire.CryptoFrame).Offset).To(Equal(protocol.ByteCount(103))) 59 Expect(q.HasInitialData()).To(BeFalse()) 60 }) 61 62 It("returns other frames when a CRYPTO frame wouldn't fit", func() { 63 f := &wire.CryptoFrame{Data: []byte("foobar")} 64 q.addInitial(f) 65 q.addInitial(&wire.PingFrame{}) 66 f1 := q.GetInitialFrame(2, protocol.Version1) // too small for a CRYPTO frame 67 Expect(f1).ToNot(BeNil()) 68 Expect(f1).To(BeAssignableToTypeOf(&wire.PingFrame{})) 69 Expect(q.HasInitialData()).To(BeTrue()) 70 f2 := q.GetInitialFrame(protocol.MaxByteCount, protocol.Version1) 71 Expect(f2).To(Equal(f)) 72 }) 73 74 It("retrieves both a CRYPTO frame and a control frame", func() { 75 cf := &wire.MaxDataFrame{MaximumData: 0x42} 76 f := &wire.CryptoFrame{Data: []byte("foobar")} 77 q.addInitial(f) 78 q.addInitial(cf) 79 Expect(q.HasInitialData()).To(BeTrue()) 80 Expect(q.GetInitialFrame(protocol.MaxByteCount, protocol.Version1)).To(Equal(f)) 81 Expect(q.GetInitialFrame(protocol.MaxByteCount, protocol.Version1)).To(Equal(cf)) 82 Expect(q.HasInitialData()).To(BeFalse()) 83 }) 84 85 It("drops all Initial frames", func() { 86 q.addInitial(&wire.CryptoFrame{Data: []byte("foobar")}) 87 q.addInitial(&wire.MaxDataFrame{MaximumData: 0x42}) 88 q.DropPackets(protocol.EncryptionInitial) 89 Expect(q.HasInitialData()).To(BeFalse()) 90 Expect(q.GetInitialFrame(protocol.MaxByteCount, protocol.Version1)).To(BeNil()) 91 }) 92 93 It("retransmits a frame", func() { 94 f := &wire.MaxDataFrame{MaximumData: 0x42} 95 q.InitialAckHandler().OnLost(f) 96 Expect(q.HasInitialData()).To(BeTrue()) 97 Expect(q.GetInitialFrame(protocol.MaxByteCount, protocol.Version1)).To(Equal(f)) 98 }) 99 100 It("adds a PING", func() { 101 q.AddPing(protocol.EncryptionInitial) 102 Expect(q.HasInitialData()).To(BeTrue()) 103 Expect(q.GetInitialFrame(protocol.MaxByteCount, protocol.Version1)).To(Equal(&wire.PingFrame{})) 104 }) 105 }) 106 107 Context("Handshake data", func() { 108 It("doesn't dequeue anything when it's empty", func() { 109 Expect(q.HasHandshakeData()).To(BeFalse()) 110 Expect(q.GetHandshakeFrame(protocol.MaxByteCount, protocol.Version1)).To(BeNil()) 111 }) 112 113 It("queues and retrieves a control frame", func() { 114 f := &wire.MaxDataFrame{MaximumData: 0x42} 115 q.addHandshake(f) 116 Expect(q.HasHandshakeData()).To(BeTrue()) 117 Expect(q.GetHandshakeFrame(f.Length(protocol.Version1)-1, protocol.Version1)).To(BeNil()) 118 Expect(q.GetHandshakeFrame(f.Length(protocol.Version1), protocol.Version1)).To(Equal(f)) 119 Expect(q.HasHandshakeData()).To(BeFalse()) 120 }) 121 122 It("queues and retrieves a CRYPTO frame", func() { 123 f := &wire.CryptoFrame{Data: []byte("foobar")} 124 q.addHandshake(f) 125 Expect(q.HasHandshakeData()).To(BeTrue()) 126 Expect(q.GetHandshakeFrame(f.Length(protocol.Version1), protocol.Version1)).To(Equal(f)) 127 Expect(q.HasHandshakeData()).To(BeFalse()) 128 }) 129 130 It("returns split CRYPTO frames", func() { 131 f := &wire.CryptoFrame{ 132 Offset: 100, 133 Data: []byte("foobar"), 134 } 135 q.addHandshake(f) 136 Expect(q.HasHandshakeData()).To(BeTrue()) 137 f1 := q.GetHandshakeFrame(f.Length(protocol.Version1)-3, protocol.Version1) 138 Expect(f1).ToNot(BeNil()) 139 Expect(f1).To(BeAssignableToTypeOf(&wire.CryptoFrame{})) 140 Expect(f1.(*wire.CryptoFrame).Data).To(Equal([]byte("foo"))) 141 Expect(f1.(*wire.CryptoFrame).Offset).To(Equal(protocol.ByteCount(100))) 142 Expect(q.HasHandshakeData()).To(BeTrue()) 143 f2 := q.GetHandshakeFrame(protocol.MaxByteCount, protocol.Version1) 144 Expect(f2).ToNot(BeNil()) 145 Expect(f2).To(BeAssignableToTypeOf(&wire.CryptoFrame{})) 146 Expect(f2.(*wire.CryptoFrame).Data).To(Equal([]byte("bar"))) 147 Expect(f2.(*wire.CryptoFrame).Offset).To(Equal(protocol.ByteCount(103))) 148 Expect(q.HasHandshakeData()).To(BeFalse()) 149 }) 150 151 It("returns other frames when a CRYPTO frame wouldn't fit", func() { 152 f := &wire.CryptoFrame{Data: []byte("foobar")} 153 q.addHandshake(f) 154 q.addHandshake(&wire.PingFrame{}) 155 f1 := q.GetHandshakeFrame(2, protocol.Version1) // too small for a CRYPTO frame 156 Expect(f1).ToNot(BeNil()) 157 Expect(f1).To(BeAssignableToTypeOf(&wire.PingFrame{})) 158 Expect(q.HasHandshakeData()).To(BeTrue()) 159 f2 := q.GetHandshakeFrame(protocol.MaxByteCount, protocol.Version1) 160 Expect(f2).To(Equal(f)) 161 }) 162 163 It("retrieves both a CRYPTO frame and a control frame", func() { 164 cf := &wire.MaxDataFrame{MaximumData: 0x42} 165 f := &wire.CryptoFrame{Data: []byte("foobar")} 166 q.addHandshake(f) 167 q.addHandshake(cf) 168 Expect(q.HasHandshakeData()).To(BeTrue()) 169 Expect(q.GetHandshakeFrame(protocol.MaxByteCount, protocol.Version1)).To(Equal(f)) 170 Expect(q.GetHandshakeFrame(protocol.MaxByteCount, protocol.Version1)).To(Equal(cf)) 171 Expect(q.HasHandshakeData()).To(BeFalse()) 172 }) 173 174 It("drops all Handshake frames", func() { 175 q.addHandshake(&wire.CryptoFrame{Data: []byte("foobar")}) 176 q.addHandshake(&wire.MaxDataFrame{MaximumData: 0x42}) 177 q.DropPackets(protocol.EncryptionHandshake) 178 Expect(q.HasHandshakeData()).To(BeFalse()) 179 Expect(q.GetHandshakeFrame(protocol.MaxByteCount, protocol.Version1)).To(BeNil()) 180 }) 181 182 It("retransmits a frame", func() { 183 f := &wire.MaxDataFrame{MaximumData: 0x42} 184 q.HandshakeAckHandler().OnLost(f) 185 Expect(q.HasHandshakeData()).To(BeTrue()) 186 Expect(q.GetHandshakeFrame(protocol.MaxByteCount, protocol.Version1)).To(Equal(f)) 187 }) 188 189 It("adds a PING", func() { 190 q.AddPing(protocol.EncryptionHandshake) 191 Expect(q.HasHandshakeData()).To(BeTrue()) 192 Expect(q.GetHandshakeFrame(protocol.MaxByteCount, protocol.Version1)).To(Equal(&wire.PingFrame{})) 193 }) 194 }) 195 196 Context("Application data", func() { 197 It("doesn't dequeue anything when it's empty", func() { 198 Expect(q.GetAppDataFrame(protocol.MaxByteCount, protocol.Version1)).To(BeNil()) 199 }) 200 201 It("queues and retrieves a control frame", func() { 202 f := &wire.MaxDataFrame{MaximumData: 0x42} 203 Expect(q.HasAppData()).To(BeFalse()) 204 q.addAppData(f) 205 Expect(q.HasAppData()).To(BeTrue()) 206 Expect(q.GetAppDataFrame(f.Length(protocol.Version1)-1, protocol.Version1)).To(BeNil()) 207 Expect(q.GetAppDataFrame(f.Length(protocol.Version1), protocol.Version1)).To(Equal(f)) 208 Expect(q.HasAppData()).To(BeFalse()) 209 }) 210 211 It("retransmits a frame", func() { 212 f := &wire.MaxDataFrame{MaximumData: 0x42} 213 q.AppDataAckHandler().OnLost(f) 214 Expect(q.HasAppData()).To(BeTrue()) 215 Expect(q.GetAppDataFrame(protocol.MaxByteCount, protocol.Version1)).To(Equal(f)) 216 }) 217 218 It("adds a PING", func() { 219 q.AddPing(protocol.Encryption1RTT) 220 Expect(q.HasAppData()).To(BeTrue()) 221 Expect(q.GetAppDataFrame(protocol.MaxByteCount, protocol.Version1)).To(Equal(&wire.PingFrame{})) 222 }) 223 }) 224 })