rtp_demuxer.h 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /*
  2. * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
  3. *
  4. * Use of this source code is governed by a BSD-style license
  5. * that can be found in the LICENSE file in the root of the source
  6. * tree. An additional intellectual property rights grant can be found
  7. * in the file PATENTS. All contributing project authors may
  8. * be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #ifndef CALL_RTP_DEMUXER_H_
  11. #define CALL_RTP_DEMUXER_H_
  12. #include <map>
  13. #include <set>
  14. #include <string>
  15. #include <utility>
  16. #include <vector>
  17. namespace webrtc {
  18. class RtpPacketReceived;
  19. class RtpPacketSinkInterface;
  20. class SsrcBindingObserver;
  21. // This struct describes the criteria that will be used to match packets to a
  22. // specific sink.
  23. struct RtpDemuxerCriteria {
  24. RtpDemuxerCriteria();
  25. ~RtpDemuxerCriteria();
  26. // If not the empty string, will match packets with this MID.
  27. std::string mid;
  28. // If not the empty string, will match packets with this as their RTP stream
  29. // ID or repaired RTP stream ID.
  30. // Note that if both MID and RSID are specified, this will only match packets
  31. // that have both specified (either through RTP header extensions, SSRC
  32. // latching or RTCP).
  33. std::string rsid;
  34. // Will match packets with any of these SSRCs.
  35. std::set<uint32_t> ssrcs;
  36. // Will match packets with any of these payload types.
  37. std::set<uint8_t> payload_types;
  38. // Return string representation of demux criteria to facilitate logging
  39. std::string ToString() const;
  40. };
  41. // This class represents the RTP demuxing, for a single RTP session (i.e., one
  42. // SSRC space, see RFC 7656). It isn't thread aware, leaving responsibility of
  43. // multithreading issues to the user of this class.
  44. // The demuxing algorithm follows the sketch given in the BUNDLE draft:
  45. // https://tools.ietf.org/html/draft-ietf-mmusic-sdp-bundle-negotiation-38#section-10.2
  46. // with modifications to support RTP stream IDs also.
  47. //
  48. // When a packet is received, the RtpDemuxer will route according to the
  49. // following rules:
  50. // 1. If the packet contains the MID header extension, and no sink has been
  51. // added with that MID as a criteria, the packet is not routed.
  52. // 2. If the packet has the MID header extension, but no RSID or RRID extension,
  53. // and the MID is bound to a sink, then bind its SSRC to the same sink and
  54. // forward the packet to that sink. Note that rebinding to the same sink is
  55. // not an error. (Later packets with that SSRC would therefore be forwarded
  56. // to the same sink, whether they have the MID header extension or not.)
  57. // 3. If the packet has the MID header extension and either the RSID or RRID
  58. // extension, and the MID, RSID (or RRID) pair is bound to a sink, then bind
  59. // its SSRC to the same sink and forward the packet to that sink. Later
  60. // packets with that SSRC will be forwarded to the same sink.
  61. // 4. If the packet has the RSID or RRID header extension, but no MID extension,
  62. // and the RSID or RRID is bound to an RSID sink, then bind its SSRC to the
  63. // same sink and forward the packet to that sink. Later packets with that
  64. // SSRC will be forwarded to the same sink.
  65. // 5. If the packet's SSRC is bound to an SSRC through a previous call to
  66. // AddSink, then forward the packet to that sink. Note that the RtpDemuxer
  67. // will not verify the payload type even if included in the sink's criteria.
  68. // The sink is expected to do the check in its handler.
  69. // 6. If the packet's payload type is bound to exactly one payload type sink
  70. // through an earlier call to AddSink, then forward the packet to that sink.
  71. // 7. Otherwise, the packet is not routed.
  72. //
  73. // In summary, the routing algorithm will always try to first match MID and RSID
  74. // (including through SSRC binding), match SSRC directly as needed, and use
  75. // payload types only if all else fails.
  76. class RtpDemuxer {
  77. public:
  78. // Maximum number of unique SSRC bindings allowed. This limit is to prevent
  79. // memory overuse attacks due to a malicious peer sending many packets with
  80. // different SSRCs.
  81. static constexpr int kMaxSsrcBindings = 1000;
  82. // Returns a string that contains all the attributes of the given packet
  83. // relevant for demuxing.
  84. static std::string DescribePacket(const RtpPacketReceived& packet);
  85. RtpDemuxer();
  86. ~RtpDemuxer();
  87. RtpDemuxer(const RtpDemuxer&) = delete;
  88. void operator=(const RtpDemuxer&) = delete;
  89. // Registers a sink that will be notified when RTP packets match its given
  90. // criteria according to the algorithm described in the class description.
  91. // Returns true if the sink was successfully added.
  92. // Returns false in the following situations:
  93. // - Only MID is specified and the MID is already registered.
  94. // - Only RSID is specified and the RSID is already registered.
  95. // - Both MID and RSID is specified and the (MID, RSID) pair is already
  96. // registered.
  97. // - Any of the criteria SSRCs are already registered.
  98. // If false is returned, no changes are made to the demuxer state.
  99. bool AddSink(const RtpDemuxerCriteria& criteria,
  100. RtpPacketSinkInterface* sink);
  101. // Registers a sink. Multiple SSRCs may be mapped to the same sink, but
  102. // each SSRC may only be mapped to one sink. The return value reports
  103. // whether the association has been recorded or rejected. Rejection may occur
  104. // if the SSRC has already been associated with a sink. The previously added
  105. // sink is *not* forgotten.
  106. bool AddSink(uint32_t ssrc, RtpPacketSinkInterface* sink);
  107. // Registers a sink's association to an RSID. Only one sink may be associated
  108. // with a given RSID. Null pointer is not allowed.
  109. void AddSink(const std::string& rsid, RtpPacketSinkInterface* sink);
  110. // Removes a sink. Return value reports if anything was actually removed.
  111. // Null pointer is not allowed.
  112. bool RemoveSink(const RtpPacketSinkInterface* sink);
  113. // Demuxes the given packet and forwards it to the chosen sink. Returns true
  114. // if the packet was forwarded and false if the packet was dropped.
  115. bool OnRtpPacket(const RtpPacketReceived& packet);
  116. // The Observer will be notified when an attribute (e.g., RSID, MID, etc.) is
  117. // bound to an SSRC.
  118. void RegisterSsrcBindingObserver(SsrcBindingObserver* observer);
  119. // Deprecated: Use the above method.
  120. void RegisterRsidResolutionObserver(SsrcBindingObserver* observer);
  121. // Undo a previous RegisterSsrcBindingObserver().
  122. void DeregisterSsrcBindingObserver(const SsrcBindingObserver* observer);
  123. // Deprecated: Use the above method.
  124. void DeregisterRsidResolutionObserver(const SsrcBindingObserver* observer);
  125. // Configure whether to look at the MID header extension when demuxing
  126. // incoming RTP packets. By default this is enabled.
  127. void set_use_mid(bool use_mid) { use_mid_ = use_mid; }
  128. private:
  129. // Returns true if adding a sink with the given criteria would cause conflicts
  130. // with the existing criteria and should be rejected.
  131. bool CriteriaWouldConflict(const RtpDemuxerCriteria& criteria) const;
  132. // Runs the demux algorithm on the given packet and returns the sink that
  133. // should receive the packet.
  134. // Will record any SSRC<->ID associations along the way.
  135. // If the packet should be dropped, this method returns null.
  136. RtpPacketSinkInterface* ResolveSink(const RtpPacketReceived& packet);
  137. // Used by the ResolveSink algorithm.
  138. RtpPacketSinkInterface* ResolveSinkByMid(const std::string& mid,
  139. uint32_t ssrc);
  140. RtpPacketSinkInterface* ResolveSinkByMidRsid(const std::string& mid,
  141. const std::string& rsid,
  142. uint32_t ssrc);
  143. RtpPacketSinkInterface* ResolveSinkByRsid(const std::string& rsid,
  144. uint32_t ssrc);
  145. RtpPacketSinkInterface* ResolveSinkByPayloadType(uint8_t payload_type,
  146. uint32_t ssrc);
  147. // Regenerate the known_mids_ set from information in the sink_by_mid_ and
  148. // sink_by_mid_and_rsid_ maps.
  149. void RefreshKnownMids();
  150. // Map each sink by its component attributes to facilitate quick lookups.
  151. // Payload Type mapping is a multimap because if two sinks register for the
  152. // same payload type, both AddSinks succeed but we must know not to demux on
  153. // that attribute since it is ambiguous.
  154. // Note: Mappings are only modified by AddSink/RemoveSink (except for
  155. // SSRC mapping which receives all MID, payload type, or RSID to SSRC bindings
  156. // discovered when demuxing packets).
  157. std::map<std::string, RtpPacketSinkInterface*> sink_by_mid_;
  158. std::map<uint32_t, RtpPacketSinkInterface*> sink_by_ssrc_;
  159. std::multimap<uint8_t, RtpPacketSinkInterface*> sinks_by_pt_;
  160. std::map<std::pair<std::string, std::string>, RtpPacketSinkInterface*>
  161. sink_by_mid_and_rsid_;
  162. std::map<std::string, RtpPacketSinkInterface*> sink_by_rsid_;
  163. // Tracks all the MIDs that have been identified in added criteria. Used to
  164. // determine if a packet should be dropped right away because the MID is
  165. // unknown.
  166. std::set<std::string> known_mids_;
  167. // Records learned mappings of MID --> SSRC and RSID --> SSRC as packets are
  168. // received.
  169. // This is stored separately from the sink mappings because if a sink is
  170. // removed we want to still remember these associations.
  171. std::map<uint32_t, std::string> mid_by_ssrc_;
  172. std::map<uint32_t, std::string> rsid_by_ssrc_;
  173. // Adds a binding from the SSRC to the given sink. Returns true if there was
  174. // not already a sink bound to the SSRC or if the sink replaced a different
  175. // sink. Returns false if the binding was unchanged.
  176. bool AddSsrcSinkBinding(uint32_t ssrc, RtpPacketSinkInterface* sink);
  177. // Observers which will be notified when an RSID association to an SSRC is
  178. // resolved by this object.
  179. std::vector<SsrcBindingObserver*> ssrc_binding_observers_;
  180. bool use_mid_ = true;
  181. };
  182. } // namespace webrtc
  183. #endif // CALL_RTP_DEMUXER_H_