2
0

localconfig.go 4.4 KB

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