109 lines
1.8 KiB
Go
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
|
|
}
|