chore: refresh gramsrv public release

This commit is contained in:
A 2026-06-30 14:37:43 +08:00
parent 75cebe8dbf
commit 70b6820474
1274 changed files with 378751 additions and 59919 deletions

108
internal/sfu/demux.go Normal file
View file

@ -0,0 +1,108 @@
package sfu
import (
"errors"
"io"
"net"
"time"
"github.com/pion/transport/v4/packetio"
)
// demuxer 把 ICE conn 上的混合流量按 RFC 7983 首字节分发:
// - [20,63] → DTLS(握手与应用数据)
// - [128,191] → RTP/RTCP(再按 RTCP PT 200..207 细分)
//
// 写方向全部直写底层 ICE conn(同一 5 元组,RTCP-mux)。
type demuxer struct {
base net.Conn
dtls *packetio.Buffer
srtp *packetio.Buffer
srtcp *packetio.Buffer
done chan struct{}
}
func newDemuxer(base net.Conn) *demuxer {
d := &demuxer{
base: base,
dtls: packetio.NewBuffer(),
srtp: packetio.NewBuffer(),
srtcp: packetio.NewBuffer(),
done: make(chan struct{}),
}
go d.readLoop()
return d
}
func (d *demuxer) readLoop() {
defer close(d.done)
buf := make([]byte, 1500)
for {
n, err := d.base.Read(buf)
if err != nil {
_ = d.dtls.Close()
_ = d.srtp.Close()
_ = d.srtcp.Close()
return
}
if n == 0 {
continue
}
first := buf[0]
switch {
case first >= 20 && first <= 63:
_, _ = d.dtls.Write(buf[:n])
case first >= 128 && first <= 191:
if n >= 2 && isRTCPPayloadType(buf[1]) {
_, _ = d.srtcp.Write(buf[:n])
} else {
_, _ = d.srtp.Write(buf[:n])
}
default:
// STUN 已被 ICE 层消费;其余丢弃。
}
}
}
func isRTCPPayloadType(pt byte) bool {
// RTCP packet type 范围(SR/RR/SDES/BYE/APP/RTPFB/PSFB...)。
return pt >= 192 && pt <= 223
}
func (d *demuxer) Close() {
_ = d.dtls.Close()
_ = d.srtp.Close()
_ = d.srtcp.Close()
}
// demuxConn 把单一 buffer 包成 net.Conn:读取自 buffer,写直达底层。
type demuxConn struct {
buf *packetio.Buffer
base net.Conn
}
func (c *demuxConn) Read(b []byte) (int, error) {
n, err := c.buf.Read(b)
if errors.Is(err, io.EOF) || errors.Is(err, packetio.ErrFull) {
return n, err
}
return n, err
}
func (c *demuxConn) Write(b []byte) (int, error) { return c.base.Write(b) }
func (c *demuxConn) Close() error { return c.buf.Close() }
func (c *demuxConn) LocalAddr() net.Addr { return c.base.LocalAddr() }
func (c *demuxConn) RemoteAddr() net.Addr { return c.base.RemoteAddr() }
// SetDeadline/SetReadDeadline 透传给 packetio.Buffer:DTLS 握手依赖读超时
// 推进重传与失败退出(pion/dtls v3 默认 Handshake 无限期阻塞,调用方必须
// 在握手期间设硬上限,否则停滞的握手会把 goroutine 挂死)。
func (c *demuxConn) SetDeadline(t time.Time) error { return c.buf.SetReadDeadline(t) }
func (c *demuxConn) SetReadDeadline(t time.Time) error { return c.buf.SetReadDeadline(t) }
// 写方向直达底层 ICE conn,无队列可超时。
func (c *demuxConn) SetWriteDeadline(t time.Time) error { return nil }
func (d *demuxer) dtlsConn() net.Conn { return &demuxConn{buf: d.dtls, base: d.base} }
func (d *demuxer) srtpConn() net.Conn { return &demuxConn{buf: d.srtp, base: d.base} }
func (d *demuxer) srtcpConn() net.Conn { return &demuxConn{buf: d.srtcp, base: d.base} }