dockerfiles/anylink/dtls-2.0.9/pkg/protocol/recordlayer/header.go

62 lines
1.5 KiB
Go

package recordlayer
import (
"encoding/binary"
"github.com/pion/dtls/v2/internal/util"
"github.com/pion/dtls/v2/pkg/protocol"
)
// Header implements a TLS RecordLayer header
type Header struct {
ContentType protocol.ContentType
ContentLen uint16
Version protocol.Version
Epoch uint16
SequenceNumber uint64 // uint48 in spec
}
// RecordLayer enums
const (
HeaderSize = 13
MaxSequenceNumber = 0x0000FFFFFFFFFFFF
)
// Marshal encodes a TLS RecordLayer Header to binary
func (h *Header) Marshal() ([]byte, error) {
if h.SequenceNumber > MaxSequenceNumber {
return nil, errSequenceNumberOverflow
}
out := make([]byte, HeaderSize)
out[0] = byte(h.ContentType)
out[1] = h.Version.Major
out[2] = h.Version.Minor
binary.BigEndian.PutUint16(out[3:], h.Epoch)
util.PutBigEndianUint48(out[5:], h.SequenceNumber)
binary.BigEndian.PutUint16(out[HeaderSize-2:], h.ContentLen)
return out, nil
}
// Unmarshal populates a TLS RecordLayer Header from binary
func (h *Header) Unmarshal(data []byte) error {
if len(data) < HeaderSize {
return errBufferTooSmall
}
h.ContentType = protocol.ContentType(data[0])
h.Version.Major = data[1]
h.Version.Minor = data[2]
h.Epoch = binary.BigEndian.Uint16(data[3:])
// SequenceNumber is stored as uint48, make into uint64
seqCopy := make([]byte, 8)
copy(seqCopy[2:], data[5:11])
h.SequenceNumber = binary.BigEndian.Uint64(seqCopy)
if !h.Version.Equal(protocol.Version1_0) && !h.Version.Equal(protocol.Version1_2) {
return errUnsupportedProtocolVersion
}
return nil
}