Rate limiting the update of lastseen date for route.

This commit is contained in:
Kevin Liang 2024-03-22 19:13:14 +00:00
parent 2dfe7593ed
commit 735838a0f1
3 changed files with 53 additions and 15 deletions

View File

@ -15,6 +15,7 @@ import (
"slices" "slices"
"strings" "strings"
"sync" "sync"
"time"
xmaps "golang.org/x/exp/maps" xmaps "golang.org/x/exp/maps"
"golang.org/x/net/dns/dnsmessage" "golang.org/x/net/dns/dnsmessage"
@ -69,6 +70,9 @@ type AppConnector struct {
// queue provides ordering for update operations // queue provides ordering for update operations
queue execqueue.ExecQueue queue execqueue.ExecQueue
discoveredToUpdateDate map[string][]netip.Prefix
discoveredLastUpdate time.Time
} }
// NewAppConnector creates a new AppConnector. // NewAppConnector creates a new AppConnector.
@ -335,12 +339,17 @@ func (e *AppConnector) ObserveDNSResponse(res []byte) {
// advertise each address we have learned for the routed domain, that // advertise each address we have learned for the routed domain, that
// was not already known. // was not already known.
var toAdvertise []netip.Prefix var toAdvertise []netip.Prefix
var toUpdateDate []netip.Prefix // var toUpdateDate []netip.Prefix
for _, addr := range addrs { for _, addr := range addrs {
if !e.isAddrKnownLocked(domain, addr) { if !e.isAddrKnownLocked(domain, addr) {
toAdvertise = append(toAdvertise, netip.PrefixFrom(addr, addr.BitLen())) toAdvertise = append(toAdvertise, netip.PrefixFrom(addr, addr.BitLen()))
} else { } else {
toUpdateDate = append(toUpdateDate, netip.PrefixFrom(addr, addr.BitLen())) if e.discoveredToUpdateDate == nil {
e.discoveredToUpdateDate = make(map[string][]netip.Prefix)
}
e.discoveredToUpdateDate[domain] = append(e.discoveredToUpdateDate[domain], netip.PrefixFrom(addr, addr.BitLen()))
slices.SortFunc(e.discoveredToUpdateDate[domain], func(i, j netip.Prefix) int { return i.Addr().Compare(j.Addr()) })
slices.Compact(e.discoveredToUpdateDate[domain])
} }
} }
@ -348,15 +357,34 @@ func (e *AppConnector) ObserveDNSResponse(res []byte) {
// update the pm.currentroutes, then advertise those routes. // update the pm.currentroutes, then advertise those routes.
// we might also able to do this in local backend's advertiseRoute method, doing the update one domain by one domain. // we might also able to do this in local backend's advertiseRoute method, doing the update one domain by one domain.
// currentRouteInfo := nil // currentRouteInfo := nil
routesToUpdate := append(toAdvertise, toUpdateDate...)
updateStore := false
routeInfo := e.routeAdvertiser.ReadRouteInfoFromStore() routeInfo := e.routeAdvertiser.ReadRouteInfoFromStore()
if routeInfo.Discovered == nil { if len(toAdvertise) != 0 {
routeInfo.Discovered = make(map[string]*ipn.DatedRoute) routeInfo.AddRoutesInDiscoveredForDomain(domain, toAdvertise)
updateStore = true
} }
routeInfo.UpdateRoutesInDiscoveredForDomain(domain, routesToUpdate) now := time.Now()
if len(e.discoveredToUpdateDate) > 0 && now.Sub(e.discoveredLastUpdate) > 5*time.Minute {
// fmt.Println("We did a date update to the existing routes") // Kevin debug
// fmt.Println("The time now is: ", now, " The last update was; ", e.discoveredLastUpdate) // Kevin debug
routeInfo.UpdateDatesForRoutesInDiscovered(e.discoveredToUpdateDate)
e.discoveredToUpdateDate = make(map[string][]netip.Prefix)
e.discoveredLastUpdate = now
updateStore = true
}
// fmt.Println("The time I updated the date was: ", now) // Kevin debug
// fmt.Println("Next time we update the date will be: ", now.Add(1*time.Minute)) // Kevin debug
// fmt.Println("The last update was; ", e.discoveredLastUpdate)// Kevin debug
// fmt.Println("discoveredToUpdate: ", e.discoveredToUpdateDate)// Kevin debug
outDated := routeInfo.OutDatedRoutesInDiscoveredForDomain(domain) outDated := routeInfo.OutDatedRoutesInDiscoveredForDomain(domain)
e.routeAdvertiser.UpdateRoutesInfoToStore(routeInfo) if len(outDated) != 0 {
// fmt.Println("Route infos after dns update: ", e.routeAdvertiser.ReadRouteInfoFromStore()) updateStore = true
}
if updateStore {
e.routeAdvertiser.UpdateRoutesInfoToStore(routeInfo)
}
// fmt.Println("Route infos after dns update: ", e.routeAdvertiser.ReadRouteInfoFromStore()) // Kevin debug
e.scheduleAdvertisement(domain, toAdvertise...) e.scheduleAdvertisement(domain, toAdvertise...)
e.scheduleUndvertisement(domain, outDated...) e.scheduleUndvertisement(domain, outDated...)
} }

View File

@ -53,7 +53,10 @@ func (pm *profileManager) CurrentRoutes() *ipn.RouteInfo {
func (pm *profileManager) SetCurrentRoutes(in *ipn.RouteInfo) error { func (pm *profileManager) SetCurrentRoutes(in *ipn.RouteInfo) error {
pm.currentRoutes = in pm.currentRoutes = in
return pm.WriteRoutesForCurrentProfile() if err := pm.WriteRoutesForCurrentProfile(); err != nil {
return err
}
return nil
} }
func (pm *profileManager) WriteState(id ipn.StateKey, val []byte) error { func (pm *profileManager) WriteState(id ipn.StateKey, val []byte) error {

View File

@ -960,11 +960,10 @@ type RouteInfo struct {
Discovered map[string]*DatedRoute Discovered map[string]*DatedRoute
} }
func (r RouteInfo) UpdateRoutesInDiscoveredForDomain(domain string, addrs []netip.Prefix) { func (r RouteInfo) AddRoutesInDiscoveredForDomain(domain string, addrs []netip.Prefix) {
dr, hasKey := r.Discovered[domain] dr, hasKey := r.Discovered[domain]
fmt.Println("FRAN URIDFD", hasKey, dr, dr.Routes)
if !hasKey || dr == nil || dr.Routes == nil { if !hasKey || dr == nil || dr.Routes == nil {
newDatedRoutes := &DatedRoute{make(map[netip.Prefix]time.Time), time.Now().Truncate(1 * time.Hour)} newDatedRoutes := &DatedRoute{make(map[netip.Prefix]time.Time), time.Now()}
newDatedRoutes.addAddrsToDatedRoute(addrs) newDatedRoutes.addAddrsToDatedRoute(addrs)
r.Discovered[domain] = newDatedRoutes r.Discovered[domain] = newDatedRoutes
return return
@ -977,11 +976,19 @@ func (r RouteInfo) UpdateRoutesInDiscoveredForDomain(domain string, addrs []neti
return return
} }
func (r RouteInfo) UpdateDatesForRoutesInDiscovered(toUpdate map[string][]netip.Prefix) {
for domain, addrs := range toUpdate {
for _, addr := range addrs {
r.Discovered[domain].Routes[addr] = time.Now()
}
}
}
func (r RouteInfo) OutDatedRoutesInDiscoveredForDomain(domain string) []netip.Prefix { func (r RouteInfo) OutDatedRoutesInDiscoveredForDomain(domain string) []netip.Prefix {
dr, hasKey := r.Discovered[domain] dr, hasKey := r.Discovered[domain]
var outdate []netip.Prefix var outdate []netip.Prefix
now := time.Now() now := time.Now()
if !hasKey || dr == nil || dr.Routes == nil || now.Sub(dr.LastCleanUp) < 360 { if !hasKey || dr == nil || dr.Routes == nil || now.Sub(dr.LastCleanUp) < 360*time.Hour {
return nil return nil
} }
for addr, date := range dr.Routes { for addr, date := range dr.Routes {
@ -992,7 +999,7 @@ func (r RouteInfo) OutDatedRoutesInDiscoveredForDomain(domain string) []netip.Pr
} }
} }
r.Discovered[domain] = dr r.Discovered[domain] = dr
dr.LastCleanUp = time.Now().Truncate(1 * time.Hour) dr.LastCleanUp = time.Now()
return outdate return outdate
} }
@ -1018,7 +1025,7 @@ func (d *DatedRoute) String() string {
} }
func (d *DatedRoute) addAddrsToDatedRoute(addrs []netip.Prefix) { func (d *DatedRoute) addAddrsToDatedRoute(addrs []netip.Prefix) {
time := time.Now().Truncate(1 * time.Hour) time := time.Now()
for _, addr := range addrs { for _, addr := range addrs {
d.Routes[addr] = time d.Routes[addr] = time
} }