forked from quic-go/quic-go
basic ACK frame parsing
This commit is contained in:
86
ack_frame.go
86
ack_frame.go
@@ -9,18 +9,90 @@ import (
|
||||
// An AckFrame in QUIC
|
||||
type AckFrame struct {
|
||||
Entropy byte
|
||||
LargestObserved uint32 // TODO: change to uint64
|
||||
LargestObserved uint64
|
||||
DelayTime uint16 // Todo: properly interpret this value as described in the specification
|
||||
}
|
||||
|
||||
// WriteAckFrame writes an ack frame.
|
||||
// Write writes an ACK frame.
|
||||
func (f *AckFrame) Write(b *bytes.Buffer) error {
|
||||
typeByte := uint8(0x48)
|
||||
b.WriteByte(typeByte)
|
||||
b.WriteByte(f.Entropy)
|
||||
utils.WriteUint32(b, f.LargestObserved)
|
||||
utils.WriteUint16(b, 1) // TODO: Ack delay time
|
||||
b.WriteByte(0x01) // Just one timestamp
|
||||
b.WriteByte(0x00) // Largest observed
|
||||
utils.WriteUint32(b, 0) // First timestamp
|
||||
utils.WriteUint32(b, uint32(f.LargestObserved)) // TODO: send the correct length
|
||||
utils.WriteUint16(b, 1) // TODO: Ack delay time
|
||||
b.WriteByte(0x01) // Just one timestamp
|
||||
b.WriteByte(0x00) // Largest observed
|
||||
utils.WriteUint32(b, 0) // First timestamp
|
||||
return nil
|
||||
}
|
||||
|
||||
// ParseAckFrame reads an ACK frame
|
||||
func ParseAckFrame(r *bytes.Reader, typeByte byte) (*AckFrame, error) {
|
||||
frame := &AckFrame{}
|
||||
|
||||
if typeByte&0x20 == 0x20 {
|
||||
panic("NACK ranges not yet implemented.")
|
||||
}
|
||||
if typeByte&0x10 == 0x10 {
|
||||
panic("truncated ACKs not yet implemented.")
|
||||
}
|
||||
|
||||
var largestObservedLen uint8 = 2 * ((typeByte & 0x0C) >> 2)
|
||||
if largestObservedLen == 0 {
|
||||
largestObservedLen = 1
|
||||
}
|
||||
|
||||
var missingSequenceNumberDeltaLen uint8 = 2 * (typeByte & 0x03)
|
||||
if missingSequenceNumberDeltaLen == 0 {
|
||||
missingSequenceNumberDeltaLen = 1
|
||||
}
|
||||
|
||||
var err error
|
||||
frame.Entropy, err = r.ReadByte()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
frame.LargestObserved, err = utils.ReadUintN(r, largestObservedLen)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
frame.DelayTime, err = utils.ReadUint16(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
numTimestampByte, err := r.ReadByte()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
numTimestamp := uint8(numTimestampByte)
|
||||
|
||||
// Delta Largest observed
|
||||
_, err = r.ReadByte()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// First Timestamp
|
||||
_, err = utils.ReadUint32(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i := 0; i < int(numTimestamp)-1; i++ {
|
||||
// Delta Largest observed
|
||||
_, err = r.ReadByte()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Time Since Previous Timestamp
|
||||
_, err := utils.ReadUint16(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return frame, nil
|
||||
}
|
||||
|
||||
@@ -88,6 +88,13 @@ func (s *Session) HandlePacket(addr *net.UDPAddr, publicHeaderBinary []byte, pub
|
||||
}
|
||||
} else if typeByte&0xC0 == 0x40 { // ACK
|
||||
fmt.Println("Detected ACK")
|
||||
frame, err := ParseAckFrame(r, typeByte)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("%#v\n", frame)
|
||||
|
||||
continue // not yet implemented
|
||||
} else if typeByte&0xE0 == 0x20 { // CONGESTION_FEEDBACK
|
||||
fmt.Println("Detected CONGESTION_FEEDBACK")
|
||||
|
||||
Reference in New Issue
Block a user