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