Files
go2rtc/pkg/srtp/session.go
T
2023-09-01 10:38:38 +03:00

109 lines
1.8 KiB
Go

package srtp
import (
"net"
"github.com/pion/rtcp"
"github.com/pion/rtp"
"github.com/pion/srtp/v2"
)
type Session struct {
Local *Endpoint
Remote *Endpoint
OnReadRTP func(packet *rtp.Packet)
Recv int // bytes recv
Send int // bytes send
conn net.PacketConn // local conn endpoint
addr net.Addr // remote addr
}
type Endpoint struct {
Addr string
Port uint16
MasterKey []byte
MasterSalt []byte
SSRC uint32
srtp *srtp.Context
}
func (e *Endpoint) Init() error {
var profile srtp.ProtectionProfile
switch len(e.MasterKey) {
case 16:
profile = srtp.ProtectionProfileAes128CmHmacSha1_80
//case 32:
// return srtp.ProtectionProfileAes256CmHmacSha1_80
}
var err error
e.srtp, err = srtp.CreateContext(e.MasterKey, e.MasterSalt, profile)
return err
}
func (s *Session) WriteRTP(packet *rtp.Packet) (int, error) {
b, err := packet.Marshal()
if err != nil {
return 0, err
}
if b, err = s.Local.srtp.EncryptRTP(nil, b, nil); err != nil {
return 0, err
}
return s.conn.WriteTo(b, s.addr)
}
func (s *Session) ReadRTP(b []byte) {
packet := &rtp.Packet{}
b, err := s.Remote.srtp.DecryptRTP(nil, b, &packet.Header)
if err != nil {
return
}
if err = packet.Unmarshal(b); err != nil {
return
}
if s.OnReadRTP != nil {
s.OnReadRTP(packet)
}
}
func (s *Session) ReadRTCP(b []byte) {
header := &rtcp.Header{}
b, err := s.Remote.srtp.DecryptRTCP(nil, b, header)
if err != nil {
return
}
if _, err = rtcp.Unmarshal(b); err != nil {
return
}
if header.Type == rtcp.TypeSenderReport {
_ = s.KeepAlive()
}
}
func (s *Session) KeepAlive() error {
rep := rtcp.ReceiverReport{SSRC: s.Local.SSRC}
b, err := rep.Marshal()
if err != nil {
return err
}
if b, err = s.Local.srtp.EncryptRTCP(nil, b, nil); err != nil {
return err
}
_, err = s.conn.WriteTo(b, s.addr)
return err
}