icecontrol.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
  2. // SPDX-License-Identifier: MIT
  3. package ice
  4. import (
  5. "encoding/binary"
  6. "github.com/pion/stun"
  7. )
  8. // tiebreaker is common helper for ICE-{CONTROLLED,CONTROLLING}
  9. // and represents the so-called tiebreaker number.
  10. type tiebreaker uint64
  11. const tiebreakerSize = 8 // 64 bit
  12. // AddToAs adds tiebreaker value to m as t attribute.
  13. func (a tiebreaker) AddToAs(m *stun.Message, t stun.AttrType) error {
  14. v := make([]byte, tiebreakerSize)
  15. binary.BigEndian.PutUint64(v, uint64(a))
  16. m.Add(t, v)
  17. return nil
  18. }
  19. // GetFromAs decodes tiebreaker value in message getting it as for t type.
  20. func (a *tiebreaker) GetFromAs(m *stun.Message, t stun.AttrType) error {
  21. v, err := m.Get(t)
  22. if err != nil {
  23. return err
  24. }
  25. if err = stun.CheckSize(t, len(v), tiebreakerSize); err != nil {
  26. return err
  27. }
  28. *a = tiebreaker(binary.BigEndian.Uint64(v))
  29. return nil
  30. }
  31. // AttrControlled represents ICE-CONTROLLED attribute.
  32. type AttrControlled uint64
  33. // AddTo adds ICE-CONTROLLED to message.
  34. func (c AttrControlled) AddTo(m *stun.Message) error {
  35. return tiebreaker(c).AddToAs(m, stun.AttrICEControlled)
  36. }
  37. // GetFrom decodes ICE-CONTROLLED from message.
  38. func (c *AttrControlled) GetFrom(m *stun.Message) error {
  39. return (*tiebreaker)(c).GetFromAs(m, stun.AttrICEControlled)
  40. }
  41. // AttrControlling represents ICE-CONTROLLING attribute.
  42. type AttrControlling uint64
  43. // AddTo adds ICE-CONTROLLING to message.
  44. func (c AttrControlling) AddTo(m *stun.Message) error {
  45. return tiebreaker(c).AddToAs(m, stun.AttrICEControlling)
  46. }
  47. // GetFrom decodes ICE-CONTROLLING from message.
  48. func (c *AttrControlling) GetFrom(m *stun.Message) error {
  49. return (*tiebreaker)(c).GetFromAs(m, stun.AttrICEControlling)
  50. }
  51. // AttrControl is helper that wraps ICE-{CONTROLLED,CONTROLLING}.
  52. type AttrControl struct {
  53. Role Role
  54. Tiebreaker uint64
  55. }
  56. // AddTo adds ICE-CONTROLLED or ICE-CONTROLLING attribute depending on Role.
  57. func (c AttrControl) AddTo(m *stun.Message) error {
  58. if c.Role == Controlling {
  59. return tiebreaker(c.Tiebreaker).AddToAs(m, stun.AttrICEControlling)
  60. }
  61. return tiebreaker(c.Tiebreaker).AddToAs(m, stun.AttrICEControlled)
  62. }
  63. // GetFrom decodes Role and Tiebreaker value from message.
  64. func (c *AttrControl) GetFrom(m *stun.Message) error {
  65. if m.Contains(stun.AttrICEControlling) {
  66. c.Role = Controlling
  67. return (*tiebreaker)(&c.Tiebreaker).GetFromAs(m, stun.AttrICEControlling)
  68. }
  69. if m.Contains(stun.AttrICEControlled) {
  70. c.Role = Controlled
  71. return (*tiebreaker)(&c.Tiebreaker).GetFromAs(m, stun.AttrICEControlled)
  72. }
  73. return stun.ErrAttributeNotFound
  74. }