You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

217 lines
6.1 KiB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
  1. // Modified for Tendermint
  2. // Originally Copyright (c) 2013-2014 Conformal Systems LLC.
  3. // https://github.com/conformal/btcd/blob/master/LICENSE
  4. package p2p
  5. import (
  6. "io"
  7. "net"
  8. "strconv"
  9. "time"
  10. . "github.com/tendermint/tendermint/binary"
  11. . "github.com/tendermint/tendermint/common"
  12. )
  13. /* NetAddress */
  14. type NetAddress struct {
  15. IP net.IP
  16. Port uint16
  17. str string
  18. }
  19. // TODO: socks proxies?
  20. func NewNetAddress(addr net.Addr) *NetAddress {
  21. tcpAddr, ok := addr.(*net.TCPAddr)
  22. if !ok {
  23. Panicf("Only TCPAddrs are supported. Got: %v", addr)
  24. }
  25. ip := tcpAddr.IP
  26. port := uint16(tcpAddr.Port)
  27. return NewNetAddressIPPort(ip, port)
  28. }
  29. func NewNetAddressString(addr string) *NetAddress {
  30. host, portStr, err := net.SplitHostPort(addr)
  31. if err != nil {
  32. panic(err)
  33. }
  34. ip := net.ParseIP(host)
  35. port, err := strconv.ParseUint(portStr, 10, 16)
  36. if err != nil {
  37. panic(err)
  38. }
  39. na := NewNetAddressIPPort(ip, uint16(port))
  40. return na
  41. }
  42. func ReadNetAddress(r io.Reader, n *int64, err *error) *NetAddress {
  43. ipBytes := ReadByteSlice(r, n, err)
  44. port := ReadUInt16(r, n, err)
  45. return NewNetAddressIPPort(net.IP(ipBytes), port)
  46. }
  47. func NewNetAddressIPPort(ip net.IP, port uint16) *NetAddress {
  48. na := &NetAddress{
  49. IP: ip,
  50. Port: port,
  51. str: net.JoinHostPort(
  52. ip.String(),
  53. strconv.FormatUint(uint64(port), 10),
  54. ),
  55. }
  56. return na
  57. }
  58. func (na *NetAddress) WriteTo(w io.Writer) (n int64, err error) {
  59. WriteByteSlice(w, na.IP.To16(), &n, &err)
  60. WriteUInt16(w, na.Port, &n, &err)
  61. return
  62. }
  63. func (na *NetAddress) Equals(other interface{}) bool {
  64. if o, ok := other.(*NetAddress); ok {
  65. return na.String() == o.String()
  66. } else {
  67. return false
  68. }
  69. }
  70. func (na *NetAddress) Less(other interface{}) bool {
  71. if o, ok := other.(*NetAddress); ok {
  72. return na.String() < o.String()
  73. } else {
  74. panic("Cannot compare unequal types")
  75. }
  76. }
  77. func (na *NetAddress) String() string {
  78. if na.str == "" {
  79. na.str = net.JoinHostPort(
  80. na.IP.String(),
  81. strconv.FormatUint(uint64(na.Port), 10),
  82. )
  83. }
  84. return na.str
  85. }
  86. func (na *NetAddress) Dial() (net.Conn, error) {
  87. conn, err := net.Dial("tcp", na.String())
  88. if err != nil {
  89. return nil, err
  90. }
  91. return conn, nil
  92. }
  93. func (na *NetAddress) DialTimeout(timeout time.Duration) (net.Conn, error) {
  94. conn, err := net.DialTimeout("tcp", na.String(), timeout)
  95. if err != nil {
  96. return nil, err
  97. }
  98. return conn, nil
  99. }
  100. func (na *NetAddress) Routable() bool {
  101. // TODO(oga) bitcoind doesn't include RFC3849 here, but should we?
  102. return na.Valid() && !(na.RFC1918() || na.RFC3927() || na.RFC4862() ||
  103. na.RFC4193() || na.RFC4843() || na.Local())
  104. }
  105. // For IPv4 these are either a 0 or all bits set address. For IPv6 a zero
  106. // address or one that matches the RFC3849 documentation address format.
  107. func (na *NetAddress) Valid() bool {
  108. return na.IP != nil && !(na.IP.IsUnspecified() || na.RFC3849() ||
  109. na.IP.Equal(net.IPv4bcast))
  110. }
  111. func (na *NetAddress) Local() bool {
  112. return na.IP.IsLoopback() || zero4.Contains(na.IP)
  113. }
  114. func (na *NetAddress) ReachabilityTo(o *NetAddress) int {
  115. const (
  116. Unreachable = 0
  117. Default = iota
  118. Teredo
  119. Ipv6_weak
  120. Ipv4
  121. Ipv6_strong
  122. Private
  123. )
  124. if !na.Routable() {
  125. return Unreachable
  126. } else if na.RFC4380() {
  127. if !o.Routable() {
  128. return Default
  129. } else if o.RFC4380() {
  130. return Teredo
  131. } else if o.IP.To4() != nil {
  132. return Ipv4
  133. } else { // ipv6
  134. return Ipv6_weak
  135. }
  136. } else if na.IP.To4() != nil {
  137. if o.Routable() && o.IP.To4() != nil {
  138. return Ipv4
  139. }
  140. return Default
  141. } else /* ipv6 */ {
  142. var tunnelled bool
  143. // Is our v6 is tunnelled?
  144. if o.RFC3964() || o.RFC6052() || o.RFC6145() {
  145. tunnelled = true
  146. }
  147. if !o.Routable() {
  148. return Default
  149. } else if o.RFC4380() {
  150. return Teredo
  151. } else if o.IP.To4() != nil {
  152. return Ipv4
  153. } else if tunnelled {
  154. // only prioritise ipv6 if we aren't tunnelling it.
  155. return Ipv6_weak
  156. }
  157. return Ipv6_strong
  158. }
  159. }
  160. // RFC1918: IPv4 Private networks (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12)
  161. // RFC3849: IPv6 Documentation address (2001:0DB8::/32)
  162. // RFC3927: IPv4 Autoconfig (169.254.0.0/16)
  163. // RFC3964: IPv6 6to4 (2002::/16)
  164. // RFC4193: IPv6 unique local (FC00::/7)
  165. // RFC4380: IPv6 Teredo tunneling (2001::/32)
  166. // RFC4843: IPv6 ORCHID: (2001:10::/28)
  167. // RFC4862: IPv6 Autoconfig (FE80::/64)
  168. // RFC6052: IPv6 well known prefix (64:FF9B::/96)
  169. // RFC6145: IPv6 IPv4 translated address ::FFFF:0:0:0/96
  170. var rfc1918_10 = net.IPNet{IP: net.ParseIP("10.0.0.0"), Mask: net.CIDRMask(8, 32)}
  171. var rfc1918_192 = net.IPNet{IP: net.ParseIP("192.168.0.0"), Mask: net.CIDRMask(16, 32)}
  172. var rfc1918_172 = net.IPNet{IP: net.ParseIP("172.16.0.0"), Mask: net.CIDRMask(12, 32)}
  173. var rfc3849 = net.IPNet{IP: net.ParseIP("2001:0DB8::"), Mask: net.CIDRMask(32, 128)}
  174. var rfc3927 = net.IPNet{IP: net.ParseIP("169.254.0.0"), Mask: net.CIDRMask(16, 32)}
  175. var rfc3964 = net.IPNet{IP: net.ParseIP("2002::"), Mask: net.CIDRMask(16, 128)}
  176. var rfc4193 = net.IPNet{IP: net.ParseIP("FC00::"), Mask: net.CIDRMask(7, 128)}
  177. var rfc4380 = net.IPNet{IP: net.ParseIP("2001::"), Mask: net.CIDRMask(32, 128)}
  178. var rfc4843 = net.IPNet{IP: net.ParseIP("2001:10::"), Mask: net.CIDRMask(28, 128)}
  179. var rfc4862 = net.IPNet{IP: net.ParseIP("FE80::"), Mask: net.CIDRMask(64, 128)}
  180. var rfc6052 = net.IPNet{IP: net.ParseIP("64:FF9B::"), Mask: net.CIDRMask(96, 128)}
  181. var rfc6145 = net.IPNet{IP: net.ParseIP("::FFFF:0:0:0"), Mask: net.CIDRMask(96, 128)}
  182. var zero4 = net.IPNet{IP: net.ParseIP("0.0.0.0"), Mask: net.CIDRMask(8, 32)}
  183. func (na *NetAddress) RFC1918() bool {
  184. return rfc1918_10.Contains(na.IP) ||
  185. rfc1918_192.Contains(na.IP) ||
  186. rfc1918_172.Contains(na.IP)
  187. }
  188. func (na *NetAddress) RFC3849() bool { return rfc3849.Contains(na.IP) }
  189. func (na *NetAddress) RFC3927() bool { return rfc3927.Contains(na.IP) }
  190. func (na *NetAddress) RFC3964() bool { return rfc3964.Contains(na.IP) }
  191. func (na *NetAddress) RFC4193() bool { return rfc4193.Contains(na.IP) }
  192. func (na *NetAddress) RFC4380() bool { return rfc4380.Contains(na.IP) }
  193. func (na *NetAddress) RFC4843() bool { return rfc4843.Contains(na.IP) }
  194. func (na *NetAddress) RFC4862() bool { return rfc4862.Contains(na.IP) }
  195. func (na *NetAddress) RFC6052() bool { return rfc6052.Contains(na.IP) }
  196. func (na *NetAddress) RFC6145() bool { return rfc6145.Contains(na.IP) }