2020-02-06 00:55:26 +00:00
|
|
|
package allregions
|
|
|
|
|
|
|
|
// Region contains cloudflared edge addresses. The edge is partitioned into several regions for
|
|
|
|
// redundancy purposes.
|
|
|
|
type Region struct {
|
2022-06-14 23:08:03 +00:00
|
|
|
connFor map[*EdgeAddr]UsedBy
|
2020-02-06 00:55:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// NewRegion creates a region with the given addresses, which are all unused.
|
2022-06-14 23:08:03 +00:00
|
|
|
func NewRegion(addrs []*EdgeAddr) Region {
|
2020-02-06 00:55:26 +00:00
|
|
|
// The zero value of UsedBy is Unused(), so we can just initialize the map's values with their
|
|
|
|
// zero values.
|
2022-06-14 23:08:03 +00:00
|
|
|
connFor := make(map[*EdgeAddr]UsedBy)
|
|
|
|
for _, addr := range addrs {
|
|
|
|
connFor[addr] = Unused()
|
2021-08-06 13:31:22 +00:00
|
|
|
}
|
|
|
|
return Region{
|
2022-06-14 23:08:03 +00:00
|
|
|
connFor: connFor,
|
2020-02-06 00:55:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// AddrUsedBy finds the address used by the given connection in this region.
|
|
|
|
// Returns nil if the connection isn't using any IP.
|
2021-08-06 13:31:22 +00:00
|
|
|
func (r *Region) AddrUsedBy(connID int) *EdgeAddr {
|
2022-06-14 23:08:03 +00:00
|
|
|
for addr, used := range r.connFor {
|
|
|
|
if used.Used && used.ConnID == connID {
|
|
|
|
return addr
|
|
|
|
}
|
2020-02-06 00:55:26 +00:00
|
|
|
}
|
2022-06-14 23:08:03 +00:00
|
|
|
return nil
|
2020-02-06 00:55:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// AvailableAddrs counts how many unused addresses this region contains.
|
|
|
|
func (r Region) AvailableAddrs() int {
|
2022-06-14 23:08:03 +00:00
|
|
|
n := 0
|
|
|
|
for _, usedby := range r.connFor {
|
|
|
|
if !usedby.Used {
|
|
|
|
n++
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return n
|
2020-02-06 00:55:26 +00:00
|
|
|
}
|
|
|
|
|
2022-06-14 23:08:03 +00:00
|
|
|
// GetUnusedIP returns a random unused address in this region.
|
|
|
|
// Returns nil if all addresses are in use.
|
|
|
|
func (r Region) GetUnusedIP(excluding *EdgeAddr) *EdgeAddr {
|
|
|
|
for addr, usedby := range r.connFor {
|
|
|
|
if !usedby.Used && addr != excluding {
|
|
|
|
return addr
|
|
|
|
}
|
2020-02-06 00:55:26 +00:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-06-14 23:08:03 +00:00
|
|
|
// Use the address, assigning it to a proxy connection.
|
|
|
|
func (r Region) Use(addr *EdgeAddr, connID int) {
|
|
|
|
if addr == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
r.connFor[addr] = InUse(connID)
|
|
|
|
}
|
|
|
|
|
2020-02-06 00:55:26 +00:00
|
|
|
// GetAnyAddress returns an arbitrary address from the region.
|
2021-08-06 13:31:22 +00:00
|
|
|
func (r Region) GetAnyAddress() *EdgeAddr {
|
2022-06-14 23:08:03 +00:00
|
|
|
for addr := range r.connFor {
|
|
|
|
return addr
|
|
|
|
}
|
|
|
|
return nil
|
2020-02-06 00:55:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// GiveBack the address, ensuring it is no longer assigned to an IP.
|
|
|
|
// Returns true if the address is in this region.
|
2022-06-14 23:08:03 +00:00
|
|
|
func (r Region) GiveBack(addr *EdgeAddr) (ok bool) {
|
|
|
|
if _, ok := r.connFor[addr]; !ok {
|
|
|
|
return false
|
2020-02-06 00:55:26 +00:00
|
|
|
}
|
2022-06-14 23:08:03 +00:00
|
|
|
r.connFor[addr] = Unused()
|
|
|
|
return true
|
2020-02-06 00:55:26 +00:00
|
|
|
}
|