header_extension.go 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
  2. // SPDX-License-Identifier: MIT
  3. package rtp
  4. import (
  5. "encoding/binary"
  6. "fmt"
  7. "io"
  8. )
  9. const (
  10. headerExtensionProfileOneByte = 0xBEDE
  11. headerExtensionProfileTwoByte = 0x1000
  12. headerExtensionIDReserved = 0xF
  13. )
  14. // HeaderExtension represents an RTP extension header.
  15. type HeaderExtension interface {
  16. Set(id uint8, payload []byte) error
  17. GetIDs() []uint8
  18. Get(id uint8) []byte
  19. Del(id uint8) error
  20. Unmarshal(buf []byte) (int, error)
  21. Marshal() ([]byte, error)
  22. MarshalTo(buf []byte) (int, error)
  23. MarshalSize() int
  24. }
  25. // OneByteHeaderExtension is an RFC8285 one-byte header extension.
  26. type OneByteHeaderExtension struct {
  27. payload []byte
  28. }
  29. // Set sets the extension payload for the specified ID.
  30. func (e *OneByteHeaderExtension) Set(id uint8, buf []byte) error {
  31. if id < 1 || id > 14 {
  32. return fmt.Errorf("%w actual(%d)", errRFC8285OneByteHeaderIDRange, id)
  33. }
  34. if len(buf) > 16 {
  35. return fmt.Errorf("%w actual(%d)", errRFC8285OneByteHeaderSize, len(buf))
  36. }
  37. for n := 4; n < len(e.payload); {
  38. if e.payload[n] == 0x00 { // padding
  39. n++
  40. continue
  41. }
  42. extid := e.payload[n] >> 4
  43. payloadLen := int(e.payload[n]&^0xF0 + 1)
  44. n++
  45. if extid == id {
  46. e.payload = append(e.payload[:n+1], append(buf, e.payload[n+1+payloadLen:]...)...)
  47. return nil
  48. }
  49. n += payloadLen
  50. }
  51. e.payload = append(e.payload, (id<<4 | uint8(len(buf)-1)))
  52. e.payload = append(e.payload, buf...)
  53. binary.BigEndian.PutUint16(e.payload[2:4], binary.BigEndian.Uint16(e.payload[2:4])+1)
  54. return nil
  55. }
  56. // GetIDs returns the available IDs.
  57. func (e *OneByteHeaderExtension) GetIDs() []uint8 {
  58. ids := make([]uint8, 0, binary.BigEndian.Uint16(e.payload[2:4]))
  59. for n := 4; n < len(e.payload); {
  60. if e.payload[n] == 0x00 { // padding
  61. n++
  62. continue
  63. }
  64. extid := e.payload[n] >> 4
  65. payloadLen := int(e.payload[n]&^0xF0 + 1)
  66. n++
  67. if extid == headerExtensionIDReserved {
  68. break
  69. }
  70. ids = append(ids, extid)
  71. n += payloadLen
  72. }
  73. return ids
  74. }
  75. // Get returns the payload of the extension with the given ID.
  76. func (e *OneByteHeaderExtension) Get(id uint8) []byte {
  77. for n := 4; n < len(e.payload); {
  78. if e.payload[n] == 0x00 { // padding
  79. n++
  80. continue
  81. }
  82. extid := e.payload[n] >> 4
  83. payloadLen := int(e.payload[n]&^0xF0 + 1)
  84. n++
  85. if extid == id {
  86. return e.payload[n : n+payloadLen]
  87. }
  88. n += payloadLen
  89. }
  90. return nil
  91. }
  92. // Del deletes the extension with the specified ID.
  93. func (e *OneByteHeaderExtension) Del(id uint8) error {
  94. for n := 4; n < len(e.payload); {
  95. if e.payload[n] == 0x00 { // padding
  96. n++
  97. continue
  98. }
  99. extid := e.payload[n] >> 4
  100. payloadLen := int(e.payload[n]&^0xF0 + 1)
  101. if extid == id {
  102. e.payload = append(e.payload[:n], e.payload[n+1+payloadLen:]...)
  103. return nil
  104. }
  105. n += payloadLen + 1
  106. }
  107. return errHeaderExtensionNotFound
  108. }
  109. // Unmarshal parses the extension payload.
  110. func (e *OneByteHeaderExtension) Unmarshal(buf []byte) (int, error) {
  111. profile := binary.BigEndian.Uint16(buf[0:2])
  112. if profile != headerExtensionProfileOneByte {
  113. return 0, fmt.Errorf("%w actual(%x)", errHeaderExtensionNotFound, buf[0:2])
  114. }
  115. e.payload = buf
  116. return len(buf), nil
  117. }
  118. // Marshal returns the extension payload.
  119. func (e OneByteHeaderExtension) Marshal() ([]byte, error) {
  120. return e.payload, nil
  121. }
  122. // MarshalTo writes the extension payload to the given buffer.
  123. func (e OneByteHeaderExtension) MarshalTo(buf []byte) (int, error) {
  124. size := e.MarshalSize()
  125. if size > len(buf) {
  126. return 0, io.ErrShortBuffer
  127. }
  128. return copy(buf, e.payload), nil
  129. }
  130. // MarshalSize returns the size of the extension payload.
  131. func (e OneByteHeaderExtension) MarshalSize() int {
  132. return len(e.payload)
  133. }
  134. // TwoByteHeaderExtension is an RFC8285 two-byte header extension.
  135. type TwoByteHeaderExtension struct {
  136. payload []byte
  137. }
  138. // Set sets the extension payload for the specified ID.
  139. func (e *TwoByteHeaderExtension) Set(id uint8, buf []byte) error {
  140. if id < 1 || id > 255 {
  141. return fmt.Errorf("%w actual(%d)", errRFC8285TwoByteHeaderIDRange, id)
  142. }
  143. if len(buf) > 255 {
  144. return fmt.Errorf("%w actual(%d)", errRFC8285TwoByteHeaderSize, len(buf))
  145. }
  146. for n := 4; n < len(e.payload); {
  147. if e.payload[n] == 0x00 { // padding
  148. n++
  149. continue
  150. }
  151. extid := e.payload[n]
  152. n++
  153. payloadLen := int(e.payload[n])
  154. n++
  155. if extid == id {
  156. e.payload = append(e.payload[:n+2], append(buf, e.payload[n+2+payloadLen:]...)...)
  157. return nil
  158. }
  159. n += payloadLen
  160. }
  161. e.payload = append(e.payload, id, uint8(len(buf)))
  162. e.payload = append(e.payload, buf...)
  163. binary.BigEndian.PutUint16(e.payload[2:4], binary.BigEndian.Uint16(e.payload[2:4])+1)
  164. return nil
  165. }
  166. // GetIDs returns the available IDs.
  167. func (e *TwoByteHeaderExtension) GetIDs() []uint8 {
  168. ids := make([]uint8, 0, binary.BigEndian.Uint16(e.payload[2:4]))
  169. for n := 4; n < len(e.payload); {
  170. if e.payload[n] == 0x00 { // padding
  171. n++
  172. continue
  173. }
  174. extid := e.payload[n]
  175. n++
  176. payloadLen := int(e.payload[n])
  177. n++
  178. ids = append(ids, extid)
  179. n += payloadLen
  180. }
  181. return ids
  182. }
  183. // Get returns the payload of the extension with the given ID.
  184. func (e *TwoByteHeaderExtension) Get(id uint8) []byte {
  185. for n := 4; n < len(e.payload); {
  186. if e.payload[n] == 0x00 { // padding
  187. n++
  188. continue
  189. }
  190. extid := e.payload[n]
  191. n++
  192. payloadLen := int(e.payload[n])
  193. n++
  194. if extid == id {
  195. return e.payload[n : n+payloadLen]
  196. }
  197. n += payloadLen
  198. }
  199. return nil
  200. }
  201. // Del deletes the extension with the specified ID.
  202. func (e *TwoByteHeaderExtension) Del(id uint8) error {
  203. for n := 4; n < len(e.payload); {
  204. if e.payload[n] == 0x00 { // padding
  205. n++
  206. continue
  207. }
  208. extid := e.payload[n]
  209. payloadLen := int(e.payload[n+1])
  210. if extid == id {
  211. e.payload = append(e.payload[:n], e.payload[n+2+payloadLen:]...)
  212. return nil
  213. }
  214. n += payloadLen + 2
  215. }
  216. return errHeaderExtensionNotFound
  217. }
  218. // Unmarshal parses the extension payload.
  219. func (e *TwoByteHeaderExtension) Unmarshal(buf []byte) (int, error) {
  220. profile := binary.BigEndian.Uint16(buf[0:2])
  221. if profile != headerExtensionProfileTwoByte {
  222. return 0, fmt.Errorf("%w actual(%x)", errHeaderExtensionNotFound, buf[0:2])
  223. }
  224. e.payload = buf
  225. return len(buf), nil
  226. }
  227. // Marshal returns the extension payload.
  228. func (e TwoByteHeaderExtension) Marshal() ([]byte, error) {
  229. return e.payload, nil
  230. }
  231. // MarshalTo marshals the extension to the given buffer.
  232. func (e TwoByteHeaderExtension) MarshalTo(buf []byte) (int, error) {
  233. size := e.MarshalSize()
  234. if size > len(buf) {
  235. return 0, io.ErrShortBuffer
  236. }
  237. return copy(buf, e.payload), nil
  238. }
  239. // MarshalSize returns the size of the extension payload.
  240. func (e TwoByteHeaderExtension) MarshalSize() int {
  241. return len(e.payload)
  242. }
  243. // RawExtension represents an RFC3550 header extension.
  244. type RawExtension struct {
  245. payload []byte
  246. }
  247. // Set sets the extension payload for the specified ID.
  248. func (e *RawExtension) Set(id uint8, payload []byte) error {
  249. if id != 0 {
  250. return fmt.Errorf("%w actual(%d)", errRFC3550HeaderIDRange, id)
  251. }
  252. e.payload = payload
  253. return nil
  254. }
  255. // GetIDs returns the available IDs.
  256. func (e *RawExtension) GetIDs() []uint8 {
  257. return []uint8{0}
  258. }
  259. // Get returns the payload of the extension with the given ID.
  260. func (e *RawExtension) Get(id uint8) []byte {
  261. if id == 0 {
  262. return e.payload
  263. }
  264. return nil
  265. }
  266. // Del deletes the extension with the specified ID.
  267. func (e *RawExtension) Del(id uint8) error {
  268. if id == 0 {
  269. e.payload = nil
  270. return nil
  271. }
  272. return fmt.Errorf("%w actual(%d)", errRFC3550HeaderIDRange, id)
  273. }
  274. // Unmarshal parses the extension from the given buffer.
  275. func (e *RawExtension) Unmarshal(buf []byte) (int, error) {
  276. profile := binary.BigEndian.Uint16(buf[0:2])
  277. if profile == headerExtensionProfileOneByte || profile == headerExtensionProfileTwoByte {
  278. return 0, fmt.Errorf("%w actual(%x)", errHeaderExtensionNotFound, buf[0:2])
  279. }
  280. e.payload = buf
  281. return len(buf), nil
  282. }
  283. // Marshal returns the raw extension payload.
  284. func (e RawExtension) Marshal() ([]byte, error) {
  285. return e.payload, nil
  286. }
  287. // MarshalTo marshals the extension to the given buffer.
  288. func (e RawExtension) MarshalTo(buf []byte) (int, error) {
  289. size := e.MarshalSize()
  290. if size > len(buf) {
  291. return 0, io.ErrShortBuffer
  292. }
  293. return copy(buf, e.payload), nil
  294. }
  295. // MarshalSize returns the size of the extension when marshaled.
  296. func (e RawExtension) MarshalSize() int {
  297. return len(e.payload)
  298. }