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.

342 lines
9.8 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
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 == nil {
  157. return "<nil-NetAddress>"
  158. }
  159. if na.str == "" {
  160. addrStr := na.DialString()
  161. if na.ID != "" {
  162. addrStr = IDAddressString(na.ID, addrStr)
  163. }
  164. na.str = addrStr
  165. }
  166. return na.str
  167. }
  168. func (na *NetAddress) DialString() string {
  169. if na == nil {
  170. return "<nil-NetAddress>"
  171. }
  172. return net.JoinHostPort(
  173. na.IP.String(),
  174. strconv.FormatUint(uint64(na.Port), 10),
  175. )
  176. }
  177. // Dial calls net.Dial on the address.
  178. func (na *NetAddress) Dial() (net.Conn, error) {
  179. conn, err := net.Dial("tcp", na.DialString())
  180. if err != nil {
  181. return nil, err
  182. }
  183. return conn, nil
  184. }
  185. // DialTimeout calls net.DialTimeout on the address.
  186. func (na *NetAddress) DialTimeout(timeout time.Duration) (net.Conn, error) {
  187. conn, err := net.DialTimeout("tcp", na.DialString(), timeout)
  188. if err != nil {
  189. return nil, err
  190. }
  191. return conn, nil
  192. }
  193. // Routable returns true if the address is routable.
  194. func (na *NetAddress) Routable() bool {
  195. // TODO(oga) bitcoind doesn't include RFC3849 here, but should we?
  196. return na.Valid() && !(na.RFC1918() || na.RFC3927() || na.RFC4862() ||
  197. na.RFC4193() || na.RFC4843() || na.Local())
  198. }
  199. // For IPv4 these are either a 0 or all bits set address. For IPv6 a zero
  200. // address or one that matches the RFC3849 documentation address format.
  201. func (na *NetAddress) Valid() bool {
  202. if string(na.ID) != "" {
  203. data, err := hex.DecodeString(string(na.ID))
  204. if err != nil || len(data) != IDByteLength {
  205. return false
  206. }
  207. }
  208. return na.IP != nil && !(na.IP.IsUnspecified() || na.RFC3849() ||
  209. na.IP.Equal(net.IPv4bcast))
  210. }
  211. // HasID returns true if the address has an ID.
  212. // NOTE: It does not check whether the ID is valid or not.
  213. func (na *NetAddress) HasID() bool {
  214. return string(na.ID) != ""
  215. }
  216. // Local returns true if it is a local address.
  217. func (na *NetAddress) Local() bool {
  218. return na.IP.IsLoopback() || zero4.Contains(na.IP)
  219. }
  220. // ReachabilityTo checks whenever o can be reached from na.
  221. func (na *NetAddress) ReachabilityTo(o *NetAddress) int {
  222. const (
  223. Unreachable = 0
  224. Default = iota
  225. Teredo
  226. Ipv6_weak
  227. Ipv4
  228. Ipv6_strong
  229. )
  230. if !na.Routable() {
  231. return Unreachable
  232. } else if na.RFC4380() {
  233. if !o.Routable() {
  234. return Default
  235. } else if o.RFC4380() {
  236. return Teredo
  237. } else if o.IP.To4() != nil {
  238. return Ipv4
  239. } else { // ipv6
  240. return Ipv6_weak
  241. }
  242. } else if na.IP.To4() != nil {
  243. if o.Routable() && o.IP.To4() != nil {
  244. return Ipv4
  245. }
  246. return Default
  247. } else /* ipv6 */ {
  248. var tunnelled bool
  249. // Is our v6 is tunnelled?
  250. if o.RFC3964() || o.RFC6052() || o.RFC6145() {
  251. tunnelled = true
  252. }
  253. if !o.Routable() {
  254. return Default
  255. } else if o.RFC4380() {
  256. return Teredo
  257. } else if o.IP.To4() != nil {
  258. return Ipv4
  259. } else if tunnelled {
  260. // only prioritise ipv6 if we aren't tunnelling it.
  261. return Ipv6_weak
  262. }
  263. return Ipv6_strong
  264. }
  265. }
  266. // RFC1918: IPv4 Private networks (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12)
  267. // RFC3849: IPv6 Documentation address (2001:0DB8::/32)
  268. // RFC3927: IPv4 Autoconfig (169.254.0.0/16)
  269. // RFC3964: IPv6 6to4 (2002::/16)
  270. // RFC4193: IPv6 unique local (FC00::/7)
  271. // RFC4380: IPv6 Teredo tunneling (2001::/32)
  272. // RFC4843: IPv6 ORCHID: (2001:10::/28)
  273. // RFC4862: IPv6 Autoconfig (FE80::/64)
  274. // RFC6052: IPv6 well known prefix (64:FF9B::/96)
  275. // RFC6145: IPv6 IPv4 translated address ::FFFF:0:0:0/96
  276. var rfc1918_10 = net.IPNet{IP: net.ParseIP("10.0.0.0"), Mask: net.CIDRMask(8, 32)}
  277. var rfc1918_192 = net.IPNet{IP: net.ParseIP("192.168.0.0"), Mask: net.CIDRMask(16, 32)}
  278. var rfc1918_172 = net.IPNet{IP: net.ParseIP("172.16.0.0"), Mask: net.CIDRMask(12, 32)}
  279. var rfc3849 = net.IPNet{IP: net.ParseIP("2001:0DB8::"), Mask: net.CIDRMask(32, 128)}
  280. var rfc3927 = net.IPNet{IP: net.ParseIP("169.254.0.0"), Mask: net.CIDRMask(16, 32)}
  281. var rfc3964 = net.IPNet{IP: net.ParseIP("2002::"), Mask: net.CIDRMask(16, 128)}
  282. var rfc4193 = net.IPNet{IP: net.ParseIP("FC00::"), Mask: net.CIDRMask(7, 128)}
  283. var rfc4380 = net.IPNet{IP: net.ParseIP("2001::"), Mask: net.CIDRMask(32, 128)}
  284. var rfc4843 = net.IPNet{IP: net.ParseIP("2001:10::"), Mask: net.CIDRMask(28, 128)}
  285. var rfc4862 = net.IPNet{IP: net.ParseIP("FE80::"), Mask: net.CIDRMask(64, 128)}
  286. var rfc6052 = net.IPNet{IP: net.ParseIP("64:FF9B::"), Mask: net.CIDRMask(96, 128)}
  287. var rfc6145 = net.IPNet{IP: net.ParseIP("::FFFF:0:0:0"), Mask: net.CIDRMask(96, 128)}
  288. var zero4 = net.IPNet{IP: net.ParseIP("0.0.0.0"), Mask: net.CIDRMask(8, 32)}
  289. func (na *NetAddress) RFC1918() bool {
  290. return rfc1918_10.Contains(na.IP) ||
  291. rfc1918_192.Contains(na.IP) ||
  292. rfc1918_172.Contains(na.IP)
  293. }
  294. func (na *NetAddress) RFC3849() bool { return rfc3849.Contains(na.IP) }
  295. func (na *NetAddress) RFC3927() bool { return rfc3927.Contains(na.IP) }
  296. func (na *NetAddress) RFC3964() bool { return rfc3964.Contains(na.IP) }
  297. func (na *NetAddress) RFC4193() bool { return rfc4193.Contains(na.IP) }
  298. func (na *NetAddress) RFC4380() bool { return rfc4380.Contains(na.IP) }
  299. func (na *NetAddress) RFC4843() bool { return rfc4843.Contains(na.IP) }
  300. func (na *NetAddress) RFC4862() bool { return rfc4862.Contains(na.IP) }
  301. func (na *NetAddress) RFC6052() bool { return rfc6052.Contains(na.IP) }
  302. func (na *NetAddress) RFC6145() bool { return rfc6145.Contains(na.IP) }
  303. func removeProtocolIfDefined(addr string) string {
  304. if strings.Contains(addr, "://") {
  305. return strings.Split(addr, "://")[1]
  306. }
  307. return addr
  308. }