github.com/pion/dtls/v2@v2.2.12/pkg/protocol/handshake/header.go (about)

     1  // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
     2  // SPDX-License-Identifier: MIT
     3  
     4  package handshake
     5  
     6  import (
     7  	"encoding/binary"
     8  
     9  	"github.com/pion/dtls/v2/internal/util"
    10  )
    11  
    12  // HeaderLength msg_len for Handshake messages assumes an extra
    13  // 12 bytes for sequence, fragment and version information vs TLS
    14  const HeaderLength = 12
    15  
    16  // Header is the static first 12 bytes of each RecordLayer
    17  // of type Handshake. These fields allow us to support message loss, reordering, and
    18  // message fragmentation,
    19  //
    20  // https://tools.ietf.org/html/rfc6347#section-4.2.2
    21  type Header struct {
    22  	Type            Type
    23  	Length          uint32 // uint24 in spec
    24  	MessageSequence uint16
    25  	FragmentOffset  uint32 // uint24 in spec
    26  	FragmentLength  uint32 // uint24 in spec
    27  }
    28  
    29  // Marshal encodes the Header
    30  func (h *Header) Marshal() ([]byte, error) {
    31  	out := make([]byte, HeaderLength)
    32  
    33  	out[0] = byte(h.Type)
    34  	util.PutBigEndianUint24(out[1:], h.Length)
    35  	binary.BigEndian.PutUint16(out[4:], h.MessageSequence)
    36  	util.PutBigEndianUint24(out[6:], h.FragmentOffset)
    37  	util.PutBigEndianUint24(out[9:], h.FragmentLength)
    38  	return out, nil
    39  }
    40  
    41  // Unmarshal populates the header from encoded data
    42  func (h *Header) Unmarshal(data []byte) error {
    43  	if len(data) < HeaderLength {
    44  		return errBufferTooSmall
    45  	}
    46  
    47  	h.Type = Type(data[0])
    48  	h.Length = util.BigEndianUint24(data[1:])
    49  	h.MessageSequence = binary.BigEndian.Uint16(data[4:])
    50  	h.FragmentOffset = util.BigEndianUint24(data[6:])
    51  	h.FragmentLength = util.BigEndianUint24(data[9:])
    52  	return nil
    53  }