Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
8e96f76
feat(multicast): share subscriptions within each worker
stackia Sep 6, 2026
a15ff5f
perf(multicast): share reordered batches and immutable sendfile payloads
stackia Sep 6, 2026
8cfe35e
perf(multicast): cap shared batches at 64 KiB
stackia Sep 6, 2026
52b4d82
refactor(stream): remove MSG_ZEROCOPY send option
stackia Sep 6, 2026
530dc98
refactor(config): remove unused listener query
stackia Sep 6, 2026
9d0f59a
test(perf): add repeated multicast benchmarks with payload validation
stackia Sep 6, 2026
85261b0
docs(perf): refresh comparative benchmarks and explain multicast opti…
stackia Sep 6, 2026
2825d08
perf(buffer): share immutable batch pages on FreeBSD
stackia Sep 6, 2026
913e360
perf(benchmark): measure TVGate with default scheduling
stackia Sep 6, 2026
becbaa7
docs(perf): label optimization strategies as an appendix
stackia Sep 6, 2026
e7a9a1c
perf(connection): allocate protocol and request state on demand
stackia Sep 6, 2026
4661657
perf(stream): reduce dispatch overhead and idle memory
stackia Sep 6, 2026
946d83f
perf(multicast): avoid redundant receive and status syscalls
stackia Sep 6, 2026
ccbcbbf
perf(stream): defer queue snapshots and private reorder allocation
stackia Sep 6, 2026
68338df
perf(multicast): coalesce receives with bounded readiness fallback
stackia Sep 6, 2026
b4fd92a
perf(multicast): resume receive coalescing after transient bursts
stackia Sep 6, 2026
c7aefc8
docs(benchmark): publish balanced four-program resource measurements
stackia Sep 6, 2026
8c073a5
fix(poller): replace kqueue filters when receive mode changes
stackia Sep 6, 2026
be6b20a
fix(stream): release deferred sessions during final connection cleanup
stackia Sep 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .agents/skills/e2e/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ description: >
flaky, slow, or hanging e2e tests, (4) mentions any file under e2e/ or scripts/run-e2e.sh,
(5) mentions MockRTSP*, MockHTTP*, MockFCC*, MockSTUN*, R2HProcess, MulticastSender, helper APIs,
or test fixtures, (6) asks about multicast, RTSP, HTTP proxy, FCC, STUN, M3U, EPG, URL template,
or zerocopy test coverage in rtp2httpd, or (7) uses Chinese phrases such as "端到端测试",
or shared multicast test coverage in rtp2httpd, or (7) uses Chinese phrases such as "端到端测试",
"跑测试", or "e2e 测试" in this repo.
---

Expand Down Expand Up @@ -59,7 +59,7 @@ e2e/
├── conftest.py
├── test_m3u.py
├── test_epg.py / test_pages.py / test_auth.py / test_config.py / test_error.py
├── test_multicast.py / test_fcc.py / test_zerocopy.py
├── test_multicast.py / test_fcc.py / test_multicast_shared.py
├── test_http_proxy*.py
├── test_rtsp_*.py
├── test_url_template_http.py
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ __pycache__/

# Benchmark results
tools/benchmark_results_*.txt
tools/stress-test/results/

# iKuai package outputs
ikuai-support/.staging/
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ set(COMMON_SOURCES
src/worker.c
src/unix_socket.c
src/buffer_pool.c
src/zerocopy.c
src/send_queue.c
src/m3u.c
src/epg.c
src/embedded_web.c
Expand Down
3 changes: 1 addition & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,9 @@ EXPOSE 5140

# Recommended options:
# --cap-add=NET_ADMIN: Allow setting larger UDP receive buffers (bypassing rmem_max via SO_RCVBUFFORCE)
# --ulimit memlock=-1:-1: Required for zero-copy (MSG_ZEROCOPY needs locked memory pages)
#
# Usage:
# docker run --network=host --cap-add=NET_ADMIN --ulimit memlock=-1:-1 --rm \
# docker run --network=host --cap-add=NET_ADMIN --rm \
# ghcr.io/stackia/rtp2httpd:latest

# Run the application
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ rtp2httpd 是一个 IPTV 转发服务器,支持将组播 RTP/UDP、RTSP 转换
- **非阻塞 IO 模型**:使用 epoll 事件驱动,高效处理大量并发连接
- **多核优化**:支持多 worker 进程,充分利用多核 CPU 提高最大吞吐量
- **缓冲池优化**:预分配缓冲池,避免频繁内存分配,多客户端根据负载动态共享,避免慢客户端吃满资源
- **零拷贝技术**:支持 Linux 内核 MSG_ZEROCOPY 特性,避免数据在用户态和内核态之间的拷贝
- **同源复用**:同一工作进程内共享组播订阅、RTP 处理和批量缓冲,减少多客户端重复工作
- **轻量化**:使用纯 C 语言编写,零依赖,小巧简洁,适合运行在各种嵌入式设备上(路由器、光猫、NAS 等)
- 程序大小仅 509KB (x86_64),并内置了 Web 播放器所有前端资源
- 查看 **[性能测试报告](https://rtp2httpd.com/reference/benchmark)**(与 msd_lite、udpxy、tvgate 的性能对比)
Expand Down
10 changes: 2 additions & 8 deletions docs/en/guide/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ Group=rtp2httpd
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
NoNewPrivileges=true
LimitMEMLOCK=infinity

[Install]
WantedBy=multi-user.target
Expand All @@ -96,7 +95,7 @@ Suitable for Docker-capable devices. **Requires host network mode** to properly
### Basic Startup

```bash
docker run --network=host --cap-add=NET_ADMIN --ulimit memlock=-1:-1 --rm \
docker run --network=host --cap-add=NET_ADMIN --rm \
ghcr.io/stackia/rtp2httpd:latest \
--noconfig --verbose 2 --listen 5140 --maxclients 20
```
Expand All @@ -111,25 +110,20 @@ services:
restart: always
cap_add:
- NET_ADMIN
ulimits:
memlock:
soft: -1
hard: -1
command: --noconfig --verbose 2 --listen 5140 --maxclients 20
```

> [!NOTE]
> **About recommended parameters**:
>
> - `cap_add: NET_ADMIN`: Allows bypassing the kernel parameter `net.core.rmem_max` limit via `SO_RCVBUFFORCE`, setting a larger UDP receive buffer
> - `ulimits: memlock: -1`: Required when zero-copy is enabled (`--zerocopy-on-send`), MSG_ZEROCOPY needs to lock memory pages

### Mount Configuration File

If you need to use a configuration file (assuming config file is at `/path/to/rtp2httpd.conf`):

```bash
docker run --network=host --cap-add=NET_ADMIN --ulimit memlock=-1:-1 --rm \
docker run --network=host --cap-add=NET_ADMIN --rm \
-v /path/to/rtp2httpd.conf:/usr/local/etc/rtp2httpd.conf:ro \
ghcr.io/stackia/rtp2httpd:latest
```
Expand Down
2 changes: 1 addition & 1 deletion docs/en/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ features:
details: Web status page with connection statistics, bandwidth monitoring, log viewing, remote management
- icon: 🚀
title: Lightweight & High Performance
details: Pure C with zero dependencies, epoll + multi-core + zero-copy, only 509KB for x86_64
details: Pure C with zero dependencies, epoll + multi-core + shared buffers, only 509KB for x86_64
---

<div class="demo-section">
Expand Down
182 changes: 109 additions & 73 deletions docs/en/reference/benchmark.md

Large diffs are not rendered by default.

13 changes: 1 addition & 12 deletions docs/en/reference/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ rtp2httpd [options]
rtp2httpd --listen 5140 --listen 192.168.1.1:8081 --listen '[::1]:5140' --listen /var/run/rtp2httpd.sock
```

Unix socket listen paths must be absolute and must not contain whitespace. At startup, if the same path already contains a socket file, rtp2httpd first probes whether the socket is still in use: if another process is listening on that path, startup is rejected; only confirmed stale socket files are removed automatically. If the path is a regular file, directory, or symbolic link, startup is rejected to avoid deleting user data. When any Unix socket listener is enabled, `zerocopy-on-send` is disabled globally.
Unix socket listen paths must be absolute and must not contain whitespace. At startup, if the same path already contains a socket file, rtp2httpd first probes whether the socket is still in use: if another process is listening on that path, startup is rejected; only confirmed stale socket files are removed automatically. If the path is a regular file, directory, or symbolic link, startup is rejected to avoid deleting user data.

#### Upstream Network Interface Configuration

Expand All @@ -53,10 +53,6 @@ Unix socket listen paths must be absolute and must not contain whitespace. At st
- For 30 Mbps 4K IPTV streams, 512KB provides approximately 140ms of buffering
- Increase this value to reduce packet loss for high-bandwidth streams
- Actual buffer size may be limited by kernel parameter `net.core.rmem_max`
- `-Z, --zerocopy-on-send` - Enable zero-copy send to improve performance (default: disabled)
- Requires kernel support for MSG_ZEROCOPY (Linux 4.14+)
- Improves throughput and reduces CPU usage on supported devices
- Not recommended if rtp2httpd is behind a reverse proxy (nginx/caddy/lucky, etc.)

### FCC (Fast Channel Change)

Expand Down Expand Up @@ -230,13 +226,6 @@ buffer-pool-max-size = 16384
# Actual buffer size may be limited by kernel parameter net.core.rmem_max
udp-rcvbuf-size = 524288

# Enable zero-copy send to improve performance (default: no)
# Set to yes/true/on/1 to enable zero-copy
# Requires kernel support for MSG_ZEROCOPY (Linux 4.14+)
# Can improve throughput and reduce CPU usage on supported devices, especially under high concurrent loads
# Not recommended if rtp2httpd is behind a reverse proxy (nginx/caddy/lucky, etc.)
zerocopy-on-send = no

# Override the User-Agent for upstream HTTP proxy requests (default: no override)
# When set, this replaces the client User-Agent sent to upstream servers for /http/ requests
http-proxy-user-agent = rtp2httpd-http-proxy/1.0
Expand Down
10 changes: 2 additions & 8 deletions docs/guide/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ Group=rtp2httpd
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
NoNewPrivileges=true
LimitMEMLOCK=infinity

[Install]
WantedBy=multi-user.target
Expand All @@ -96,7 +95,7 @@ sudo systemctl status rtp2httpd
### 基本启动方式

```bash
docker run --network=host --cap-add=NET_ADMIN --ulimit memlock=-1:-1 --rm \
docker run --network=host --cap-add=NET_ADMIN --rm \
ghcr.io/stackia/rtp2httpd:latest \
--noconfig --verbose 2 --listen 5140 --maxclients 20
```
Expand All @@ -111,25 +110,20 @@ services:
restart: always
cap_add:
- NET_ADMIN
ulimits:
memlock:
soft: -1
hard: -1
command: --noconfig --verbose 2 --listen 5140 --maxclients 20
```

> [!NOTE]
> **关于推荐参数**:
>
> - `cap_add: NET_ADMIN`:允许通过 `SO_RCVBUFFORCE` 绕过内核参数 `net.core.rmem_max` 限制,设置更大的 UDP 接收缓冲区
> - `ulimits: memlock: -1`:启用零拷贝(`--zerocopy-on-send`)时必需,MSG_ZEROCOPY 需要锁定内存页

### 挂载配置文件

如果需要使用配置文件(假设配置文件位于 `/path/to/rtp2httpd.conf`):

```bash
docker run --network=host --cap-add=NET_ADMIN --ulimit memlock=-1:-1 --rm \
docker run --network=host --cap-add=NET_ADMIN --rm \
-v /path/to/rtp2httpd.conf:/usr/local/etc/rtp2httpd.conf:ro \
ghcr.io/stackia/rtp2httpd:latest
```
Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ features:
details: Web 状态页面,连接统计、带宽监控、日志查看、远程管理
- icon: 🚀
title: 轻量高性能
details: 纯 C 零依赖,epoll + 多核 + 零拷贝,x86_64 仅 509KB
details: 纯 C 零依赖,epoll + 多核 + 共享缓冲,x86_64 仅 509KB
---

<div class="demo-section">
Expand Down
Loading
Loading