Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 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 | |
| 11 | #ifndef P2P_BASE_CONNECTION_H_ |
| 12 | #define P2P_BASE_CONNECTION_H_ |
| 13 | |
Jonas Oreland | 9a52bd7 | 2019-12-11 10:35:48 | [diff] [blame] | 14 | #include <memory> |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 15 | #include <string> |
| 16 | #include <vector> |
| 17 | |
Tommi | 94ad387 | 2022-05-27 09:25:05 | [diff] [blame] | 18 | #include "absl/strings/string_view.h" |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 19 | #include "absl/types/optional.h" |
| 20 | #include "api/candidate.h" |
Patrik Höglund | 56d9452 | 2019-11-18 14:53:32 | [diff] [blame] | 21 | #include "api/transport/stun.h" |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 22 | #include "logging/rtc_event_log/ice_logger.h" |
| 23 | #include "p2p/base/candidate_pair_interface.h" |
| 24 | #include "p2p/base/connection_info.h" |
Jonas Oreland | bfcb6c3 | 2019-11-28 08:40:01 | [diff] [blame] | 25 | #include "p2p/base/p2p_transport_channel_ice_field_trials.h" |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 26 | #include "p2p/base/stun_request.h" |
| 27 | #include "p2p/base/transport_description.h" |
| 28 | #include "rtc_base/async_packet_socket.h" |
Jonas Oreland | 98e745b | 2019-11-27 10:02:45 | [diff] [blame] | 29 | #include "rtc_base/network.h" |
Jonas Oreland | bfcb6c3 | 2019-11-28 08:40:01 | [diff] [blame] | 30 | #include "rtc_base/numerics/event_based_exponential_moving_average.h" |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 31 | #include "rtc_base/rate_tracker.h" |
Tommi | d7e5cfb | 2022-03-30 18:13:06 | [diff] [blame] | 32 | #include "rtc_base/weak_ptr.h" |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 33 | |
| 34 | namespace cricket { |
| 35 | |
Jonas Oreland | 9a52bd7 | 2019-12-11 10:35:48 | [diff] [blame] | 36 | // Version number for GOOG_PING, this is added to have the option of |
| 37 | // adding other flavors in the future. |
| 38 | constexpr int kGoogPingVersion = 1; |
| 39 | |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 40 | // Connection and Port has circular dependencies. |
| 41 | // So we use forward declaration rather than include. |
| 42 | class Port; |
| 43 | |
| 44 | // Forward declaration so that a ConnectionRequest can contain a Connection. |
| 45 | class Connection; |
| 46 | |
Qingsi Wang | e5defb1 | 2019-08-15 18:01:53 | [diff] [blame] | 47 | struct CandidatePair final : public CandidatePairInterface { |
| 48 | ~CandidatePair() override = default; |
| 49 | |
| 50 | const Candidate& local_candidate() const override { return local; } |
| 51 | const Candidate& remote_candidate() const override { return remote; } |
| 52 | |
| 53 | Candidate local; |
| 54 | Candidate remote; |
| 55 | }; |
| 56 | |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 57 | // Represents a communication link between a port on the local client and a |
| 58 | // port on the remote client. |
Tommi | b44a794 | 2022-04-28 10:31:47 | [diff] [blame] | 59 | class Connection : public CandidatePairInterface { |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 60 | public: |
| 61 | struct SentPing { |
Ali Tofigh | de2ac5a | 2022-06-30 09:58:26 | [diff] [blame] | 62 | SentPing(absl::string_view id, int64_t sent_time, uint32_t nomination) |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 63 | : id(id), sent_time(sent_time), nomination(nomination) {} |
| 64 | |
| 65 | std::string id; |
| 66 | int64_t sent_time; |
| 67 | uint32_t nomination; |
| 68 | }; |
| 69 | |
| 70 | ~Connection() override; |
| 71 | |
| 72 | // A unique ID assigned when the connection is created. |
Jonas Oreland | e665500 | 2020-03-05 08:00:37 | [diff] [blame] | 73 | uint32_t id() const { return id_; } |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 74 | |
Tommi | cb01e5e | 2022-01-31 08:12:48 | [diff] [blame] | 75 | webrtc::TaskQueueBase* network_thread() const; |
| 76 | |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 77 | // Implementation of virtual methods in CandidatePairInterface. |
| 78 | // Returns the description of the local port |
| 79 | const Candidate& local_candidate() const override; |
| 80 | // Returns the description of the remote port to which we communicate. |
| 81 | const Candidate& remote_candidate() const override; |
| 82 | |
Jonas Oreland | 98e745b | 2019-11-27 10:02:45 | [diff] [blame] | 83 | // Return local network for this connection. |
| 84 | virtual const rtc::Network* network() const; |
| 85 | // Return generation for this connection. |
| 86 | virtual int generation() const; |
| 87 | |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 88 | // Returns the pair priority. |
Jonas Oreland | 98e745b | 2019-11-27 10:02:45 | [diff] [blame] | 89 | virtual uint64_t priority() const; |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 90 | |
| 91 | enum WriteState { |
| 92 | STATE_WRITABLE = 0, // we have received ping responses recently |
| 93 | STATE_WRITE_UNRELIABLE = 1, // we have had a few ping failures |
| 94 | STATE_WRITE_INIT = 2, // we have yet to receive a ping response |
| 95 | STATE_WRITE_TIMEOUT = 3, // we have had a large number of ping failures |
| 96 | }; |
| 97 | |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 98 | WriteState write_state() const; |
| 99 | bool writable() const; |
| 100 | bool receiving() const; |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 101 | |
Tommi | 2d13363 | 2022-05-27 13:55:09 | [diff] [blame] | 102 | const Port* port() const { |
| 103 | RTC_DCHECK_RUN_ON(network_thread_); |
| 104 | return port_.get(); |
| 105 | } |
| 106 | |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 107 | // Determines whether the connection has finished connecting. This can only |
| 108 | // be false for TCP connections. |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 109 | bool connected() const; |
| 110 | bool weak() const; |
| 111 | bool active() const; |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 112 | |
| 113 | // A connection is dead if it can be safely deleted. |
| 114 | bool dead(int64_t now) const; |
| 115 | |
| 116 | // Estimate of the round-trip time over this connection. |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 117 | int rtt() const; |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 118 | |
| 119 | int unwritable_timeout() const; |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 120 | void set_unwritable_timeout(const absl::optional<int>& value_ms); |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 121 | int unwritable_min_checks() const; |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 122 | void set_unwritable_min_checks(const absl::optional<int>& value); |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 123 | int inactive_timeout() const; |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 124 | void set_inactive_timeout(const absl::optional<int>& value); |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 125 | |
Artem Titov | 2dbb4c9 | 2021-07-26 13:12:41 | [diff] [blame] | 126 | // Gets the `ConnectionInfo` stats, where `best_connection` has not been |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 127 | // populated (default value false). |
| 128 | ConnectionInfo stats(); |
| 129 | |
| 130 | sigslot::signal1<Connection*> SignalStateChange; |
| 131 | |
| 132 | // Sent when the connection has decided that it is no longer of value. It |
| 133 | // will delete itself immediately after this call. |
| 134 | sigslot::signal1<Connection*> SignalDestroyed; |
| 135 | |
| 136 | // The connection can send and receive packets asynchronously. This matches |
| 137 | // the interface of AsyncPacketSocket, which may use UDP or TCP under the |
| 138 | // covers. |
| 139 | virtual int Send(const void* data, |
| 140 | size_t size, |
| 141 | const rtc::PacketOptions& options) = 0; |
| 142 | |
| 143 | // Error if Send() returns < 0 |
| 144 | virtual int GetError() = 0; |
| 145 | |
| 146 | sigslot::signal4<Connection*, const char*, size_t, int64_t> SignalReadPacket; |
| 147 | |
| 148 | sigslot::signal1<Connection*> SignalReadyToSend; |
| 149 | |
| 150 | // Called when a packet is received on this connection. |
| 151 | void OnReadPacket(const char* data, size_t size, int64_t packet_time_us); |
| 152 | |
| 153 | // Called when the socket is currently able to send. |
| 154 | void OnReadyToSend(); |
| 155 | |
| 156 | // Called when a connection is determined to be no longer useful to us. We |
| 157 | // still keep it around in case the other side wants to use it. But we can |
| 158 | // safely stop pinging on it and we can allow it to time out if the other |
| 159 | // side stops using it as well. |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 160 | bool pruned() const; |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 161 | void Prune(); |
| 162 | |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 163 | bool use_candidate_attr() const; |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 164 | void set_use_candidate_attr(bool enable); |
| 165 | |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 166 | void set_nomination(uint32_t value); |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 167 | |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 168 | uint32_t remote_nomination() const; |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 169 | // One or several pairs may be nominated based on if Regular or Aggressive |
| 170 | // Nomination is used. https://tools.ietf.org/html/rfc5245#section-8 |
Artem Titov | 2dbb4c9 | 2021-07-26 13:12:41 | [diff] [blame] | 171 | // `nominated` is defined both for the controlling or controlled agent based |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 172 | // on if a nomination has been pinged or acknowledged. The controlled agent |
Artem Titov | 2dbb4c9 | 2021-07-26 13:12:41 | [diff] [blame] | 173 | // gets its `remote_nomination_` set when pinged by the controlling agent with |
| 174 | // a nomination value. The controlling agent gets its `acked_nomination_` set |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 175 | // when receiving a response to a nominating ping. |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 176 | bool nominated() const; |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 177 | |
| 178 | int receiving_timeout() const; |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 179 | void set_receiving_timeout(absl::optional<int> receiving_timeout_ms); |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 180 | |
Tommi | 6fd77f3 | 2022-06-09 19:45:56 | [diff] [blame] | 181 | // Deletes a `Connection` instance is by calling the `DestroyConnection` |
| 182 | // method in `Port`. |
| 183 | // Note: When the function returns, the object has been deleted. |
Tomas Gunnarsson | 869c87a | 2022-05-02 19:08:43 | [diff] [blame] | 184 | void Destroy(); |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 185 | |
Tommi | 6fd77f3 | 2022-06-09 19:45:56 | [diff] [blame] | 186 | // Signals object destruction, releases outstanding references and performs |
| 187 | // final logging. |
| 188 | // The function will return `true` when shutdown was performed, signals |
| 189 | // emitted and outstanding references released. If the function returns |
| 190 | // `false`, `Shutdown()` has previously been called. |
| 191 | bool Shutdown(); |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 192 | |
| 193 | // Prunes the connection and sets its state to STATE_FAILED, |
| 194 | // It will not be used or send pings although it can still receive packets. |
| 195 | void FailAndPrune(); |
| 196 | |
| 197 | // Checks that the state of this connection is up-to-date. The argument is |
| 198 | // the current time, which is compared against various timeouts. |
| 199 | void UpdateState(int64_t now); |
| 200 | |
Tommi | 94ad387 | 2022-05-27 09:25:05 | [diff] [blame] | 201 | void UpdateLocalIceParameters(int component, |
| 202 | absl::string_view username_fragment, |
| 203 | absl::string_view password); |
| 204 | |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 205 | // Called when this connection should try checking writability again. |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 206 | int64_t last_ping_sent() const; |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 207 | void Ping(int64_t now); |
Qingsi Wang | 0894f0f | 2019-06-18 21:11:36 | [diff] [blame] | 208 | void ReceivedPingResponse( |
| 209 | int rtt, |
Tommi | e83500e | 2022-06-03 12:28:59 | [diff] [blame] | 210 | absl::string_view request_id, |
Qingsi Wang | 0894f0f | 2019-06-18 21:11:36 | [diff] [blame] | 211 | const absl::optional<uint32_t>& nomination = absl::nullopt); |
Tommi | e83500e | 2022-06-03 12:28:59 | [diff] [blame] | 212 | std::unique_ptr<IceMessage> BuildPingRequest() RTC_RUN_ON(network_thread_); |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 213 | |
| 214 | int64_t last_ping_response_received() const; |
| 215 | const absl::optional<std::string>& last_ping_id_received() const; |
| 216 | |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 217 | // Used to check if any STUN ping response has been received. |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 218 | int rtt_samples() const; |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 219 | |
| 220 | // Called whenever a valid ping is received on this connection. This is |
| 221 | // public because the connection intercepts the first ping for us. |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 222 | int64_t last_ping_received() const; |
| 223 | |
Qingsi Wang | 0894f0f | 2019-06-18 21:11:36 | [diff] [blame] | 224 | void ReceivedPing( |
| 225 | const absl::optional<std::string>& request_id = absl::nullopt); |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 226 | // Handles the binding request; sends a response if this is a valid request. |
Jonas Oreland | 9a52bd7 | 2019-12-11 10:35:48 | [diff] [blame] | 227 | void HandleStunBindingOrGoogPingRequest(IceMessage* msg); |
Qingsi Wang | 0894f0f | 2019-06-18 21:11:36 | [diff] [blame] | 228 | // Handles the piggyback acknowledgement of the lastest connectivity check |
| 229 | // that the remote peer has received, if it is indicated in the incoming |
| 230 | // connectivity check from the peer. |
| 231 | void HandlePiggybackCheckAcknowledgementIfAny(StunMessage* msg); |
Jonas Oreland | 3c5d582 | 2020-12-14 11:45:05 | [diff] [blame] | 232 | // Timestamp when data was last sent (or attempted to be sent). |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 233 | int64_t last_send_data() const; |
| 234 | int64_t last_data_received() const; |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 235 | |
| 236 | // Debugging description of this connection |
| 237 | std::string ToDebugId() const; |
| 238 | std::string ToString() const; |
| 239 | std::string ToSensitiveString() const; |
| 240 | // Structured description of this candidate pair. |
| 241 | const webrtc::IceCandidatePairDescription& ToLogDescription(); |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 242 | void set_ice_event_log(webrtc::IceEventLog* ice_event_log); |
| 243 | |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 244 | // Prints pings_since_last_response_ into a string. |
| 245 | void PrintPingsSinceLastResponse(std::string* pings, size_t max); |
| 246 | |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 247 | // `set_selected` is only used for logging in ToString above. The flag is |
| 248 | // set true by P2PTransportChannel for its selected candidate pair. |
| 249 | // TODO(tommi): Remove `selected()` once not referenced downstream. |
| 250 | bool selected() const; |
| 251 | void set_selected(bool selected); |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 252 | |
| 253 | // This signal will be fired if this connection is nominated by the |
| 254 | // controlling side. |
| 255 | sigslot::signal1<Connection*> SignalNominated; |
| 256 | |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 257 | IceCandidatePairState state() const; |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 258 | |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 259 | int num_pings_sent() const; |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 260 | |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 261 | uint32_t ComputeNetworkCost() const; |
| 262 | |
| 263 | // Update the ICE password and/or generation of the remote candidate if the |
Artem Titov | 2dbb4c9 | 2021-07-26 13:12:41 | [diff] [blame] | 264 | // ufrag in `params` matches the candidate's ufrag, and the |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 265 | // candidate's password and/or ufrag has not been set. |
| 266 | void MaybeSetRemoteIceParametersAndGeneration(const IceParameters& params, |
| 267 | int generation); |
| 268 | |
Artem Titov | 2dbb4c9 | 2021-07-26 13:12:41 | [diff] [blame] | 269 | // If `remote_candidate_` is peer reflexive and is equivalent to |
| 270 | // `new_candidate` except the type, update `remote_candidate_` to |
| 271 | // `new_candidate`. |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 272 | void MaybeUpdatePeerReflexiveCandidate(const Candidate& new_candidate); |
| 273 | |
| 274 | // Returns the last received time of any data, stun request, or stun |
| 275 | // response in milliseconds |
| 276 | int64_t last_received() const; |
| 277 | // Returns the last time when the connection changed its receiving state. |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 278 | int64_t receiving_unchanged_since() const; |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 279 | |
Tommi | e83500e | 2022-06-03 12:28:59 | [diff] [blame] | 280 | // Constructs the prflx priority as described in |
| 281 | // https://datatracker.ietf.org/doc/html/rfc5245#section-4.1.2.1 |
| 282 | uint32_t prflx_priority() const; |
| 283 | |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 284 | bool stable(int64_t now) const; |
| 285 | |
Artem Titov | 2dbb4c9 | 2021-07-26 13:12:41 | [diff] [blame] | 286 | // Check if we sent `val` pings without receving a response. |
Jonas Oreland | c6404a1 | 2019-10-14 13:52:15 | [diff] [blame] | 287 | bool TooManyOutstandingPings(const absl::optional<int>& val) const; |
| 288 | |
Tommi | 94ad387 | 2022-05-27 09:25:05 | [diff] [blame] | 289 | // Called by Port when the network cost changes. |
| 290 | void SetLocalCandidateNetworkCost(uint16_t cost); |
| 291 | |
Jonas Oreland | d003662 | 2019-11-29 14:58:13 | [diff] [blame] | 292 | void SetIceFieldTrials(const IceFieldTrials* field_trials); |
| 293 | const rtc::EventBasedExponentialMovingAverage& GetRttEstimate() const { |
| 294 | return rtt_estimate_; |
| 295 | } |
| 296 | |
Jonas Oreland | ef60c2b | 2020-03-26 14:10:39 | [diff] [blame] | 297 | // Reset the connection to a state of a newly connected. |
| 298 | // - STATE_WRITE_INIT |
| 299 | // - receving = false |
| 300 | // - throw away all pending request |
| 301 | // - reset RttEstimate |
| 302 | // |
| 303 | // Keep the following unchanged: |
| 304 | // - connected |
| 305 | // - remote_candidate |
| 306 | // - statistics |
| 307 | // |
| 308 | // Does not trigger SignalStateChange |
| 309 | void ForgetLearnedState(); |
| 310 | |
Tommi | 278b19d | 2022-04-12 12:03:40 | [diff] [blame] | 311 | void SendStunBindingResponse(const StunMessage* message); |
| 312 | void SendGoogPingResponse(const StunMessage* message); |
Jonas Oreland | 9a52bd7 | 2019-12-11 10:35:48 | [diff] [blame] | 313 | void SendResponseMessage(const StunMessage& response); |
Jonas Oreland | d003662 | 2019-11-29 14:58:13 | [diff] [blame] | 314 | |
Jonas Oreland | 98e745b | 2019-11-27 10:02:45 | [diff] [blame] | 315 | // An accessor for unit tests. |
Tommi | d7e5cfb | 2022-03-30 18:13:06 | [diff] [blame] | 316 | Port* PortForTest() { return port_.get(); } |
| 317 | const Port* PortForTest() const { return port_.get(); } |
Jonas Oreland | 98e745b | 2019-11-27 10:02:45 | [diff] [blame] | 318 | |
Jonas Oreland | d003662 | 2019-11-29 14:58:13 | [diff] [blame] | 319 | // Public for unit tests. |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 320 | uint32_t acked_nomination() const; |
| 321 | void set_remote_nomination(uint32_t remote_nomination); |
Jonas Oreland | bfcb6c3 | 2019-11-28 08:40:01 | [diff] [blame] | 322 | |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 323 | protected: |
Tommi | c85e473 | 2022-05-27 14:37:42 | [diff] [blame] | 324 | // A ConnectionRequest is a simple STUN ping used to determine writability. |
| 325 | class ConnectionRequest; |
| 326 | |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 327 | // Constructs a new connection to the given remote port. |
Tommi | d7e5cfb | 2022-03-30 18:13:06 | [diff] [blame] | 328 | Connection(rtc::WeakPtr<Port> port, size_t index, const Candidate& candidate); |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 329 | |
| 330 | // Called back when StunRequestManager has a stun packet to send |
| 331 | void OnSendStunPacket(const void* data, size_t size, StunRequest* req); |
| 332 | |
| 333 | // Callbacks from ConnectionRequest |
Tommi | c85e473 | 2022-05-27 14:37:42 | [diff] [blame] | 334 | virtual void OnConnectionRequestResponse(StunRequest* req, |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 335 | StunMessage* response); |
| 336 | void OnConnectionRequestErrorResponse(ConnectionRequest* req, |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 337 | StunMessage* response) |
| 338 | RTC_RUN_ON(network_thread_); |
| 339 | void OnConnectionRequestTimeout(ConnectionRequest* req) |
| 340 | RTC_RUN_ON(network_thread_); |
| 341 | void OnConnectionRequestSent(ConnectionRequest* req) |
| 342 | RTC_RUN_ON(network_thread_); |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 343 | |
| 344 | bool rtt_converged() const; |
| 345 | |
| 346 | // If the response is not received within 2 * RTT, the response is assumed to |
| 347 | // be missing. |
| 348 | bool missing_responses(int64_t now) const; |
| 349 | |
| 350 | // Changes the state and signals if necessary. |
| 351 | void set_write_state(WriteState value); |
| 352 | void UpdateReceiving(int64_t now); |
| 353 | void set_state(IceCandidatePairState state); |
| 354 | void set_connected(bool value); |
| 355 | |
Jonas Oreland | 98e745b | 2019-11-27 10:02:45 | [diff] [blame] | 356 | // The local port where this connection sends and receives packets. |
Tommi | d7e5cfb | 2022-03-30 18:13:06 | [diff] [blame] | 357 | Port* port() { return port_.get(); } |
Jonas Oreland | 98e745b | 2019-11-27 10:02:45 | [diff] [blame] | 358 | |
Tommi | cb01e5e | 2022-01-31 08:12:48 | [diff] [blame] | 359 | // NOTE: A pointer to the network thread is held by `port_` so in theory we |
| 360 | // shouldn't need to hold on to this pointer here, but rather defer to |
| 361 | // port_->thread(). However, some tests delete the classes in the wrong order |
| 362 | // so `port_` may be deleted before an instance of this class is deleted. |
| 363 | // TODO(tommi): This ^^^ should be fixed. |
| 364 | webrtc::TaskQueueBase* const network_thread_; |
| 365 | const uint32_t id_; |
Tommi | d7e5cfb | 2022-03-30 18:13:06 | [diff] [blame] | 366 | rtc::WeakPtr<Port> port_; |
Tommi | 94ad387 | 2022-05-27 09:25:05 | [diff] [blame] | 367 | Candidate local_candidate_ RTC_GUARDED_BY(network_thread_); |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 368 | Candidate remote_candidate_; |
| 369 | |
| 370 | ConnectionInfo stats_; |
| 371 | rtc::RateTracker recv_rate_tracker_; |
| 372 | rtc::RateTracker send_rate_tracker_; |
Jonas Oreland | 3c5d582 | 2020-12-14 11:45:05 | [diff] [blame] | 373 | int64_t last_send_data_ = 0; |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 374 | |
| 375 | private: |
| 376 | // Update the local candidate based on the mapped address attribute. |
| 377 | // If the local candidate changed, fires SignalStateChange. |
Tommi | c85e473 | 2022-05-27 14:37:42 | [diff] [blame] | 378 | void MaybeUpdateLocalCandidate(StunRequest* request, StunMessage* response) |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 379 | RTC_RUN_ON(network_thread_); |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 380 | |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 381 | void LogCandidatePairConfig(webrtc::IceCandidatePairConfigType type) |
| 382 | RTC_RUN_ON(network_thread_); |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 383 | void LogCandidatePairEvent(webrtc::IceCandidatePairEventType type, |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 384 | uint32_t transaction_id) |
| 385 | RTC_RUN_ON(network_thread_); |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 386 | |
Jonas Oreland | 9a52bd7 | 2019-12-11 10:35:48 | [diff] [blame] | 387 | // Check if this IceMessage is identical |
| 388 | // to last message ack:ed STUN_BINDING_REQUEST. |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 389 | bool ShouldSendGoogPing(const StunMessage* message) |
| 390 | RTC_RUN_ON(network_thread_); |
Jonas Oreland | 9a52bd7 | 2019-12-11 10:35:48 | [diff] [blame] | 391 | |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 392 | WriteState write_state_ RTC_GUARDED_BY(network_thread_); |
| 393 | bool receiving_ RTC_GUARDED_BY(network_thread_); |
| 394 | bool connected_ RTC_GUARDED_BY(network_thread_); |
| 395 | bool pruned_ RTC_GUARDED_BY(network_thread_); |
| 396 | bool selected_ RTC_GUARDED_BY(network_thread_) = false; |
Artem Titov | 2dbb4c9 | 2021-07-26 13:12:41 | [diff] [blame] | 397 | // By default `use_candidate_attr_` flag will be true, |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 398 | // as we will be using aggressive nomination. |
| 399 | // But when peer is ice-lite, this flag "must" be initialized to false and |
| 400 | // turn on when connection becomes "best connection". |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 401 | bool use_candidate_attr_ RTC_GUARDED_BY(network_thread_); |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 402 | // Used by the controlling side to indicate that this connection will be |
| 403 | // selected for transmission if the peer supports ICE-renomination when this |
| 404 | // value is positive. A larger-value indicates that a connection is nominated |
| 405 | // later and should be selected by the controlled side with higher precedence. |
| 406 | // A zero-value indicates not nominating this connection. |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 407 | uint32_t nomination_ RTC_GUARDED_BY(network_thread_) = 0; |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 408 | // The last nomination that has been acknowledged. |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 409 | uint32_t acked_nomination_ RTC_GUARDED_BY(network_thread_) = 0; |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 410 | // Used by the controlled side to remember the nomination value received from |
Qingsi Wang | 0894f0f | 2019-06-18 21:11:36 | [diff] [blame] | 411 | // the controlling side. When the peer does not support ICE re-nomination, its |
| 412 | // value will be 1 if the connection has been nominated. |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 413 | uint32_t remote_nomination_ RTC_GUARDED_BY(network_thread_) = 0; |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 414 | |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 415 | StunRequestManager requests_ RTC_GUARDED_BY(network_thread_); |
| 416 | int rtt_ RTC_GUARDED_BY(network_thread_); |
| 417 | int rtt_samples_ RTC_GUARDED_BY(network_thread_) = 0; |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 418 | // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-totalroundtriptime |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 419 | uint64_t total_round_trip_time_ms_ RTC_GUARDED_BY(network_thread_) = 0; |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 420 | // https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatepairstats-currentroundtriptime |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 421 | absl::optional<uint32_t> current_round_trip_time_ms_ |
| 422 | RTC_GUARDED_BY(network_thread_); |
| 423 | int64_t last_ping_sent_ RTC_GUARDED_BY( |
| 424 | network_thread_); // last time we sent a ping to the other side |
| 425 | int64_t last_ping_received_ |
| 426 | RTC_GUARDED_BY(network_thread_); // last time we received a ping from the |
| 427 | // other side |
| 428 | int64_t last_data_received_ RTC_GUARDED_BY(network_thread_); |
| 429 | int64_t last_ping_response_received_ RTC_GUARDED_BY(network_thread_); |
| 430 | int64_t receiving_unchanged_since_ RTC_GUARDED_BY(network_thread_) = 0; |
| 431 | std::vector<SentPing> pings_since_last_response_ |
| 432 | RTC_GUARDED_BY(network_thread_); |
Qingsi Wang | 0894f0f | 2019-06-18 21:11:36 | [diff] [blame] | 433 | // Transaction ID of the last connectivity check received. Null if having not |
| 434 | // received a ping yet. |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 435 | absl::optional<std::string> last_ping_id_received_ |
| 436 | RTC_GUARDED_BY(network_thread_); |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 437 | |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 438 | absl::optional<int> unwritable_timeout_ RTC_GUARDED_BY(network_thread_); |
| 439 | absl::optional<int> unwritable_min_checks_ RTC_GUARDED_BY(network_thread_); |
| 440 | absl::optional<int> inactive_timeout_ RTC_GUARDED_BY(network_thread_); |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 441 | |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 442 | IceCandidatePairState state_ RTC_GUARDED_BY(network_thread_); |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 443 | // Time duration to switch from receiving to not receiving. |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 444 | absl::optional<int> receiving_timeout_ RTC_GUARDED_BY(network_thread_); |
| 445 | int64_t time_created_ms_ RTC_GUARDED_BY(network_thread_); |
| 446 | int num_pings_sent_ RTC_GUARDED_BY(network_thread_) = 0; |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 447 | |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 448 | absl::optional<webrtc::IceCandidatePairDescription> log_description_ |
| 449 | RTC_GUARDED_BY(network_thread_); |
| 450 | webrtc::IceEventLog* ice_event_log_ RTC_GUARDED_BY(network_thread_) = nullptr; |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 451 | |
Jonas Oreland | 9a52bd7 | 2019-12-11 10:35:48 | [diff] [blame] | 452 | // GOOG_PING_REQUEST is sent in place of STUN_BINDING_REQUEST |
| 453 | // if configured via field trial, the remote peer supports it (signaled |
| 454 | // in STUN_BINDING) and if the last STUN BINDING is identical to the one |
| 455 | // that is about to be sent. |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 456 | absl::optional<bool> remote_support_goog_ping_ |
| 457 | RTC_GUARDED_BY(network_thread_); |
| 458 | std::unique_ptr<StunMessage> cached_stun_binding_ |
| 459 | RTC_GUARDED_BY(network_thread_); |
Jonas Oreland | 9a52bd7 | 2019-12-11 10:35:48 | [diff] [blame] | 460 | |
Jonas Oreland | bfcb6c3 | 2019-11-28 08:40:01 | [diff] [blame] | 461 | const IceFieldTrials* field_trials_; |
Tommi | 9897649 | 2022-01-31 10:19:11 | [diff] [blame] | 462 | rtc::EventBasedExponentialMovingAverage rtt_estimate_ |
| 463 | RTC_GUARDED_BY(network_thread_); |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 464 | }; |
| 465 | |
| 466 | // ProxyConnection defers all the interesting work to the port. |
| 467 | class ProxyConnection : public Connection { |
| 468 | public: |
Tommi | d7e5cfb | 2022-03-30 18:13:06 | [diff] [blame] | 469 | ProxyConnection(rtc::WeakPtr<Port> port, |
| 470 | size_t index, |
| 471 | const Candidate& remote_candidate); |
| 472 | |
Jonas Oreland | e8e7d7b | 2019-05-29 07:30:55 | [diff] [blame] | 473 | int Send(const void* data, |
| 474 | size_t size, |
| 475 | const rtc::PacketOptions& options) override; |
| 476 | int GetError() override; |
| 477 | |
| 478 | private: |
| 479 | int error_ = 0; |
| 480 | }; |
| 481 | |
| 482 | } // namespace cricket |
| 483 | |
| 484 | #endif // P2P_BASE_CONNECTION_H_ |