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 }