region.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. package allregions
  2. import (
  3. "net"
  4. )
  5. // Region contains cloudflared edge addresses. The edge is partitioned into several regions for
  6. // redundancy purposes.
  7. type Region struct {
  8. connFor map[*net.TCPAddr]UsedBy
  9. }
  10. // NewRegion creates a region with the given addresses, which are all unused.
  11. func NewRegion(addrs []*net.TCPAddr) Region {
  12. // The zero value of UsedBy is Unused(), so we can just initialize the map's values with their
  13. // zero values.
  14. m := make(map[*net.TCPAddr]UsedBy)
  15. for _, addr := range addrs {
  16. m[addr] = Unused()
  17. }
  18. return Region{connFor: m}
  19. }
  20. // AddrUsedBy finds the address used by the given connection in this region.
  21. // Returns nil if the connection isn't using any IP.
  22. func (r *Region) AddrUsedBy(connID int) *net.TCPAddr {
  23. for addr, used := range r.connFor {
  24. if used.Used && used.ConnID == connID {
  25. return addr
  26. }
  27. }
  28. return nil
  29. }
  30. // AvailableAddrs counts how many unused addresses this region contains.
  31. func (r Region) AvailableAddrs() int {
  32. n := 0
  33. for _, usedby := range r.connFor {
  34. if !usedby.Used {
  35. n++
  36. }
  37. }
  38. return n
  39. }
  40. // GetUnusedIP returns a random unused address in this region.
  41. // Returns nil if all addresses are in use.
  42. func (r Region) GetUnusedIP(excluding *net.TCPAddr) *net.TCPAddr {
  43. for addr, usedby := range r.connFor {
  44. if !usedby.Used && addr != excluding {
  45. return addr
  46. }
  47. }
  48. return nil
  49. }
  50. // Use the address, assigning it to a proxy connection.
  51. func (r Region) Use(addr *net.TCPAddr, connID int) {
  52. if addr == nil {
  53. //logrus.Errorf("Attempted to use nil address for connection %d", connID)
  54. return
  55. }
  56. r.connFor[addr] = InUse(connID)
  57. }
  58. // GetAnyAddress returns an arbitrary address from the region.
  59. func (r Region) GetAnyAddress() *net.TCPAddr {
  60. for addr := range r.connFor {
  61. return addr
  62. }
  63. return nil
  64. }
  65. // GiveBack the address, ensuring it is no longer assigned to an IP.
  66. // Returns true if the address is in this region.
  67. func (r Region) GiveBack(addr *net.TCPAddr) (ok bool) {
  68. if _, ok := r.connFor[addr]; !ok {
  69. return false
  70. }
  71. r.connFor[addr] = Unused()
  72. return true
  73. }