fake_ice_transport.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. /*
  2. * Copyright 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 P2P_BASE_FAKE_ICE_TRANSPORT_H_
  11. #define P2P_BASE_FAKE_ICE_TRANSPORT_H_
  12. #include <map>
  13. #include <memory>
  14. #include <string>
  15. #include <utility>
  16. #include "absl/algorithm/container.h"
  17. #include "absl/types/optional.h"
  18. #include "api/ice_transport_interface.h"
  19. #include "p2p/base/ice_transport_internal.h"
  20. #include "rtc_base/async_invoker.h"
  21. #include "rtc_base/copy_on_write_buffer.h"
  22. namespace cricket {
  23. class FakeIceTransport : public IceTransportInternal {
  24. public:
  25. explicit FakeIceTransport(const std::string& name,
  26. int component,
  27. rtc::Thread* network_thread = nullptr)
  28. : name_(name),
  29. component_(component),
  30. network_thread_(network_thread ? network_thread
  31. : rtc::Thread::Current()) {}
  32. ~FakeIceTransport() override {
  33. if (dest_ && dest_->dest_ == this) {
  34. dest_->dest_ = nullptr;
  35. }
  36. }
  37. // If async, will send packets by "Post"-ing to message queue instead of
  38. // synchronously "Send"-ing.
  39. void SetAsync(bool async) { async_ = async; }
  40. void SetAsyncDelay(int delay_ms) { async_delay_ms_ = delay_ms; }
  41. // SetWritable, SetReceiving and SetDestination are the main methods that can
  42. // be used for testing, to simulate connectivity or lack thereof.
  43. void SetWritable(bool writable) { set_writable(writable); }
  44. void SetReceiving(bool receiving) { set_receiving(receiving); }
  45. // Simulates the two transports connecting to each other.
  46. // If |asymmetric| is true this method only affects this FakeIceTransport.
  47. // If false, it affects |dest| as well.
  48. void SetDestination(FakeIceTransport* dest, bool asymmetric = false) {
  49. if (dest == dest_) {
  50. return;
  51. }
  52. RTC_DCHECK(!dest || !dest_)
  53. << "Changing fake destination from one to another is not supported.";
  54. if (dest) {
  55. // This simulates the delivery of candidates.
  56. dest_ = dest;
  57. set_writable(true);
  58. if (!asymmetric) {
  59. dest->SetDestination(this, true);
  60. }
  61. } else {
  62. // Simulates loss of connectivity, by asymmetrically forgetting dest_.
  63. dest_ = nullptr;
  64. set_writable(false);
  65. }
  66. }
  67. void SetTransportState(webrtc::IceTransportState state,
  68. IceTransportState legacy_state) {
  69. transport_state_ = state;
  70. legacy_transport_state_ = legacy_state;
  71. SignalIceTransportStateChanged(this);
  72. }
  73. void SetConnectionCount(size_t connection_count) {
  74. size_t old_connection_count = connection_count_;
  75. connection_count_ = connection_count;
  76. if (connection_count) {
  77. had_connection_ = true;
  78. }
  79. // In this fake transport channel, |connection_count_| determines the
  80. // transport state.
  81. if (connection_count_ < old_connection_count) {
  82. SignalStateChanged(this);
  83. }
  84. }
  85. void SetCandidatesGatheringComplete() {
  86. if (gathering_state_ != kIceGatheringComplete) {
  87. gathering_state_ = kIceGatheringComplete;
  88. SignalGatheringState(this);
  89. }
  90. }
  91. // Convenience functions for accessing ICE config and other things.
  92. int receiving_timeout() const {
  93. return ice_config_.receiving_timeout_or_default();
  94. }
  95. bool gather_continually() const { return ice_config_.gather_continually(); }
  96. const Candidates& remote_candidates() const { return remote_candidates_; }
  97. // Fake IceTransportInternal implementation.
  98. const std::string& transport_name() const override { return name_; }
  99. int component() const override { return component_; }
  100. uint64_t IceTiebreaker() const { return tiebreaker_; }
  101. IceMode remote_ice_mode() const { return remote_ice_mode_; }
  102. const std::string& ice_ufrag() const { return ice_parameters_.ufrag; }
  103. const std::string& ice_pwd() const { return ice_parameters_.pwd; }
  104. const std::string& remote_ice_ufrag() const {
  105. return remote_ice_parameters_.ufrag;
  106. }
  107. const std::string& remote_ice_pwd() const {
  108. return remote_ice_parameters_.pwd;
  109. }
  110. const IceParameters& ice_parameters() const { return ice_parameters_; }
  111. const IceParameters& remote_ice_parameters() const {
  112. return remote_ice_parameters_;
  113. }
  114. IceTransportState GetState() const override {
  115. if (legacy_transport_state_) {
  116. return *legacy_transport_state_;
  117. }
  118. if (connection_count_ == 0) {
  119. return had_connection_ ? IceTransportState::STATE_FAILED
  120. : IceTransportState::STATE_INIT;
  121. }
  122. if (connection_count_ == 1) {
  123. return IceTransportState::STATE_COMPLETED;
  124. }
  125. return IceTransportState::STATE_CONNECTING;
  126. }
  127. webrtc::IceTransportState GetIceTransportState() const override {
  128. if (transport_state_) {
  129. return *transport_state_;
  130. }
  131. if (connection_count_ == 0) {
  132. return had_connection_ ? webrtc::IceTransportState::kFailed
  133. : webrtc::IceTransportState::kNew;
  134. }
  135. if (connection_count_ == 1) {
  136. return webrtc::IceTransportState::kCompleted;
  137. }
  138. return webrtc::IceTransportState::kConnected;
  139. }
  140. void SetIceRole(IceRole role) override { role_ = role; }
  141. IceRole GetIceRole() const override { return role_; }
  142. void SetIceTiebreaker(uint64_t tiebreaker) override {
  143. tiebreaker_ = tiebreaker;
  144. }
  145. void SetIceParameters(const IceParameters& ice_params) override {
  146. ice_parameters_ = ice_params;
  147. }
  148. void SetRemoteIceParameters(const IceParameters& params) override {
  149. remote_ice_parameters_ = params;
  150. }
  151. void SetRemoteIceMode(IceMode mode) override { remote_ice_mode_ = mode; }
  152. void MaybeStartGathering() override {
  153. if (gathering_state_ == kIceGatheringNew) {
  154. gathering_state_ = kIceGatheringGathering;
  155. SignalGatheringState(this);
  156. }
  157. }
  158. IceGatheringState gathering_state() const override {
  159. return gathering_state_;
  160. }
  161. void SetIceConfig(const IceConfig& config) override { ice_config_ = config; }
  162. void AddRemoteCandidate(const Candidate& candidate) override {
  163. remote_candidates_.push_back(candidate);
  164. }
  165. void RemoveRemoteCandidate(const Candidate& candidate) override {
  166. auto it = absl::c_find(remote_candidates_, candidate);
  167. if (it == remote_candidates_.end()) {
  168. RTC_LOG(LS_INFO) << "Trying to remove a candidate which doesn't exist.";
  169. return;
  170. }
  171. remote_candidates_.erase(it);
  172. }
  173. void RemoveAllRemoteCandidates() override { remote_candidates_.clear(); }
  174. bool GetStats(IceTransportStats* ice_transport_stats) override {
  175. CandidateStats candidate_stats;
  176. ConnectionInfo candidate_pair_stats;
  177. ice_transport_stats->candidate_stats_list.clear();
  178. ice_transport_stats->candidate_stats_list.push_back(candidate_stats);
  179. ice_transport_stats->connection_infos.clear();
  180. ice_transport_stats->connection_infos.push_back(candidate_pair_stats);
  181. return true;
  182. }
  183. absl::optional<int> GetRttEstimate() override { return absl::nullopt; }
  184. const Connection* selected_connection() const override { return nullptr; }
  185. absl::optional<const CandidatePair> GetSelectedCandidatePair()
  186. const override {
  187. return absl::nullopt;
  188. }
  189. // Fake PacketTransportInternal implementation.
  190. bool writable() const override { return writable_; }
  191. bool receiving() const override { return receiving_; }
  192. // If combine is enabled, every two consecutive packets to be sent with
  193. // "SendPacket" will be combined into one outgoing packet.
  194. void combine_outgoing_packets(bool combine) {
  195. combine_outgoing_packets_ = combine;
  196. }
  197. int SendPacket(const char* data,
  198. size_t len,
  199. const rtc::PacketOptions& options,
  200. int flags) override {
  201. if (!dest_) {
  202. return -1;
  203. }
  204. send_packet_.AppendData(data, len);
  205. if (!combine_outgoing_packets_ || send_packet_.size() > len) {
  206. rtc::CopyOnWriteBuffer packet(std::move(send_packet_));
  207. if (async_) {
  208. invoker_.AsyncInvokeDelayed<void>(
  209. RTC_FROM_HERE, rtc::Thread::Current(),
  210. rtc::Bind(&FakeIceTransport::SendPacketInternal, this, packet),
  211. async_delay_ms_);
  212. } else {
  213. SendPacketInternal(packet);
  214. }
  215. }
  216. rtc::SentPacket sent_packet(options.packet_id, rtc::TimeMillis());
  217. SignalSentPacket(this, sent_packet);
  218. return static_cast<int>(len);
  219. }
  220. int SetOption(rtc::Socket::Option opt, int value) override {
  221. socket_options_[opt] = value;
  222. return true;
  223. }
  224. bool GetOption(rtc::Socket::Option opt, int* value) override {
  225. auto it = socket_options_.find(opt);
  226. if (it != socket_options_.end()) {
  227. *value = it->second;
  228. return true;
  229. } else {
  230. return false;
  231. }
  232. }
  233. int GetError() override { return 0; }
  234. rtc::CopyOnWriteBuffer last_sent_packet() { return last_sent_packet_; }
  235. absl::optional<rtc::NetworkRoute> network_route() const override {
  236. return network_route_;
  237. }
  238. void SetNetworkRoute(absl::optional<rtc::NetworkRoute> network_route) {
  239. network_route_ = network_route;
  240. network_thread_->Invoke<void>(
  241. RTC_FROM_HERE, [this] { SignalNetworkRouteChanged(network_route_); });
  242. }
  243. private:
  244. void set_writable(bool writable) {
  245. if (writable_ == writable) {
  246. return;
  247. }
  248. RTC_LOG(INFO) << "Change writable_ to " << writable;
  249. writable_ = writable;
  250. if (writable_) {
  251. SignalReadyToSend(this);
  252. }
  253. SignalWritableState(this);
  254. }
  255. void set_receiving(bool receiving) {
  256. if (receiving_ == receiving) {
  257. return;
  258. }
  259. receiving_ = receiving;
  260. SignalReceivingState(this);
  261. }
  262. void SendPacketInternal(const rtc::CopyOnWriteBuffer& packet) {
  263. if (dest_) {
  264. last_sent_packet_ = packet;
  265. dest_->SignalReadPacket(dest_, packet.data<char>(), packet.size(),
  266. rtc::TimeMicros(), 0);
  267. }
  268. }
  269. rtc::AsyncInvoker invoker_;
  270. std::string name_;
  271. int component_;
  272. FakeIceTransport* dest_ = nullptr;
  273. bool async_ = false;
  274. int async_delay_ms_ = 0;
  275. Candidates remote_candidates_;
  276. IceConfig ice_config_;
  277. IceRole role_ = ICEROLE_UNKNOWN;
  278. uint64_t tiebreaker_ = 0;
  279. IceParameters ice_parameters_;
  280. IceParameters remote_ice_parameters_;
  281. IceMode remote_ice_mode_ = ICEMODE_FULL;
  282. size_t connection_count_ = 0;
  283. absl::optional<webrtc::IceTransportState> transport_state_;
  284. absl::optional<IceTransportState> legacy_transport_state_;
  285. IceGatheringState gathering_state_ = kIceGatheringNew;
  286. bool had_connection_ = false;
  287. bool writable_ = false;
  288. bool receiving_ = false;
  289. bool combine_outgoing_packets_ = false;
  290. rtc::CopyOnWriteBuffer send_packet_;
  291. absl::optional<rtc::NetworkRoute> network_route_;
  292. std::map<rtc::Socket::Option, int> socket_options_;
  293. rtc::CopyOnWriteBuffer last_sent_packet_;
  294. rtc::Thread* const network_thread_;
  295. };
  296. class FakeIceTransportWrapper : public webrtc::IceTransportInterface {
  297. public:
  298. explicit FakeIceTransportWrapper(
  299. std::unique_ptr<cricket::FakeIceTransport> internal)
  300. : internal_(std::move(internal)) {}
  301. cricket::IceTransportInternal* internal() override { return internal_.get(); }
  302. private:
  303. std::unique_ptr<cricket::FakeIceTransport> internal_;
  304. };
  305. } // namespace cricket
  306. #endif // P2P_BASE_FAKE_ICE_TRANSPORT_H_