WIP RTMP machine

This commit is contained in:
Josh Deprez 2024-04-07 15:14:54 +10:00
parent 261ad84d23
commit 112012bf5b
Signed by: josh
SSH key fingerprint: SHA256:zZji7w1Ilh2RuUpbQcqkLPrqmRwpiCSycbF2EfKm6Kw
2 changed files with 101 additions and 2 deletions

14
main.go
View file

@ -125,6 +125,7 @@ func main() {
}()
}
// --------------- Configured peer setup ---------------
for _, peerStr := range cfg.Peers {
if !hasPortRE.MatchString(peerStr) {
peerStr += ":387"
@ -152,11 +153,20 @@ func main() {
goPeerHandler(peer)
}
// AppleTalk packet loops
// -------------------- AARP --------------------
aarpMachine := NewAARPMachine(cfg, pcapHandle, myHWAddr)
aarpCh := make(chan *ethertalk.Packet, 1024)
go aarpMachine.Run(ctx, aarpCh)
// -------------------- RTMP --------------------
rtmpMachine := &RTMPMachine{
aarp: aarpMachine,
cfg: cfg,
pcapHandle: pcapHandle,
}
go rtmpMachine.Run(ctx)
// ---------- Raw AppleTalk/AARP inbound ----------
go func() {
for {
if ctx.Err() != nil {
@ -212,7 +222,7 @@ func main() {
}
}()
// AURP packet loop
// ---------- AURP inbound ----------
for {
if ctx.Err() != nil {
return

89
rtmp.go Normal file
View file

@ -0,0 +1,89 @@
package main
import (
"context"
"log"
"time"
"gitea.drjosh.dev/josh/jrouter/atalk/rtmp"
"github.com/google/gopacket/pcap"
"github.com/sfiera/multitalk/pkg/ddp"
"github.com/sfiera/multitalk/pkg/ethertalk"
)
// RTMPMachine implements RTMP on an AppleTalk network attached to the router.
type RTMPMachine struct {
aarp *AARPMachine
cfg *config
pcapHandle *pcap.Handle
}
func (m *RTMPMachine) Run(ctx context.Context) error {
bcastTicker := time.NewTicker(10 * time.Second)
defer bcastTicker.Stop()
for {
select {
case <-ctx.Done():
return ctx.Err()
case <-bcastTicker.C:
// Broadcast an RTMP Data
myAddr, ok := m.aarp.Address()
if !ok {
continue
}
dataPkt := &rtmp.DataPacket{
RouterAddr: myAddr.Proto,
Extended: true,
NetworkTuples: []rtmp.NetworkTuple{
// "The first tuple in RTMP Data packets sent on extended
// networks ... indicates the network number range assigned
// to that network."
{
Extended: true,
RangeStart: m.cfg.EtherTalk.NetStart,
RangeEnd: m.cfg.EtherTalk.NetEnd,
Distance: 0,
},
},
}
// TODO: append more networks!
dataPktRaw, err := dataPkt.Marshal()
if err != nil {
log.Printf("RTMP: Couldn't marshal Data packet: %v", err)
continue
}
ddpPkt := ddp.ExtPacket{
ExtHeader: ddp.ExtHeader{
Size: uint16(len(dataPktRaw)),
DstNet: 0,
DstNode: 0xff, // broadcast packet
DstSocket: 1, // the special RTMP socket
SrcNet: myAddr.Proto.Network,
SrcNode: myAddr.Proto.Node,
SrcSocket: 1, // the special RTMP socket
Proto: ddp.ProtoRTMPResp,
},
Data: dataPktRaw,
}
ethFrame, err := ethertalk.AppleTalk(ethertalk.AppleTalkBroadcast, ddpPkt)
if err != nil {
log.Printf("RTMP: Couldn't create EtherTalk frame: %v", err)
}
ethFrameRaw, err := ethertalk.Marshal(*ethFrame)
if err != nil {
log.Printf("RTMP: Couldn't marshal EtherTalk frame: %v", err)
}
if err := m.pcapHandle.WritePacketData(ethFrameRaw); err != nil {
log.Printf("RTMP: Couldn't write frame: %v", err)
}
}
}
}