Commit Graph

661 Commits

Author SHA1 Message Date
zarazaex69
f51889ac52 fix(jitsi): keep bytestream endpoints alive 2026-05-16 20:25:54 +03:00
zarazaex69
5d4592f055 fix(jitsi): reset reconnect limit by window start 2026-05-16 19:28:28 +03:00
zarazaex69
cae76a6c34 fix(jitsi): reset peer epoch before reconnect announce 2026-05-16 19:09:29 +03:00
zarazaex69
032151be98 fix(server): reset peer binding on handshake failure 2026-05-16 18:57:04 +03:00
zarazaex69
acac1121a7 fix(jitsi): add epoch-based bridge frame filtering 2026-05-16 18:46:58 +03:00
zarazaex69
07b86a7559 test(jitsi): guard session type assertions in tests 2026-05-16 18:38:14 +03:00
zarazaex69
a329b1fd56 feat(jitsi): add automatic bridge reconnection 2026-05-16 18:33:24 +03:00
zarazaex69
2fdbe5c0ca fix(session): apply custom DNS before connect 2026-05-16 18:22:02 +03:00
zarazaex69
a321413f83 fix: golangci 2026-05-16 16:44:36 +03:00
zarazaex69
60e731c4bb fix(salutejazz): bound session close on wedged pc shutdown 2026-05-16 16:39:07 +03:00
zarazaex69
6df6ecb3c6 Merge branch 'refactor/bigrefactor'
Big structural refactor in 9 atomic commits:
- internal/framing: shared length-prefix codec for handshake/control
- typed per-transport options replace flat tunables in transport/link/server/client/session Configs
- remove internal/link layer (one-to-one proxy over transport.Transport)
- collapse internal/carrier into engine; transports go through enginebuiltin.Open + engine.VideoTrackCapable
- internal/transport/common: shared RandomID/FragmentPayload/Reassembler/AckRegistry
- internal/runtime: shared SetupCipher/SmuxConfig/HealthTracker between server and client
- session.Config: typed Video/VP8/SEI subsections instead of flat fields
- chore: drop abusive header comment in vp8channel
- chore: satisfy golangci-lint (cyclop/exhaustive/gosec/lll/wrapcheck)

Net: 57 files changed, -330 lines, 5 packages deleted (link, link/direct,
carrier, carrier/builtin), 4 new (framing, transport/common, runtime,
engine/builtin). All 33 packages green on each commit; golangci-lint clean.
2026-05-16 15:10:01 +03:00
zarazaex69
80cc3bafe4 chore(lint): satisfy golangci-lint after big refactor
Address 25 issues reported by golangci-lint following the structural
refactor:

- cyclop: split common.Reassembler.Push into upsert/storeChunk/deliver
  helpers (12→5). Move seichannel option-default fill into Options.
  withDefaults so New stays under the limit.
- exhaustive: enumerate ResultPartial / ResultIgnore explicitly in
  seichannel and videochannel switches over common.Result.
- gosec G115: annotate the test-fixture int→uint16/uint32 conversions
  in common_test.go with //nolint:gosec.
- lll: break up the 130+ character one-liners in transport
  unit/integration tests and the videochannel track-ID construction.
- nolintlint: drop the stale //nolint:cyclop in mobile_test.go where
  the underlying complexity already cleared the limit.
- wrapcheck: wrap errors returned from internal/framing and
  internal/runtime in their public callers (handshake, control,
  server.setupCipher, client.setupCipher) so they carry the layer name.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 14:38:03 +03:00
zarazaex69
190c2b5f84 chore(vp8channel): replace abusive header comment with package doc
internal/transport/vp8channel/transport.go opened with a 24-line block
of Russian profanity addressed at Yandex SFU engineers (the engine
vp8channel targets to evade). It served no engineering purpose and is
not suitable for an open-source codebase.

Replace with a one-paragraph package doc summarising what the package
actually does (KCP-over-VP8-keyframes byte transport for SFUs that
validate VP8 conformance).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 14:30:16 +03:00
zarazaex69
35e6c16333 refactor: split flat session.Config tunables into typed sections
session.Config used to spread 16 per-transport tuning fields across its
top level (VideoWidth/Height/.../VP8FPS/.../SEIAckTimeoutMS). The flat
layout meant every caller had to know which fields belong to which
transport, and the YAML→session bridge in internal/config repeated the
same name 32 times across Apply/ApplyProfile.

Group them under VideoConfig/VP8Config/SEIConfig structs hung off
session.Config. internal/config now does e.g.
  dst.Video.Width = pickInt(dst.Video.Width, f.Video.Width)
instead of touching dst.VideoWidth. session.ApplyTransportDefaults,
validateVideoChannel/VP8Channel/SEIChannel and buildTransportOptions
read through cfg.Video.*/cfg.VP8.*/cfg.SEI.* in the same way.

The YAML schema itself was already grouped (Video / VP8 / SEI sections);
this commit lines session.Config up with it so the Apply functions can
mirror the YAML structure 1:1 instead of unpacking it into 32 flat
assignments.

All session/config/e2e/cmd/main tests that referenced cfg.VideoX directly
are updated to cfg.Video.X.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 14:28:57 +03:00
zarazaex69
f469bd72af refactor: extract shared session runtime into internal/runtime
server.go and client.go each carried byte-identical copies of
smuxConfig (~20 lines), setupCipher (~18 lines), and the health
bookkeeping pair recordSession/Pong/Missed/Unhealthy/Reconnect plus a
private healthMu+status+notifyHealth scaffold. Same code, twice.

Add internal/runtime exposing:
- SetupCipher, SmuxConfig, MaxPayload — common construction helpers,
  ErrKeyRequired/ErrKeySize re-exported from runtime so existing
  errors.Is checks on server.ErrKeyRequired etc. keep working.
- HealthTracker — nil-safe wrapper around control.Status with
  RecordSession/Pong/Missed/Unhealthy/Reconnect that publishes through an
  OnHealth callback supplied at construction.

server and client now hold a *runtime.HealthTracker instead of their own
mu+status+notify scaffolds. recordX methods on Server/Client are now
one-liners that forward to the tracker. smuxConfig(0) replaces the prior
variadic smuxConfig() in test call sites; nil-safe Status()/update() on
HealthTracker means tests that build raw &Server{}/&Client{} no longer
need to wire up a tracker for the records to be no-ops.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 14:24:46 +03:00
zarazaex69
4639e0b3b7 refactor: extract shared transport framing helpers into internal/transport/common
videochannel, seichannel and vp8channel each carried independent copies of
randomID(), fragmentPayload(), inboundMessage + upsertInbound +
assembleMessage + ackWaiters/ackMu. The reassembly logic was almost
byte-identical across videochannel and seichannel; vp8channel only needed
randomID. Three copies of the same idea.

Add internal/transport/common with:
- RandomID(): 8-char hex per-peer ID (Jitsi msid uniqueness requirement).
- FragmentPayload(): split bytes into max-size chunks.
- Reassembler: stores in-flight messages keyed by Seq, validates CRC, and
  reports Partial / Delivered / Duplicate / Ignore via a Result enum.
- AckRegistry: Register/Unregister/Resolve for ack waiters.

videochannel and seichannel now hold *common.AckRegistry and
*common.Reassembler instead of raw maps + mutexes. Their Send paths route
through acks.Register/Unregister; their handleInboundFrame is a 20-line
switch over reassembler.Push. vp8channel keeps its KCP framing but reuses
common.RandomID.

Tests that constructed raw streamTransport with inbound/delivered/ackWaiters
maps are updated to instantiate the new common types instead. Two now-
redundant low-level tests (upsertInbound out-of-range, assembleMessage)
collapse into the new TestInboundRejectsBadCRC.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 14:16:43 +03:00
zarazaex69
a083dfc5f3 refactor: collapse carrier layer into engine
internal/carrier and internal/carrier/builtin sat between transports and
engines, wrapping every engine.Session in carrier.Session +
engineByteStream/engineVideoTrack adapters that mechanically proxied every
method. That layer existed solely to translate Capabilities/AddTrack names;
no behaviour lived above engine.

Replace with internal/engine/builtin: a name-keyed registry that calls
auth.Issue and engine.New directly. Transports look up engine.Session via
enginebuiltin.Open, then type-assert engine.VideoTrackCapable for video
transports. A small per-transport engineVideoSession adapter unifies the
reconnect callback signature (engine uses func(*webrtc.DataChannel); the
transports want func()).

Updates:
- internal/engine/builtin/builtin.go: new Register/Open registry + auth
  pass-through ("none") + auth-driven factories for jazz/telemost/wbstream/jitsi.
- internal/transport/datachannel/transport.go: uses engine.Session directly
  via Capabilities().ByteStream check.
- internal/transport/{seichannel,videochannel,vp8channel}: each gains an
  engineVideoSession adapter and routes Connect/Send/Close/AddTrack through
  the engine session.
- internal/app/session: imports enginebuiltin; carrier.Available() →
  enginebuiltin.Available().
- pkg/olcrtc/olcrtc.go: switches to enginebuiltin.RegisterDefaults.
- internal/carrier and internal/carrier/builtin: deleted.
- Tests rewritten to register a fakeEngineSession (implements engine.Session
  + engine.VideoTrackCapable) through enginebuiltin.Register. The e2e
  memoryStream gains the same dual interface so memorySession is gone.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 14:07:44 +03:00
zarazaex69
e7657b2619 refactor: remove link layer
internal/link and internal/link/direct were a single-implementation
abstraction layer where directLink mechanically proxied every method to
transport.Transport — only Features() lived above transport.Transport,
and even that was a Features() alias. Six layers of plumbing for zero
behavioural value.

Drop the layer entirely:
- muxconn.Conn now takes a transport.Transport directly.
- server.Server and client.Client store transport.Transport, call
  transport.New, and expose Features() through transport.Transport's
  built-in method.
- server.Config and client.Config lose their Link string field.
- session.Config loses Link + validateLink + ErrLinkRequired/ErrUnsupportedLink.
- config.File and config.Profile lose the link YAML key.
- pkg/olcrtc/tunnel.Config loses Link.
- mobile drops defaultLink, SetLink, and mobileConfig.link.

Two e2e tests that exercised link.New directly are renamed to call
transport.New (TestTransportCreatesAllProviderTransportCombinations and
TestTransportConnectsFastProviderTransportMatrix); behaviour is unchanged.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 13:51:02 +03:00
zarazaex69
74fb1d81b7 refactor: introduce typed per-transport options
transport.Config used to carry a flat union of video+vp8+sei tuning fields
that every transport ignored except its own. Replace with an opaque
transport.Options marker interface and per-transport Options structs
(videochannel.Options, vp8channel.Options, seichannel.Options). Datachannel
keeps an unset Options.

link.Config gains TransportOptions and drops the 16 transport-specific
fields. server.Config and client.Config follow suit. session.Config is
left untouched in this commit — buildTransportOptions packs its existing
flat fields into the typed Options bundle before calling server/client
(session.Config is rebuilt in a later commit when YAML config moves to
typed sections).

Tests that synthesized link/server/client/transport configs are updated
to pass typed Options bundles. The shared e2eTransportOptions helper
replaces three copies of the flat field bundle in e2e/tunnel_test.go.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 07:01:07 +03:00
zarazaex69
76026c5452 refactor: extract length-prefix framing into shared package
handshake and control duplicated the same 4-byte BE length + body framing
with independent ErrFrameTooLarge constants. Centralize in internal/framing
and have both callers delegate. ErrFrameTooLarge is re-exported so existing
errors.Is checks keep working.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 06:51:12 +03:00
zarazaex69
a48db522b1 refactor(jitsi): extract peer latch helper logic 2026-05-16 05:43:36 +03:00
zarazaex69
d60f649ba7 fix(e2e): isolate default Jitsi test rooms 2026-05-16 05:35:37 +03:00
zarazaex69
d80d725d5e fix(jitsi): isolate bridge and video to one peer 2026-05-16 05:29:51 +03:00
zarazaex69
a636236523 refactor(videochannel): simplify frame decoding logic 2026-05-16 05:01:41 +03:00
zarazaex69
6633c1ef8a fix: isolate videochannel peers in shared rooms 2026-05-16 04:55:25 +03:00
zarazaex69
00a79b3c99 fix: update jitsi video source handling 2026-05-16 04:34:59 +03:00
zarazaex69
ff90942214 fix: close sessions before connections on shutdown 2026-05-16 04:13:07 +03:00
zarazaex69
6222896921 refactor: improve error context and test clarity 2026-05-16 04:06:55 +03:00
zarazaex
6116130e3b Merge pull request #58 from cyber-debug/refine/livekit-reconnect
refine livekit reconnect and liveness
2026-05-16 03:47:47 +03:00
cyber-debug
79c1511268 Fix seichannel readiness before sending 2026-05-16 02:44:18 +03:00
zarazaex69
4bf72e5b87 fix(salutejazz): close websocket before waiting on shutdown 2026-05-16 02:24:21 +03:00
cyber-debug
b7a7e40899 feat: add safe traffic shaping and TLS hardening 2026-05-16 02:10:34 +03:00
cyber-debug
b0aee57aa5 feat: track failover supervisor status 2026-05-16 02:10:33 +03:00
cyber-debug
82b5741ab1 feat: add planned session rotation 2026-05-16 02:10:33 +03:00
cyber-debug
4c6bd2b838 feat: expose control health status 2026-05-16 02:10:33 +03:00
cyber-debug
d16cd0686a feat: expose mobile liveness options 2026-05-16 02:10:33 +03:00
cyber-debug
b0fc3bd0f1 feat: add control stream liveness 2026-05-16 02:10:33 +03:00
cyber-debug
a86f5c6948 feat: add reconnect hardening and failover profiles 2026-05-16 02:10:33 +03:00
zarazaex69
71c2c926a9 ci: add jitsi to real provider e2e matrix 2026-05-16 02:07:00 +03:00
zarazaex69
70fe69c909 style(ci): normalize yaml quoting and spacing 2026-05-16 02:06:51 +03:00
zarazaex69
5ec58bee98 refactor: extract unstable test logging helper 2026-05-16 01:53:55 +03:00
zarazaex69
1ee1ddd7f0 test(e2e): mark sei transport on jitsi as unstable 2026-05-16 01:50:48 +03:00
zarazaex69
82e8067384 fix(client,server): defer shutdown BEFORE bringUpLink to close MUC on early failures
When bringUpLink errored — a handshake timeout against a wedged transport,
for instance — Run/RunWithReady returned straight to the caller without
calling shutdown, so the carrier link that had already joined the MUC
was never closed. The result was a ghost participant lingering on
Jicofo/JVB until idle timeout, which the next test in the same room
inherited as stale endpoints in 'bridge open'.

The clue from logs was that failing seichannel runs produced one
'leave-muc handshake ok' instead of two: the server's normal
ctx-cancel path got there cleanly, but the client's bringUpLink
returned early and skipped its defer.

Both paths now register shutdown before the bringUpLink call. shutdown
is nil-safe and idempotent so it works whether or not bringUpLink
actually populated link/session fields. server's wg.Wait moves into
the same defer so wg goroutines spawned by partial setup also drain
before Run returns.
2026-05-16 01:38:52 +03:00
zarazaex69
bc22e0c76b build(deps): bump github.com/zarazaex69/j 2026-05-16 01:23:05 +03:00
zarazaex69
f7c157dfe3 fix(jitsi): align session close with leave flow 2026-05-16 01:09:01 +03:00
zarazaex69
0676fc2e47 fix(engine): delay session close teardown 2s 2026-05-16 00:09:41 +03:00
zarazaex69
4db4007985 fix(jitsi): wait longer after leaving MUC 2026-05-16 00:04:51 +03:00
zarazaex69
71db9c4700 fix(jitsi): start stanza drain before session accept 2026-05-15 23:41:36 +03:00
zarazaex69
5e0a89a78d Revert "fix(transport): isolate peer frames by channel id"
This reverts commit 75e2674f48.
2026-05-15 23:09:24 +03:00
zarazaex69
a9512d2488 Revert "fix(transport): pin peer channel after validation"
This reverts commit 7f9351dad6.
2026-05-15 23:09:24 +03:00