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.

336 lines
9.7 KiB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
7 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 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. "encoding/hex"
  7. "flag"
  8. "fmt"
  9. "net"
  10. "strconv"
  11. "strings"
  12. "time"
  13. "errors"
  14. cmn "github.com/tendermint/tendermint/libs/common"
  15. )
  16. // NetAddress defines information about a peer on the network
  17. // including its ID, IP address, and port.
  18. type NetAddress struct {
  19. ID ID `json:"id"`
  20. IP net.IP `json:"ip"`
  21. Port uint16 `json:"port"`
  22. // TODO:
  23. // Name string `json:"name"` // optional DNS name
  24. // memoize .String()
  25. str string
  26. }
  27. // IDAddressString returns id@hostPort. It strips the leading
  28. // protocol from protocolHostPort if it exists.
  29. func IDAddressString(id ID, protocolHostPort string) string {
  30. hostPort := removeProtocolIfDefined(protocolHostPort)
  31. return fmt.Sprintf("%s@%s", id, hostPort)
  32. }
  33. // NewNetAddress returns a new NetAddress using the provided TCP
  34. // address. When testing, other net.Addr (except TCP) will result in
  35. // using 0.0.0.0:0. When normal run, other net.Addr (except TCP) will
  36. // panic.
  37. // TODO: socks proxies?
  38. func NewNetAddress(id ID, addr net.Addr) *NetAddress {
  39. tcpAddr, ok := addr.(*net.TCPAddr)
  40. if !ok {
  41. if flag.Lookup("test.v") == nil { // normal run
  42. cmn.PanicSanity(fmt.Sprintf("Only TCPAddrs are supported. Got: %v", addr))
  43. } else { // in testing
  44. netAddr := NewNetAddressIPPort(net.IP("0.0.0.0"), 0)
  45. netAddr.ID = id
  46. return netAddr
  47. }
  48. }
  49. ip := tcpAddr.IP
  50. port := uint16(tcpAddr.Port)
  51. na := NewNetAddressIPPort(ip, port)
  52. na.ID = id
  53. return na
  54. }
  55. // NewNetAddressString returns a new NetAddress using the provided address in
  56. // the form of "ID@IP:Port".
  57. // Also resolves the host if host is not an IP.
  58. // Errors are of type ErrNetAddressXxx where Xxx is in (NoID, Invalid, Lookup)
  59. func NewNetAddressString(addr string) (*NetAddress, error) {
  60. spl := strings.Split(addr, "@")
  61. if len(spl) < 2 {
  62. return nil, ErrNetAddressNoID{addr}
  63. }
  64. return NewNetAddressStringWithOptionalID(addr)
  65. }
  66. // NewNetAddressStringWithOptionalID returns a new NetAddress using the
  67. // provided address in the form of "ID@IP:Port", where the ID is optional.
  68. // Also resolves the host if host is not an IP.
  69. func NewNetAddressStringWithOptionalID(addr string) (*NetAddress, error) {
  70. addrWithoutProtocol := removeProtocolIfDefined(addr)
  71. var id ID
  72. spl := strings.Split(addrWithoutProtocol, "@")
  73. if len(spl) == 2 {
  74. idStr := spl[0]
  75. idBytes, err := hex.DecodeString(idStr)
  76. if err != nil {
  77. return nil, ErrNetAddressInvalid{addrWithoutProtocol, err}
  78. }
  79. if len(idBytes) != IDByteLength {
  80. return nil, ErrNetAddressInvalid{
  81. addrWithoutProtocol,
  82. fmt.Errorf("invalid hex length - got %d, expected %d", len(idBytes), IDByteLength)}
  83. }
  84. id, addrWithoutProtocol = ID(idStr), spl[1]
  85. }
  86. host, portStr, err := net.SplitHostPort(addrWithoutProtocol)
  87. if err != nil {
  88. return nil, ErrNetAddressInvalid{addrWithoutProtocol, err}
  89. }
  90. if len(host) == 0 {
  91. return nil, ErrNetAddressInvalid{
  92. addrWithoutProtocol,
  93. errors.New("host is empty")}
  94. }
  95. ip := net.ParseIP(host)
  96. if ip == nil {
  97. ips, err := net.LookupIP(host)
  98. if err != nil {
  99. return nil, ErrNetAddressLookup{host, err}
  100. }
  101. ip = ips[0]
  102. }
  103. port, err := strconv.ParseUint(portStr, 10, 16)
  104. if err != nil {
  105. return nil, ErrNetAddressInvalid{portStr, err}
  106. }
  107. na := NewNetAddressIPPort(ip, uint16(port))
  108. na.ID = id
  109. return na, nil
  110. }
  111. // NewNetAddressStrings returns an array of NetAddress'es build using
  112. // the provided strings.
  113. func NewNetAddressStrings(addrs []string) ([]*NetAddress, []error) {
  114. netAddrs := make([]*NetAddress, 0)
  115. errs := make([]error, 0)
  116. for _, addr := range addrs {
  117. netAddr, err := NewNetAddressString(addr)
  118. if err != nil {
  119. errs = append(errs, err)
  120. } else {
  121. netAddrs = append(netAddrs, netAddr)
  122. }
  123. }
  124. return netAddrs, errs
  125. }
  126. // NewNetAddressIPPort returns a new NetAddress using the provided IP
  127. // and port number.
  128. func NewNetAddressIPPort(ip net.IP, port uint16) *NetAddress {
  129. return &NetAddress{
  130. IP: ip,
  131. Port: port,
  132. }
  133. }
  134. // Equals reports whether na and other are the same addresses,
  135. // including their ID, IP, and Port.
  136. func (na *NetAddress) Equals(other interface{}) bool {
  137. if o, ok := other.(*NetAddress); ok {
  138. return na.String() == o.String()
  139. }
  140. return false
  141. }
  142. // Same returns true is na has the same non-empty ID or DialString as other.
  143. func (na *NetAddress) Same(other interface{}) bool {
  144. if o, ok := other.(*NetAddress); ok {
  145. if na.DialString() == o.DialString() {
  146. return true
  147. }
  148. if na.ID != "" && na.ID == o.ID {
  149. return true
  150. }
  151. }
  152. return false
  153. }
  154. // String representation: <ID>@<IP>:<PORT>
  155. func (na *NetAddress) String() string {
  156. if na.str == "" {
  157. addrStr := na.DialString()
  158. if na.ID != "" {
  159. addrStr = IDAddressString(na.ID, addrStr)
  160. }
  161. na.str = addrStr
  162. }
  163. return na.str
  164. }
  165. func (na *NetAddress) DialString() string {
  166. return net.JoinHostPort(
  167. na.IP.String(),
  168. strconv.FormatUint(uint64(na.Port), 10),
  169. )
  170. }
  171. // Dial calls net.Dial on the address.
  172. func (na *NetAddress) Dial() (net.Conn, error) {
  173. conn, err := net.Dial("tcp", na.DialString())
  174. if err != nil {
  175. return nil, err
  176. }
  177. return conn, nil
  178. }
  179. // DialTimeout calls net.DialTimeout on the address.
  180. func (na *NetAddress) DialTimeout(timeout time.Duration) (net.Conn, error) {
  181. conn, err := net.DialTimeout("tcp", na.DialString(), timeout)
  182. if err != nil {
  183. return nil, err
  184. }
  185. return conn, nil
  186. }
  187. // Routable returns true if the address is routable.
  188. func (na *NetAddress) Routable() bool {
  189. // TODO(oga) bitcoind doesn't include RFC3849 here, but should we?
  190. return na.Valid() && !(na.RFC1918() || na.RFC3927() || na.RFC4862() ||
  191. na.RFC4193() || na.RFC4843() || na.Local())
  192. }
  193. // For IPv4 these are either a 0 or all bits set address. For IPv6 a zero
  194. // address or one that matches the RFC3849 documentation address format.
  195. func (na *NetAddress) Valid() bool {
  196. if string(na.ID) != "" {
  197. data, err := hex.DecodeString(string(na.ID))
  198. if err != nil || len(data) != IDByteLength {
  199. return false
  200. }
  201. }
  202. return na.IP != nil && !(na.IP.IsUnspecified() || na.RFC3849() ||
  203. na.IP.Equal(net.IPv4bcast))
  204. }
  205. // HasID returns true if the address has an ID.
  206. // NOTE: It does not check whether the ID is valid or not.
  207. func (na *NetAddress) HasID() bool {
  208. return string(na.ID) != ""
  209. }
  210. // Local returns true if it is a local address.
  211. func (na *NetAddress) Local() bool {
  212. return na.IP.IsLoopback() || zero4.Contains(na.IP)
  213. }
  214. // ReachabilityTo checks whenever o can be reached from na.
  215. func (na *NetAddress) ReachabilityTo(o *NetAddress) int {
  216. const (
  217. Unreachable = 0
  218. Default = iota
  219. Teredo
  220. Ipv6_weak
  221. Ipv4
  222. Ipv6_strong
  223. )
  224. if !na.Routable() {
  225. return Unreachable
  226. } else if na.RFC4380() {
  227. if !o.Routable() {
  228. return Default
  229. } else if o.RFC4380() {
  230. return Teredo
  231. } else if o.IP.To4() != nil {
  232. return Ipv4
  233. } else { // ipv6
  234. return Ipv6_weak
  235. }
  236. } else if na.IP.To4() != nil {
  237. if o.Routable() && o.IP.To4() != nil {
  238. return Ipv4
  239. }
  240. return Default
  241. } else /* ipv6 */ {
  242. var tunnelled bool
  243. // Is our v6 is tunnelled?
  244. if o.RFC3964() || o.RFC6052() || o.RFC6145() {
  245. tunnelled = true
  246. }
  247. if !o.Routable() {
  248. return Default
  249. } else if o.RFC4380() {
  250. return Teredo
  251. } else if o.IP.To4() != nil {
  252. return Ipv4
  253. } else if tunnelled {
  254. // only prioritise ipv6 if we aren't tunnelling it.
  255. return Ipv6_weak
  256. }
  257. return Ipv6_strong
  258. }
  259. }
  260. // RFC1918: IPv4 Private networks (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12)
  261. // RFC3849: IPv6 Documentation address (2001:0DB8::/32)
  262. // RFC3927: IPv4 Autoconfig (169.254.0.0/16)
  263. // RFC3964: IPv6 6to4 (2002::/16)
  264. // RFC4193: IPv6 unique local (FC00::/7)
  265. // RFC4380: IPv6 Teredo tunneling (2001::/32)
  266. // RFC4843: IPv6 ORCHID: (2001:10::/28)
  267. // RFC4862: IPv6 Autoconfig (FE80::/64)
  268. // RFC6052: IPv6 well known prefix (64:FF9B::/96)
  269. // RFC6145: IPv6 IPv4 translated address ::FFFF:0:0:0/96
  270. var rfc1918_10 = net.IPNet{IP: net.ParseIP("10.0.0.0"), Mask: net.CIDRMask(8, 32)}
  271. var rfc1918_192 = net.IPNet{IP: net.ParseIP("192.168.0.0"), Mask: net.CIDRMask(16, 32)}
  272. var rfc1918_172 = net.IPNet{IP: net.ParseIP("172.16.0.0"), Mask: net.CIDRMask(12, 32)}
  273. var rfc3849 = net.IPNet{IP: net.ParseIP("2001:0DB8::"), Mask: net.CIDRMask(32, 128)}
  274. var rfc3927 = net.IPNet{IP: net.ParseIP("169.254.0.0"), Mask: net.CIDRMask(16, 32)}
  275. var rfc3964 = net.IPNet{IP: net.ParseIP("2002::"), Mask: net.CIDRMask(16, 128)}
  276. var rfc4193 = net.IPNet{IP: net.ParseIP("FC00::"), Mask: net.CIDRMask(7, 128)}
  277. var rfc4380 = net.IPNet{IP: net.ParseIP("2001::"), Mask: net.CIDRMask(32, 128)}
  278. var rfc4843 = net.IPNet{IP: net.ParseIP("2001:10::"), Mask: net.CIDRMask(28, 128)}
  279. var rfc4862 = net.IPNet{IP: net.ParseIP("FE80::"), Mask: net.CIDRMask(64, 128)}
  280. var rfc6052 = net.IPNet{IP: net.ParseIP("64:FF9B::"), Mask: net.CIDRMask(96, 128)}
  281. var rfc6145 = net.IPNet{IP: net.ParseIP("::FFFF:0:0:0"), Mask: net.CIDRMask(96, 128)}
  282. var zero4 = net.IPNet{IP: net.ParseIP("0.0.0.0"), Mask: net.CIDRMask(8, 32)}
  283. func (na *NetAddress) RFC1918() bool {
  284. return rfc1918_10.Contains(na.IP) ||
  285. rfc1918_192.Contains(na.IP) ||
  286. rfc1918_172.Contains(na.IP)
  287. }
  288. func (na *NetAddress) RFC3849() bool { return rfc3849.Contains(na.IP) }
  289. func (na *NetAddress) RFC3927() bool { return rfc3927.Contains(na.IP) }
  290. func (na *NetAddress) RFC3964() bool { return rfc3964.Contains(na.IP) }
  291. func (na *NetAddress) RFC4193() bool { return rfc4193.Contains(na.IP) }
  292. func (na *NetAddress) RFC4380() bool { return rfc4380.Contains(na.IP) }
  293. func (na *NetAddress) RFC4843() bool { return rfc4843.Contains(na.IP) }
  294. func (na *NetAddress) RFC4862() bool { return rfc4862.Contains(na.IP) }
  295. func (na *NetAddress) RFC6052() bool { return rfc6052.Contains(na.IP) }
  296. func (na *NetAddress) RFC6145() bool { return rfc6145.Contains(na.IP) }
  297. func removeProtocolIfDefined(addr string) string {
  298. if strings.Contains(addr, "://") {
  299. return strings.Split(addr, "://")[1]
  300. }
  301. return addr
  302. }