network.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. /*
  2. * Copyright (c)2013-2020 ZeroTier, Inc.
  3. *
  4. * Use of this software is governed by the Business Source License included
  5. * in the LICENSE.TXT file in the project's root directory.
  6. *
  7. * Change Date: 2024-01-01
  8. *
  9. * On the date above, in accordance with the Business Source License, use
  10. * of this software will be governed by version 2.0 of the Apache License.
  11. */
  12. /****/
  13. package zerotier
  14. import (
  15. "encoding/binary"
  16. "encoding/json"
  17. "fmt"
  18. "net"
  19. "sort"
  20. "strconv"
  21. "sync"
  22. )
  23. // NetworkID is a network's 64-bit unique ID
  24. type NetworkID uint64
  25. // NewNetworkIDFromString parses a network ID in string form
  26. func NewNetworkIDFromString(s string) (NetworkID, error) {
  27. if len(s) != 16 {
  28. return NetworkID(0), ErrInvalidNetworkID
  29. }
  30. n, err := strconv.ParseUint(s, 16, 64)
  31. return NetworkID(n), err
  32. }
  33. // NewNetworkIDFromBytes reads an 8-byte / 64-bit network ID.
  34. func NewNetworkIDFromBytes(b []byte) (NetworkID, error) {
  35. if len(b) < 8 {
  36. return NetworkID(0), ErrInvalidNetworkID
  37. }
  38. return NetworkID(binary.BigEndian.Uint64(b)), nil
  39. }
  40. // Controller gets the Address of this network's controller.
  41. func (n NetworkID) Controller() Address {
  42. return Address(uint64(n) >> 24)
  43. }
  44. // String returns this network ID's 16-digit hex identifier
  45. func (n NetworkID) String() string {
  46. return fmt.Sprintf("%.16x", uint64(n))
  47. }
  48. // Bytes returns this network ID as an 8-byte / 64-bit big-endian value.
  49. func (n NetworkID) Bytes() []byte {
  50. var b [8]byte
  51. binary.BigEndian.PutUint64(b[:], uint64(n))
  52. return b[:]
  53. }
  54. // MarshalJSON marshals this NetworkID as a string
  55. func (n NetworkID) MarshalJSON() ([]byte, error) {
  56. return []byte("\"" + n.String() + "\""), nil
  57. }
  58. // UnmarshalJSON unmarshals this NetworkID from a string
  59. func (n *NetworkID) UnmarshalJSON(j []byte) error {
  60. var s string
  61. err := json.Unmarshal(j, &s)
  62. if err != nil {
  63. return err
  64. }
  65. tmp, err := NewNetworkIDFromString(s)
  66. *n = tmp
  67. return err
  68. }
  69. // NetworkConfig represents the network's current configuration as distributed by its network controller.
  70. type NetworkConfig struct {
  71. // ID is this network's 64-bit globally unique identifier
  72. ID NetworkID
  73. // MAC is the Ethernet MAC address of this device on this network
  74. MAC MAC
  75. // Name is a short human-readable name set by the controller
  76. Name string
  77. // Status is a status code indicating this network's authorization status
  78. Status int
  79. // Type is this network's type
  80. Type int
  81. // MTU is the Ethernet MTU for this network
  82. MTU int
  83. // Bridge is true if this network is allowed to bridge in other devices with different Ethernet addresses
  84. Bridge bool
  85. // BroadcastEnabled is true if the broadcast (ff:ff:ff:ff:ff:ff) address works (excluding IPv4 ARP which is handled via a special path)
  86. BroadcastEnabled bool
  87. // NetconfRevision is the revision number reported by the controller
  88. NetconfRevision uint64
  89. // AssignedAddresses are static IPs assigned by the network controller to this device
  90. AssignedAddresses []net.IPNet
  91. // Routes are static routes assigned by the network controller to this device
  92. Routes []Route
  93. }
  94. // NetworkLocalSettings is settings for this network that can be changed locally
  95. type NetworkLocalSettings struct {
  96. // AllowManagedIPs determines whether managed IP assignment is allowed
  97. AllowManagedIPs bool
  98. // AllowGlobalIPs determines if managed IPs that overlap with public Internet addresses are allowed
  99. AllowGlobalIPs bool
  100. // AllowManagedRoutes determines whether managed routes can be set
  101. AllowManagedRoutes bool
  102. // AllowGlobalRoutes determines if managed routes can overlap with public Internet addresses
  103. AllowGlobalRoutes bool
  104. // AllowDefaultRouteOverride determines if the default (0.0.0.0 or ::0) route on the system can be overridden ("full tunnel" mode)
  105. AllowDefaultRouteOverride bool
  106. }
  107. // Network is a currently joined network
  108. type Network struct {
  109. node *Node
  110. id NetworkID
  111. mac MAC
  112. tap Tap
  113. config NetworkConfig
  114. settings NetworkLocalSettings // locked by configLock
  115. multicastSubscriptions map[[2]uint64]*MulticastGroup
  116. configLock sync.RWMutex
  117. multicastSubscriptionsLock sync.RWMutex
  118. }
  119. // newNetwork creates a new network with default settings
  120. func newNetwork(node *Node, id NetworkID, t Tap) (*Network, error) {
  121. m := NewMACForNetworkMember(node.Identity().address, id)
  122. n := &Network{
  123. node: node,
  124. id: id,
  125. mac: m,
  126. tap: t,
  127. config: NetworkConfig{
  128. ID: id,
  129. MAC: m,
  130. Status: NetworkStatusRequestConfiguration,
  131. Type: NetworkTypePrivate,
  132. MTU: int(defaultVirtualNetworkMTU),
  133. },
  134. settings: NetworkLocalSettings{
  135. AllowManagedIPs: true,
  136. AllowGlobalIPs: false,
  137. AllowManagedRoutes: true,
  138. AllowGlobalRoutes: false,
  139. AllowDefaultRouteOverride: false,
  140. },
  141. multicastSubscriptions: make(map[[2]uint64]*MulticastGroup),
  142. }
  143. t.AddMulticastGroupChangeHandler(func(added bool, mg *MulticastGroup) {
  144. if added {
  145. n.MulticastSubscribe(mg)
  146. } else {
  147. n.MulticastUnsubscribe(mg)
  148. }
  149. })
  150. return n, nil
  151. }
  152. // ID gets this network's unique ID
  153. func (n *Network) ID() NetworkID { return n.id }
  154. // MAC returns the assigned MAC address of this network
  155. func (n *Network) MAC() MAC { return n.mac }
  156. // Tap gets this network's tap device
  157. func (n *Network) Tap() Tap { return n.tap }
  158. // Config returns a copy of this network's current configuration
  159. func (n *Network) Config() NetworkConfig {
  160. n.configLock.RLock()
  161. defer n.configLock.RUnlock()
  162. return n.config
  163. }
  164. // SetLocalSettings modifies this network's local settings
  165. func (n *Network) SetLocalSettings(ls *NetworkLocalSettings) { n.updateConfig(nil, ls) }
  166. // LocalSettings gets this network's current local settings
  167. func (n *Network) LocalSettings() NetworkLocalSettings {
  168. n.configLock.RLock()
  169. defer n.configLock.RUnlock()
  170. return n.settings
  171. }
  172. // MulticastSubscribe subscribes to a multicast group
  173. func (n *Network) MulticastSubscribe(mg *MulticastGroup) {
  174. n.node.infoLog.Printf("%.16x joined multicast group %s", uint64(n.id), mg.String())
  175. k := mg.key()
  176. n.multicastSubscriptionsLock.Lock()
  177. if _, have := n.multicastSubscriptions[k]; have {
  178. n.multicastSubscriptionsLock.Unlock()
  179. return
  180. }
  181. n.multicastSubscriptions[k] = mg
  182. n.multicastSubscriptionsLock.Unlock()
  183. n.node.multicastSubscribe(uint64(n.id), mg)
  184. }
  185. // MulticastUnsubscribe removes a subscription to a multicast group
  186. func (n *Network) MulticastUnsubscribe(mg *MulticastGroup) {
  187. n.node.infoLog.Printf("%.16x left multicast group %s", uint64(n.id), mg.String())
  188. n.multicastSubscriptionsLock.Lock()
  189. delete(n.multicastSubscriptions, mg.key())
  190. n.multicastSubscriptionsLock.Unlock()
  191. n.node.multicastUnsubscribe(uint64(n.id), mg)
  192. }
  193. // MulticastSubscriptions returns an array of all multicast subscriptions for this network
  194. func (n *Network) MulticastSubscriptions() []*MulticastGroup {
  195. n.multicastSubscriptionsLock.RLock()
  196. mgs := make([]*MulticastGroup, 0, len(n.multicastSubscriptions))
  197. for _, mg := range n.multicastSubscriptions {
  198. mgs = append(mgs, mg)
  199. }
  200. n.multicastSubscriptionsLock.RUnlock()
  201. sort.Slice(mgs, func(a, b int) bool { return mgs[a].Less(mgs[b]) })
  202. return mgs
  203. }
  204. // leaving is called by Node when the network is being left
  205. func (n *Network) leaving() {
  206. n.tap.Close()
  207. }
  208. func (n *Network) networkConfigRevision() uint64 {
  209. n.configLock.RLock()
  210. defer n.configLock.RUnlock()
  211. return n.config.NetconfRevision
  212. }
  213. func networkManagedIPAllowed(ip net.IP, ls *NetworkLocalSettings) bool {
  214. if !ls.AllowManagedIPs {
  215. return false
  216. }
  217. switch ipClassify(ip) {
  218. case ipClassificationNone, ipClassificationLoopback, ipClassificationLinkLocal, ipClassificationMulticast:
  219. return false
  220. case ipClassificationGlobal:
  221. return ls.AllowGlobalIPs
  222. }
  223. return true
  224. }
  225. func networkManagedRouteAllowed(r *Route, ls *NetworkLocalSettings) bool {
  226. if !ls.AllowManagedRoutes {
  227. return false
  228. }
  229. bits, _ := r.Target.Mask.Size()
  230. if len(r.Target.IP) > 0 && allZero(r.Target.IP) && bits == 0 {
  231. return ls.AllowDefaultRouteOverride
  232. }
  233. switch ipClassify(r.Target.IP) {
  234. case ipClassificationNone, ipClassificationLoopback, ipClassificationLinkLocal, ipClassificationMulticast:
  235. return false
  236. case ipClassificationGlobal:
  237. return ls.AllowGlobalRoutes
  238. }
  239. return true
  240. }
  241. func (n *Network) updateConfig(nc *NetworkConfig, ls *NetworkLocalSettings) {
  242. n.configLock.Lock()
  243. defer n.configLock.Unlock()
  244. if n.tap == nil { // sanity check, should never happen
  245. return
  246. }
  247. if nc == nil {
  248. nc = &n.config
  249. }
  250. if ls == nil {
  251. ls = &n.settings
  252. }
  253. // Add IPs to tap that are newly assigned in this config update,
  254. // and remove any IPs from the tap that were assigned that are no
  255. // longer wanted. IPs assigned to the tap externally (e.g. by an
  256. // "ifconfig" command) are left alone.
  257. haveAssignedIPs := make(map[[3]uint64]*net.IPNet)
  258. wantAssignedIPs := make(map[[3]uint64]bool)
  259. if n.settings.AllowManagedIPs {
  260. for _, ip := range n.config.AssignedAddresses {
  261. if networkManagedIPAllowed(ip.IP, &n.settings) { // was it allowed?
  262. haveAssignedIPs[ipNetToKey(&ip)] = &ip
  263. }
  264. }
  265. }
  266. if ls.AllowManagedIPs {
  267. for _, ip := range nc.AssignedAddresses {
  268. if networkManagedIPAllowed(ip.IP, ls) { // should it be allowed now?
  269. k := ipNetToKey(&ip)
  270. wantAssignedIPs[k] = true
  271. if _, have := haveAssignedIPs[k]; !have {
  272. n.node.infoLog.Printf("%.16x adding managed IP %s", uint64(n.id), ip.String())
  273. _ = n.tap.AddIP(&ip)
  274. }
  275. }
  276. }
  277. }
  278. for k, ip := range haveAssignedIPs {
  279. if _, want := wantAssignedIPs[k]; !want {
  280. n.node.infoLog.Printf("%.16x removing managed IP %s", uint64(n.id), ip.String())
  281. _ = n.tap.RemoveIP(ip)
  282. }
  283. }
  284. // Do the same for managed routes
  285. haveManagedRoutes := make(map[[6]uint64]*Route)
  286. wantManagedRoutes := make(map[[6]uint64]bool)
  287. if n.settings.AllowManagedRoutes {
  288. for _, r := range n.config.Routes {
  289. if networkManagedRouteAllowed(&r, &n.settings) { // was it allowed?
  290. haveManagedRoutes[r.key()] = &r
  291. }
  292. }
  293. }
  294. if ls.AllowManagedRoutes {
  295. for _, r := range nc.Routes {
  296. if networkManagedRouteAllowed(&r, ls) { // should it be allowed now?
  297. k := r.key()
  298. wantManagedRoutes[k] = true
  299. if _, have := haveManagedRoutes[k]; !have {
  300. n.node.infoLog.Printf("%.16x adding managed route %s", uint64(n.id), r.String())
  301. //TODO _ = n.tap.AddRoute(&r)
  302. }
  303. }
  304. }
  305. }
  306. for k, r := range haveManagedRoutes {
  307. if _, want := wantManagedRoutes[k]; !want {
  308. n.node.infoLog.Printf("%.16x removing managed route %s", uint64(n.id), r.String())
  309. //TODO _ = n.tap.RemoveRoute(r)
  310. }
  311. }
  312. if nc != &n.config {
  313. n.config = *nc
  314. }
  315. if ls != &n.settings {
  316. n.settings = *ls
  317. }
  318. }