From a5bc218057a01754ef21ecc5acda1bba56a9b2e1 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 18 Sep 2026 10:09:35 +0000 Subject: [PATCH] chore(release): bump version to 0.3.0, librtmp2 dependency to 0.8.1 Bump to 0.3.0 (minor) rather than a patch release since the range since v0.2.2 includes a new feature (recording/HLS/push-relay/exec media outputs), not just fixes. Document the security and correctness fixes landed alongside it in CHANGELOG.md, and pick up librtmp2 0.8.1 (published to crates.io) in Cargo.toml/Cargo.lock. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_0127FS9rE6vo3k4EW8oFeT4B --- CHANGELOG.md | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- Cargo.lock | 6 +++--- Cargo.toml | 4 ++-- 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c6e443..69f88a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,54 @@ begin at `1.0.0`. ## [Unreleased] +## [0.3.0] — 2026-09-18 + +### Added +- Recording, HLS, push-relay, and exec media outputs, wired into the RTMP + and HTTP lifecycle (HLS and push outputs require FFmpeg on `PATH`); see + the updated documentation for configuration. +- Depends on `librtmp2` `0.8.1`. + +### Security +- HLS viewer requests now count against `MAX_CONNECTIONS_PER_PLAY_KEY` + (including cluster-remote RTMP viewer counts), closing a gap where RTMP + play was capped at five sessions per key but HTTP HLS clients were + unlimited. +- Recording and HLS output directories/files are created with private + permissions (0700/0600, mirroring the existing SQLite hardening) instead + of world-readable under the default umask. +- The new HLS output module validates active-session path resolution stays + contained under the configured media root. +- `LRTMP2_DB` is opened with `SQLITE_OPEN_NOFOLLOW`, rejecting a symlinked + database path a local attacker planted before startup. +- Cluster control-plane and media-plane frame reads are now capped by a + process-wide in-flight byte budget, closing a `CLUSTER_SECRET`-only + memory-exhaustion DoS from parallel max-size frames. +- The per-IP cluster auth-failure tracker now LRU-evicts only + non-throttled buckets once full instead of rejecting every new source + IP — including ones presenting a valid `CLUSTER_SECRET` — once its + 10k-entry map filled. +- A failed cluster join no longer poisons `ClusterMeta` state. + +### Fixed +- Cluster owners fan out live `MediaFrame`s on the subscriber inbound + session and retry a rejected `Subscribe` on protocol `Error` instead of + dropping it; standalone stream delete honors `pending_delete` and + refuses removing the last play key. +- Cluster `InitCache` timeline remapping is staged and saturates at + `u32::MAX` instead of overflowing, and deleted streams are no longer + pruned by live-session presence during Raft delete ambiguity. +- Stats/RTT flushes from stale cluster nodes can no longer resurrect a + session that was already released (guarded by `active=1`). +- HLS redirect path resolution moved off the async request path via + `spawn_blocking`, avoiding a blocking `fs::canonicalize` call in an + async handler. + +### Changed +- GitHub Actions pinned to full commit SHAs (Dependabot keeps them + current). +- Package version `0.2.2` → `0.3.0`. + ## [0.2.2] — 2026-09-03 ### Security @@ -495,7 +543,8 @@ plaintext RTMP and RTMPS. ### Planned - REST API enhancements for server management -[Unreleased]: https://github.com/OpenRTMP/librtmp2-server/compare/v0.2.2...HEAD +[Unreleased]: https://github.com/OpenRTMP/librtmp2-server/compare/v0.3.0...HEAD +[0.3.0]: https://github.com/OpenRTMP/librtmp2-server/compare/v0.2.2...v0.3.0 [0.2.2]: https://github.com/OpenRTMP/librtmp2-server/compare/v0.2.1...v0.2.2 [0.2.1]: https://github.com/OpenRTMP/librtmp2-server/compare/v0.2.0...v0.2.1 [0.2.0]: https://github.com/OpenRTMP/librtmp2-server/compare/v0.1.9...v0.2.0 diff --git a/Cargo.lock b/Cargo.lock index c6e4031..07efb1e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1255,9 +1255,9 @@ checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] name = "librtmp2" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b3a5f38d4b3b1249f5c02e4f0ff02d6b8e2bc4374ee2fbcec05cd14990363f2" +checksum = "8ffdbbeed05c0bc21f98a579ecf1813c6bbcbcd7fcf475f479e6d93d77072bb8" dependencies = [ "cc", "libc", @@ -1268,7 +1268,7 @@ dependencies = [ [[package]] name = "librtmp2-server" -version = "0.2.2" +version = "0.3.0" dependencies = [ "axum", "bytes", diff --git a/Cargo.toml b/Cargo.toml index 0eca97c..9938f48 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "librtmp2-server" -version = "0.2.2" +version = "0.3.0" edition = "2024" rust-version = "1.95" license = "MIT" @@ -18,7 +18,7 @@ path = "src/main.rs" # Pinned to the crates.io release. Local sibling override: # [patch.crates-io] # librtmp2 = { path = "../librtmp2" } -librtmp2 = { version = "0.8.0", features = ["tls"] } +librtmp2 = { version = "0.8.1", features = ["tls"] } axum = "0.8" tokio = { version = "1", features = ["rt-multi-thread", "macros", "net", "signal", "time", "sync", "io-util", "fs"] } tokio-util = { version = "0.7", features = ["io"] }