forked from quic-go/quic-go
/
stop_waiting_frame.go
77 lines (67 loc) · 2.45 KB
/
stop_waiting_frame.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package wire
import (
"bytes"
"errors"
"github.com/lucas-clemente/quic-go/internal/protocol"
"github.com/lucas-clemente/quic-go/internal/utils"
)
// A StopWaitingFrame in QUIC
type StopWaitingFrame struct {
LeastUnacked protocol.PacketNumber
PacketNumberLen protocol.PacketNumberLen
// PacketNumber is the packet number of the packet that this StopWaitingFrame will be sent with
PacketNumber protocol.PacketNumber
}
var (
errLeastUnackedHigherThanPacketNumber = errors.New("StopWaitingFrame: LeastUnacked can't be greater than the packet number")
errPacketNumberNotSet = errors.New("StopWaitingFrame: PacketNumber not set")
errPacketNumberLenNotSet = errors.New("StopWaitingFrame: PacketNumberLen not set")
)
func (f *StopWaitingFrame) Write(b *bytes.Buffer, v protocol.VersionNumber) error {
if v.UsesIETFFrameFormat() {
return errors.New("STOP_WAITING not defined in IETF QUIC")
}
// make sure the PacketNumber was set
if f.PacketNumber == protocol.PacketNumber(0) {
return errPacketNumberNotSet
}
if f.LeastUnacked > f.PacketNumber {
return errLeastUnackedHigherThanPacketNumber
}
b.WriteByte(0x06)
leastUnackedDelta := uint64(f.PacketNumber - f.LeastUnacked)
switch f.PacketNumberLen {
case protocol.PacketNumberLen1:
b.WriteByte(uint8(leastUnackedDelta))
case protocol.PacketNumberLen2:
utils.BigEndian.WriteUint16(b, uint16(leastUnackedDelta))
case protocol.PacketNumberLen4:
utils.BigEndian.WriteUint32(b, uint32(leastUnackedDelta))
case protocol.PacketNumberLen6:
utils.BigEndian.WriteUint48(b, leastUnackedDelta&(1<<48-1))
default:
return errPacketNumberLenNotSet
}
return nil
}
// Length of a written frame
func (f *StopWaitingFrame) Length(_ protocol.VersionNumber) protocol.ByteCount {
return 1 + protocol.ByteCount(f.PacketNumberLen)
}
// parseStopWaitingFrame parses a StopWaiting frame
func parseStopWaitingFrame(r *bytes.Reader, packetNumber protocol.PacketNumber, packetNumberLen protocol.PacketNumberLen, _ protocol.VersionNumber) (*StopWaitingFrame, error) {
frame := &StopWaitingFrame{}
// read the TypeByte
if _, err := r.ReadByte(); err != nil {
return nil, err
}
leastUnackedDelta, err := utils.BigEndian.ReadUintN(r, uint8(packetNumberLen))
if err != nil {
return nil, err
}
if leastUnackedDelta > uint64(packetNumber) {
return nil, errors.New("invalid LeastUnackedDelta")
}
frame.LeastUnacked = protocol.PacketNumber(uint64(packetNumber) - leastUnackedDelta)
return frame, nil
}