[WIP] Refactor AMT
This commit is contained in:
parent
7d7fa3a753
commit
5f7e07157e
2 changed files with 50 additions and 18 deletions
46
amt.go
Normal file
46
amt.go
Normal file
|
@ -0,0 +1,46 @@
|
|||
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
|
||||
}
|
22
main.go
22
main.go
|
@ -34,7 +34,6 @@ import (
|
|||
"gitea.drjosh.dev/josh/jrouter/aurp"
|
||||
"github.com/sfiera/multitalk/pkg/aarp"
|
||||
"github.com/sfiera/multitalk/pkg/ddp"
|
||||
"github.com/sfiera/multitalk/pkg/ethernet"
|
||||
"github.com/sfiera/multitalk/pkg/ethertalk"
|
||||
)
|
||||
|
||||
|
@ -140,11 +139,7 @@ func main() {
|
|||
}
|
||||
|
||||
// AppleTalk packet loop
|
||||
type amtEntry struct {
|
||||
hwAddr ethernet.Addr
|
||||
last time.Time
|
||||
}
|
||||
amt := make(map[ddp.Addr]amtEntry)
|
||||
var amt AMT
|
||||
go func() {
|
||||
iface, err := net.InterfaceByName(cfg.EtherTalk.Device)
|
||||
if err != nil {
|
||||
|
@ -186,18 +181,12 @@ func main() {
|
|||
case aarp.RequestOp:
|
||||
log.Printf("AARP: Who has %v? Tell %v", aapkt.Dst.Proto, aapkt.Src.Proto)
|
||||
// Glean that aapkt.Src.Proto -> aapkt.Src.Hardware
|
||||
amt[aapkt.Src.Proto] = amtEntry{
|
||||
hwAddr: aapkt.Src.Hardware,
|
||||
last: time.Now(),
|
||||
}
|
||||
amt.Learn(aapkt.Src.Proto, aapkt.Src.Hardware)
|
||||
log.Printf("AARP: Gleaned that %v -> %v", aapkt.Src.Proto, aapkt.Src.Hardware)
|
||||
|
||||
case aarp.ResponseOp:
|
||||
log.Printf("AARP: %v is at %v", aapkt.Dst.Proto, aapkt.Dst.Hardware)
|
||||
amt[aapkt.Dst.Proto] = amtEntry{
|
||||
hwAddr: aapkt.Dst.Hardware,
|
||||
last: time.Now(),
|
||||
}
|
||||
amt.Learn(aapkt.Dst.Proto, aapkt.Dst.Hardware)
|
||||
|
||||
case aarp.ProbeOp:
|
||||
log.Printf("AARP: %v probing to see if %v is available", aapkt.Src.Hardware, aapkt.Src.Proto)
|
||||
|
@ -216,10 +205,7 @@ func main() {
|
|||
ddpkt.Proto, len(ddpkt.Data))
|
||||
// Glean address info for AMT
|
||||
srcAddr := ddp.Addr{Network: ddpkt.SrcNet, Node: ddpkt.SrcNode}
|
||||
amt[srcAddr] = amtEntry{
|
||||
hwAddr: ethFrame.Src,
|
||||
last: time.Now(),
|
||||
}
|
||||
amt.Learn(srcAddr, ethFrame.Src)
|
||||
log.Printf("DDP: Gleaned that %v -> %v", srcAddr, ethFrame.Src)
|
||||
|
||||
default:
|
||||
|
|
Loading…
Reference in a new issue