addr.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. package stun
  2. import (
  3. "fmt"
  4. "io"
  5. "net"
  6. "strconv"
  7. )
  8. // MappedAddress represents MAPPED-ADDRESS attribute.
  9. //
  10. // This attribute is used only by servers for achieving backwards
  11. // compatibility with RFC 3489 clients.
  12. //
  13. // RFC 5389 Section 15.1
  14. type MappedAddress struct {
  15. IP net.IP
  16. Port int
  17. }
  18. // AlternateServer represents ALTERNATE-SERVER attribute.
  19. //
  20. // RFC 5389 Section 15.11
  21. type AlternateServer struct {
  22. IP net.IP
  23. Port int
  24. }
  25. // ResponseOrigin represents RESPONSE-ORIGIN attribute.
  26. //
  27. // RFC 5780 Section 7.3
  28. type ResponseOrigin struct {
  29. IP net.IP
  30. Port int
  31. }
  32. // OtherAddress represents OTHER-ADDRESS attribute.
  33. //
  34. // RFC 5780 Section 7.4
  35. type OtherAddress struct {
  36. IP net.IP
  37. Port int
  38. }
  39. // AddTo adds ALTERNATE-SERVER attribute to message.
  40. func (s *AlternateServer) AddTo(m *Message) error {
  41. a := (*MappedAddress)(s)
  42. return a.AddToAs(m, AttrAlternateServer)
  43. }
  44. // GetFrom decodes ALTERNATE-SERVER from message.
  45. func (s *AlternateServer) GetFrom(m *Message) error {
  46. a := (*MappedAddress)(s)
  47. return a.GetFromAs(m, AttrAlternateServer)
  48. }
  49. func (a MappedAddress) String() string {
  50. return net.JoinHostPort(a.IP.String(), strconv.Itoa(a.Port))
  51. }
  52. // GetFromAs decodes MAPPED-ADDRESS value in message m as an attribute of type t.
  53. func (a *MappedAddress) GetFromAs(m *Message, t AttrType) error {
  54. v, err := m.Get(t)
  55. if err != nil {
  56. return err
  57. }
  58. if len(v) <= 4 {
  59. return io.ErrUnexpectedEOF
  60. }
  61. family := bin.Uint16(v[0:2])
  62. if family != familyIPv6 && family != familyIPv4 {
  63. return newDecodeErr("xor-mapped address", "family",
  64. fmt.Sprintf("bad value %d", family),
  65. )
  66. }
  67. ipLen := net.IPv4len
  68. if family == familyIPv6 {
  69. ipLen = net.IPv6len
  70. }
  71. // Ensuring len(a.IP) == ipLen and reusing a.IP.
  72. if len(a.IP) < ipLen {
  73. a.IP = a.IP[:cap(a.IP)]
  74. for len(a.IP) < ipLen {
  75. a.IP = append(a.IP, 0)
  76. }
  77. }
  78. a.IP = a.IP[:ipLen]
  79. for i := range a.IP {
  80. a.IP[i] = 0
  81. }
  82. a.Port = int(bin.Uint16(v[2:4]))
  83. copy(a.IP, v[4:])
  84. return nil
  85. }
  86. // AddToAs adds MAPPED-ADDRESS value to m as t attribute.
  87. func (a *MappedAddress) AddToAs(m *Message, t AttrType) error {
  88. var (
  89. family = familyIPv4
  90. ip = a.IP
  91. )
  92. if len(a.IP) == net.IPv6len {
  93. if isIPv4(ip) {
  94. ip = ip[12:16] // like in ip.To4()
  95. } else {
  96. family = familyIPv6
  97. }
  98. } else if len(ip) != net.IPv4len {
  99. return ErrBadIPLength
  100. }
  101. value := make([]byte, 128)
  102. value[0] = 0 // first 8 bits are zeroes
  103. bin.PutUint16(value[0:2], family)
  104. bin.PutUint16(value[2:4], uint16(a.Port))
  105. copy(value[4:], ip)
  106. m.Add(t, value[:4+len(ip)])
  107. return nil
  108. }
  109. // AddTo adds MAPPED-ADDRESS to message.
  110. func (a *MappedAddress) AddTo(m *Message) error {
  111. return a.AddToAs(m, AttrMappedAddress)
  112. }
  113. // GetFrom decodes MAPPED-ADDRESS from message.
  114. func (a *MappedAddress) GetFrom(m *Message) error {
  115. return a.GetFromAs(m, AttrMappedAddress)
  116. }
  117. // AddTo adds OTHER-ADDRESS attribute to message.
  118. func (o *OtherAddress) AddTo(m *Message) error {
  119. a := (*MappedAddress)(o)
  120. return a.AddToAs(m, AttrOtherAddress)
  121. }
  122. // GetFrom decodes OTHER-ADDRESS from message.
  123. func (o *OtherAddress) GetFrom(m *Message) error {
  124. a := (*MappedAddress)(o)
  125. return a.GetFromAs(m, AttrOtherAddress)
  126. }
  127. func (o OtherAddress) String() string {
  128. return net.JoinHostPort(o.IP.String(), strconv.Itoa(o.Port))
  129. }
  130. // AddTo adds RESPONSE-ORIGIN attribute to message.
  131. func (o *ResponseOrigin) AddTo(m *Message) error {
  132. a := (*MappedAddress)(o)
  133. return a.AddToAs(m, AttrResponseOrigin)
  134. }
  135. // GetFrom decodes RESPONSE-ORIGIN from message.
  136. func (o *ResponseOrigin) GetFrom(m *Message) error {
  137. a := (*MappedAddress)(o)
  138. return a.GetFromAs(m, AttrResponseOrigin)
  139. }
  140. func (o ResponseOrigin) String() string {
  141. return net.JoinHostPort(o.IP.String(), strconv.Itoa(o.Port))
  142. }