Files

57 lines
1.7 KiB
Go

package media
import (
"errors"
"fmt"
"github.com/pion/rtp"
)
// PacketGuard is a thin policy adapter around Pion's RTP parser. It does not
// implement RTP/RTCP framing; the mature library owns wire parsing.
type PacketGuard struct {
MaxPacketBytes int
MaxPayloadBytes int
AllowedSSRC uint32
RequireSSRC bool
AllowedPayloadTypes map[uint8]struct{}
}
type Packet struct {
PayloadType uint8
SequenceNumber uint16
Timestamp uint32
SSRC uint32
Marker bool
Payload []byte
}
func (g PacketGuard) Parse(raw []byte) (Packet, error) {
if len(raw) == 0 {
return Packet{}, errors.New("empty RTP packet")
}
if g.MaxPacketBytes > 0 && len(raw) > g.MaxPacketBytes {
return Packet{}, fmt.Errorf("RTP packet exceeds limit: %d > %d", len(raw), g.MaxPacketBytes)
}
var parsed rtp.Packet
if err := parsed.Unmarshal(raw); err != nil {
return Packet{}, fmt.Errorf("parse RTP packet: %w", err)
}
if len(g.AllowedPayloadTypes) > 0 {
if _, ok := g.AllowedPayloadTypes[parsed.PayloadType]; !ok {
return Packet{}, fmt.Errorf("RTP payload type %d is not allowed", parsed.PayloadType)
}
}
if g.RequireSSRC && parsed.SSRC != g.AllowedSSRC {
return Packet{}, fmt.Errorf("RTP SSRC %d is not allowed", parsed.SSRC)
}
if g.MaxPayloadBytes > 0 && len(parsed.Payload) > g.MaxPayloadBytes {
return Packet{}, fmt.Errorf("RTP payload exceeds limit: %d > %d", len(parsed.Payload), g.MaxPayloadBytes)
}
return Packet{
PayloadType: parsed.PayloadType, SequenceNumber: parsed.SequenceNumber,
Timestamp: parsed.Timestamp, SSRC: parsed.SSRC, Marker: parsed.Marker,
Payload: append([]byte(nil), parsed.Payload...),
}, nil
}