github.com/pion/dtls/v2@v2.2.12/pkg/protocol/extension/use_srtp.go (about)

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