summaryrefslogtreecommitdiff
path: root/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/use_srtp.go
blob: 729fa3a98e421b77fae31878e15c453cb380000e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package extension

import "encoding/binary"

const (
	useSRTPHeaderSize = 6
)

// UseSRTP allows a Client/Server to negotiate what SRTPProtectionProfiles
// they both support
//
// https://tools.ietf.org/html/rfc8422
type UseSRTP struct {
	ProtectionProfiles []SRTPProtectionProfile
}

// TypeValue returns the extension TypeValue
func (u UseSRTP) TypeValue() TypeValue {
	return UseSRTPTypeValue
}

// Marshal encodes the extension
func (u *UseSRTP) Marshal() ([]byte, error) {
	out := make([]byte, useSRTPHeaderSize)

	binary.BigEndian.PutUint16(out, uint16(u.TypeValue()))
	binary.BigEndian.PutUint16(out[2:], uint16(2+(len(u.ProtectionProfiles)*2)+ /* MKI Length */ 1))
	binary.BigEndian.PutUint16(out[4:], uint16(len(u.ProtectionProfiles)*2))

	for _, v := range u.ProtectionProfiles {
		out = append(out, []byte{0x00, 0x00}...)
		binary.BigEndian.PutUint16(out[len(out)-2:], uint16(v))
	}

	out = append(out, 0x00) /* MKI Length */
	return out, nil
}

// Unmarshal populates the extension from encoded data
func (u *UseSRTP) Unmarshal(data []byte) error {
	if len(data) <= useSRTPHeaderSize {
		return errBufferTooSmall
	} else if TypeValue(binary.BigEndian.Uint16(data)) != u.TypeValue() {
		return errInvalidExtensionType
	}

	profileCount := int(binary.BigEndian.Uint16(data[4:]) / 2)
	if supportedGroupsHeaderSize+(profileCount*2) > len(data) {
		return errLengthMismatch
	}

	for i := 0; i < profileCount; i++ {
		supportedProfile := SRTPProtectionProfile(binary.BigEndian.Uint16(data[(useSRTPHeaderSize + (i * 2)):]))
		if _, ok := srtpProtectionProfiles()[supportedProfile]; ok {
			u.ProtectionProfiles = append(u.ProtectionProfiles, supportedProfile)
		}
	}
	return nil
}