mirror of
				https://github.com/tailscale/tailscale.git
				synced 2025-11-04 02:01:14 +01:00 
			
		
		
		
	So a region can be used if needed, but won't be STUN-probed or used as its home. This gives us another possible debugging mechanism for #1310, or can be used as a short-term measure against DERP flip-flops for people equidistant between regions if our hysteresis still isn't good enough. Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
		
			
				
	
	
		
			135 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright (c) 2020 Tailscale Inc & AUTHORS All rights reserved.
 | 
						|
// Use of this source code is governed by a BSD-style
 | 
						|
// license that can be found in the LICENSE file.
 | 
						|
 | 
						|
package tailcfg
 | 
						|
 | 
						|
import "sort"
 | 
						|
 | 
						|
// DERPMap describes the set of DERP packet relay servers that are available.
 | 
						|
type DERPMap struct {
 | 
						|
	// Regions is the set of geographic regions running DERP node(s).
 | 
						|
	//
 | 
						|
	// It's keyed by the DERPRegion.RegionID.
 | 
						|
	//
 | 
						|
	// The numbers are not necessarily contiguous.
 | 
						|
	Regions map[int]*DERPRegion
 | 
						|
}
 | 
						|
 | 
						|
/// RegionIDs returns the sorted region IDs.
 | 
						|
func (m *DERPMap) RegionIDs() []int {
 | 
						|
	ret := make([]int, 0, len(m.Regions))
 | 
						|
	for rid := range m.Regions {
 | 
						|
		ret = append(ret, rid)
 | 
						|
	}
 | 
						|
	sort.Ints(ret)
 | 
						|
	return ret
 | 
						|
}
 | 
						|
 | 
						|
// DERPRegion is a geographic region running DERP relay node(s).
 | 
						|
//
 | 
						|
// Client nodes discover which region they're closest to, advertise
 | 
						|
// that "home" DERP region (previously called "home node", when there
 | 
						|
// was only 1 node per region) and maintain a persistent connection
 | 
						|
// that region as long as it's the closest. Client nodes will further
 | 
						|
// connect to other regions as necessary to communicate with peers
 | 
						|
// advertising other regions as their homes.
 | 
						|
type DERPRegion struct {
 | 
						|
	// RegionID is a unique integer for a geographic region.
 | 
						|
	//
 | 
						|
	// It corresponds to the legacy derpN.tailscale.com hostnames
 | 
						|
	// used by older clients. (Older clients will continue to resolve
 | 
						|
	// derpN.tailscale.com when contacting peers, rather than use
 | 
						|
	// the server-provided DERPMap)
 | 
						|
	//
 | 
						|
	// RegionIDs must be non-zero, positive, and guaranteed to fit
 | 
						|
	// in a JavaScript number.
 | 
						|
	RegionID int
 | 
						|
 | 
						|
	// RegionCode is a short name for the region. It's usually a popular
 | 
						|
	// city or airport code in the region: "nyc", "sf", "sin",
 | 
						|
	// "fra", etc.
 | 
						|
	RegionCode string
 | 
						|
 | 
						|
	// RegionName is a long English name for the region: "New York City",
 | 
						|
	// "San Francisco", "Singapore", "Frankfurt", etc.
 | 
						|
	RegionName string
 | 
						|
 | 
						|
	// Avoid is whether the client should avoid picking this as its home
 | 
						|
	// region. The region should only be used if a peer is there.
 | 
						|
	// Clients already using this region as their home should migrate
 | 
						|
	// away to a new region without Avoid set.
 | 
						|
	Avoid bool `json:",omitempty"`
 | 
						|
 | 
						|
	// Nodes are the DERP nodes running in this region, in
 | 
						|
	// priority order for the current client. Client TLS
 | 
						|
	// connections should ideally only go to the first entry
 | 
						|
	// (falling back to the second if necessary). STUN packets
 | 
						|
	// should go to the first 1 or 2.
 | 
						|
	//
 | 
						|
	// If nodes within a region route packets amongst themselves,
 | 
						|
	// but not to other regions. That said, each user/domain
 | 
						|
	// should get a the same preferred node order, so if all nodes
 | 
						|
	// for a user/network pick the first one (as they should, when
 | 
						|
	// things are healthy), the inter-cluster routing is minimal
 | 
						|
	// to zero.
 | 
						|
	Nodes []*DERPNode
 | 
						|
}
 | 
						|
 | 
						|
// DERPNode describes a DERP packet relay node running within a DERPRegion.
 | 
						|
type DERPNode struct {
 | 
						|
	// Name is a unique node name (across all regions).
 | 
						|
	// It is not a host name.
 | 
						|
	// It's typically of the form "1b", "2a", "3b", etc. (region
 | 
						|
	// ID + suffix within that region)
 | 
						|
	Name string
 | 
						|
 | 
						|
	// RegionID is the RegionID of the DERPRegion that this node
 | 
						|
	// is running in.
 | 
						|
	RegionID int
 | 
						|
 | 
						|
	// HostName is the DERP node's hostname.
 | 
						|
	//
 | 
						|
	// It is required but need not be unique; multiple nodes may
 | 
						|
	// have the same HostName but vary in configuration otherwise.
 | 
						|
	HostName string
 | 
						|
 | 
						|
	// CertName optionally specifies the expected TLS cert common
 | 
						|
	// name. If empty, HostName is used. If CertName is non-empty,
 | 
						|
	// HostName is only used for the TCP dial (if IPv4/IPv6 are
 | 
						|
	// not present) + TLS ClientHello.
 | 
						|
	CertName string `json:",omitempty"`
 | 
						|
 | 
						|
	// IPv4 optionally forces an IPv4 address to use, instead of using DNS.
 | 
						|
	// If empty, A record(s) from DNS lookups of HostName are used.
 | 
						|
	// If the string is not an IPv4 address, IPv4 is not used; the
 | 
						|
	// conventional string to disable IPv4 (and not use DNS) is
 | 
						|
	// "none".
 | 
						|
	IPv4 string `json:",omitempty"`
 | 
						|
 | 
						|
	// IPv6 optionally forces an IPv6 address to use, instead of using DNS.
 | 
						|
	// If empty, AAAA record(s) from DNS lookups of HostName are used.
 | 
						|
	// If the string is not an IPv6 address, IPv6 is not used; the
 | 
						|
	// conventional string to disable IPv6 (and not use DNS) is
 | 
						|
	// "none".
 | 
						|
	IPv6 string `json:",omitempty"`
 | 
						|
 | 
						|
	// Port optionally specifies a STUN port to use.
 | 
						|
	// Zero means 3478.
 | 
						|
	// To disable STUN on this node, use -1.
 | 
						|
	STUNPort int `json:",omitempty"`
 | 
						|
 | 
						|
	// STUNOnly marks a node as only a STUN server and not a DERP
 | 
						|
	// server.
 | 
						|
	STUNOnly bool `json:",omitempty"`
 | 
						|
 | 
						|
	// DERPTestPort is used in tests to override the port, instead
 | 
						|
	// of using the default port of 443. If non-zero, TLS
 | 
						|
	// verification is skipped.
 | 
						|
	DERPTestPort int `json:",omitempty"`
 | 
						|
 | 
						|
	// STUNTestIP is used in tests to override the STUN server's IP.
 | 
						|
	// If empty, it's assumed to be the same as the DERP server.
 | 
						|
	STUNTestIP string `json:",omitempty"`
 | 
						|
}
 |