use_srtp.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
  2. // SPDX-License-Identifier: MIT
  3. package extension
  4. import "encoding/binary"
  5. const (
  6. useSRTPHeaderSize = 6
  7. )
  8. // UseSRTP allows a Client/Server to negotiate what SRTPProtectionProfiles
  9. // they both support
  10. //
  11. // https://tools.ietf.org/html/rfc8422
  12. type UseSRTP struct {
  13. ProtectionProfiles []SRTPProtectionProfile
  14. }
  15. // TypeValue returns the extension TypeValue
  16. func (u UseSRTP) TypeValue() TypeValue {
  17. return UseSRTPTypeValue
  18. }
  19. // Marshal encodes the extension
  20. func (u *UseSRTP) Marshal() ([]byte, error) {
  21. out := make([]byte, useSRTPHeaderSize)
  22. binary.BigEndian.PutUint16(out, uint16(u.TypeValue()))
  23. binary.BigEndian.PutUint16(out[2:], uint16(2+(len(u.ProtectionProfiles)*2)+ /* MKI Length */ 1))
  24. binary.BigEndian.PutUint16(out[4:], uint16(len(u.ProtectionProfiles)*2))
  25. for _, v := range u.ProtectionProfiles {
  26. out = append(out, []byte{0x00, 0x00}...)
  27. binary.BigEndian.PutUint16(out[len(out)-2:], uint16(v))
  28. }
  29. out = append(out, 0x00) /* MKI Length */
  30. return out, nil
  31. }
  32. // Unmarshal populates the extension from encoded data
  33. func (u *UseSRTP) Unmarshal(data []byte) error {
  34. if len(data) <= useSRTPHeaderSize {
  35. return errBufferTooSmall
  36. } else if TypeValue(binary.BigEndian.Uint16(data)) != u.TypeValue() {
  37. return errInvalidExtensionType
  38. }
  39. profileCount := int(binary.BigEndian.Uint16(data[4:]) / 2)
  40. if supportedGroupsHeaderSize+(profileCount*2) > len(data) {
  41. return errLengthMismatch
  42. }
  43. for i := 0; i < profileCount; i++ {
  44. supportedProfile := SRTPProtectionProfile(binary.BigEndian.Uint16(data[(useSRTPHeaderSize + (i * 2)):]))
  45. if _, ok := srtpProtectionProfiles()[supportedProfile]; ok {
  46. u.ProtectionProfiles = append(u.ProtectionProfiles, supportedProfile)
  47. }
  48. }
  49. return nil
  50. }