mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-06 13:47:35 +03:00
implement parsing of ACK_ECN frames
This commit is contained in:
parent
6f0a027f0f
commit
3d087d522c
5 changed files with 68 additions and 2 deletions
|
@ -17,6 +17,7 @@
|
|||
"vet"
|
||||
],
|
||||
"Linters": {
|
||||
"vet": "go tool vet -printfuncs=Infof,Debugf,Warningf,Errorf:PATH:LINE:MESSAGE"
|
||||
"vet": "go tool vet -printfuncs=Infof,Debugf,Warningf,Errorf:PATH:LINE:MESSAGE",
|
||||
"misspell": "misspell -i ect:PATH:LINE:COL:MESSAGE"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,16 @@ type AckFrame struct {
|
|||
DelayTime time.Duration
|
||||
}
|
||||
|
||||
// parseAckFrame reads an ACK frame
|
||||
func parseAckFrame(r *bytes.Reader, version protocol.VersionNumber) (*AckFrame, error) {
|
||||
return parseAckOrAckEcnFrame(r, false, version)
|
||||
}
|
||||
|
||||
func parseAckEcnFrame(r *bytes.Reader, version protocol.VersionNumber) (*AckFrame, error) {
|
||||
return parseAckOrAckEcnFrame(r, true, version)
|
||||
}
|
||||
|
||||
// parseAckFrame reads an ACK frame
|
||||
func parseAckOrAckEcnFrame(r *bytes.Reader, ecn bool, version protocol.VersionNumber) (*AckFrame, error) {
|
||||
if !version.UsesIETFFrameFormat() {
|
||||
return parseAckFrameLegacy(r, version)
|
||||
}
|
||||
|
@ -41,6 +49,15 @@ func parseAckFrame(r *bytes.Reader, version protocol.VersionNumber) (*AckFrame,
|
|||
return nil, err
|
||||
}
|
||||
frame.DelayTime = time.Duration(delay*1<<ackDelayExponent) * time.Microsecond
|
||||
|
||||
if ecn {
|
||||
for i := 0; i < 3; i++ {
|
||||
if _, err := utils.ReadVarInt(r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
numBlocks, err := utils.ReadVarInt(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -366,3 +366,45 @@ var _ = Describe("ACK Frame (for IETF QUIC)", func() {
|
|||
})
|
||||
})
|
||||
})
|
||||
|
||||
var _ = Describe("ACK_ECN frame", func() {
|
||||
Context("parsing", func() {
|
||||
It("parses an ACK_ECN frame", func() {
|
||||
data := []byte{0xd}
|
||||
data = append(data, encodeVarInt(100)...) // largest acked
|
||||
data = append(data, encodeVarInt(0)...) // delay
|
||||
data = append(data, encodeVarInt(0x42)...) // ECT(0)
|
||||
data = append(data, encodeVarInt(0x12345)...) // ECT(1)
|
||||
data = append(data, encodeVarInt(0x12345678)...) // ECN-CE
|
||||
data = append(data, encodeVarInt(0)...) // num blocks
|
||||
data = append(data, encodeVarInt(10)...) // first ack block
|
||||
b := bytes.NewReader(data)
|
||||
frame, err := parseAckEcnFrame(b, versionIETFFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(frame.LargestAcked()).To(Equal(protocol.PacketNumber(100)))
|
||||
Expect(frame.LowestAcked()).To(Equal(protocol.PacketNumber(90)))
|
||||
Expect(frame.HasMissingRanges()).To(BeFalse())
|
||||
Expect(b.Len()).To(BeZero())
|
||||
})
|
||||
|
||||
It("errors on EOF", func() {
|
||||
data := []byte{0x1a}
|
||||
data = append(data, encodeVarInt(1000)...) // largest acked
|
||||
data = append(data, encodeVarInt(0)...) // delay
|
||||
data = append(data, encodeVarInt(0x42)...) // ECT(0)
|
||||
data = append(data, encodeVarInt(0x12345)...) // ECT(1)
|
||||
data = append(data, encodeVarInt(0x12345678)...) // ECN-CE
|
||||
data = append(data, encodeVarInt(1)...) // num blocks
|
||||
data = append(data, encodeVarInt(100)...) // first ack block
|
||||
data = append(data, encodeVarInt(98)...) // gap
|
||||
data = append(data, encodeVarInt(50)...) // ack block
|
||||
_, err := parseAckEcnFrame(bytes.NewReader(data), versionIETFFrames)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
for i := range data {
|
||||
_, err := parseAckEcnFrame(bytes.NewReader(data[0:i]), versionIETFFrames)
|
||||
Expect(err).To(MatchError(io.EOF))
|
||||
}
|
||||
})
|
||||
|
||||
})
|
||||
})
|
||||
|
|
|
@ -100,6 +100,11 @@ func parseIETFFrame(r *bytes.Reader, typeByte byte, v protocol.VersionNumber) (F
|
|||
if err != nil {
|
||||
err = qerr.Error(qerr.InvalidFrameData, err.Error())
|
||||
}
|
||||
case 0x1a:
|
||||
frame, err = parseAckEcnFrame(r, v)
|
||||
if err != nil {
|
||||
err = qerr.Error(qerr.InvalidAckData, err.Error())
|
||||
}
|
||||
default:
|
||||
err = qerr.Error(qerr.InvalidFrameData, fmt.Sprintf("unknown type byte 0x%x", typeByte))
|
||||
}
|
||||
|
|
|
@ -331,6 +331,7 @@ var _ = Describe("Frame parsing", func() {
|
|||
0x0e: qerr.InvalidFrameData,
|
||||
0x0f: qerr.InvalidFrameData,
|
||||
0x10: qerr.InvalidStreamData,
|
||||
0x1a: qerr.InvalidAckData,
|
||||
} {
|
||||
_, err := ParseNextFrame(bytes.NewReader([]byte{b}), nil, versionIETFFrames)
|
||||
Expect(err).To(HaveOccurred())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue