You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Establish a peer connection to send a track then call webrtc.TrackLocalStaticRTP.WriteRTP() to write RTP packets with non-empty payload and payload padding (PaddingSize > 1), e.g. with packets like this:
In webrtc.TrackLocalStaticRTP.writeRTP(p *rtp.Packet), the packet is not passed down as a whole but only its header and payload (missing PaddingSize) are passed down via b.writeStream.WriteRTP(&p.Header, p.Payload), to TrackLocalWriter, then to interceptor, then to srtp.SessionSRTP.writeRTP(header *rtp.Header, payload []byte), and finally to srtp.Context.encryptRTP(dst []byte, header *rtp.Header, payload []byte).
Currently, there's only one way to generate padding bytes, that is to marshal RTP packet via rtp.Packet.Marshal()(See pion/rtp#155). But even with marshalled packet, the plaintext will always be unmarshalled and its padding info is thrown away: both webrtc.TrackLocalStaticRTP.Write(b []byte) and srtp.SessionSRTP.write(b []byte) just p.Unmarshal(b) then call the "writeRTP()" counterparts.
Suggested solutions
Either call rtp.Packet.Marshal() or add the padding appending codes to update the payload somewhere before passing it to srtp.
Discussion
Usually, padding packets contain only padding bytes. These padding-only packets hide this issue with empty payload. But in the general case of non-empty payload + padding, current system will send wrong SRTPs which will make the receiver peer crash.
The public function srtp.Context.EncryptRTP(dst []byte, plaintext []byte, header *rtp.Header) does require a marshalled plaintext, but the private function srtp.Context.encryptRTP(dst []byte, header *rtp.Header, payload []byte) has a shortcut to the payload which can be unmarshalled. So, these interfaces should be re-considered.
The text was updated successfully, but these errors were encountered:
@bixycler I think the simplest way in your case is to add padding to payload manually and set Padding flag in Header.
PaddingSize indeed doesn't work. Moreover I don't understand how it should work in case Packet unmarshalled before interceptor.
But I honestly don't think this is a problem for webrtc.TrackLocalStaticRTP as you always can append padding to rtp payload before you can webrtc.TrackLocalStaticRTP.Write* functions and just set Header's padding field.
I agree that PaddingSize cannot be used to pass packets with padding. But in your case you could just add padding to rtp manually.
I did the same for webrtc.TrackLocalStaticSample. It was a little harder as webrtc.TrackLocalStaticSample works with samples. But it works in anyway
What did you do?
Establish a peer connection to send a track then call
webrtc.TrackLocalStaticRTP.WriteRTP()
to write RTP packets with non-empty payload and payload padding (PaddingSize > 1
), e.g. with packets like this:What did you expect?
The sent ciphertext (SRTP) should have corresponding plaintext containing trailing padding bytes, e.g. with plaintext like this:
What happened?
The sent ciphertext (SRTP) has corresponding plaintext with
Header.Padding == true
but no padding bytes, e.g. with plaintext like this:which makes the receiver peer wrongly parse the received packet, e.g. as
Causes of the problem:
In
webrtc.TrackLocalStaticRTP.writeRTP(p *rtp.Packet)
, the packet is not passed down as a whole but only its header and payload (missing PaddingSize) are passed down viab.writeStream.WriteRTP(&p.Header, p.Payload)
, toTrackLocalWriter
, then tointerceptor
, then tosrtp.SessionSRTP.writeRTP(header *rtp.Header, payload []byte)
, and finally tosrtp.Context.encryptRTP(dst []byte, header *rtp.Header, payload []byte)
.Currently, there's only one way to generate padding bytes, that is to marshal RTP packet via
rtp.Packet.Marshal()
(See pion/rtp#155). But even with marshalled packet, the plaintext will always be unmarshalled and its padding info is thrown away: bothwebrtc.TrackLocalStaticRTP.Write(b []byte)
andsrtp.SessionSRTP.write(b []byte)
justp.Unmarshal(b)
then call the "writeRTP()" counterparts.Suggested solutions
Either call
rtp.Packet.Marshal()
or add the padding appending codes to update the payload somewhere before passing it tosrtp
.Discussion
srtp.Context.EncryptRTP(dst []byte, plaintext []byte, header *rtp.Header)
does require a marshalled plaintext, but the private functionsrtp.Context.encryptRTP(dst []byte, header *rtp.Header, payload []byte)
has a shortcut to the payload which can be unmarshalled. So, these interfaces should be re-considered.The text was updated successfully, but these errors were encountered: