Commit Graph

4 Commits

Author SHA1 Message Date
winlin
41528168e4 Claude: RTMP: Add protocol unit-test suite and harden packet unmarshal.
Implements the Go RTMP stack unit-test plan (internal/rtmp), cross-referenced
to the C++ srs_utest_manual_protocol/protocol2/rtmp suites, and fixes the one
panic class the fuzz targets exposed.

Tests added (rtmp_test.go):
- TestReadMessageInterleavedMultiStream    interleaved multi-cid reassembly
- TestReadMessageLargeChunkStreamID        2-/3-byte cid full-message read
- TestProtocolWritePacketReadMessageRoundTrip  encoder<->decoder, 14 pkts x 4 sizes
- TestReadMessageTimestampDiscontinuity    backward/forward jump, 31-bit wrap
- TestReadWriteLargePayloadChunkBoundaries chunk-boundary stress
- TestGoldenWireBytes                       golden bytes for headers + controls
- FuzzReadMessage / FuzzDecodeMessage / FuzzPacketUnmarshal  untrusted-input fuzz
- TestPacketUnmarshalAdversarialInputs      resource-safety / truncation
- TestProtocolTransactionMapConcurrency     -race on the transaction map

Hardening (rtmp.go): the fuzz targets found that the variantCallPacket family
counted a stale optional-field default (CommandObject/Args pre-set to Null by a
New*Packet constructor) when the wire data was exhausted, so Size() overran the
caller's p = p[Size():] advance and panicked on truncated, untrusted input.
Reset those fields to nil before the presence check, and route the embedded
advances in CallPacket/CreateStreamResPacket/PublishPacket/PlayPacket through a
bounds-checked advanceBytes helper so any future Size()/consumed mismatch becomes
a clean error instead of a slice-out-of-range panic.

Verified: full proxy unit suite passes; TestProtocolTransactionMapConcurrency
clean under go test -race -count=3; all proxy E2E scripts pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 21:09:27 -04:00
winlin
abfb0cd8ae Claude: RTMP: Fix 3-byte chunk basic header decode in proxy.
readBasicHeader overwrote cid with the 2-byte form (64 + byte2) before testing
whether the 3-byte form was in use, so the `cid == 1` check could never be true
and the 3-byte branch was dead code. Chunk basic headers with marker == 1 (chunk
stream IDs 320-65599) consumed only one of the two trailing bytes, leaving the
high-order byte in the stream and desyncing the chunk parser.

Keep the original marker before cid is overwritten and branch on it, matching the
C++ reference (srs_protocol_rtmp_stack.cpp, read_basic_header). The arithmetic
inside the branch was already correct.

Also correct the unit test, which had encoded the buggy result (expected cid=65
instead of 577, leaving a byte unread); it now guards the 3-byte path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 20:22:34 -04:00
winlin
26803ac4f4 Claude: RTMP: Use extended timestamp as delta for chunk fmt=1/2 in proxy.
Port the C++ srs_protocol_rtmp_stack.cpp fix (#4356) to the Go proxy's RTMP parser in internal/rtmp.

For chunk fmt=1/2 the extended timestamp encodes a timestamp delta, not an absolute timestamp. The parser previously assigned the extended value to the message timestamp unconditionally, so once a delta reached 0xffffff the DTS was miscomputed, and since audio and video deltas differ this could cause A/V desync.

Changes:
- Split chunkStream's single ext-ts bool into hasExtendedTimestamp (presence) plus a raw extendedTimestamp uint32, mirroring the C++ has_extended_timestamp_ / extended_timestamp_ fields.
- Compute the message timestamp once: extended value when present, else the 3-byte header delta; assign it as absolute for fmt=0 and accumulate it as a delta for fmt=1/2 (and a fmt=3 first chunk).
- Resolve the 'detect the extended timestamp' TODO: peek the 4 bytes and leave them as payload when a librtmp/ffmpeg-style sender omits the ext-ts on a Type-3 chunk (Go equivalent of the C++ skip(-4)).
- Add unit tests for the fmt=1 delta-crossing-0xffffff case and the Type-3 omitted-ext-ts case.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 18:10:51 -04:00
Winlin
3663a8e38f
Proxy: Refactor server APIs and expand RTMP test coverage. v7.0.147 (#4672)
This PR refactors the Go proxy server internals and significantly
expands RTMP/proxy verification coverage.

- Rename internal/protocol to internal/server to better describe the
package responsibility.
- Refactor proxy server constructors and types toward cleaner exported
interfaces:
      - NewRTMPServer
      - NewWebRTCServer
      - NewHTTPAPIServer
      - NewHTTPStreamServer
      - NewSystemAPI
  - Expose RTMP protocol interfaces for better testability:
      - Handshake
      - Protocol
      - Message
- AMF0 public interfaces such as Amf0Any, Amf0Number, Amf0String,
Amf0Object, etc.
- Add RTMP unit tests covering AMF0, handshake, protocol messages,
packet encoding/decoding, and API examples.
  - Add generated RTMP fakes for interface-based tests.
  - Add proxy E2E scripts for:
      - multi-origin memory load-balancer routing
      - Redis multi-proxy routing
- RTMP transmuxing verification across RTMP, HTTP-FLV, HLS, and optional
WebRTC WHEP
- Update OpenClaw/SRSBot development docs and memory to reflect the new
package layout, new verification scripts, and unsupported origin/edge
development scope.

---------

Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
2026-05-02 09:36:55 -04:00