network.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  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: 2025-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. *n, err = NewNetworkIDFromString(s)
  66. return err
  67. }
  68. // NetworkConfig represents the network's current configuration as distributed by its network controller.
  69. type NetworkConfig struct {
  70. // ID is this network's 64-bit globally unique identifier
  71. ID NetworkID `json:"id"`
  72. // MAC is the Ethernet MAC address of this device on this network
  73. MAC MAC `json:"mac"`
  74. // Name is a short human-readable name set by the controller
  75. Name string `json:"name"`
  76. // Status is a status code indicating this network's authorization status
  77. Status int `json:"status"`
  78. // Type is this network's type
  79. Type int `json:"type"`
  80. // MTU is the Ethernet MTU for this network
  81. MTU int `json:"mtu"`
  82. // Bridge is true if this network is allowed to bridge in other devices with different Ethernet addresses
  83. Bridge bool `json:"bridge"`
  84. // BroadcastEnabled is true if the broadcast (ff:ff:ff:ff:ff:ff) address works (excluding IPv4 ARP which is handled via a special path)
  85. BroadcastEnabled bool `json:"broadcastEnabled"`
  86. // NetconfRevision is the revision number reported by the controller
  87. NetconfRevision uint64 `json:"netconfRevision"`
  88. // AssignedAddresses are static IPs assigned by the network controller to this device
  89. AssignedAddresses []InetAddress `json:"assignedAddresses,omitempty"`
  90. // Routes are static routes assigned by the network controller to this device
  91. Routes []Route `json:"routes,omitempty"`
  92. }
  93. // NetworkLocalSettings is settings for this network that can be changed locally
  94. type NetworkLocalSettings struct {
  95. // AllowManagedIPs determines whether managed IP assignment is allowed
  96. AllowManagedIPs bool `json:"allowManagedIPs"`
  97. // AllowGlobalIPs determines if managed IPs that overlap with public Internet addresses are allowed
  98. AllowGlobalIPs bool `json:"allowGlobalIPs"`
  99. // AllowManagedRoutes determines whether managed routes can be set
  100. AllowManagedRoutes bool `json:"allowManagedRoutes"`
  101. // AllowGlobalRoutes determines if managed routes can overlap with public Internet addresses
  102. AllowGlobalRoutes bool `json:"allowGlobalRoutes"`
  103. // AllowDefaultRouteOverride determines if the default (0.0.0.0 or ::0) route on the system can be overridden ("full tunnel" mode)
  104. AllowDefaultRouteOverride bool `json:"allowDefaultRouteOverride"`
  105. }
  106. // Network is a currently joined network
  107. type Network struct {
  108. node *Node
  109. id NetworkID
  110. mac MAC
  111. tap Tap
  112. config NetworkConfig
  113. settings NetworkLocalSettings // locked by configLock
  114. multicastSubscriptions map[[2]uint64]*MulticastGroup
  115. configLock sync.RWMutex
  116. multicastSubscriptionsLock sync.RWMutex
  117. }
  118. // newNetwork creates a new network with default settings
  119. func newNetwork(node *Node, id NetworkID, t Tap) (*Network, error) {
  120. m := NewMACForNetworkMember(node.Identity().address, id)
  121. n := &Network{
  122. node: node,
  123. id: id,
  124. mac: m,
  125. tap: t,
  126. config: NetworkConfig{
  127. ID: id,
  128. MAC: m,
  129. Status: NetworkStatusRequestingConfiguration,
  130. Type: NetworkTypePrivate,
  131. MTU: int(defaultVirtualNetworkMTU),
  132. },
  133. settings: NetworkLocalSettings{
  134. AllowManagedIPs: true,
  135. AllowGlobalIPs: false,
  136. AllowManagedRoutes: true,
  137. AllowGlobalRoutes: false,
  138. AllowDefaultRouteOverride: false,
  139. },
  140. multicastSubscriptions: make(map[[2]uint64]*MulticastGroup),
  141. }
  142. t.AddMulticastGroupChangeHandler(func(added bool, mg *MulticastGroup) {
  143. if added {
  144. n.MulticastSubscribe(mg)
  145. } else {
  146. n.MulticastUnsubscribe(mg)
  147. }
  148. })
  149. return n, nil
  150. }
  151. // ID gets this network's unique ID
  152. func (n *Network) ID() NetworkID { return n.id }
  153. // MAC returns the assigned MAC address of this network
  154. func (n *Network) MAC() MAC { return n.mac }
  155. // Tap gets this network's tap device
  156. func (n *Network) Tap() Tap { return n.tap }
  157. // Config returns a copy of this network's current configuration
  158. func (n *Network) Config() NetworkConfig {
  159. n.configLock.RLock()
  160. defer n.configLock.RUnlock()
  161. return n.config
  162. }
  163. // SetLocalSettings modifies this network's local settings
  164. func (n *Network) SetLocalSettings(ls *NetworkLocalSettings) { n.updateConfig(nil, ls) }
  165. // LocalSettings gets this network's current local settings
  166. func (n *Network) LocalSettings() NetworkLocalSettings {
  167. n.configLock.RLock()
  168. defer n.configLock.RUnlock()
  169. return n.settings
  170. }
  171. // MulticastSubscribe subscribes to a multicast group
  172. func (n *Network) MulticastSubscribe(mg *MulticastGroup) {
  173. n.node.infoLog.Printf("%.16x joined multicast group %s", uint64(n.id), mg.String())
  174. k := mg.key()
  175. n.multicastSubscriptionsLock.Lock()
  176. if _, have := n.multicastSubscriptions[k]; have {
  177. n.multicastSubscriptionsLock.Unlock()
  178. return
  179. }
  180. n.multicastSubscriptions[k] = mg
  181. n.multicastSubscriptionsLock.Unlock()
  182. n.node.multicastSubscribe(uint64(n.id), mg)
  183. }
  184. // MulticastUnsubscribe removes a subscription to a multicast group
  185. func (n *Network) MulticastUnsubscribe(mg *MulticastGroup) {
  186. n.node.infoLog.Printf("%.16x left multicast group %s", uint64(n.id), mg.String())
  187. n.multicastSubscriptionsLock.Lock()
  188. delete(n.multicastSubscriptions, mg.key())
  189. n.multicastSubscriptionsLock.Unlock()
  190. n.node.multicastUnsubscribe(uint64(n.id), mg)
  191. }
  192. // MulticastSubscriptions returns an array of all multicast subscriptions for this network
  193. func (n *Network) MulticastSubscriptions() []*MulticastGroup {
  194. n.multicastSubscriptionsLock.RLock()
  195. mgs := make([]*MulticastGroup, 0, len(n.multicastSubscriptions))
  196. for _, mg := range n.multicastSubscriptions {
  197. mgs = append(mgs, mg)
  198. }
  199. n.multicastSubscriptionsLock.RUnlock()
  200. sort.Slice(mgs, func(a, b int) bool { return mgs[a].Less(mgs[b]) })
  201. return mgs
  202. }
  203. // leaving is called by Node when the network is being left
  204. func (n *Network) leaving() {
  205. n.tap.Close()
  206. }
  207. func (n *Network) networkConfigRevision() uint64 {
  208. n.configLock.RLock()
  209. defer n.configLock.RUnlock()
  210. return n.config.NetconfRevision
  211. }
  212. func networkManagedIPAllowed(ip net.IP, ls *NetworkLocalSettings) bool {
  213. if !ls.AllowManagedIPs {
  214. return false
  215. }
  216. switch ipClassify(ip) {
  217. case ipClassificationNone, ipClassificationLoopback, ipClassificationLinkLocal, ipClassificationMulticast:
  218. return false
  219. case ipClassificationGlobal:
  220. return ls.AllowGlobalIPs
  221. }
  222. return true
  223. }
  224. func networkManagedRouteAllowed(r *Route, ls *NetworkLocalSettings) bool {
  225. if !ls.AllowManagedRoutes {
  226. return false
  227. }
  228. bits, _ := r.Target.Mask.Size()
  229. if len(r.Target.IP) > 0 && allZero(r.Target.IP) && bits == 0 {
  230. return ls.AllowDefaultRouteOverride
  231. }
  232. switch ipClassify(r.Target.IP) {
  233. case ipClassificationNone, ipClassificationLoopback, ipClassificationLinkLocal, ipClassificationMulticast:
  234. return false
  235. case ipClassificationGlobal:
  236. return ls.AllowGlobalRoutes
  237. }
  238. return true
  239. }
  240. func (n *Network) updateConfig(nc *NetworkConfig, ls *NetworkLocalSettings) {
  241. n.configLock.Lock()
  242. defer n.configLock.Unlock()
  243. if n.tap == nil { // sanity check, should never happen
  244. return
  245. }
  246. if nc == nil {
  247. nc = &n.config
  248. }
  249. if ls == nil {
  250. ls = &n.settings
  251. }
  252. // Add IPs to tap that are newly assigned in this config update,
  253. // and remove any IPs from the tap that were assigned that are no
  254. // longer wanted. IPs assigned to the tap externally (e.g. by an
  255. // "ifconfig" command) are left alone.
  256. haveAssignedIPs := make(map[[3]uint64]*InetAddress)
  257. wantAssignedIPs := make(map[[3]uint64]bool)
  258. if n.settings.AllowManagedIPs {
  259. for _, ip := range n.config.AssignedAddresses {
  260. if networkManagedIPAllowed(ip.IP, &n.settings) { // was it allowed?
  261. haveAssignedIPs[ipNetToKey(&ip)] = &ip
  262. }
  263. }
  264. }
  265. if ls.AllowManagedIPs {
  266. for _, ip := range nc.AssignedAddresses {
  267. if networkManagedIPAllowed(ip.IP, ls) { // should it be allowed now?
  268. k := ipNetToKey(&ip)
  269. wantAssignedIPs[k] = true
  270. if _, have := haveAssignedIPs[k]; !have {
  271. n.node.infoLog.Printf("%.16x adding managed IP %s", uint64(n.id), ip.String())
  272. _ = n.tap.AddIP(&ip)
  273. }
  274. }
  275. }
  276. }
  277. for k, ip := range haveAssignedIPs {
  278. if _, want := wantAssignedIPs[k]; !want {
  279. n.node.infoLog.Printf("%.16x removing managed IP %s", uint64(n.id), ip.String())
  280. _ = n.tap.RemoveIP(ip)
  281. }
  282. }
  283. // Do the same for managed routes
  284. haveManagedRoutes := make(map[[6]uint64]*Route)
  285. wantManagedRoutes := make(map[[6]uint64]bool)
  286. if n.settings.AllowManagedRoutes {
  287. for _, r := range n.config.Routes {
  288. if networkManagedRouteAllowed(&r, &n.settings) { // was it allowed?
  289. haveManagedRoutes[r.key()] = &r
  290. }
  291. }
  292. }
  293. if ls.AllowManagedRoutes {
  294. for _, r := range nc.Routes {
  295. if networkManagedRouteAllowed(&r, ls) { // should it be allowed now?
  296. k := r.key()
  297. wantManagedRoutes[k] = true
  298. if _, have := haveManagedRoutes[k]; !have {
  299. n.node.infoLog.Printf("%.16x adding managed route %s", uint64(n.id), r.String())
  300. //TODO _ = n.tap.AddRoute(&r)
  301. }
  302. }
  303. }
  304. }
  305. for k, r := range haveManagedRoutes {
  306. if _, want := wantManagedRoutes[k]; !want {
  307. n.node.infoLog.Printf("%.16x removing managed route %s", uint64(n.id), r.String())
  308. //TODO _ = n.tap.RemoveRoute(r)
  309. }
  310. }
  311. if nc != &n.config {
  312. n.config = *nc
  313. }
  314. if ls != &n.settings {
  315. n.settings = *ls
  316. }
  317. }