Routing table simplifications
This commit is contained in:
parent
abbe8c542b
commit
c7d5ecec49
4 changed files with 68 additions and 64 deletions
11
main.go
11
main.go
|
@ -131,10 +131,7 @@ func main() {
|
|||
}
|
||||
|
||||
// ----------------------------- Routing table ----------------------------
|
||||
routing := &routingTable{
|
||||
table: make(map[ddp.Network][]*route),
|
||||
allRoutes: make(map[*route]struct{}),
|
||||
}
|
||||
routing := NewRoutingTable()
|
||||
|
||||
// ------------------------- Configured peer setup ------------------------
|
||||
for _, peerStr := range cfg.Peers {
|
||||
|
@ -250,15 +247,15 @@ func main() {
|
|||
// addressed to a node on the local network."
|
||||
if ddpkt.DstNet != 0 && (ddpkt.DstNet < cfg.EtherTalk.NetStart || ddpkt.DstNet > cfg.EtherTalk.NetEnd) {
|
||||
// Is it for a network in the routing table?
|
||||
rt := routing.lookupRoute(ddpkt.DstNet)
|
||||
rt := routing.LookupRoute(ddpkt.DstNet)
|
||||
if rt == nil {
|
||||
log.Printf("DDP: no route for network %d", ddpkt.DstNet)
|
||||
continue
|
||||
}
|
||||
|
||||
// Encap ethPacket.Payload into an AURP packet
|
||||
log.Printf("DDP: forwarding to AURP peer %v", rt.peer.tr.RemoteDI)
|
||||
if _, err := rt.peer.send(rt.peer.tr.NewAppleTalkPacket(ethFrame.Payload)); err != nil {
|
||||
log.Printf("DDP: forwarding to AURP peer %v", rt.Peer.tr.RemoteDI)
|
||||
if _, err := rt.Peer.send(rt.Peer.tr.NewAppleTalkPacket(ethFrame.Payload)); err != nil {
|
||||
log.Printf("DDP: Couldn't forward packet to AURP peer: %v", err)
|
||||
}
|
||||
|
||||
|
|
4
peer.go
4
peer.go
|
@ -82,7 +82,7 @@ type peer struct {
|
|||
raddr *net.UDPAddr
|
||||
recv chan aurp.Packet
|
||||
|
||||
routingTable *routingTable
|
||||
routingTable *RoutingTable
|
||||
}
|
||||
|
||||
// send encodes and sends pkt to the remote host.
|
||||
|
@ -279,7 +279,7 @@ func (p *peer) handle(ctx context.Context) error {
|
|||
log.Printf("Learned about these networks: %v", pkt.Networks)
|
||||
|
||||
for _, nt := range pkt.Networks {
|
||||
p.routingTable.upsertRoutes(
|
||||
p.routingTable.UpsertRoute(
|
||||
nt.Extended,
|
||||
ddp.Network(nt.RangeStart),
|
||||
ddp.Network(nt.RangeEnd),
|
||||
|
|
105
route.go
105
route.go
|
@ -1,9 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"fmt"
|
||||
"slices"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
|
@ -12,74 +10,83 @@ import (
|
|||
|
||||
const maxRouteAge = 10 * time.Minute // TODO: confirm
|
||||
|
||||
type route struct {
|
||||
extended bool
|
||||
netStart ddp.Network
|
||||
netEnd ddp.Network
|
||||
peer *peer
|
||||
metric uint8
|
||||
last time.Time
|
||||
type Route struct {
|
||||
Extended bool
|
||||
NetStart ddp.Network
|
||||
NetEnd ddp.Network
|
||||
Peer *peer
|
||||
Distance uint8
|
||||
LastSeen time.Time
|
||||
}
|
||||
|
||||
type routingTable struct {
|
||||
tableMu sync.Mutex
|
||||
table map[ddp.Network][]*route
|
||||
|
||||
allRoutesMu sync.Mutex
|
||||
allRoutes map[*route]struct{}
|
||||
type RoutingTable struct {
|
||||
mu sync.Mutex
|
||||
routes map[*Route]struct{}
|
||||
}
|
||||
|
||||
func (rt *routingTable) lookupRoute(network ddp.Network) *route {
|
||||
rt.tableMu.Lock()
|
||||
defer rt.tableMu.Unlock()
|
||||
func NewRoutingTable() *RoutingTable {
|
||||
return &RoutingTable{
|
||||
routes: make(map[*Route]struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
for _, rs := range rt.table[network] {
|
||||
if time.Since(rs.last) > maxRouteAge {
|
||||
func (rt *RoutingTable) LookupRoute(network ddp.Network) *Route {
|
||||
rt.mu.Lock()
|
||||
defer rt.mu.Unlock()
|
||||
|
||||
var bestRoute *Route
|
||||
for r := range rt.routes {
|
||||
if r.Peer == nil {
|
||||
continue
|
||||
}
|
||||
return rs
|
||||
if network < r.NetStart || network > r.NetEnd {
|
||||
continue
|
||||
}
|
||||
return nil
|
||||
if time.Since(r.LastSeen) > maxRouteAge {
|
||||
continue
|
||||
}
|
||||
if bestRoute == nil {
|
||||
bestRoute = r
|
||||
continue
|
||||
}
|
||||
if r.Distance < bestRoute.Distance {
|
||||
bestRoute = r
|
||||
}
|
||||
}
|
||||
return bestRoute
|
||||
}
|
||||
|
||||
func (rt *routingTable) upsertRoutes(extended bool, netStart, netEnd ddp.Network, peer *peer, metric uint8) error {
|
||||
func (rt *RoutingTable) UpsertRoute(extended bool, netStart, netEnd ddp.Network, peer *peer, metric uint8) error {
|
||||
if netStart > netEnd {
|
||||
return fmt.Errorf("invalid network range [%d, %d]", netStart, netEnd)
|
||||
}
|
||||
|
||||
r := &route{
|
||||
extended: extended,
|
||||
netStart: netStart,
|
||||
netEnd: netEnd,
|
||||
peer: peer,
|
||||
metric: metric,
|
||||
last: time.Now(),
|
||||
// TODO: handle the Update part of "Upsert"
|
||||
|
||||
r := &Route{
|
||||
Extended: extended,
|
||||
NetStart: netStart,
|
||||
NetEnd: netEnd,
|
||||
Peer: peer,
|
||||
Distance: metric,
|
||||
LastSeen: time.Now(),
|
||||
}
|
||||
|
||||
rt.allRoutesMu.Lock()
|
||||
rt.allRoutes[r] = struct{}{}
|
||||
rt.allRoutesMu.Unlock()
|
||||
|
||||
rt.tableMu.Lock()
|
||||
defer rt.tableMu.Unlock()
|
||||
for n := netStart; n <= netEnd; n++ {
|
||||
rt.table[n] = append(rt.table[n], r)
|
||||
slices.SortFunc(rt.table[n], func(r, s *route) int {
|
||||
return cmp.Compare(r.metric, s.metric)
|
||||
})
|
||||
}
|
||||
rt.mu.Lock()
|
||||
defer rt.mu.Unlock()
|
||||
rt.routes[r] = struct{}{}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rt *routingTable) validRoutes() []*route {
|
||||
rt.allRoutesMu.Lock()
|
||||
defer rt.allRoutesMu.Unlock()
|
||||
valid := make([]*route, 0, len(rt.allRoutes))
|
||||
for r := range rt.allRoutes {
|
||||
if r.peer == nil {
|
||||
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 {
|
||||
continue
|
||||
}
|
||||
if time.Since(r.last) > maxRouteAge {
|
||||
if time.Since(r.LastSeen) > maxRouteAge {
|
||||
continue
|
||||
}
|
||||
valid = append(valid, r)
|
||||
|
|
12
rtmp.go
12
rtmp.go
|
@ -35,7 +35,7 @@ type RTMPMachine struct {
|
|||
aarp *AARPMachine
|
||||
cfg *config
|
||||
pcapHandle *pcap.Handle
|
||||
routingTable *routingTable
|
||||
routingTable *RoutingTable
|
||||
}
|
||||
|
||||
// Run executes the machine.
|
||||
|
@ -214,12 +214,12 @@ func (m *RTMPMachine) dataPacket(myAddr ddp.Addr) *rtmp.DataPacket {
|
|||
},
|
||||
},
|
||||
}
|
||||
for _, rt := range m.routingTable.validRoutes() {
|
||||
for _, rt := range m.routingTable.ValidRoutes() {
|
||||
p.NetworkTuples = append(p.NetworkTuples, rtmp.NetworkTuple{
|
||||
Extended: rt.extended,
|
||||
RangeStart: rt.netStart,
|
||||
RangeEnd: rt.netEnd,
|
||||
Distance: rt.metric + 1,
|
||||
Extended: rt.Extended,
|
||||
RangeStart: rt.NetStart,
|
||||
RangeEnd: rt.NetEnd,
|
||||
Distance: rt.Distance + 1,
|
||||
})
|
||||
}
|
||||
return p
|
||||
|
|
Loading…
Reference in a new issue