Reuse rtp.Header in SessionSRTP.decrypt - #378
Conversation
|
One alternative I considered, and rejected, was having |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #378 +/- ##
==========================================
+ Coverage 83.62% 83.82% +0.20%
==========================================
Files 19 19
Lines 1484 1490 +6
==========================================
+ Hits 1241 1249 +8
+ Misses 135 134 -1
+ Partials 108 107 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
To make sure I understand, it appears that #372 is intended to prevent the memory footprint from growing due to things like malicious packets with spoofed ssrcs, so it discards any memory allocated unless the packet is authenticated. It does seem like allocations occur, but we are fine with that so long as they get garbage collected shortly after. And is the relation to this PR that since the header is reused, a malicious packet could cause the extension or CSRC slices within the reused header to balloon to large values? Or did you have other concerns? Assuming that is your concern, it appears like the CSRC slice would be bounded at 16 elements no matter what is in the packet. The extension slice is a bit more complicated. The total number of extensions would be bounded more or less only by the size of the packet. The read loop uses an 8192 byte packet buffer, and each extension consumes at least two bytes, so I think extension count would be bounded at a little less than 4096 (so the slice would be at most ~100KB). This would be total, even when getting hammered by malicious packets, due to the header being reused. I don't think this exhibits the same unbounded per-SSRC growth that #372 fixed. Please let me know if I missed something important though @JoTurk! |
|
If the ~100KB high water mark of memory is unacceptable, one alternative would be to restore the previous extension slice if decryption fails. Would you prefer that? |
d127cb0 to
a074fd3
Compare
Decrypt used to allocate a new header for every inbound RTP packet, causing 1 or more allocations (extensions could cause several allocations due to slice growth, and CSRC could add one more). Reusing a header, something `(*Context).decryptRTP()` already supports, avoids that allocation. `rtp.Header` supports reuse and will reuse the extension and CSRC slices when possible, causing per-packet allocations to drop to zero inside the srtp package. Safety note: the header does not currently escape the srtp package to callers. The public `(*Context).DecryptRTP()` API seems to encourage (or at least allow) header reuse, so this change does not seem to add any new obligations. In fact, if somehow the header was retained or leaked to the caller, this would be a bug as the extension payloads alias the payload buffer that is already reused today. Future work: srtp does still incur an allocation per incoming packet due to the replay detector. Removing this would likely involve a breaking API change in the replay detector.
a074fd3 to
261dbd3
Compare
|
@JoTurk I have amended the commit to include restoring the slices if decryption or unmarshalling fails, which I believe addresses the concerns you raised. |
Decrypt used to allocate a new header for every inbound RTP packet, causing 1 or more allocations (extensions could cause several allocations due to slice growth, and CSRC could add one more). Reusing a header, something
(*Context).decryptRTP()already supports, avoids that allocation.rtp.Headersupports reuse and will reuse the extension and CSRC slices when possible, causing per-packet allocations to drop to zero inside the srtp package.Safety note: the header does not currently escape the srtp package to callers. The public
(*Context).DecryptRTP()API seems to encourage (or at least allow) header reuse, so this change does not seem to add any new obligations. In fact, if somehow the header was retained or leaked to the caller, this would be a bug as the extension payloads alias the payload buffer that is already reused today.Future work: srtp does still incur an allocation per incoming packet due to the replay detector. Removing this would likely involve a breaking API change in the replay detector.
Benchmark on all ciphers show a reduction from 2 allocs/op to 0 allocs/op (test packet had a single extension).