chore: refresh gramsrv public release
This commit is contained in:
parent
75cebe8dbf
commit
70b6820474
1274 changed files with 378751 additions and 59919 deletions
108
internal/sfu/demux.go
Normal file
108
internal/sfu/demux.go
Normal 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} }
|
||||
Loading…
Add table
Add a link
Reference in a new issue