1 /* 2 * Copyright 2004 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 // P2PTransportChannel wraps up the state management of the connection between 12 // two P2P clients. Clients have candidate ports for connecting, and 13 // connections which are combinations of candidates from each end (Alice and 14 // Bob each have candidates, one candidate from Alice and one candidate from 15 // Bob are used to make a connection, repeat to make many connections). 16 // 17 // When all of the available connections become invalid (non-writable), we 18 // kick off a process of determining more candidates and more connections. 19 // 20 #ifndef P2P_BASE_P2P_TRANSPORT_CHANNEL_H_ 21 #define P2P_BASE_P2P_TRANSPORT_CHANNEL_H_ 22 23 #include <algorithm> 24 #include <map> 25 #include <memory> 26 #include <set> 27 #include <string> 28 #include <vector> 29 30 #include "api/async_resolver_factory.h" 31 #include "api/candidate.h" 32 #include "api/rtc_error.h" 33 #include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h" 34 #include "logging/rtc_event_log/ice_logger.h" 35 #include "p2p/base/candidate_pair_interface.h" 36 #include "p2p/base/ice_controller_factory_interface.h" 37 #include "p2p/base/ice_controller_interface.h" 38 #include "p2p/base/ice_transport_internal.h" 39 #include "p2p/base/p2p_constants.h" 40 #include "p2p/base/p2p_transport_channel_ice_field_trials.h" 41 #include "p2p/base/port_allocator.h" 42 #include "p2p/base/port_interface.h" 43 #include "p2p/base/regathering_controller.h" 44 #include "rtc_base/async_invoker.h" 45 #include "rtc_base/async_packet_socket.h" 46 #include "rtc_base/constructor_magic.h" 47 #include "rtc_base/strings/string_builder.h" 48 #include "rtc_base/system/rtc_export.h" 49 #include "rtc_base/third_party/sigslot/sigslot.h" 50 #include "rtc_base/thread_annotations.h" 51 52 namespace webrtc { 53 class RtcEventLog; 54 } // namespace webrtc 55 56 namespace cricket { 57 58 // Enum for UMA metrics, used to record whether the channel is 59 // connected/connecting/disconnected when ICE restart happens. 60 enum class IceRestartState { CONNECTING, CONNECTED, DISCONNECTED, MAX_VALUE }; 61 62 static const int MIN_PINGS_AT_WEAK_PING_INTERVAL = 3; 63 64 bool IceCredentialsChanged(const std::string& old_ufrag, 65 const std::string& old_pwd, 66 const std::string& new_ufrag, 67 const std::string& new_pwd); 68 69 // Adds the port on which the candidate originated. 70 class RemoteCandidate : public Candidate { 71 public: RemoteCandidate(const Candidate & c,PortInterface * origin_port)72 RemoteCandidate(const Candidate& c, PortInterface* origin_port) 73 : Candidate(c), origin_port_(origin_port) {} 74 origin_port()75 PortInterface* origin_port() { return origin_port_; } 76 77 private: 78 PortInterface* origin_port_; 79 }; 80 81 // P2PTransportChannel manages the candidates and connection process to keep 82 // two P2P clients connected to each other. 83 class RTC_EXPORT P2PTransportChannel : public IceTransportInternal { 84 public: 85 // For testing only. 86 // TODO(zstein): Remove once AsyncResolverFactory is required. 87 P2PTransportChannel(const std::string& transport_name, 88 int component, 89 PortAllocator* allocator); 90 P2PTransportChannel( 91 const std::string& transport_name, 92 int component, 93 PortAllocator* allocator, 94 webrtc::AsyncResolverFactory* async_resolver_factory, 95 webrtc::RtcEventLog* event_log = nullptr, 96 IceControllerFactoryInterface* ice_controller_factory = nullptr); 97 ~P2PTransportChannel() override; 98 99 // From TransportChannelImpl: 100 IceTransportState GetState() const override; 101 webrtc::IceTransportState GetIceTransportState() const override; 102 103 const std::string& transport_name() const override; 104 int component() const override; 105 bool writable() const override; 106 bool receiving() const override; 107 void SetIceRole(IceRole role) override; 108 IceRole GetIceRole() const override; 109 void SetIceTiebreaker(uint64_t tiebreaker) override; 110 void SetIceParameters(const IceParameters& ice_params) override; 111 void SetRemoteIceParameters(const IceParameters& ice_params) override; 112 void SetRemoteIceMode(IceMode mode) override; 113 // TODO(deadbeef): Deprecated. Remove when Chromium's 114 // IceTransportChannel does not depend on this. Connect()115 void Connect() {} 116 void MaybeStartGathering() override; 117 IceGatheringState gathering_state() const override; 118 void ResolveHostnameCandidate(const Candidate& candidate); 119 void AddRemoteCandidate(const Candidate& candidate) override; 120 void RemoveRemoteCandidate(const Candidate& candidate) override; 121 void RemoveAllRemoteCandidates() override; 122 // Sets the parameters in IceConfig. We do not set them blindly. Instead, we 123 // only update the parameter if it is considered set in |config|. For example, 124 // a negative value of receiving_timeout will be considered "not set" and we 125 // will not use it to update the respective parameter in |config_|. 126 // TODO(deadbeef): Use absl::optional instead of negative values. 127 void SetIceConfig(const IceConfig& config) override; 128 const IceConfig& config() const; 129 static webrtc::RTCError ValidateIceConfig(const IceConfig& config); 130 131 // From TransportChannel: 132 int SendPacket(const char* data, 133 size_t len, 134 const rtc::PacketOptions& options, 135 int flags) override; 136 int SetOption(rtc::Socket::Option opt, int value) override; 137 bool GetOption(rtc::Socket::Option opt, int* value) override; 138 int GetError() override; 139 bool GetStats(IceTransportStats* ice_transport_stats) override; 140 absl::optional<int> GetRttEstimate() override; 141 const Connection* selected_connection() const override; 142 absl::optional<const CandidatePair> GetSelectedCandidatePair() const override; 143 144 // TODO(honghaiz): Remove this method once the reference of it in 145 // Chromoting is removed. best_connection()146 const Connection* best_connection() const { 147 RTC_DCHECK_RUN_ON(network_thread_); 148 return selected_connection_; 149 } 150 set_incoming_only(bool value)151 void set_incoming_only(bool value) { 152 RTC_DCHECK_RUN_ON(network_thread_); 153 incoming_only_ = value; 154 } 155 156 // Note: These are only for testing purpose. 157 // |ports_| and |pruned_ports| should not be changed from outside. ports()158 const std::vector<PortInterface*>& ports() { 159 RTC_DCHECK_RUN_ON(network_thread_); 160 return ports_; 161 } pruned_ports()162 const std::vector<PortInterface*>& pruned_ports() { 163 RTC_DCHECK_RUN_ON(network_thread_); 164 return pruned_ports_; 165 } 166 remote_ice_mode()167 IceMode remote_ice_mode() const { 168 RTC_DCHECK_RUN_ON(network_thread_); 169 return remote_ice_mode_; 170 } 171 172 void PruneAllPorts(); 173 int check_receiving_interval() const; 174 absl::optional<rtc::NetworkRoute> network_route() const override; 175 176 // Helper method used only in unittest. 177 rtc::DiffServCodePoint DefaultDscpValue() const; 178 179 // Public for unit tests. 180 Connection* FindNextPingableConnection(); 181 void MarkConnectionPinged(Connection* conn); 182 183 // Public for unit tests. 184 rtc::ArrayView<Connection*> connections() const; 185 186 // Public for unit tests. allocator_session()187 PortAllocatorSession* allocator_session() const { 188 RTC_DCHECK_RUN_ON(network_thread_); 189 if (allocator_sessions_.empty()) { 190 return nullptr; 191 } 192 return allocator_sessions_.back().get(); 193 } 194 195 // Public for unit tests. remote_candidates()196 const std::vector<RemoteCandidate>& remote_candidates() const { 197 RTC_DCHECK_RUN_ON(network_thread_); 198 return remote_candidates_; 199 } 200 ToString()201 std::string ToString() const { 202 RTC_DCHECK_RUN_ON(network_thread_); 203 const std::string RECEIVING_ABBREV[2] = {"_", "R"}; 204 const std::string WRITABLE_ABBREV[2] = {"_", "W"}; 205 rtc::StringBuilder ss; 206 ss << "Channel[" << transport_name_ << "|" << component_ << "|" 207 << RECEIVING_ABBREV[receiving_] << WRITABLE_ABBREV[writable_] << "]"; 208 return ss.Release(); 209 } 210 211 private: thread()212 rtc::Thread* thread() const { return network_thread_; } 213 IsGettingPorts()214 bool IsGettingPorts() { 215 RTC_DCHECK_RUN_ON(network_thread_); 216 return allocator_session()->IsGettingPorts(); 217 } 218 219 // Returns true if it's possible to send packets on |connection|. 220 bool ReadyToSend(Connection* connection) const; 221 bool PresumedWritable(const Connection* conn) const; 222 void UpdateConnectionStates(); 223 void RequestSortAndStateUpdate(IceControllerEvent reason_to_sort); 224 // Start pinging if we haven't already started, and we now have a connection 225 // that's pingable. 226 void MaybeStartPinging(); 227 228 void SortConnectionsAndUpdateState(IceControllerEvent reason_to_sort); 229 void SortConnections(); 230 void SortConnectionsIfNeeded(); 231 void SwitchSelectedConnection(Connection* conn, IceControllerEvent reason); 232 void UpdateState(); 233 void HandleAllTimedOut(); 234 void MaybeStopPortAllocatorSessions(); 235 236 // ComputeIceTransportState computes the RTCIceTransportState as described in 237 // https://w3c.github.io/webrtc-pc/#dom-rtcicetransportstate. ComputeState 238 // computes the value we currently export as RTCIceTransportState. 239 // TODO(bugs.webrtc.org/9308): Remove ComputeState once it's no longer used. 240 IceTransportState ComputeState() const; 241 webrtc::IceTransportState ComputeIceTransportState() const; 242 243 bool CreateConnections(const Candidate& remote_candidate, 244 PortInterface* origin_port); 245 bool CreateConnection(PortInterface* port, 246 const Candidate& remote_candidate, 247 PortInterface* origin_port); 248 bool FindConnection(const Connection* connection) const; 249 250 uint32_t GetRemoteCandidateGeneration(const Candidate& candidate); 251 bool IsDuplicateRemoteCandidate(const Candidate& candidate); 252 void RememberRemoteCandidate(const Candidate& remote_candidate, 253 PortInterface* origin_port); 254 void PingConnection(Connection* conn); 255 void AddAllocatorSession(std::unique_ptr<PortAllocatorSession> session); 256 void AddConnection(Connection* connection); 257 258 void OnPortReady(PortAllocatorSession* session, PortInterface* port); 259 void OnPortsPruned(PortAllocatorSession* session, 260 const std::vector<PortInterface*>& ports); 261 void OnCandidatesReady(PortAllocatorSession* session, 262 const std::vector<Candidate>& candidates); 263 void OnCandidateError(PortAllocatorSession* session, 264 const IceCandidateErrorEvent& event); 265 void OnCandidatesRemoved(PortAllocatorSession* session, 266 const std::vector<Candidate>& candidates); 267 void OnCandidatesAllocationDone(PortAllocatorSession* session); 268 void OnUnknownAddress(PortInterface* port, 269 const rtc::SocketAddress& addr, 270 ProtocolType proto, 271 IceMessage* stun_msg, 272 const std::string& remote_username, 273 bool port_muxed); 274 void OnCandidateFilterChanged(uint32_t prev_filter, uint32_t cur_filter); 275 276 // When a port is destroyed, remove it from both lists |ports_| 277 // and |pruned_ports_|. 278 void OnPortDestroyed(PortInterface* port); 279 // When pruning a port, move it from |ports_| to |pruned_ports_|. 280 // Returns true if the port is found and removed from |ports_|. 281 bool PrunePort(PortInterface* port); 282 void OnRoleConflict(PortInterface* port); 283 284 void OnConnectionStateChange(Connection* connection); 285 void OnReadPacket(Connection* connection, 286 const char* data, 287 size_t len, 288 int64_t packet_time_us); 289 void OnSentPacket(const rtc::SentPacket& sent_packet); 290 void OnReadyToSend(Connection* connection); 291 void OnConnectionDestroyed(Connection* connection); 292 293 void OnNominated(Connection* conn); 294 295 void CheckAndPing(); 296 297 void LogCandidatePairConfig(Connection* conn, 298 webrtc::IceCandidatePairConfigType type); 299 300 uint32_t GetNominationAttr(Connection* conn) const; 301 bool GetUseCandidateAttr(Connection* conn) const; 302 303 // Returns true if the new_connection is selected for transmission. 304 bool MaybeSwitchSelectedConnection(Connection* new_connection, 305 IceControllerEvent reason); 306 bool MaybeSwitchSelectedConnection( 307 IceControllerEvent reason, 308 IceControllerInterface::SwitchResult result); 309 void PruneConnections(); 310 311 // Returns the latest remote ICE parameters or nullptr if there are no remote 312 // ICE parameters yet. remote_ice()313 IceParameters* remote_ice() { 314 RTC_DCHECK_RUN_ON(network_thread_); 315 return remote_ice_parameters_.empty() ? nullptr 316 : &remote_ice_parameters_.back(); 317 } 318 // Returns the remote IceParameters and generation that match |ufrag| 319 // if found, and returns nullptr otherwise. 320 const IceParameters* FindRemoteIceFromUfrag(const std::string& ufrag, 321 uint32_t* generation); 322 // Returns the index of the latest remote ICE parameters, or 0 if no remote 323 // ICE parameters have been received. remote_ice_generation()324 uint32_t remote_ice_generation() { 325 RTC_DCHECK_RUN_ON(network_thread_); 326 return remote_ice_parameters_.empty() 327 ? 0 328 : static_cast<uint32_t>(remote_ice_parameters_.size() - 1); 329 } 330 331 // Indicates if the given local port has been pruned. 332 bool IsPortPruned(const Port* port) const; 333 334 // Indicates if the given remote candidate has been pruned. 335 bool IsRemoteCandidatePruned(const Candidate& cand) const; 336 337 // Sets the writable state, signaling if necessary. 338 void SetWritable(bool writable); 339 // Sets the receiving state, signaling if necessary. 340 void SetReceiving(bool receiving); 341 // Clears the address and the related address fields of a local candidate to 342 // avoid IP leakage. This is applicable in several scenarios as commented in 343 // |PortAllocator::SanitizeCandidate|. 344 Candidate SanitizeLocalCandidate(const Candidate& c) const; 345 // Clears the address field of a remote candidate to avoid IP leakage. This is 346 // applicable in the following scenarios: 347 // 1. mDNS candidates are received. 348 // 2. Peer-reflexive remote candidates. 349 Candidate SanitizeRemoteCandidate(const Candidate& c) const; 350 351 // Cast a Connection returned from IceController and verify that it exists. 352 // (P2P owns all Connections, and only gives const pointers to IceController, 353 // see IceControllerInterface). FromIceController(const Connection * conn)354 Connection* FromIceController(const Connection* conn) { 355 // Verify that IceController does not return a connection 356 // that we have destroyed. 357 RTC_DCHECK(FindConnection(conn)); 358 return const_cast<Connection*>(conn); 359 } 360 361 std::string transport_name_ RTC_GUARDED_BY(network_thread_); 362 int component_ RTC_GUARDED_BY(network_thread_); 363 PortAllocator* allocator_ RTC_GUARDED_BY(network_thread_); 364 webrtc::AsyncResolverFactory* async_resolver_factory_ 365 RTC_GUARDED_BY(network_thread_); 366 rtc::Thread* network_thread_; 367 bool incoming_only_ RTC_GUARDED_BY(network_thread_); 368 int error_ RTC_GUARDED_BY(network_thread_); 369 std::vector<std::unique_ptr<PortAllocatorSession>> allocator_sessions_ 370 RTC_GUARDED_BY(network_thread_); 371 // |ports_| contains ports that are used to form new connections when 372 // new remote candidates are added. 373 std::vector<PortInterface*> ports_ RTC_GUARDED_BY(network_thread_); 374 // |pruned_ports_| contains ports that have been removed from |ports_| and 375 // are not being used to form new connections, but that aren't yet destroyed. 376 // They may have existing connections, and they still fire signals such as 377 // SignalUnknownAddress. 378 std::vector<PortInterface*> pruned_ports_ RTC_GUARDED_BY(network_thread_); 379 380 Connection* selected_connection_ RTC_GUARDED_BY(network_thread_) = nullptr; 381 382 std::vector<RemoteCandidate> remote_candidates_ 383 RTC_GUARDED_BY(network_thread_); 384 bool sort_dirty_ RTC_GUARDED_BY( 385 network_thread_); // indicates whether another sort is needed right now 386 bool had_connection_ RTC_GUARDED_BY(network_thread_) = 387 false; // if connections_ has ever been nonempty 388 typedef std::map<rtc::Socket::Option, int> OptionMap; 389 OptionMap options_ RTC_GUARDED_BY(network_thread_); 390 IceParameters ice_parameters_ RTC_GUARDED_BY(network_thread_); 391 std::vector<IceParameters> remote_ice_parameters_ 392 RTC_GUARDED_BY(network_thread_); 393 IceMode remote_ice_mode_ RTC_GUARDED_BY(network_thread_); 394 IceRole ice_role_ RTC_GUARDED_BY(network_thread_); 395 uint64_t tiebreaker_ RTC_GUARDED_BY(network_thread_); 396 IceGatheringState gathering_state_ RTC_GUARDED_BY(network_thread_); 397 std::unique_ptr<webrtc::BasicRegatheringController> regathering_controller_ 398 RTC_GUARDED_BY(network_thread_); 399 int64_t last_ping_sent_ms_ RTC_GUARDED_BY(network_thread_) = 0; 400 int weak_ping_interval_ RTC_GUARDED_BY(network_thread_) = WEAK_PING_INTERVAL; 401 // TODO(jonasolsson): Remove state_ and rename standardized_state_ once state_ 402 // is no longer used to compute the ICE connection state. 403 IceTransportState state_ RTC_GUARDED_BY(network_thread_) = 404 IceTransportState::STATE_INIT; 405 webrtc::IceTransportState standardized_state_ 406 RTC_GUARDED_BY(network_thread_) = webrtc::IceTransportState::kNew; 407 IceConfig config_ RTC_GUARDED_BY(network_thread_); 408 int last_sent_packet_id_ RTC_GUARDED_BY(network_thread_) = 409 -1; // -1 indicates no packet was sent before. 410 bool started_pinging_ RTC_GUARDED_BY(network_thread_) = false; 411 // The value put in the "nomination" attribute for the next nominated 412 // connection. A zero-value indicates the connection will not be nominated. 413 uint32_t nomination_ RTC_GUARDED_BY(network_thread_) = 0; 414 bool receiving_ RTC_GUARDED_BY(network_thread_) = false; 415 bool writable_ RTC_GUARDED_BY(network_thread_) = false; 416 bool has_been_writable_ RTC_GUARDED_BY(network_thread_) = 417 false; // if writable_ has ever been true 418 419 rtc::AsyncInvoker invoker_ RTC_GUARDED_BY(network_thread_); 420 absl::optional<rtc::NetworkRoute> network_route_ 421 RTC_GUARDED_BY(network_thread_); 422 webrtc::IceEventLog ice_event_log_ RTC_GUARDED_BY(network_thread_); 423 424 std::unique_ptr<IceControllerInterface> ice_controller_ 425 RTC_GUARDED_BY(network_thread_); 426 427 struct CandidateAndResolver final { 428 CandidateAndResolver(const Candidate& candidate, 429 rtc::AsyncResolverInterface* resolver); 430 ~CandidateAndResolver(); 431 Candidate candidate_; 432 rtc::AsyncResolverInterface* resolver_; 433 }; 434 std::vector<CandidateAndResolver> resolvers_ RTC_GUARDED_BY(network_thread_); 435 void FinishAddingRemoteCandidate(const Candidate& new_remote_candidate); 436 void OnCandidateResolved(rtc::AsyncResolverInterface* resolver); 437 void AddRemoteCandidateWithResolver(Candidate candidate, 438 rtc::AsyncResolverInterface* resolver); 439 440 // Number of times the selected_connection_ has been modified. 441 uint32_t selected_candidate_pair_changes_ = 0; 442 443 IceFieldTrials field_trials_; 444 445 RTC_DISALLOW_COPY_AND_ASSIGN(P2PTransportChannel); 446 }; 447 448 } // namespace cricket 449 450 #endif // P2P_BASE_P2P_TRANSPORT_CHANNEL_H_ 451