TUN-4927: Parameterize region in edge discovery code

This commit is contained in:
Areg Harutyunyan 2021-08-17 13:07:40 -05:00
parent 12ad264eb3
commit 3ef3e7a99a
No known key found for this signature in database
GPG Key ID: 97A3DFFE8E9320B7
6 changed files with 35 additions and 10 deletions

View File

@ -22,6 +22,8 @@ const (
dotServerName = "cloudflare-dns.com"
dotServerAddr = "1.1.1.1:853"
dotTimeout = 15 * time.Second
logFieldAddress = "address"
)
// Redeclare network functions so they can be overridden in tests.
@ -59,7 +61,9 @@ var friendlyDNSErrorLines = []string{
}
// EdgeDiscovery implements HA service discovery lookup.
func edgeDiscovery(log *zerolog.Logger) ([][]*EdgeAddr, error) {
func edgeDiscovery(log *zerolog.Logger, srvService string) ([][]*EdgeAddr, error) {
log.Debug().Str("domain", "_"+srvService+"._"+srvProto+"."+srvName).Msg("looking up edge SRV record")
_, addrs, err := netLookupSRV(srvService, srvProto, srvName)
if err != nil {
_, fallbackAddrs, fallbackErr := fallbackLookupSRV(srvService, srvProto, srvName)
@ -87,7 +91,7 @@ func edgeDiscovery(log *zerolog.Logger) ([][]*EdgeAddr, error) {
return resolvedAddrPerCNAME, nil
}
func lookupSRVWithDOT(service, proto, name string) (cname string, addrs []*net.SRV, err error) {
func lookupSRVWithDOT(string, string, string) (cname string, addrs []*net.SRV, err error) {
// Inspiration: https://github.com/artyom/dot/blob/master/dot.go
r := &net.Resolver{
PreferGo: true,
@ -130,13 +134,13 @@ func ResolveAddrs(addrs []string, log *zerolog.Logger) (resolved []*EdgeAddr) {
for _, addr := range addrs {
tcpAddr, err := net.ResolveTCPAddr("tcp", addr)
if err != nil {
log.Error().Msgf("Failed to resolve %s to TCP address, err: %v", addr, err)
log.Error().Str(logFieldAddress, addr).Err(err).Msg("failed to resolve to TCP address")
continue
}
udpAddr, err := net.ResolveUDPAddr("udp", addr)
if err != nil {
log.Error().Msgf("Failed to resolve %s to UDP address, err: %v", addr, err)
log.Error().Str(logFieldAddress, addr).Err(err).Msg("failed to resolve to UDP address")
continue
}
resolved = append(resolved, &EdgeAddr{

View File

@ -25,7 +25,7 @@ func TestEdgeDiscovery(t *testing.T) {
}
l := zerolog.Nop()
addrLists, err := edgeDiscovery(&l)
addrLists, err := edgeDiscovery(&l, "")
assert.NoError(t, err)
actualAddrSet := map[string]bool{}
for _, addrs := range addrLists {

View File

@ -18,8 +18,8 @@ type Regions struct {
// ------------------------------------
// ResolveEdge resolves the Cloudflare edge, returning all regions discovered.
func ResolveEdge(log *zerolog.Logger) (*Regions, error) {
edgeAddrs, err := edgeDiscovery(log)
func ResolveEdge(log *zerolog.Logger, region string) (*Regions, error) {
edgeAddrs, err := edgeDiscovery(log, getRegionalServiceName(region))
if err != nil {
return nil, err
}
@ -122,3 +122,12 @@ func (rs *Regions) GiveBack(addr *EdgeAddr) bool {
}
return rs.region2.GiveBack(addr)
}
// Return regionalized service name if `region` isn't empty, otherwise return the global service name for origintunneld
func getRegionalServiceName(region string) string {
if region != "" {
return region + "-" + srvService // Example: `us-origintunneld`
}
return srvService // Global service is just `origintunneld`
}

View File

@ -156,6 +156,18 @@ func TestNewNoResolveBalancesRegions(t *testing.T) {
}
}
func TestGetRegionalServiceName(t *testing.T) {
// Empty region should just go to origintunneld
globalServiceName := getRegionalServiceName("")
assert.Equal(t, srvService, globalServiceName)
// Non-empty region should go to the regional origintunneld variant
for _, region := range []string{"us", "pt", "am"} {
regionalServiceName := getRegionalServiceName(region)
assert.Equal(t, region+"-"+srvService, regionalServiceName)
}
}
func RegionsIsBalanced(t *testing.T, rs *Regions) {
delta := rs.region1.AvailableAddrs() - rs.region2.AvailableAddrs()
assert.True(t, abs(delta) <= 1)

View File

@ -30,8 +30,8 @@ type Edge struct {
// ResolveEdge runs the initial discovery of the Cloudflare edge, finding Addrs that can be allocated
// to connections.
func ResolveEdge(log *zerolog.Logger) (*Edge, error) {
regions, err := allregions.ResolveEdge(log)
func ResolveEdge(log *zerolog.Logger, region string) (*Edge, error) {
regions, err := allregions.ResolveEdge(log, region)
if err != nil {
return new(Edge), err
}

View File

@ -74,7 +74,7 @@ func NewSupervisor(config *TunnelConfig, reconnectCh chan ReconnectSignal, grace
if len(config.EdgeAddrs) > 0 {
edgeIPs, err = edgediscovery.StaticEdge(config.Log, config.EdgeAddrs)
} else {
edgeIPs, err = edgediscovery.ResolveEdge(config.Log)
edgeIPs, err = edgediscovery.ResolveEdge(config.Log, "")
}
if err != nil {
return nil, err