jrouter/amt.go
2024-04-06 15:19:42 +11:00

46 lines
1,021 B
Go

package main
import (
"sync"
"time"
"github.com/sfiera/multitalk/pkg/ddp"
"github.com/sfiera/multitalk/pkg/ethernet"
)
// TODO: verify this parameter
const maxAMTEntryAge = 30 * time.Second
type amtEntry struct {
hwAddr ethernet.Addr
last time.Time
}
// AMT implements a concurrent-safe Address Mapping Table for AppleTalk (DDP)
// addresses to Ethernet hardware addresses.
type AMT struct {
mu sync.RWMutex
table map[ddp.Addr]amtEntry
}
// Learn adds or updates an AMT entry.
func (t *AMT) Learn(ddpAddr ddp.Addr, hwAddr ethernet.Addr) {
t.mu.Lock()
defer t.mu.Unlock()
if t.table == nil {
t.table = make(map[ddp.Addr]amtEntry)
}
t.table[ddpAddr] = amtEntry{
hwAddr: hwAddr,
last: time.Now(),
}
}
// Lookup searches for a non-expired entry in the table only. It does not send
// any packets.
func (t *AMT) Lookup(ddpAddr ddp.Addr) (ethernet.Addr, bool) {
t.mu.RLock()
defer t.mu.RUnlock()
ent, ok := t.table[ddpAddr]
return ent.hwAddr, ok && time.Since(ent.last) < maxAMTEntryAge
}