TUN-6007: Implement new edge discovery algorithm

This commit is contained in:
Devin Carr
2022-05-20 14:51:36 -07:00
parent e3aad7799e
commit 4f468b8a5d
14 changed files with 1378 additions and 587 deletions

View File

@@ -11,9 +11,10 @@ import (
const (
LogFieldConnIndex = "connIndex"
LogFieldIPAddress = "ip"
)
var errNoAddressesLeft = fmt.Errorf("there are no free edge addresses left")
var ErrNoAddressesLeft = fmt.Errorf("there are no free edge addresses left")
// Edge finds addresses on the Cloudflare edge and hands them out to connections.
type Edge struct {
@@ -28,8 +29,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, region string) (*Edge, error) {
regions, err := allregions.ResolveEdge(log, region)
func ResolveEdge(log *zerolog.Logger, region string, edgeIpVersion allregions.ConfigIPVersion) (*Edge, error) {
regions, err := allregions.ResolveEdge(log, region, edgeIpVersion)
if err != nil {
return new(Edge), err
}
@@ -51,15 +52,6 @@ func StaticEdge(log *zerolog.Logger, hostnames []string) (*Edge, error) {
}, nil
}
// MockEdge creates a Cloudflare Edge from arbitrary TCP addresses. Used for testing.
func MockEdge(log *zerolog.Logger, addrs []*allregions.EdgeAddr) *Edge {
regions := allregions.NewNoResolve(addrs)
return &Edge{
log: log,
regions: regions,
}
}
// ------------------------------------
// Methods
// ------------------------------------
@@ -70,7 +62,7 @@ func (ed *Edge) GetAddrForRPC() (*allregions.EdgeAddr, error) {
defer ed.Unlock()
addr := ed.regions.GetAnyAddress()
if addr == nil {
return nil, errNoAddressesLeft
return nil, ErrNoAddressesLeft
}
return addr, nil
}
@@ -91,14 +83,17 @@ func (ed *Edge) GetAddr(connIndex int) (*allregions.EdgeAddr, error) {
addr := ed.regions.GetUnusedAddr(nil, connIndex)
if addr == nil {
log.Debug().Msg("edgediscovery - GetAddr: No addresses left to give proxy connection")
return nil, errNoAddressesLeft
return nil, ErrNoAddressesLeft
}
log.Debug().Msg("edgediscovery - GetAddr: Giving connection its new address")
log = ed.log.With().
Int(LogFieldConnIndex, connIndex).
IPAddr(LogFieldIPAddress, addr.UDP.IP).Logger()
log.Debug().Msgf("edgediscovery - GetAddr: Giving connection its new address")
return addr, nil
}
// GetDifferentAddr gives back the proxy connection's edge Addr and uses a new one.
func (ed *Edge) GetDifferentAddr(connIndex int) (*allregions.EdgeAddr, error) {
func (ed *Edge) GetDifferentAddr(connIndex int, hasConnectivityError bool) (*allregions.EdgeAddr, error) {
log := ed.log.With().Int(LogFieldConnIndex, connIndex).Logger()
ed.Lock()
@@ -106,16 +101,18 @@ func (ed *Edge) GetDifferentAddr(connIndex int) (*allregions.EdgeAddr, error) {
oldAddr := ed.regions.AddrUsedBy(connIndex)
if oldAddr != nil {
ed.regions.GiveBack(oldAddr)
ed.regions.GiveBack(oldAddr, hasConnectivityError)
}
addr := ed.regions.GetUnusedAddr(oldAddr, connIndex)
if addr == nil {
log.Debug().Msg("edgediscovery - GetDifferentAddr: No addresses left to give proxy connection")
// note: if oldAddr were not nil, it will become available on the next iteration
return nil, errNoAddressesLeft
return nil, ErrNoAddressesLeft
}
log.Debug().Msgf("edgediscovery - GetDifferentAddr: Giving connection its new address: %v from the address list: %v",
addr, ed.regions.AvailableAddrs())
log = ed.log.With().
Int(LogFieldConnIndex, connIndex).
IPAddr(LogFieldIPAddress, addr.UDP.IP).Logger()
log.Debug().Msgf("edgediscovery - GetDifferentAddr: Giving connection its new address from the address list: %v", ed.regions.AvailableAddrs())
return addr, nil
}
@@ -128,9 +125,11 @@ func (ed *Edge) AvailableAddrs() int {
// GiveBack the address so that other connections can use it.
// Returns true if the address is in this edge.
func (ed *Edge) GiveBack(addr *allregions.EdgeAddr) bool {
func (ed *Edge) GiveBack(addr *allregions.EdgeAddr, hasConnectivityError bool) bool {
ed.Lock()
defer ed.Unlock()
ed.log.Debug().Msg("edgediscovery - GiveBack: Address now unused")
return ed.regions.GiveBack(addr)
log := ed.log.With().
IPAddr(LogFieldIPAddress, addr.UDP.IP).Logger()
log.Debug().Msgf("edgediscovery - GiveBack: Address now unused")
return ed.regions.GiveBack(addr, hasConnectivityError)
}