icecontrol.go 2.5 KB

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