Start routing table
This commit is contained in:
parent
10c447c78d
commit
1a83e4d543
5 changed files with 98 additions and 9 deletions
|
@ -79,6 +79,14 @@ func Unmarshal(data []byte) (*Packet, error) {
|
|||
NBPID: data[1],
|
||||
}
|
||||
tupleCount := data[0] & 0x0F
|
||||
if tupleCount == 0 {
|
||||
return nil, fmt.Errorf("no tuples")
|
||||
}
|
||||
// Only LkUp-Reply can have more than 1 tuple
|
||||
if tupleCount > 1 && p.Function != FunctionLkUpReply {
|
||||
return nil, fmt.Errorf("wrong number of tuples %d for function %s", tupleCount, p.Function)
|
||||
}
|
||||
|
||||
data = data[2:]
|
||||
for range tupleCount {
|
||||
if len(data) < 8 {
|
||||
|
@ -144,7 +152,7 @@ func (t *Tuple) writeTo(b *bytes.Buffer) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (t *Tuple) String() string {
|
||||
func (t Tuple) String() string {
|
||||
return fmt.Sprintf("%d.%d.%d (enum %d) <-> %s:%s@%s",
|
||||
t.Network, t.Node, t.Socket, t.Enumerator, t.Object, t.Type, t.Zone,
|
||||
)
|
||||
|
|
|
@ -102,6 +102,14 @@ func (tr *Transport) sequenced(connID, seq uint16) TrHeader {
|
|||
}
|
||||
}
|
||||
|
||||
// NewAppleTalkPacket returns a new AppleTalkPacket.
|
||||
func (tr *Transport) NewAppleTalkPacket(data []byte) *AppleTalkPacket {
|
||||
return &AppleTalkPacket{
|
||||
DomainHeader: tr.domainHeader(PacketTypeAppleTalk),
|
||||
Data: data,
|
||||
}
|
||||
}
|
||||
|
||||
// NewOpenReqPacket returns a new Open-Req packet structure. By default it sets
|
||||
// all SUI flags and uses version 1.
|
||||
func (tr *Transport) NewOpenReqPacket(opts Options) *OpenReqPacket {
|
||||
|
|
30
main.go
30
main.go
|
@ -128,7 +128,7 @@ func main() {
|
|||
}()
|
||||
}
|
||||
|
||||
// --------------- Configured peer setup ---------------
|
||||
// ------------------------- Configured peer setup ------------------------
|
||||
for _, peerStr := range cfg.Peers {
|
||||
if !hasPortRE.MatchString(peerStr) {
|
||||
peerStr += ":387"
|
||||
|
@ -156,12 +156,12 @@ func main() {
|
|||
goPeerHandler(peer)
|
||||
}
|
||||
|
||||
// -------------------- AARP --------------------
|
||||
// --------------------------------- AARP ---------------------------------
|
||||
aarpMachine := NewAARPMachine(cfg, pcapHandle, myHWAddr)
|
||||
aarpCh := make(chan *ethertalk.Packet, 1024)
|
||||
go aarpMachine.Run(ctx, aarpCh)
|
||||
|
||||
// -------------------- RTMP --------------------
|
||||
// --------------------------------- RTMP ---------------------------------
|
||||
rtmpMachine := &RTMPMachine{
|
||||
aarp: aarpMachine,
|
||||
cfg: cfg,
|
||||
|
@ -170,7 +170,7 @@ func main() {
|
|||
rtmpCh := make(chan *ddp.ExtPacket, 1024)
|
||||
go rtmpMachine.Run(ctx, rtmpCh)
|
||||
|
||||
// --------------------- NBP --------------------
|
||||
// ---------------------------------- NBP ---------------------------------
|
||||
nbpMachine := &NBPMachine{
|
||||
aarp: aarpMachine,
|
||||
pcapHandle: pcapHandle,
|
||||
|
@ -178,7 +178,7 @@ func main() {
|
|||
nbpCh := make(chan *ddp.ExtPacket, 1024)
|
||||
go nbpMachine.Run(ctx, nbpCh)
|
||||
|
||||
// ---------- Raw AppleTalk/AARP inbound ----------
|
||||
// ---------------------- Raw AppleTalk/AARP inbound ----------------------
|
||||
go func() {
|
||||
for {
|
||||
if ctx.Err() != nil {
|
||||
|
@ -235,12 +235,28 @@ func main() {
|
|||
continue
|
||||
}
|
||||
|
||||
// TODO: If the packet is NBP BrRq and for a zone we have in
|
||||
// our zone info table, convert it to a FwdReq and send that
|
||||
// out to the peer
|
||||
// TODO: implement the zone information table
|
||||
|
||||
// Our network?
|
||||
// "The network number 0 is reserved to mean unknown; by default
|
||||
// it specifies the local network to which the node is
|
||||
// connected. Packets whose destination network number is 0 are
|
||||
// addressed to a node on the local network."
|
||||
if ddpkt.DstNet != 0 && ddpkt.DstNet != myAddr.Proto.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 := lookupRoute(ddpkt.DstNet)
|
||||
if rt == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Encap ethPacket.Payload into an AURP packet
|
||||
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)
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -275,7 +291,7 @@ func main() {
|
|||
}
|
||||
}()
|
||||
|
||||
// ---------- AURP inbound ----------
|
||||
// ----------------------------- AURP inbound -----------------------------
|
||||
for {
|
||||
if ctx.Err() != nil {
|
||||
return
|
||||
|
|
5
peer.go
5
peer.go
|
@ -24,6 +24,7 @@ import (
|
|||
"time"
|
||||
|
||||
"gitea.drjosh.dev/josh/jrouter/aurp"
|
||||
"github.com/sfiera/multitalk/pkg/ddp"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -275,7 +276,9 @@ func (p *peer) handle(ctx context.Context) error {
|
|||
|
||||
log.Printf("Learned about these networks: %v", pkt.Networks)
|
||||
|
||||
// TODO: Integrate info into route table
|
||||
for _, nt := range pkt.Networks {
|
||||
upsertRoutes(ddp.Network(nt.RangeStart), ddp.Network(nt.RangeEnd), p, nt.Distance)
|
||||
}
|
||||
|
||||
// TODO: track which networks we don't have zone info for, and
|
||||
// only set SZI for those ?
|
||||
|
|
54
route.go
Normal file
54
route.go
Normal file
|
@ -0,0 +1,54 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"fmt"
|
||||
"slices"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/sfiera/multitalk/pkg/ddp"
|
||||
)
|
||||
|
||||
type route struct {
|
||||
peer *peer
|
||||
metric uint8
|
||||
last time.Time
|
||||
}
|
||||
|
||||
var (
|
||||
routingTableMu sync.Mutex
|
||||
routingTable = make(map[ddp.Network][]*route)
|
||||
)
|
||||
|
||||
func lookupRoute(network ddp.Network) *route {
|
||||
routingTableMu.Lock()
|
||||
defer routingTableMu.Unlock()
|
||||
|
||||
rs := routingTable[network]
|
||||
if len(rs) == 0 {
|
||||
return nil
|
||||
}
|
||||
return rs[0]
|
||||
}
|
||||
|
||||
func upsertRoutes(netStart, netEnd ddp.Network, peer *peer, metric uint8) error {
|
||||
if netStart > netEnd {
|
||||
return fmt.Errorf("invalid network range [%d, %d]", netStart, netEnd)
|
||||
}
|
||||
r := &route{
|
||||
peer: peer,
|
||||
metric: metric,
|
||||
last: time.Now(),
|
||||
}
|
||||
|
||||
routingTableMu.Lock()
|
||||
defer routingTableMu.Unlock()
|
||||
for n := netStart; n <= netEnd; n++ {
|
||||
routingTable[n] = append(routingTable[n], r)
|
||||
slices.SortFunc(routingTable[n], func(r, s *route) int {
|
||||
return cmp.Compare(r.metric, s.metric)
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
Loading…
Reference in a new issue