localconfig.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  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/json"
  16. "io/ioutil"
  17. "os"
  18. "runtime"
  19. )
  20. // LocalConfigPhysicalPathConfiguration contains settings for physical paths
  21. type LocalConfigPhysicalPathConfiguration struct {
  22. // Blacklist flags this path as unusable for ZeroTier traffic
  23. Blacklist bool
  24. // TrustedPathID identifies a path for unencrypted/unauthenticated traffic
  25. TrustedPathID uint64
  26. }
  27. // LocalConfigVirtualAddressConfiguration contains settings for virtual addresses
  28. type LocalConfigVirtualAddressConfiguration struct {
  29. // Try is a list of IPs/ports to try for this peer in addition to anything learned from roots or direct path push
  30. Try []InetAddress `json:"try,omitempty"`
  31. }
  32. // ExternalAddress is an externally visible address
  33. type ExternalAddress struct {
  34. InetAddress
  35. // Permanent indicates that this address should be incorporated into this node's Locator
  36. Permanent bool `json:"permanent"`
  37. }
  38. // LocalConfigSettings contains node settings
  39. type LocalConfigSettings struct {
  40. // PrimaryPort is the main UDP port and must be set (defaults to 9993)
  41. PrimaryPort int `json:"primaryPort"`
  42. // SecondaryPort is the secondary UDP port, set to 0 to disbale (picked at random by default)
  43. SecondaryPort int `json:"secondaryPort"`
  44. // PortSearch causes ZeroTier to try other ports automatically if it can't bind to configured ports
  45. PortSearch bool `json:"portSearch"`
  46. // PortMapping enables uPnP and NAT-PMP support
  47. PortMapping bool `json:"portMapping"`
  48. // LogSizeMax is the maximum size of the infoLog in kilobytes or 0 for no limit and -1 to disable logging
  49. LogSizeMax int `json:"logSizeMax"`
  50. // IP/port to bind for TCP access to control API (disabled if null)
  51. APITCPBindAddress *InetAddress `json:"apiTCPBindAddress,omitempty"`
  52. // InterfacePrefixBlacklist are prefixes of physical network interface names that won't be used by ZeroTier (e.g. "lo" or "utun")
  53. InterfacePrefixBlacklist []string `json:"interfacePrefixBlacklist,omitempty"`
  54. // ExplicitAddresses are explicit IP/port addresses to advertise to other nodes, such as externally mapped ports on a router
  55. ExplicitAddresses []ExternalAddress `json:"explicitAddresses,omitempty"`
  56. }
  57. // LocalConfig is the local.conf file and stores local settings for the node.
  58. type LocalConfig struct {
  59. // Physical path configurations by CIDR IP/bits
  60. Physical map[string]LocalConfigPhysicalPathConfiguration `json:"physical,omitempty"`
  61. // Virtual node specific configurations by 10-digit hex ZeroTier address
  62. Virtual map[Address]LocalConfigVirtualAddressConfiguration `json:"virtual,omitempty"`
  63. // Network local configurations by 16-digit hex ZeroTier network ID
  64. Network map[NetworkID]NetworkLocalSettings `json:"network,omitempty"`
  65. // LocalConfigSettings contains other local settings for this node
  66. Settings LocalConfigSettings `json:"settings"`
  67. initialized bool
  68. }
  69. // Read this local config from a file, initializing to defaults if the file does not exist.
  70. func (lc *LocalConfig) Read(p string, saveDefaultsIfNotExist bool, isTotallyNewNode bool) error {
  71. // Initialize defaults, which may be replaced if we read a file from disk.
  72. if !lc.initialized {
  73. lc.initialized = true
  74. lc.Physical = make(map[string]LocalConfigPhysicalPathConfiguration)
  75. lc.Virtual = make(map[Address]LocalConfigVirtualAddressConfiguration)
  76. lc.Network = make(map[NetworkID]NetworkLocalSettings)
  77. if isTotallyNewNode {
  78. lc.Settings.PrimaryPort = 893
  79. } else {
  80. lc.Settings.PrimaryPort = 9993
  81. }
  82. lc.Settings.SecondaryPort = unassignedPrivilegedPorts[randomUInt()%uint(len(unassignedPrivilegedPorts))]
  83. lc.Settings.PortSearch = true
  84. lc.Settings.PortMapping = true
  85. lc.Settings.LogSizeMax = 128
  86. if !isTotallyNewNode {
  87. lc.Settings.APITCPBindAddress = NewInetAddressFromString("127.0.0.1/9993")
  88. }
  89. switch runtime.GOOS {
  90. case "windows":
  91. lc.Settings.InterfacePrefixBlacklist = []string{"loopback"}
  92. case "darwin":
  93. lc.Settings.InterfacePrefixBlacklist = []string{"lo", "utun", "feth"}
  94. default:
  95. lc.Settings.InterfacePrefixBlacklist = []string{"lo"}
  96. }
  97. }
  98. data, err := ioutil.ReadFile(p)
  99. if err != nil {
  100. if !os.IsNotExist(err) {
  101. return err
  102. }
  103. if saveDefaultsIfNotExist {
  104. err = lc.Write(p)
  105. if err != nil {
  106. return err
  107. }
  108. }
  109. return nil
  110. }
  111. return json.Unmarshal(data, lc)
  112. }
  113. // Write this local config to a file
  114. func (lc *LocalConfig) Write(p string) error {
  115. data, err := json.MarshalIndent(lc, "", "\t")
  116. if err != nil {
  117. return err
  118. }
  119. return ioutil.WriteFile(p, data, 0644)
  120. }