derpmap.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. package tailcfg
  4. import "sort"
  5. // DERPMap describes the set of DERP packet relay servers that are available.
  6. type DERPMap struct {
  7. // HomeParams, if non-nil, is a change in home parameters.
  8. //
  9. // The rest of the DEPRMap fields, if zero, means unchanged.
  10. HomeParams *DERPHomeParams `json:",omitempty"`
  11. // Regions is the set of geographic regions running DERP node(s).
  12. //
  13. // It's keyed by the DERPRegion.RegionID.
  14. //
  15. // The numbers are not necessarily contiguous.
  16. Regions map[int]*DERPRegion
  17. // OmitDefaultRegions specifies to not use Tailscale's DERP servers, and only use those
  18. // specified in this DERPMap. If there are none set outside of the defaults, this is a noop.
  19. //
  20. // This field is only meaningful if the Regions map is non-nil (indicating a change).
  21. OmitDefaultRegions bool `json:"omitDefaultRegions,omitempty"`
  22. }
  23. // / RegionIDs returns the sorted region IDs.
  24. func (m *DERPMap) RegionIDs() []int {
  25. ret := make([]int, 0, len(m.Regions))
  26. for rid := range m.Regions {
  27. ret = append(ret, rid)
  28. }
  29. sort.Ints(ret)
  30. return ret
  31. }
  32. // DERPHomeParams contains parameters from the server related to selecting a
  33. // DERP home region (sometimes referred to as the "preferred DERP").
  34. type DERPHomeParams struct {
  35. // RegionScore scales latencies of DERP regions by a given scaling
  36. // factor when determining which region to use as the home
  37. // ("preferred") DERP. Scores in the range (0, 1) will cause this
  38. // region to be proportionally more preferred, and scores in the range
  39. // (1, ∞) will penalize a region.
  40. //
  41. // If a region is not present in this map, it is treated as having a
  42. // score of 1.0.
  43. //
  44. // Scores should not be 0 or negative; such scores will be ignored.
  45. //
  46. // A nil map means no change from the previous value (if any); an empty
  47. // non-nil map can be sent to reset all scores back to 1.0.
  48. RegionScore map[int]float64 `json:",omitempty"`
  49. }
  50. // DERPRegion is a geographic region running DERP relay node(s).
  51. //
  52. // Client nodes discover which region they're closest to, advertise
  53. // that "home" DERP region (previously called "home node", when there
  54. // was only 1 node per region) and maintain a persistent connection
  55. // that region as long as it's the closest. Client nodes will further
  56. // connect to other regions as necessary to communicate with peers
  57. // advertising other regions as their homes.
  58. type DERPRegion struct {
  59. // RegionID is a unique integer for a geographic region.
  60. //
  61. // It corresponds to the legacy derpN.tailscale.com hostnames
  62. // used by older clients. (Older clients will continue to resolve
  63. // derpN.tailscale.com when contacting peers, rather than use
  64. // the server-provided DERPMap)
  65. //
  66. // RegionIDs must be non-zero, positive, and guaranteed to fit
  67. // in a JavaScript number.
  68. //
  69. // RegionIDs in range 900-999 are reserved for end users to run their
  70. // own DERP nodes.
  71. RegionID int
  72. // RegionCode is a short name for the region. It's usually a popular
  73. // city or airport code in the region: "nyc", "sf", "sin",
  74. // "fra", etc.
  75. RegionCode string
  76. // RegionName is a long English name for the region: "New York City",
  77. // "San Francisco", "Singapore", "Frankfurt", etc.
  78. RegionName string
  79. // Avoid is whether the client should avoid picking this as its home
  80. // region. The region should only be used if a peer is there.
  81. // Clients already using this region as their home should migrate
  82. // away to a new region without Avoid set.
  83. Avoid bool `json:",omitempty"`
  84. // Nodes are the DERP nodes running in this region, in
  85. // priority order for the current client. Client TLS
  86. // connections should ideally only go to the first entry
  87. // (falling back to the second if necessary). STUN packets
  88. // should go to the first 1 or 2.
  89. //
  90. // If nodes within a region route packets amongst themselves,
  91. // but not to other regions. That said, each user/domain
  92. // should get a the same preferred node order, so if all nodes
  93. // for a user/network pick the first one (as they should, when
  94. // things are healthy), the inter-cluster routing is minimal
  95. // to zero.
  96. Nodes []*DERPNode
  97. }
  98. // DERPNode describes a DERP packet relay node running within a DERPRegion.
  99. type DERPNode struct {
  100. // Name is a unique node name (across all regions).
  101. // It is not a host name.
  102. // It's typically of the form "1b", "2a", "3b", etc. (region
  103. // ID + suffix within that region)
  104. Name string
  105. // RegionID is the RegionID of the DERPRegion that this node
  106. // is running in.
  107. RegionID int
  108. // HostName is the DERP node's hostname.
  109. //
  110. // It is required but need not be unique; multiple nodes may
  111. // have the same HostName but vary in configuration otherwise.
  112. HostName string
  113. // CertName optionally specifies the expected TLS cert common
  114. // name. If empty, HostName is used. If CertName is non-empty,
  115. // HostName is only used for the TCP dial (if IPv4/IPv6 are
  116. // not present) + TLS ClientHello.
  117. CertName string `json:",omitempty"`
  118. // IPv4 optionally forces an IPv4 address to use, instead of using DNS.
  119. // If empty, A record(s) from DNS lookups of HostName are used.
  120. // If the string is not an IPv4 address, IPv4 is not used; the
  121. // conventional string to disable IPv4 (and not use DNS) is
  122. // "none".
  123. IPv4 string `json:",omitempty"`
  124. // IPv6 optionally forces an IPv6 address to use, instead of using DNS.
  125. // If empty, AAAA record(s) from DNS lookups of HostName are used.
  126. // If the string is not an IPv6 address, IPv6 is not used; the
  127. // conventional string to disable IPv6 (and not use DNS) is
  128. // "none".
  129. IPv6 string `json:",omitempty"`
  130. // Port optionally specifies a STUN port to use.
  131. // Zero means 3478.
  132. // To disable STUN on this node, use -1.
  133. STUNPort int `json:",omitempty"`
  134. // STUNOnly marks a node as only a STUN server and not a DERP
  135. // server.
  136. STUNOnly bool `json:",omitempty"`
  137. // DERPPort optionally provides an alternate TLS port number
  138. // for the DERP HTTPS server.
  139. //
  140. // If zero, 443 is used.
  141. DERPPort int `json:",omitempty"`
  142. // InsecureForTests is used by unit tests to disable TLS verification.
  143. // It should not be set by users.
  144. InsecureForTests bool `json:",omitempty"`
  145. // STUNTestIP is used in tests to override the STUN server's IP.
  146. // If empty, it's assumed to be the same as the DERP server.
  147. STUNTestIP string `json:",omitempty"`
  148. // CanPort80 specifies whether this DERP node is accessible over HTTP
  149. // on port 80 specifically. This is used for captive portal checks.
  150. CanPort80 bool `json:",omitempty"`
  151. }
  152. // DotInvalid is a fake DNS TLD used in tests for an invalid hostname.
  153. const DotInvalid = ".invalid"