connection.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. /*
  2. * Copyright 2019 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_CONNECTION_H_
  11. #define P2P_BASE_CONNECTION_H_
  12. #include <memory>
  13. #include <string>
  14. #include <vector>
  15. #include "absl/types/optional.h"
  16. #include "api/candidate.h"
  17. #include "api/transport/stun.h"
  18. #include "logging/rtc_event_log/ice_logger.h"
  19. #include "p2p/base/candidate_pair_interface.h"
  20. #include "p2p/base/connection_info.h"
  21. #include "p2p/base/p2p_transport_channel_ice_field_trials.h"
  22. #include "p2p/base/stun_request.h"
  23. #include "p2p/base/transport_description.h"
  24. #include "rtc_base/async_packet_socket.h"
  25. #include "rtc_base/message_handler.h"
  26. #include "rtc_base/network.h"
  27. #include "rtc_base/numerics/event_based_exponential_moving_average.h"
  28. #include "rtc_base/rate_tracker.h"
  29. namespace cricket {
  30. // Version number for GOOG_PING, this is added to have the option of
  31. // adding other flavors in the future.
  32. constexpr int kGoogPingVersion = 1;
  33. // Connection and Port has circular dependencies.
  34. // So we use forward declaration rather than include.
  35. class Port;
  36. // Forward declaration so that a ConnectionRequest can contain a Connection.
  37. class Connection;
  38. struct CandidatePair final : public CandidatePairInterface {
  39. ~CandidatePair() override = default;
  40. const Candidate& local_candidate() const override { return local; }
  41. const Candidate& remote_candidate() const override { return remote; }
  42. Candidate local;
  43. Candidate remote;
  44. };
  45. // A ConnectionRequest is a simple STUN ping used to determine writability.
  46. class ConnectionRequest : public StunRequest {
  47. public:
  48. explicit ConnectionRequest(Connection* connection);
  49. void Prepare(StunMessage* request) override;
  50. void OnResponse(StunMessage* response) override;
  51. void OnErrorResponse(StunMessage* response) override;
  52. void OnTimeout() override;
  53. void OnSent() override;
  54. int resend_delay() override;
  55. private:
  56. Connection* const connection_;
  57. };
  58. // Represents a communication link between a port on the local client and a
  59. // port on the remote client.
  60. class Connection : public CandidatePairInterface,
  61. public rtc::MessageHandlerAutoCleanup,
  62. public sigslot::has_slots<> {
  63. public:
  64. struct SentPing {
  65. SentPing(const std::string id, int64_t sent_time, uint32_t nomination)
  66. : id(id), sent_time(sent_time), nomination(nomination) {}
  67. std::string id;
  68. int64_t sent_time;
  69. uint32_t nomination;
  70. };
  71. ~Connection() override;
  72. // A unique ID assigned when the connection is created.
  73. uint32_t id() const { return id_; }
  74. // Implementation of virtual methods in CandidatePairInterface.
  75. // Returns the description of the local port
  76. const Candidate& local_candidate() const override;
  77. // Returns the description of the remote port to which we communicate.
  78. const Candidate& remote_candidate() const override;
  79. // Return local network for this connection.
  80. virtual const rtc::Network* network() const;
  81. // Return generation for this connection.
  82. virtual int generation() const;
  83. // Returns the pair priority.
  84. virtual uint64_t priority() const;
  85. enum WriteState {
  86. STATE_WRITABLE = 0, // we have received ping responses recently
  87. STATE_WRITE_UNRELIABLE = 1, // we have had a few ping failures
  88. STATE_WRITE_INIT = 2, // we have yet to receive a ping response
  89. STATE_WRITE_TIMEOUT = 3, // we have had a large number of ping failures
  90. };
  91. WriteState write_state() const { return write_state_; }
  92. bool writable() const { return write_state_ == STATE_WRITABLE; }
  93. bool receiving() const { return receiving_; }
  94. // Determines whether the connection has finished connecting. This can only
  95. // be false for TCP connections.
  96. bool connected() const { return connected_; }
  97. bool weak() const { return !(writable() && receiving() && connected()); }
  98. bool active() const { return write_state_ != STATE_WRITE_TIMEOUT; }
  99. // A connection is dead if it can be safely deleted.
  100. bool dead(int64_t now) const;
  101. // Estimate of the round-trip time over this connection.
  102. int rtt() const { return rtt_; }
  103. int unwritable_timeout() const;
  104. void set_unwritable_timeout(const absl::optional<int>& value_ms) {
  105. unwritable_timeout_ = value_ms;
  106. }
  107. int unwritable_min_checks() const;
  108. void set_unwritable_min_checks(const absl::optional<int>& value) {
  109. unwritable_min_checks_ = value;
  110. }
  111. int inactive_timeout() const;
  112. void set_inactive_timeout(const absl::optional<int>& value) {
  113. inactive_timeout_ = value;
  114. }
  115. // Gets the |ConnectionInfo| stats, where |best_connection| has not been
  116. // populated (default value false).
  117. ConnectionInfo stats();
  118. sigslot::signal1<Connection*> SignalStateChange;
  119. // Sent when the connection has decided that it is no longer of value. It
  120. // will delete itself immediately after this call.
  121. sigslot::signal1<Connection*> SignalDestroyed;
  122. // The connection can send and receive packets asynchronously. This matches
  123. // the interface of AsyncPacketSocket, which may use UDP or TCP under the
  124. // covers.
  125. virtual int Send(const void* data,
  126. size_t size,
  127. const rtc::PacketOptions& options) = 0;
  128. // Error if Send() returns < 0
  129. virtual int GetError() = 0;
  130. sigslot::signal4<Connection*, const char*, size_t, int64_t> SignalReadPacket;
  131. sigslot::signal1<Connection*> SignalReadyToSend;
  132. // Called when a packet is received on this connection.
  133. void OnReadPacket(const char* data, size_t size, int64_t packet_time_us);
  134. // Called when the socket is currently able to send.
  135. void OnReadyToSend();
  136. // Called when a connection is determined to be no longer useful to us. We
  137. // still keep it around in case the other side wants to use it. But we can
  138. // safely stop pinging on it and we can allow it to time out if the other
  139. // side stops using it as well.
  140. bool pruned() const { return pruned_; }
  141. void Prune();
  142. bool use_candidate_attr() const { return use_candidate_attr_; }
  143. void set_use_candidate_attr(bool enable);
  144. void set_nomination(uint32_t value) { nomination_ = value; }
  145. uint32_t remote_nomination() const { return remote_nomination_; }
  146. // One or several pairs may be nominated based on if Regular or Aggressive
  147. // Nomination is used. https://tools.ietf.org/html/rfc5245#section-8
  148. // |nominated| is defined both for the controlling or controlled agent based
  149. // on if a nomination has been pinged or acknowledged. The controlled agent
  150. // gets its |remote_nomination_| set when pinged by the controlling agent with
  151. // a nomination value. The controlling agent gets its |acked_nomination_| set
  152. // when receiving a response to a nominating ping.
  153. bool nominated() const { return acked_nomination_ || remote_nomination_; }
  154. void set_remote_ice_mode(IceMode mode) { remote_ice_mode_ = mode; }
  155. int receiving_timeout() const;
  156. void set_receiving_timeout(absl::optional<int> receiving_timeout_ms) {
  157. receiving_timeout_ = receiving_timeout_ms;
  158. }
  159. // Makes the connection go away.
  160. void Destroy();
  161. // Makes the connection go away, in a failed state.
  162. void FailAndDestroy();
  163. // Prunes the connection and sets its state to STATE_FAILED,
  164. // It will not be used or send pings although it can still receive packets.
  165. void FailAndPrune();
  166. // Checks that the state of this connection is up-to-date. The argument is
  167. // the current time, which is compared against various timeouts.
  168. void UpdateState(int64_t now);
  169. // Called when this connection should try checking writability again.
  170. int64_t last_ping_sent() const { return last_ping_sent_; }
  171. void Ping(int64_t now);
  172. void ReceivedPingResponse(
  173. int rtt,
  174. const std::string& request_id,
  175. const absl::optional<uint32_t>& nomination = absl::nullopt);
  176. int64_t last_ping_response_received() const {
  177. return last_ping_response_received_;
  178. }
  179. const absl::optional<std::string>& last_ping_id_received() const {
  180. return last_ping_id_received_;
  181. }
  182. // Used to check if any STUN ping response has been received.
  183. int rtt_samples() const { return rtt_samples_; }
  184. // Called whenever a valid ping is received on this connection. This is
  185. // public because the connection intercepts the first ping for us.
  186. int64_t last_ping_received() const { return last_ping_received_; }
  187. void ReceivedPing(
  188. const absl::optional<std::string>& request_id = absl::nullopt);
  189. // Handles the binding request; sends a response if this is a valid request.
  190. void HandleStunBindingOrGoogPingRequest(IceMessage* msg);
  191. // Handles the piggyback acknowledgement of the lastest connectivity check
  192. // that the remote peer has received, if it is indicated in the incoming
  193. // connectivity check from the peer.
  194. void HandlePiggybackCheckAcknowledgementIfAny(StunMessage* msg);
  195. int64_t last_data_received() const { return last_data_received_; }
  196. // Debugging description of this connection
  197. std::string ToDebugId() const;
  198. std::string ToString() const;
  199. std::string ToSensitiveString() const;
  200. // Structured description of this candidate pair.
  201. const webrtc::IceCandidatePairDescription& ToLogDescription();
  202. void set_ice_event_log(webrtc::IceEventLog* ice_event_log) {
  203. ice_event_log_ = ice_event_log;
  204. }
  205. // Prints pings_since_last_response_ into a string.
  206. void PrintPingsSinceLastResponse(std::string* pings, size_t max);
  207. bool reported() const { return reported_; }
  208. void set_reported(bool reported) { reported_ = reported; }
  209. // The following two methods are only used for logging in ToString above, and
  210. // this flag is set true by P2PTransportChannel for its selected candidate
  211. // pair.
  212. bool selected() const { return selected_; }
  213. void set_selected(bool selected) { selected_ = selected; }
  214. // This signal will be fired if this connection is nominated by the
  215. // controlling side.
  216. sigslot::signal1<Connection*> SignalNominated;
  217. // Invoked when Connection receives STUN error response with 487 code.
  218. void HandleRoleConflictFromPeer();
  219. IceCandidatePairState state() const { return state_; }
  220. int num_pings_sent() const { return num_pings_sent_; }
  221. IceMode remote_ice_mode() const { return remote_ice_mode_; }
  222. uint32_t ComputeNetworkCost() const;
  223. // Update the ICE password and/or generation of the remote candidate if the
  224. // ufrag in |params| matches the candidate's ufrag, and the
  225. // candidate's password and/or ufrag has not been set.
  226. void MaybeSetRemoteIceParametersAndGeneration(const IceParameters& params,
  227. int generation);
  228. // If |remote_candidate_| is peer reflexive and is equivalent to
  229. // |new_candidate| except the type, update |remote_candidate_| to
  230. // |new_candidate|.
  231. void MaybeUpdatePeerReflexiveCandidate(const Candidate& new_candidate);
  232. // Returns the last received time of any data, stun request, or stun
  233. // response in milliseconds
  234. int64_t last_received() const;
  235. // Returns the last time when the connection changed its receiving state.
  236. int64_t receiving_unchanged_since() const {
  237. return receiving_unchanged_since_;
  238. }
  239. bool stable(int64_t now) const;
  240. // Check if we sent |val| pings without receving a response.
  241. bool TooManyOutstandingPings(const absl::optional<int>& val) const;
  242. void SetIceFieldTrials(const IceFieldTrials* field_trials);
  243. const rtc::EventBasedExponentialMovingAverage& GetRttEstimate() const {
  244. return rtt_estimate_;
  245. }
  246. // Reset the connection to a state of a newly connected.
  247. // - STATE_WRITE_INIT
  248. // - receving = false
  249. // - throw away all pending request
  250. // - reset RttEstimate
  251. //
  252. // Keep the following unchanged:
  253. // - connected
  254. // - remote_candidate
  255. // - statistics
  256. //
  257. // Does not trigger SignalStateChange
  258. void ForgetLearnedState();
  259. void SendStunBindingResponse(const StunMessage* request);
  260. void SendGoogPingResponse(const StunMessage* request);
  261. void SendResponseMessage(const StunMessage& response);
  262. // An accessor for unit tests.
  263. Port* PortForTest() { return port_; }
  264. const Port* PortForTest() const { return port_; }
  265. // Public for unit tests.
  266. uint32_t acked_nomination() const { return acked_nomination_; }
  267. // Public for unit tests.
  268. void set_remote_nomination(uint32_t remote_nomination) {
  269. remote_nomination_ = remote_nomination;
  270. }
  271. protected:
  272. enum { MSG_DELETE = 0, MSG_FIRST_AVAILABLE };
  273. // Constructs a new connection to the given remote port.
  274. Connection(Port* port, size_t index, const Candidate& candidate);
  275. // Called back when StunRequestManager has a stun packet to send
  276. void OnSendStunPacket(const void* data, size_t size, StunRequest* req);
  277. // Callbacks from ConnectionRequest
  278. virtual void OnConnectionRequestResponse(ConnectionRequest* req,
  279. StunMessage* response);
  280. void OnConnectionRequestErrorResponse(ConnectionRequest* req,
  281. StunMessage* response);
  282. void OnConnectionRequestTimeout(ConnectionRequest* req);
  283. void OnConnectionRequestSent(ConnectionRequest* req);
  284. bool rtt_converged() const;
  285. // If the response is not received within 2 * RTT, the response is assumed to
  286. // be missing.
  287. bool missing_responses(int64_t now) const;
  288. // Changes the state and signals if necessary.
  289. void set_write_state(WriteState value);
  290. void UpdateReceiving(int64_t now);
  291. void set_state(IceCandidatePairState state);
  292. void set_connected(bool value);
  293. uint32_t nomination() const { return nomination_; }
  294. void OnMessage(rtc::Message* pmsg) override;
  295. // The local port where this connection sends and receives packets.
  296. Port* port() { return port_; }
  297. const Port* port() const { return port_; }
  298. uint32_t id_;
  299. Port* port_;
  300. size_t local_candidate_index_;
  301. Candidate remote_candidate_;
  302. ConnectionInfo stats_;
  303. rtc::RateTracker recv_rate_tracker_;
  304. rtc::RateTracker send_rate_tracker_;
  305. private:
  306. // Update the local candidate based on the mapped address attribute.
  307. // If the local candidate changed, fires SignalStateChange.
  308. void MaybeUpdateLocalCandidate(ConnectionRequest* request,
  309. StunMessage* response);
  310. void LogCandidatePairConfig(webrtc::IceCandidatePairConfigType type);
  311. void LogCandidatePairEvent(webrtc::IceCandidatePairEventType type,
  312. uint32_t transaction_id);
  313. // Check if this IceMessage is identical
  314. // to last message ack:ed STUN_BINDING_REQUEST.
  315. bool ShouldSendGoogPing(const StunMessage* message);
  316. WriteState write_state_;
  317. bool receiving_;
  318. bool connected_;
  319. bool pruned_;
  320. bool selected_ = false;
  321. // By default |use_candidate_attr_| flag will be true,
  322. // as we will be using aggressive nomination.
  323. // But when peer is ice-lite, this flag "must" be initialized to false and
  324. // turn on when connection becomes "best connection".
  325. bool use_candidate_attr_;
  326. // Used by the controlling side to indicate that this connection will be
  327. // selected for transmission if the peer supports ICE-renomination when this
  328. // value is positive. A larger-value indicates that a connection is nominated
  329. // later and should be selected by the controlled side with higher precedence.
  330. // A zero-value indicates not nominating this connection.
  331. uint32_t nomination_ = 0;
  332. // The last nomination that has been acknowledged.
  333. uint32_t acked_nomination_ = 0;
  334. // Used by the controlled side to remember the nomination value received from
  335. // the controlling side. When the peer does not support ICE re-nomination, its
  336. // value will be 1 if the connection has been nominated.
  337. uint32_t remote_nomination_ = 0;
  338. IceMode remote_ice_mode_;
  339. StunRequestManager requests_;
  340. int rtt_;
  341. int rtt_samples_ = 0;
  342. // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-totalroundtriptime
  343. uint64_t total_round_trip_time_ms_ = 0;
  344. // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-currentroundtriptime
  345. absl::optional<uint32_t> current_round_trip_time_ms_;
  346. int64_t last_ping_sent_; // last time we sent a ping to the other side
  347. int64_t last_ping_received_; // last time we received a ping from the other
  348. // side
  349. int64_t last_data_received_;
  350. int64_t last_ping_response_received_;
  351. int64_t receiving_unchanged_since_ = 0;
  352. std::vector<SentPing> pings_since_last_response_;
  353. // Transaction ID of the last connectivity check received. Null if having not
  354. // received a ping yet.
  355. absl::optional<std::string> last_ping_id_received_;
  356. absl::optional<int> unwritable_timeout_;
  357. absl::optional<int> unwritable_min_checks_;
  358. absl::optional<int> inactive_timeout_;
  359. bool reported_;
  360. IceCandidatePairState state_;
  361. // Time duration to switch from receiving to not receiving.
  362. absl::optional<int> receiving_timeout_;
  363. int64_t time_created_ms_;
  364. int num_pings_sent_ = 0;
  365. absl::optional<webrtc::IceCandidatePairDescription> log_description_;
  366. webrtc::IceEventLog* ice_event_log_ = nullptr;
  367. // GOOG_PING_REQUEST is sent in place of STUN_BINDING_REQUEST
  368. // if configured via field trial, the remote peer supports it (signaled
  369. // in STUN_BINDING) and if the last STUN BINDING is identical to the one
  370. // that is about to be sent.
  371. absl::optional<bool> remote_support_goog_ping_;
  372. std::unique_ptr<StunMessage> cached_stun_binding_;
  373. const IceFieldTrials* field_trials_;
  374. rtc::EventBasedExponentialMovingAverage rtt_estimate_;
  375. friend class Port;
  376. friend class ConnectionRequest;
  377. friend class P2PTransportChannel;
  378. };
  379. // ProxyConnection defers all the interesting work to the port.
  380. class ProxyConnection : public Connection {
  381. public:
  382. ProxyConnection(Port* port, size_t index, const Candidate& remote_candidate);
  383. int Send(const void* data,
  384. size_t size,
  385. const rtc::PacketOptions& options) override;
  386. int GetError() override;
  387. private:
  388. int error_ = 0;
  389. };
  390. } // namespace cricket
  391. #endif // P2P_BASE_CONNECTION_H_