First pass at full fork pretty much complete.

This commit is contained in:
Storm Dragon
2026-05-20 14:29:39 -04:00
parent 6275e3adef
commit e257b344d1
11 changed files with 307 additions and 19 deletions
+97
View File
@@ -1,11 +1,70 @@
package rtpconn
import (
"net"
"testing"
"github.com/pion/webrtc/v4"
"git.stormux.org/storm/skald/conn"
"git.stormux.org/storm/skald/hall"
"git.stormux.org/storm/skald/rtptime"
)
type testClient struct {
hall *hall.Hall
}
func (c *testClient) Hall() *hall.Hall {
return c.hall
}
func (c *testClient) Addr() net.Addr {
return nil
}
func (c *testClient) Id() string {
return "test-client"
}
func (c *testClient) Username() string {
return "Test User"
}
func (c *testClient) SetUsername(string) {
}
func (c *testClient) Permissions() []string {
return []string{"present"}
}
func (c *testClient) SetPermissions([]string) {
}
func (c *testClient) Data() map[string]interface{} {
return nil
}
func (c *testClient) PushConn(*hall.Hall, string, conn.Up, []conn.UpTrack, string) error {
return nil
}
func (c *testClient) RequestConns(hall.Client, *hall.Hall, string) error {
return nil
}
func (c *testClient) Joined(string, string) error {
return nil
}
func (c *testClient) PushClient(string, string, string, string, []string, map[string]interface{}) error {
return nil
}
func (c *testClient) Kick(string, *string, string) error {
return nil
}
func TestDownTrackAtomics(t *testing.T) {
down := &rtpDownTrack{
atomics: &downTrackAtomics{},
@@ -38,6 +97,44 @@ func TestDownTrackAtomics(t *testing.T) {
}
}
func TestNewUpConnRejectsVideoMediaSection(t *testing.T) {
g, err := hall.Add("rtpconn-video-rejection-test", &hall.Description{})
if err != nil {
t.Fatalf("Add hall: %v", err)
}
defer hall.Delete(g.Name())
offer := `v=0
o=- 1 1 IN IP4 127.0.0.1
s=-
t=0 0
m=audio 9 UDP/TLS/RTP/SAVPF 111
c=IN IP4 0.0.0.0
a=mid:0
a=sendrecv
a=rtpmap:111 opus/48000/2
m=video 9 UDP/TLS/RTP/SAVPF 96
c=IN IP4 0.0.0.0
a=mid:1
a=sendrecv
a=rtpmap:96 VP8/90000
`
up, err := newUpConn(&testClient{hall: g}, "up-test", "audio", offer)
if err != nil {
t.Fatalf("newUpConn: %v", err)
}
defer up.pc.Close()
transceivers := up.pc.GetTransceivers()
if len(transceivers) != 1 {
t.Fatalf("expected only audio transceiver, got %d", len(transceivers))
}
if kind := transceivers[0].Kind(); kind != webrtc.RTPCodecTypeAudio {
t.Fatalf("expected audio transceiver, got %v", kind)
}
}
func TestSadd(t *testing.T) {
ts := []struct{ x, y, z uint64 }{
{0, 0, 0},
+18
View File
@@ -58,6 +58,18 @@ func isWSNormalError(err error) bool {
websocket.CloseGoingAway)
}
func broadcastRecordingStatus(g *hall.Hall, message string) {
err := broadcast(g.GetClients(nil), clientMessage{
Type: "usermessage",
Kind: "recording",
Privileged: true,
Value: message,
})
if err != nil {
log.Printf("broadcast(recording): %v", err)
}
}
type webClient struct {
hall *hall.Hall
addr net.Addr
@@ -1670,18 +1682,24 @@ func handleClientMessage(c *webClient, m clientMessage) error {
disk.Close()
return c.error(err)
}
broadcastRecordingStatus(g, "Recording started")
requestConns(disk, c.hall, "")
case "unrecord":
if !member("record", c.permissions) {
return c.error(hall.UserError("not authorised"))
}
stopped := false
for _, cc := range g.GetClients(c) {
disk, ok := cc.(*diskwriter.Client)
if ok {
disk.Close()
hall.DelClient(disk)
stopped = true
}
}
if stopped {
broadcastRecordingStatus(g, "Recording stopped")
}
case "subhalls":
if !member("op", c.permissions) {
return c.error(hall.UserError("not authorised"))