addr.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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. // OtherAddress represents OTHER-ADDRESS attribute.
  26. //
  27. // RFC 5780 Section 7.4
  28. type OtherAddress struct {
  29. IP net.IP
  30. Port int
  31. }
  32. // AddTo adds ALTERNATE-SERVER attribute to message.
  33. func (s *AlternateServer) AddTo(m *Message) error {
  34. a := (*MappedAddress)(s)
  35. return a.addAs(m, AttrAlternateServer)
  36. }
  37. // GetFrom decodes ALTERNATE-SERVER from message.
  38. func (s *AlternateServer) GetFrom(m *Message) error {
  39. a := (*MappedAddress)(s)
  40. return a.getAs(m, AttrAlternateServer)
  41. }
  42. func (a MappedAddress) String() string {
  43. return net.JoinHostPort(a.IP.String(), strconv.Itoa(a.Port))
  44. }
  45. func (a *MappedAddress) getAs(m *Message, t AttrType) error {
  46. v, err := m.Get(t)
  47. if err != nil {
  48. return err
  49. }
  50. if len(v) <= 4 {
  51. return io.ErrUnexpectedEOF
  52. }
  53. family := bin.Uint16(v[0:2])
  54. if family != familyIPv6 && family != familyIPv4 {
  55. return newDecodeErr("xor-mapped address", "family",
  56. fmt.Sprintf("bad value %d", family),
  57. )
  58. }
  59. ipLen := net.IPv4len
  60. if family == familyIPv6 {
  61. ipLen = net.IPv6len
  62. }
  63. // Ensuring len(a.IP) == ipLen and reusing a.IP.
  64. if len(a.IP) < ipLen {
  65. a.IP = a.IP[:cap(a.IP)]
  66. for len(a.IP) < ipLen {
  67. a.IP = append(a.IP, 0)
  68. }
  69. }
  70. a.IP = a.IP[:ipLen]
  71. for i := range a.IP {
  72. a.IP[i] = 0
  73. }
  74. a.Port = int(bin.Uint16(v[2:4]))
  75. copy(a.IP, v[4:])
  76. return nil
  77. }
  78. func (a *MappedAddress) addAs(m *Message, t AttrType) error {
  79. var (
  80. family = familyIPv4
  81. ip = a.IP
  82. )
  83. if len(a.IP) == net.IPv6len {
  84. if isIPv4(ip) {
  85. ip = ip[12:16] // like in ip.To4()
  86. } else {
  87. family = familyIPv6
  88. }
  89. } else if len(ip) != net.IPv4len {
  90. return ErrBadIPLength
  91. }
  92. value := make([]byte, 128)
  93. value[0] = 0 // first 8 bits are zeroes
  94. bin.PutUint16(value[0:2], family)
  95. bin.PutUint16(value[2:4], uint16(a.Port))
  96. copy(value[4:], ip)
  97. m.Add(t, value[:4+len(ip)])
  98. return nil
  99. }
  100. // AddTo adds MAPPED-ADDRESS to message.
  101. func (a *MappedAddress) AddTo(m *Message) error {
  102. return a.addAs(m, AttrMappedAddress)
  103. }
  104. // GetFrom decodes MAPPED-ADDRESS from message.
  105. func (a *MappedAddress) GetFrom(m *Message) error {
  106. return a.getAs(m, AttrMappedAddress)
  107. }
  108. // AddTo adds OTHER-ADDRESS attribute to message.
  109. func (o *OtherAddress) AddTo(m *Message) error {
  110. a := (*MappedAddress)(o)
  111. return a.addAs(m, AttrOtherAddress)
  112. }
  113. // GetFrom decodes OTHER-ADDRESS from message.
  114. func (o *OtherAddress) GetFrom(m *Message) error {
  115. a := (*MappedAddress)(o)
  116. return a.getAs(m, AttrOtherAddress)
  117. }
  118. func (o OtherAddress) String() string {
  119. return net.JoinHostPort(o.IP.String(), strconv.Itoa(o.Port))
  120. }