From 3ef3e7a99a9170c0511f3b2b26897e8c635023e8 Mon Sep 17 00:00:00 2001 From: Areg Harutyunyan Date: Tue, 17 Aug 2021 13:07:40 -0500 Subject: [PATCH] TUN-4927: Parameterize region in edge discovery code --- edgediscovery/allregions/discovery.go | 12 ++++++++---- edgediscovery/allregions/discovery_test.go | 2 +- edgediscovery/allregions/regions.go | 13 +++++++++++-- edgediscovery/allregions/regions_test.go | 12 ++++++++++++ edgediscovery/edgediscovery.go | 4 ++-- origin/supervisor.go | 2 +- 6 files changed, 35 insertions(+), 10 deletions(-) diff --git a/edgediscovery/allregions/discovery.go b/edgediscovery/allregions/discovery.go index 6ffeded3..9a9e531e 100644 --- a/edgediscovery/allregions/discovery.go +++ b/edgediscovery/allregions/discovery.go @@ -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{ diff --git a/edgediscovery/allregions/discovery_test.go b/edgediscovery/allregions/discovery_test.go index 007519b2..89ed13d5 100644 --- a/edgediscovery/allregions/discovery_test.go +++ b/edgediscovery/allregions/discovery_test.go @@ -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 { diff --git a/edgediscovery/allregions/regions.go b/edgediscovery/allregions/regions.go index 5098561e..cec79240 100644 --- a/edgediscovery/allregions/regions.go +++ b/edgediscovery/allregions/regions.go @@ -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` +} diff --git a/edgediscovery/allregions/regions_test.go b/edgediscovery/allregions/regions_test.go index d73b75e1..d6446df2 100644 --- a/edgediscovery/allregions/regions_test.go +++ b/edgediscovery/allregions/regions_test.go @@ -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) diff --git a/edgediscovery/edgediscovery.go b/edgediscovery/edgediscovery.go index c93e18c9..dab271d7 100644 --- a/edgediscovery/edgediscovery.go +++ b/edgediscovery/edgediscovery.go @@ -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 } diff --git a/origin/supervisor.go b/origin/supervisor.go index a0bbaa90..bcb19da0 100644 --- a/origin/supervisor.go +++ b/origin/supervisor.go @@ -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