jrouter/route.go

96 lines
1.7 KiB
Go
Raw Normal View History

2024-04-12 16:14:27 +10:00
package main
import (
"fmt"
"sync"
"time"
"github.com/sfiera/multitalk/pkg/ddp"
)
2024-04-14 13:44:35 +10:00
const maxRouteAge = 10 * time.Minute // TODO: confirm
2024-04-14 17:13:12 +10:00
type Route struct {
Extended bool
NetStart ddp.Network
NetEnd ddp.Network
Peer *peer
Distance uint8
LastSeen time.Time
2024-04-12 16:14:27 +10:00
}
2024-04-14 17:13:12 +10:00
type RoutingTable struct {
mu sync.Mutex
routes map[*Route]struct{}
}
2024-04-13 15:47:58 +10:00
2024-04-14 17:13:12 +10:00
func NewRoutingTable() *RoutingTable {
return &RoutingTable{
routes: make(map[*Route]struct{}),
}
2024-04-14 13:44:35 +10:00
}
2024-04-12 16:14:27 +10:00
2024-04-14 17:13:12 +10:00
func (rt *RoutingTable) LookupRoute(network ddp.Network) *Route {
rt.mu.Lock()
defer rt.mu.Unlock()
2024-04-12 16:14:27 +10:00
2024-04-14 17:13:12 +10:00
var bestRoute *Route
for r := range rt.routes {
if r.Peer == nil {
continue
}
if network < r.NetStart || network > r.NetEnd {
2024-04-14 13:44:35 +10:00
continue
}
2024-04-14 17:13:12 +10:00
if time.Since(r.LastSeen) > maxRouteAge {
continue
}
if bestRoute == nil {
bestRoute = r
continue
}
if r.Distance < bestRoute.Distance {
bestRoute = r
}
2024-04-12 16:14:27 +10:00
}
2024-04-14 17:13:12 +10:00
return bestRoute
2024-04-12 16:14:27 +10:00
}
2024-04-14 17:13:12 +10:00
func (rt *RoutingTable) UpsertRoute(extended bool, netStart, netEnd ddp.Network, peer *peer, metric uint8) error {
2024-04-12 16:14:27 +10:00
if netStart > netEnd {
return fmt.Errorf("invalid network range [%d, %d]", netStart, netEnd)
}
2024-04-14 13:44:35 +10:00
2024-04-14 17:13:12 +10:00
// TODO: handle the Update part of "Upsert"
2024-04-13 15:47:58 +10:00
2024-04-14 17:13:12 +10:00
r := &Route{
Extended: extended,
NetStart: netStart,
NetEnd: netEnd,
Peer: peer,
Distance: metric,
LastSeen: time.Now(),
2024-04-12 16:14:27 +10:00
}
2024-04-14 17:13:12 +10:00
rt.mu.Lock()
defer rt.mu.Unlock()
rt.routes[r] = struct{}{}
2024-04-12 16:14:27 +10:00
return nil
}
2024-04-14 13:44:35 +10:00
2024-04-14 17:13:12 +10:00
func (rt *RoutingTable) ValidRoutes() []*Route {
rt.mu.Lock()
defer rt.mu.Unlock()
valid := make([]*Route, 0, len(rt.routes))
for r := range rt.routes {
if r.Peer == nil {
2024-04-14 13:44:35 +10:00
continue
}
2024-04-14 17:13:12 +10:00
if time.Since(r.LastSeen) > maxRouteAge {
2024-04-14 13:44:35 +10:00
continue
}
valid = append(valid, r)
}
2024-04-14 13:45:05 +10:00
return valid
2024-04-14 13:44:35 +10:00
}