From c2170c058bcc2f9b0546889156bfac4171a46e73 Mon Sep 17 00:00:00 2001 From: zarazaex69 Date: Mon, 25 May 2026 10:41:23 +0300 Subject: [PATCH] feat(jitsi): add SCTP fallback when colibri-ws is unavailable - Fixed instances that were not working x3 --- go.mod | 2 +- go.sum | 2 ++ internal/engine/jitsi/jitsi.go | 34 ++++++++++++++++++++++++++++------ 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 29247a3..968a169 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/xtaci/kcp-go/v5 v5.6.72 github.com/xtaci/smux v1.5.57 github.com/zarazaex69/gr v0.1.4 - github.com/zarazaex69/j v0.0.0-20260525072612-27cb999da9fc + github.com/zarazaex69/j v0.0.0-20260525073820-97bd0a207728 golang.org/x/crypto v0.52.0 golang.org/x/mobile v0.0.0-20260520154334-0e4426e1883d golang.org/x/sys v0.45.0 diff --git a/go.sum b/go.sum index b24a49b..a0ff02c 100644 --- a/go.sum +++ b/go.sum @@ -237,6 +237,8 @@ github.com/zarazaex69/j v0.0.0-20260525070842-7db7b32d7255 h1:SGRiNJpCvIHUrAQxPK github.com/zarazaex69/j v0.0.0-20260525070842-7db7b32d7255/go.mod h1:7/ypJTenOIPx23fpo5uF7l4u+rxZqg9cFbTL/N77Ktc= github.com/zarazaex69/j v0.0.0-20260525072612-27cb999da9fc h1:LQ9YzrfcuXf4BHAgotAKBQtmW3eCegs60+YcKON9gr4= github.com/zarazaex69/j v0.0.0-20260525072612-27cb999da9fc/go.mod h1:7/ypJTenOIPx23fpo5uF7l4u+rxZqg9cFbTL/N77Ktc= +github.com/zarazaex69/j v0.0.0-20260525073820-97bd0a207728 h1:KC1+P2RytHIjaEPbqdCRF3C142Edj2KJj/1O0t57pV8= +github.com/zarazaex69/j v0.0.0-20260525073820-97bd0a207728/go.mod h1:7/ypJTenOIPx23fpo5uF7l4u+rxZqg9cFbTL/N77Ktc= github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= diff --git a/internal/engine/jitsi/jitsi.go b/internal/engine/jitsi/jitsi.go index 81f0a6f..be8382c 100644 --- a/internal/engine/jitsi/jitsi.go +++ b/internal/engine/jitsi/jitsi.go @@ -302,7 +302,10 @@ func (s *Session) joinAndOpenBridge(ctx context.Context) (*j.Session, error) { } logger.Infof("jitsi: joined %s/%s; colibri-ws=%s", s.host, s.room, jSess.ColibriWS) - if s.onData != nil || s.onPeerData != nil { + needBridge := s.onData != nil || s.onPeerData != nil + sctpBridge := needBridge && jSess.ColibriWS == "" + + if needBridge && jSess.ColibriWS != "" { bctx, bcancel := context.WithTimeout(ctx, bridgeOpenTimeout) err := jSess.OpenBridge(bctx) bcancel() @@ -310,21 +313,33 @@ func (s *Session) joinAndOpenBridge(ctx context.Context) (*j.Session, error) { _ = jSess.Close() return nil, fmt.Errorf("open bridge: %w", err) } - // Re-latch peer on every bridge open: after a reconnect the partner's - // MUC nick may have changed. s.peerEndpoint.Store(nil) s.peerVideoSSRC.Store(0) s.bridgeReady.Store(true) - logger.Infof("jitsi: bridge open (endpoints=%v)", jSess.Endpoints()) + logger.Infof("jitsi: bridge open colibri-ws (endpoints=%v)", jSess.Endpoints()) } if s.shouldNegotiatePC() { - if err := s.negotiatePC(ctx, jSess); err != nil { + if err := s.negotiatePC(ctx, jSess, sctpBridge); err != nil { _ = jSess.Close() return nil, err } } + if sctpBridge { + bctx, bcancel := context.WithTimeout(ctx, bridgeOpenTimeout) + err := jSess.WaitBridgeSCTP(bctx) + bcancel() + if err != nil { + _ = jSess.Close() + return nil, fmt.Errorf("open bridge sctp: %w", err) + } + s.peerEndpoint.Store(nil) + s.peerVideoSSRC.Store(0) + s.bridgeReady.Store(true) + logger.Infof("jitsi: bridge open sctp (endpoints=%v)", jSess.Endpoints()) + } + return jSess, nil } @@ -370,7 +385,7 @@ func (s *Session) videoTrackHandler() func(*webrtc.TrackRemote, *webrtc.RTPRecei // would obscure the wire order rather than clarify it. // //nolint:cyclop // sequential Jingle negotiation steps; refactoring would hide ordering -func (s *Session) negotiatePC(ctx context.Context, jSess *j.Session) error { +func (s *Session) negotiatePC(ctx context.Context, jSess *j.Session, sctpBridge bool) error { settings := webrtc.SettingEngine{} settings.LoggerFactory = logger.NewPionLoggerFactory() @@ -480,6 +495,13 @@ func (s *Session) negotiatePC(ctx context.Context, jSess *j.Session) error { s.wg.Add(1) go s.trickleDrainLoop(pc, neg, jSess.LowLevel().Stanzas()) + if sctpBridge { + if err := jSess.PrepareBridgeSCTP(pc); err != nil { + _ = pc.Close() + return fmt.Errorf("prepare bridge sctp: %w", err) + } + } + if err := neg.Accept(ctx); err != nil { _ = pc.Close() return fmt.Errorf("session-accept: %w", err)