header.go 1.5 KB

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