WIP: routers on ethertalk
This commit is contained in:
parent
da4c729912
commit
7f8b0cb451
7 changed files with 197 additions and 64 deletions
80
main.go
80
main.go
|
@ -224,18 +224,18 @@ func main() {
|
|||
|
||||
// -------------------------------- Peers ---------------------------------
|
||||
var peersMu sync.Mutex
|
||||
peers := make(map[udpAddr]*router.Peer)
|
||||
peers := make(map[udpAddr]*router.AURPPeer)
|
||||
status.AddItem(ctx, "AURP Peers", peerTableTemplate, func(context.Context) (any, error) {
|
||||
var peerInfo []*router.Peer
|
||||
var peerInfo []*router.AURPPeer
|
||||
func() {
|
||||
peersMu.Lock()
|
||||
defer peersMu.Unlock()
|
||||
peerInfo = make([]*router.Peer, 0, len(peers))
|
||||
peerInfo = make([]*router.AURPPeer, 0, len(peers))
|
||||
for _, p := range peers {
|
||||
peerInfo = append(peerInfo, p)
|
||||
}
|
||||
}()
|
||||
slices.SortFunc(peerInfo, func(pa, pb *router.Peer) int {
|
||||
slices.SortFunc(peerInfo, func(pa, pb *router.AURPPeer) int {
|
||||
return cmp.Or(
|
||||
-cmp.Compare(
|
||||
bool2Int(pa.ReceiverState() == router.ReceiverConnected),
|
||||
|
@ -257,7 +257,7 @@ func main() {
|
|||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
goPeerHandler := func(p *router.Peer) {
|
||||
goPeerHandler := func(p *router.AURPPeer) {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
@ -308,7 +308,7 @@ func main() {
|
|||
continue
|
||||
}
|
||||
|
||||
peer := &router.Peer{
|
||||
peer := &router.AURPPeer{
|
||||
Config: cfg,
|
||||
Transport: &aurp.Transport{
|
||||
LocalDI: localDI,
|
||||
|
@ -434,18 +434,29 @@ func main() {
|
|||
// TODO: more generic routing
|
||||
if ddpkt.DstNet != 0 && !(ddpkt.DstNet >= cfg.EtherTalk.NetStart && ddpkt.DstNet <= cfg.EtherTalk.NetEnd) {
|
||||
// Is it for a network in the routing table?
|
||||
rt := routes.LookupRoute(ddpkt.DstNet)
|
||||
if rt == nil {
|
||||
route := routes.LookupRoute(ddpkt.DstNet)
|
||||
if route == nil {
|
||||
log.Printf("DDP: no route for network %d", ddpkt.DstNet)
|
||||
continue
|
||||
}
|
||||
|
||||
switch {
|
||||
case route.AURPPeer != nil:
|
||||
// Encap ethPacket.Payload into an AURP packet
|
||||
log.Printf("DDP: forwarding to AURP peer %v", rt.Peer.RemoteAddr)
|
||||
if _, err := rt.Peer.Send(rt.Peer.Transport.NewAppleTalkPacket(ethFrame.Payload)); err != nil {
|
||||
log.Printf("DDP: forwarding to AURP peer %v", route.AURPPeer.RemoteAddr)
|
||||
if _, err := route.AURPPeer.Send(route.AURPPeer.Transport.NewAppleTalkPacket(ethFrame.Payload)); err != nil {
|
||||
log.Printf("DDP: Couldn't forward packet to AURP peer: %v", err)
|
||||
}
|
||||
|
||||
case route.EtherTalkPeer != nil:
|
||||
// Route payload to another router over EtherTalk
|
||||
// TODO: this is unlikely because we currenly only support 1 EtherTalk port
|
||||
log.Printf("DDP: forwarding to EtherTalk peer %v", route.EtherTalkPeer.PeerAddr)
|
||||
// Note: resolving AARP can block
|
||||
if err := route.EtherTalkPeer.Forward(ctx, ddpkt); err != nil {
|
||||
log.Printf("DDP: Couldn't forward packet to EtherTalk peer: %v", err)
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -534,7 +545,7 @@ func main() {
|
|||
continue
|
||||
}
|
||||
// New peer!
|
||||
pr = &router.Peer{
|
||||
pr = &router.AURPPeer{
|
||||
Config: cfg,
|
||||
Transport: &aurp.Transport{
|
||||
LocalDI: localDI,
|
||||
|
@ -584,14 +595,7 @@ func main() {
|
|||
ddpkt.DstNet, ddpkt.DstNode, ddpkt.DstSocket,
|
||||
ddpkt.Proto, len(ddpkt.Data))
|
||||
|
||||
// "Route" the packet
|
||||
// Since for now there's only one local network, the routing
|
||||
// decision is pretty easy
|
||||
// TODO: Fix this to support other AppleTalk routers
|
||||
if ddpkt.DstNet < cfg.EtherTalk.NetStart || ddpkt.DstNet > cfg.EtherTalk.NetEnd {
|
||||
log.Print("DDP/AURP: dropping packet not addressed to our EtherTalk range")
|
||||
continue
|
||||
}
|
||||
// Route the packet
|
||||
|
||||
// Check and adjust the Hop Count
|
||||
// Note the ddp package doesn't make this simple
|
||||
|
@ -604,8 +608,44 @@ func main() {
|
|||
ddpkt.Size &^= 0x3C00
|
||||
ddpkt.Size |= hopCount << 10
|
||||
|
||||
if ddpkt.DstNet < cfg.EtherTalk.NetStart || ddpkt.DstNet > cfg.EtherTalk.NetEnd {
|
||||
// Is it a network in the routing table?
|
||||
route := routes.LookupRoute(ddpkt.DstNet)
|
||||
if route == nil {
|
||||
log.Printf("DDP/AURP: no route for packet (dstnet %d); dropping packet", ddpkt.DstNet)
|
||||
break
|
||||
}
|
||||
|
||||
switch {
|
||||
case route.AURPPeer != nil:
|
||||
// Routing between AURP peers... bit weird but OK
|
||||
log.Printf("DDP/AURP: forwarding to AURP peer %v", route.AURPPeer.RemoteAddr)
|
||||
outPkt, err := ddp.ExtMarshal(*ddpkt)
|
||||
if err != nil {
|
||||
log.Printf("DDP/AURP: Couldn't re-marshal packet: %v", err)
|
||||
break
|
||||
}
|
||||
if _, err := route.AURPPeer.Send(route.AURPPeer.Transport.NewAppleTalkPacket(outPkt)); err != nil {
|
||||
log.Printf("DDP/AURP: Couldn't forward packet to AURP peer: %v", err)
|
||||
}
|
||||
|
||||
case route.EtherTalkPeer != nil:
|
||||
// AURP peer -> EtherTalk peer
|
||||
// Note: resolving AARP can block
|
||||
log.Printf("DDP/AURP: forwarding to EtherTalk peer %v", route.EtherTalkPeer.PeerAddr)
|
||||
if err := route.EtherTalkPeer.Forward(ctx, ddpkt); err != nil {
|
||||
log.Printf("DDP/AURP: Couldn't forward packet to EtherTalk peer: %v", err)
|
||||
}
|
||||
|
||||
default:
|
||||
log.Print("DDP/AURP: no forwarding mechanism for route; dropping packet")
|
||||
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Is it addressed to me? Is it NBP?
|
||||
if ddpkt.DstNode == 0 { // Node 0 = the router for the network
|
||||
if ddpkt.DstNode == 0 { // Node 0 = any router for the network = me
|
||||
if ddpkt.DstSocket != 2 {
|
||||
// Something else?? TODO
|
||||
log.Printf("DDP/AURP: I don't have anything 'listening' on socket %d", ddpkt.DstSocket)
|
||||
|
|
|
@ -110,7 +110,7 @@ func (rtr *Router) HandleNBP(srcHWAddr ethernet.Addr, ddpkt *ddp.ExtPacket) erro
|
|||
if route == nil {
|
||||
return fmt.Errorf("no route for network %d", z.Network)
|
||||
}
|
||||
peer := route.Peer
|
||||
peer := route.AURPPeer
|
||||
if peer == nil {
|
||||
return fmt.Errorf("nil peer for route for network %d", z.Network)
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ import (
|
|||
"github.com/sfiera/multitalk/pkg/ddp"
|
||||
)
|
||||
|
||||
func (rtr *Router) HandleNBPInAURP(peer *Peer, ddpkt *ddp.ExtPacket) error {
|
||||
func (rtr *Router) HandleNBPInAURP(peer *AURPPeer, ddpkt *ddp.ExtPacket) error {
|
||||
if ddpkt.Proto != ddp.ProtoNBP {
|
||||
return fmt.Errorf("invalid DDP type %d on socket 2", ddpkt.Proto)
|
||||
}
|
||||
|
|
|
@ -92,8 +92,8 @@ func (ss SenderState) String() string {
|
|||
}
|
||||
}
|
||||
|
||||
// Peer handles the peering with a peer AURP router.
|
||||
type Peer struct {
|
||||
// AURPPeer handles the peering with a peer AURP router.
|
||||
type AURPPeer struct {
|
||||
// Whole router config.
|
||||
Config *Config
|
||||
|
||||
|
@ -125,31 +125,31 @@ type Peer struct {
|
|||
sstate SenderState
|
||||
}
|
||||
|
||||
func (p *Peer) ReceiverState() ReceiverState {
|
||||
func (p *AURPPeer) ReceiverState() ReceiverState {
|
||||
p.mu.RLock()
|
||||
defer p.mu.RUnlock()
|
||||
return p.rstate
|
||||
}
|
||||
|
||||
func (p *Peer) SenderState() SenderState {
|
||||
func (p *AURPPeer) SenderState() SenderState {
|
||||
p.mu.RLock()
|
||||
defer p.mu.RUnlock()
|
||||
return p.sstate
|
||||
}
|
||||
|
||||
func (p *Peer) setRState(rstate ReceiverState) {
|
||||
func (p *AURPPeer) setRState(rstate ReceiverState) {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
p.rstate = rstate
|
||||
}
|
||||
|
||||
func (p *Peer) setSState(sstate SenderState) {
|
||||
func (p *AURPPeer) setSState(sstate SenderState) {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
p.sstate = sstate
|
||||
}
|
||||
|
||||
func (p *Peer) disconnect() {
|
||||
func (p *AURPPeer) disconnect() {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
p.rstate = ReceiverUnconnected
|
||||
|
@ -157,7 +157,7 @@ func (p *Peer) disconnect() {
|
|||
}
|
||||
|
||||
// Send encodes and sends pkt to the remote host.
|
||||
func (p *Peer) Send(pkt aurp.Packet) (int, error) {
|
||||
func (p *AURPPeer) Send(pkt aurp.Packet) (int, error) {
|
||||
var b bytes.Buffer
|
||||
if _, err := pkt.WriteTo(&b); err != nil {
|
||||
return 0, err
|
||||
|
@ -166,7 +166,7 @@ func (p *Peer) Send(pkt aurp.Packet) (int, error) {
|
|||
return p.UDPConn.WriteToUDP(b.Bytes(), p.RemoteAddr)
|
||||
}
|
||||
|
||||
func (p *Peer) Handle(ctx context.Context) error {
|
||||
func (p *AURPPeer) Handle(ctx context.Context) error {
|
||||
rticker := time.NewTicker(1 * time.Second)
|
||||
defer rticker.Stop()
|
||||
sticker := time.NewTicker(1 * time.Second)
|
||||
|
@ -244,7 +244,7 @@ func (p *Peer) Handle(ctx context.Context) error {
|
|||
if sendRetries >= tickleRetryLimit {
|
||||
log.Printf("AURP Peer: Send retry limit reached while waiting for Tickle-Ack, closing connection")
|
||||
p.setRState(ReceiverUnconnected)
|
||||
p.RoutingTable.DeletePeer(p)
|
||||
p.RoutingTable.DeleteAURPPeer(p)
|
||||
break
|
||||
}
|
||||
|
||||
|
@ -263,7 +263,7 @@ func (p *Peer) Handle(ctx context.Context) error {
|
|||
if sendRetries >= sendRetryLimit {
|
||||
log.Printf("AURP Peer: Send retry limit reached while waiting for RI-Rsp, closing connection")
|
||||
p.setRState(ReceiverUnconnected)
|
||||
p.RoutingTable.DeletePeer(p)
|
||||
p.RoutingTable.DeleteAURPPeer(p)
|
||||
break
|
||||
}
|
||||
|
||||
|
@ -458,7 +458,7 @@ func (p *Peer) Handle(ctx context.Context) error {
|
|||
log.Printf("AURP Peer: Learned about these networks: %v", pkt.Networks)
|
||||
|
||||
for _, nt := range pkt.Networks {
|
||||
p.RoutingTable.InsertRoute(
|
||||
p.RoutingTable.InsertAURPRoute(
|
||||
p,
|
||||
nt.Extended,
|
||||
ddp.Network(nt.RangeStart),
|
||||
|
@ -534,7 +534,7 @@ func (p *Peer) Handle(ctx context.Context) error {
|
|||
// Do nothing except respond with RI-Ack
|
||||
|
||||
case aurp.EventCodeNA:
|
||||
if err := p.RoutingTable.InsertRoute(
|
||||
if err := p.RoutingTable.InsertAURPRoute(
|
||||
p,
|
||||
et.Extended,
|
||||
et.RangeStart,
|
||||
|
@ -546,10 +546,10 @@ func (p *Peer) Handle(ctx context.Context) error {
|
|||
ackFlag = aurp.RoutingFlagSendZoneInfo
|
||||
|
||||
case aurp.EventCodeND:
|
||||
p.RoutingTable.DeletePeerNetwork(p, et.RangeStart)
|
||||
p.RoutingTable.DeleteAURPPeerNetwork(p, et.RangeStart)
|
||||
|
||||
case aurp.EventCodeNDC:
|
||||
p.RoutingTable.UpdateRouteDistance(p, et.RangeStart, et.Distance+1)
|
||||
p.RoutingTable.UpdateAURPRouteDistance(p, et.RangeStart, et.Distance+1)
|
||||
|
||||
case aurp.EventCodeNRC:
|
||||
// "An exterior router sends a Network Route Change
|
||||
|
@ -557,7 +557,7 @@ func (p *Peer) Handle(ctx context.Context) error {
|
|||
// through its local internet changes to a path through
|
||||
// a tunneling port, causing split-horizoned processing
|
||||
// to eliminate that network’s routing information."
|
||||
p.RoutingTable.DeletePeerNetwork(p, et.RangeStart)
|
||||
p.RoutingTable.DeleteAURPPeerNetwork(p, et.RangeStart)
|
||||
|
||||
case aurp.EventCodeZC:
|
||||
// "This event is reserved for future use."
|
||||
|
@ -575,7 +575,7 @@ func (p *Peer) Handle(ctx context.Context) error {
|
|||
}
|
||||
|
||||
log.Printf("AURP Peer: Router Down: error code %d %s", pkt.ErrorCode, pkt.ErrorCode)
|
||||
p.RoutingTable.DeletePeer(p)
|
||||
p.RoutingTable.DeleteAURPPeer(p)
|
||||
|
||||
// Respond with RI-Ack
|
||||
if _, err := p.Send(p.Transport.NewRIAckPacket(pkt.ConnectionID, pkt.Sequence, 0)); err != nil {
|
54
router/peer_eth.go
Normal file
54
router/peer_eth.go
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
Copyright 2024 Josh Deprez
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package router
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/google/gopacket/pcap"
|
||||
"github.com/sfiera/multitalk/pkg/ddp"
|
||||
"github.com/sfiera/multitalk/pkg/ethernet"
|
||||
"github.com/sfiera/multitalk/pkg/ethertalk"
|
||||
)
|
||||
|
||||
// EtherTalkPeer holds data needed to exchange routes and zones with another
|
||||
// router on the EtherTalk network.
|
||||
type EtherTalkPeer struct {
|
||||
PcapHandle *pcap.Handle
|
||||
MyHWAddr ethernet.Addr
|
||||
AARP *AARPMachine
|
||||
PeerAddr ddp.Addr
|
||||
}
|
||||
|
||||
// Forward forwards a DDP packet to the next router.
|
||||
func (p *EtherTalkPeer) Forward(ctx context.Context, pkt *ddp.ExtPacket) error {
|
||||
// TODO: AARP resolution can block
|
||||
de, err := p.AARP.Resolve(ctx, p.PeerAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
outFrame, err := ethertalk.AppleTalk(p.MyHWAddr, *pkt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
outFrame.Dst = de
|
||||
outFrameRaw, err := ethertalk.Marshal(*outFrame)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return p.PcapHandle.WritePacketData(outFrameRaw)
|
||||
}
|
|
@ -24,15 +24,18 @@ import (
|
|||
"github.com/sfiera/multitalk/pkg/ddp"
|
||||
)
|
||||
|
||||
// const maxRouteAge = 10 * time.Minute // TODO: confirm
|
||||
const maxRouteAge = 10 * time.Minute // TODO: confirm
|
||||
|
||||
type Route struct {
|
||||
Extended bool
|
||||
NetStart ddp.Network
|
||||
NetEnd ddp.Network
|
||||
Peer *Peer
|
||||
Distance uint8
|
||||
LastSeen time.Time
|
||||
|
||||
// Exactly one of the following should be set
|
||||
AURPPeer *AURPPeer
|
||||
EtherTalkPeer *EtherTalkPeer
|
||||
}
|
||||
|
||||
func (r Route) LastSeenAgo() string {
|
||||
|
@ -70,15 +73,13 @@ func (rt *RoutingTable) LookupRoute(network ddp.Network) *Route {
|
|||
|
||||
var bestRoute *Route
|
||||
for r := range rt.routes {
|
||||
if r.Peer == nil {
|
||||
continue
|
||||
}
|
||||
if network < r.NetStart || network > r.NetEnd {
|
||||
continue
|
||||
}
|
||||
// if time.Since(r.LastSeen) > maxRouteAge {
|
||||
// continue
|
||||
// }
|
||||
// Exclude EtherTalk routes that are too old
|
||||
if r.EtherTalkPeer != nil && time.Since(r.LastSeen) > maxRouteAge {
|
||||
continue
|
||||
}
|
||||
if bestRoute == nil {
|
||||
bestRoute = r
|
||||
continue
|
||||
|
@ -90,41 +91,41 @@ func (rt *RoutingTable) LookupRoute(network ddp.Network) *Route {
|
|||
return bestRoute
|
||||
}
|
||||
|
||||
func (rt *RoutingTable) DeletePeer(peer *Peer) {
|
||||
func (rt *RoutingTable) DeleteAURPPeer(peer *AURPPeer) {
|
||||
rt.mu.Lock()
|
||||
defer rt.mu.Unlock()
|
||||
|
||||
for route := range rt.routes {
|
||||
if route.Peer == peer {
|
||||
if route.AURPPeer == peer {
|
||||
delete(rt.routes, route)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (rt *RoutingTable) DeletePeerNetwork(peer *Peer, network ddp.Network) {
|
||||
func (rt *RoutingTable) DeleteAURPPeerNetwork(peer *AURPPeer, network ddp.Network) {
|
||||
rt.mu.Lock()
|
||||
defer rt.mu.Unlock()
|
||||
|
||||
for route := range rt.routes {
|
||||
if route.Peer == peer && route.NetStart == network {
|
||||
if route.AURPPeer == peer && route.NetStart == network {
|
||||
delete(rt.routes, route)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (rt *RoutingTable) UpdateRouteDistance(peer *Peer, network ddp.Network, distance uint8) {
|
||||
func (rt *RoutingTable) UpdateAURPRouteDistance(peer *AURPPeer, network ddp.Network, distance uint8) {
|
||||
rt.mu.Lock()
|
||||
defer rt.mu.Unlock()
|
||||
|
||||
for route := range rt.routes {
|
||||
if route.Peer == peer && route.NetStart == network {
|
||||
if route.AURPPeer == peer && route.NetStart == network {
|
||||
route.Distance = distance
|
||||
route.LastSeen = time.Now()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (rt *RoutingTable) InsertRoute(peer *Peer, extended bool, netStart, netEnd ddp.Network, metric uint8) error {
|
||||
func (rt *RoutingTable) UpsertEthRoute(peer *EtherTalkPeer, extended bool, netStart, netEnd ddp.Network, metric uint8) error {
|
||||
if netStart > netEnd {
|
||||
return fmt.Errorf("invalid network range [%d, %d]", netStart, netEnd)
|
||||
}
|
||||
|
@ -136,9 +137,33 @@ func (rt *RoutingTable) InsertRoute(peer *Peer, extended bool, netStart, netEnd
|
|||
Extended: extended,
|
||||
NetStart: netStart,
|
||||
NetEnd: netEnd,
|
||||
Peer: peer,
|
||||
Distance: metric,
|
||||
LastSeen: time.Now(),
|
||||
EtherTalkPeer: peer,
|
||||
}
|
||||
|
||||
rt.mu.Lock()
|
||||
defer rt.mu.Unlock()
|
||||
// TODO: update if present rather than insert
|
||||
rt.routes[r] = struct{}{}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rt *RoutingTable) InsertAURPRoute(peer *AURPPeer, extended bool, netStart, netEnd ddp.Network, metric uint8) error {
|
||||
if netStart > netEnd {
|
||||
return fmt.Errorf("invalid network range [%d, %d]", netStart, netEnd)
|
||||
}
|
||||
if netStart != netEnd && !extended {
|
||||
return fmt.Errorf("invalid network range [%d, %d] for nonextended network", netStart, netEnd)
|
||||
}
|
||||
|
||||
r := &Route{
|
||||
Extended: extended,
|
||||
NetStart: netStart,
|
||||
NetEnd: netEnd,
|
||||
Distance: metric,
|
||||
LastSeen: time.Now(),
|
||||
AURPPeer: peer,
|
||||
}
|
||||
|
||||
rt.mu.Lock()
|
||||
|
@ -152,12 +177,10 @@ func (rt *RoutingTable) ValidRoutes() []*Route {
|
|||
defer rt.mu.Unlock()
|
||||
valid := make([]*Route, 0, len(rt.routes))
|
||||
for r := range rt.routes {
|
||||
if r.Peer == nil {
|
||||
// Exclude EtherTalk routes that are too old
|
||||
if r.EtherTalkPeer != nil && time.Since(r.LastSeen) > maxRouteAge {
|
||||
continue
|
||||
}
|
||||
// if time.Since(r.LastSeen) > maxRouteAge {
|
||||
// continue
|
||||
// }
|
||||
valid = append(valid, r)
|
||||
}
|
||||
return valid
|
||||
|
|
|
@ -159,14 +159,30 @@ func (m *RTMPMachine) Run(ctx context.Context, incomingCh <-chan *ddp.ExtPacket)
|
|||
}
|
||||
|
||||
case rtmp.FunctionLoopProbe:
|
||||
log.Printf("RTMP: TODO: handle Loop Probes")
|
||||
log.Print("RTMP: TODO: handle Loop Probes")
|
||||
|
||||
}
|
||||
|
||||
case ddp.ProtoRTMPResp:
|
||||
// It's a peer router on the AppleTalk network!
|
||||
// TODO: integrate this information with the routing table?
|
||||
log.Print("RTMP: Got Response or Data")
|
||||
dataPkt, err := rtmp.UnmarshalDataPacket(pkt.Data)
|
||||
if err != nil {
|
||||
log.Printf("RTMP: Couldn't unmarshal RTMP Data packet: %v", err)
|
||||
break
|
||||
}
|
||||
peer := &EtherTalkPeer{
|
||||
PcapHandle: m.PcapHandle,
|
||||
MyHWAddr: m.AARP.myAddr.Hardware,
|
||||
AARP: m.AARP,
|
||||
PeerAddr: dataPkt.RouterAddr,
|
||||
}
|
||||
|
||||
for _, rt := range dataPkt.NetworkTuples {
|
||||
if err := m.RoutingTable.UpsertEthRoute(peer, rt.Extended, rt.RangeStart, rt.RangeEnd, rt.Distance+1); err != nil {
|
||||
log.Printf("RTMP: Couldn't upsert EtherTalk route: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
log.Printf("RTMP: invalid DDP type %d on socket 1", pkt.Proto)
|
||||
|
|
Loading…
Reference in a new issue