OLD | NEW |
(Empty) | |
| 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 // A Transport manages a set of named channels of the same type. |
| 12 // |
| 13 // Subclasses choose the appropriate class to instantiate for each channel; |
| 14 // however, this base class keeps track of the channels by name, watches their |
| 15 // state changes (in order to update the manager's state), and forwards |
| 16 // requests to begin connecting or to reset to each of the channels. |
| 17 // |
| 18 // On Threading: Transport performs work solely on the network thread, and so |
| 19 // its methods should only be called on the network thread. |
| 20 // |
| 21 // Note: Subclasses must call DestroyChannels() in their own destructors. |
| 22 // It is not possible to do so here because the subclass destructor will |
| 23 // already have run. |
| 24 |
| 25 #ifndef WEBRTC_P2P_BASE_TRANSPORT_H_ |
| 26 #define WEBRTC_P2P_BASE_TRANSPORT_H_ |
| 27 |
| 28 #include <map> |
| 29 #include <memory> |
| 30 #include <string> |
| 31 #include <vector> |
| 32 |
| 33 #include "webrtc/base/constructormagic.h" |
| 34 #include "webrtc/base/optional.h" |
| 35 #include "webrtc/p2p/base/candidate.h" |
| 36 #include "webrtc/p2p/base/p2pconstants.h" |
| 37 #include "webrtc/p2p/base/sessiondescription.h" |
| 38 #include "webrtc/p2p/base/transportinfo.h" |
| 39 #include "webrtc/base/messagequeue.h" |
| 40 #include "webrtc/base/rtccertificate.h" |
| 41 #include "webrtc/base/sigslot.h" |
| 42 #include "webrtc/base/sslstreamadapter.h" |
| 43 |
| 44 namespace cricket { |
| 45 |
| 46 class PortAllocator; |
| 47 class TransportChannel; |
| 48 class TransportChannelImpl; |
| 49 |
| 50 typedef std::vector<Candidate> Candidates; |
| 51 |
| 52 // TODO(deadbeef): Unify with PeerConnectionInterface::IceConnectionState |
| 53 // once /talk/ and /webrtc/ are combined, and also switch to ENUM_NAME naming |
| 54 // style. |
| 55 enum IceConnectionState { |
| 56 kIceConnectionConnecting = 0, |
| 57 kIceConnectionFailed, |
| 58 kIceConnectionConnected, // Writable, but still checking one or more |
| 59 // connections |
| 60 kIceConnectionCompleted, |
| 61 }; |
| 62 |
| 63 enum DtlsTransportState { |
| 64 // Haven't started negotiating. |
| 65 DTLS_TRANSPORT_NEW = 0, |
| 66 // Have started negotiating. |
| 67 DTLS_TRANSPORT_CONNECTING, |
| 68 // Negotiated, and has a secure connection. |
| 69 DTLS_TRANSPORT_CONNECTED, |
| 70 // Transport is closed. |
| 71 DTLS_TRANSPORT_CLOSED, |
| 72 // Failed due to some error in the handshake process. |
| 73 DTLS_TRANSPORT_FAILED, |
| 74 }; |
| 75 |
| 76 // TODO(deadbeef): Unify with PeerConnectionInterface::IceConnectionState |
| 77 // once /talk/ and /webrtc/ are combined, and also switch to ENUM_NAME naming |
| 78 // style. |
| 79 enum IceGatheringState { |
| 80 kIceGatheringNew = 0, |
| 81 kIceGatheringGathering, |
| 82 kIceGatheringComplete, |
| 83 }; |
| 84 |
| 85 enum ContinualGatheringPolicy { |
| 86 // All port allocator sessions will stop after a writable connection is found. |
| 87 GATHER_ONCE = 0, |
| 88 // The most recent port allocator session will keep on running. |
| 89 GATHER_CONTINUALLY, |
| 90 // The most recent port allocator session will keep on running, and it will |
| 91 // try to recover connectivity if the channel becomes disconnected. |
| 92 GATHER_CONTINUALLY_AND_RECOVER, |
| 93 }; |
| 94 |
| 95 // Stats that we can return about the connections for a transport channel. |
| 96 // TODO(hta): Rename to ConnectionStats |
| 97 struct ConnectionInfo { |
| 98 ConnectionInfo() |
| 99 : best_connection(false), |
| 100 writable(false), |
| 101 receiving(false), |
| 102 timeout(false), |
| 103 new_connection(false), |
| 104 rtt(0), |
| 105 sent_total_bytes(0), |
| 106 sent_bytes_second(0), |
| 107 sent_discarded_packets(0), |
| 108 sent_total_packets(0), |
| 109 sent_ping_requests_total(0), |
| 110 sent_ping_requests_before_first_response(0), |
| 111 sent_ping_responses(0), |
| 112 recv_total_bytes(0), |
| 113 recv_bytes_second(0), |
| 114 recv_ping_requests(0), |
| 115 recv_ping_responses(0), |
| 116 key(NULL) {} |
| 117 |
| 118 bool best_connection; // Is this the best connection we have? |
| 119 bool writable; // Has this connection received a STUN response? |
| 120 bool receiving; // Has this connection received anything? |
| 121 bool timeout; // Has this connection timed out? |
| 122 bool new_connection; // Is this a newly created connection? |
| 123 size_t rtt; // The STUN RTT for this connection. |
| 124 size_t sent_total_bytes; // Total bytes sent on this connection. |
| 125 size_t sent_bytes_second; // Bps over the last measurement interval. |
| 126 size_t sent_discarded_packets; // Number of outgoing packets discarded due to |
| 127 // socket errors. |
| 128 size_t sent_total_packets; // Number of total outgoing packets attempted for |
| 129 // sending. |
| 130 size_t sent_ping_requests_total; // Number of STUN ping request sent. |
| 131 size_t sent_ping_requests_before_first_response; // Number of STUN ping |
| 132 // sent before receiving the first response. |
| 133 size_t sent_ping_responses; // Number of STUN ping response sent. |
| 134 |
| 135 size_t recv_total_bytes; // Total bytes received on this connection. |
| 136 size_t recv_bytes_second; // Bps over the last measurement interval. |
| 137 size_t recv_ping_requests; // Number of STUN ping request received. |
| 138 size_t recv_ping_responses; // Number of STUN ping response received. |
| 139 Candidate local_candidate; // The local candidate for this connection. |
| 140 Candidate remote_candidate; // The remote candidate for this connection. |
| 141 void* key; // A static value that identifies this conn. |
| 142 }; |
| 143 |
| 144 // Information about all the connections of a channel. |
| 145 typedef std::vector<ConnectionInfo> ConnectionInfos; |
| 146 |
| 147 // Information about a specific channel |
| 148 struct TransportChannelStats { |
| 149 int component = 0; |
| 150 ConnectionInfos connection_infos; |
| 151 int srtp_crypto_suite = rtc::SRTP_INVALID_CRYPTO_SUITE; |
| 152 int ssl_cipher_suite = rtc::TLS_NULL_WITH_NULL_NULL; |
| 153 }; |
| 154 |
| 155 // Information about all the channels of a transport. |
| 156 // TODO(hta): Consider if a simple vector is as good as a map. |
| 157 typedef std::vector<TransportChannelStats> TransportChannelStatsList; |
| 158 |
| 159 // Information about the stats of a transport. |
| 160 struct TransportStats { |
| 161 std::string transport_name; |
| 162 TransportChannelStatsList channel_stats; |
| 163 }; |
| 164 |
| 165 // ICE Nomination mode. |
| 166 enum class NominationMode { |
| 167 REGULAR, // Nominate once per ICE restart (Not implemented yet). |
| 168 AGGRESSIVE, // Nominate every connection except that it will behave as if |
| 169 // REGULAR when the remote is an ICE-LITE endpoint. |
| 170 SEMI_AGGRESSIVE // Our current implementation of the nomination algorithm. |
| 171 // The details are described in P2PTransportChannel. |
| 172 }; |
| 173 |
| 174 // Information about ICE configuration. |
| 175 // TODO(deadbeef): Use rtc::Optional to represent unset values, instead of |
| 176 // -1. |
| 177 struct IceConfig { |
| 178 // The ICE connection receiving timeout value in milliseconds. |
| 179 int receiving_timeout = -1; |
| 180 // Time interval in milliseconds to ping a backup connection when the ICE |
| 181 // channel is strongly connected. |
| 182 int backup_connection_ping_interval = -1; |
| 183 |
| 184 ContinualGatheringPolicy continual_gathering_policy = GATHER_ONCE; |
| 185 |
| 186 bool gather_continually() const { |
| 187 return continual_gathering_policy == GATHER_CONTINUALLY || |
| 188 continual_gathering_policy == GATHER_CONTINUALLY_AND_RECOVER; |
| 189 } |
| 190 |
| 191 // Whether we should prioritize Relay/Relay candidate when nothing |
| 192 // is writable yet. |
| 193 bool prioritize_most_likely_candidate_pairs = false; |
| 194 |
| 195 // Writable connections are pinged at a slower rate once stablized. |
| 196 int stable_writable_connection_ping_interval = -1; |
| 197 |
| 198 // If set to true, this means the ICE transport should presume TURN-to-TURN |
| 199 // candidate pairs will succeed, even before a binding response is received. |
| 200 bool presume_writable_when_fully_relayed = false; |
| 201 |
| 202 // Interval to check on all networks and to perform ICE regathering on any |
| 203 // active network having no connection on it. |
| 204 rtc::Optional<int> regather_on_failed_networks_interval; |
| 205 |
| 206 // The time period in which we will not switch the selected connection |
| 207 // when a new connection becomes receiving but the selected connection is not |
| 208 // in case that the selected connection may become receiving soon. |
| 209 rtc::Optional<int> receiving_switching_delay; |
| 210 |
| 211 // TODO(honghaiz): Change the default to regular nomination. |
| 212 // Default nomination mode if the remote does not support renomination. |
| 213 NominationMode default_nomination_mode = NominationMode::SEMI_AGGRESSIVE; |
| 214 |
| 215 IceConfig() {} |
| 216 IceConfig(int receiving_timeout_ms, |
| 217 int backup_connection_ping_interval, |
| 218 ContinualGatheringPolicy gathering_policy, |
| 219 bool prioritize_most_likely_candidate_pairs, |
| 220 int stable_writable_connection_ping_interval_ms, |
| 221 bool presume_writable_when_fully_relayed, |
| 222 int regather_on_failed_networks_interval_ms, |
| 223 int receiving_switching_delay_ms) |
| 224 : receiving_timeout(receiving_timeout_ms), |
| 225 backup_connection_ping_interval(backup_connection_ping_interval), |
| 226 continual_gathering_policy(gathering_policy), |
| 227 prioritize_most_likely_candidate_pairs( |
| 228 prioritize_most_likely_candidate_pairs), |
| 229 stable_writable_connection_ping_interval( |
| 230 stable_writable_connection_ping_interval_ms), |
| 231 presume_writable_when_fully_relayed( |
| 232 presume_writable_when_fully_relayed), |
| 233 regather_on_failed_networks_interval( |
| 234 regather_on_failed_networks_interval_ms), |
| 235 receiving_switching_delay(receiving_switching_delay_ms) {} |
| 236 }; |
| 237 |
| 238 bool BadTransportDescription(const std::string& desc, std::string* err_desc); |
| 239 |
| 240 bool IceCredentialsChanged(const std::string& old_ufrag, |
| 241 const std::string& old_pwd, |
| 242 const std::string& new_ufrag, |
| 243 const std::string& new_pwd); |
| 244 |
| 245 class Transport : public sigslot::has_slots<> { |
| 246 public: |
| 247 Transport(const std::string& name, PortAllocator* allocator); |
| 248 virtual ~Transport(); |
| 249 |
| 250 // Returns the name of this transport. |
| 251 const std::string& name() const { return name_; } |
| 252 |
| 253 // Returns the port allocator object for this transport. |
| 254 PortAllocator* port_allocator() { return allocator_; } |
| 255 |
| 256 bool ready_for_remote_candidates() const { |
| 257 return local_description_set_ && remote_description_set_; |
| 258 } |
| 259 |
| 260 void SetIceRole(IceRole role); |
| 261 IceRole ice_role() const { return ice_role_; } |
| 262 |
| 263 void SetIceTiebreaker(uint64_t IceTiebreaker) { tiebreaker_ = IceTiebreaker; } |
| 264 uint64_t IceTiebreaker() { return tiebreaker_; } |
| 265 |
| 266 void SetIceConfig(const IceConfig& config); |
| 267 |
| 268 // Must be called before applying local session description. |
| 269 virtual void SetLocalCertificate( |
| 270 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {} |
| 271 |
| 272 // Get a copy of the local certificate provided by SetLocalCertificate. |
| 273 virtual bool GetLocalCertificate( |
| 274 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) { |
| 275 return false; |
| 276 } |
| 277 |
| 278 // Get a copy of the remote certificate in use by the specified channel. |
| 279 std::unique_ptr<rtc::SSLCertificate> GetRemoteSSLCertificate(); |
| 280 |
| 281 // Create, destroy, and lookup the channels of this type by their components. |
| 282 TransportChannelImpl* CreateChannel(int component); |
| 283 |
| 284 TransportChannelImpl* GetChannel(int component); |
| 285 |
| 286 bool HasChannel(int component) { |
| 287 return (NULL != GetChannel(component)); |
| 288 } |
| 289 bool HasChannels(); |
| 290 |
| 291 void DestroyChannel(int component); |
| 292 |
| 293 // Set the local TransportDescription to be used by TransportChannels. |
| 294 bool SetLocalTransportDescription(const TransportDescription& description, |
| 295 ContentAction action, |
| 296 std::string* error_desc); |
| 297 |
| 298 // Set the remote TransportDescription to be used by TransportChannels. |
| 299 bool SetRemoteTransportDescription(const TransportDescription& description, |
| 300 ContentAction action, |
| 301 std::string* error_desc); |
| 302 |
| 303 // Tells channels to start gathering candidates if necessary. |
| 304 // Should be called after ConnectChannels() has been called at least once, |
| 305 // which will happen in SetLocalTransportDescription. |
| 306 void MaybeStartGathering(); |
| 307 |
| 308 // Resets all of the channels back to their initial state. They are no |
| 309 // longer connecting. |
| 310 void ResetChannels(); |
| 311 |
| 312 // Destroys every channel created so far. |
| 313 void DestroyAllChannels(); |
| 314 |
| 315 bool GetStats(TransportStats* stats); |
| 316 |
| 317 // Called when one or more candidates are ready from the remote peer. |
| 318 bool AddRemoteCandidates(const std::vector<Candidate>& candidates, |
| 319 std::string* error); |
| 320 bool RemoveRemoteCandidates(const std::vector<Candidate>& candidates, |
| 321 std::string* error); |
| 322 |
| 323 virtual bool GetSslRole(rtc::SSLRole* ssl_role) const { return false; } |
| 324 |
| 325 // Must be called before channel is starting to connect. |
| 326 virtual bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version) { |
| 327 return false; |
| 328 } |
| 329 |
| 330 // The current local transport description, for use by derived classes |
| 331 // when performing transport description negotiation, and possibly used |
| 332 // by the transport controller. |
| 333 const TransportDescription* local_description() const { |
| 334 return local_description_.get(); |
| 335 } |
| 336 |
| 337 // The current remote transport description, for use by derived classes |
| 338 // when performing transport description negotiation, and possibly used |
| 339 // by the transport controller. |
| 340 const TransportDescription* remote_description() const { |
| 341 return remote_description_.get(); |
| 342 } |
| 343 |
| 344 protected: |
| 345 // These are called by Create/DestroyChannel above in order to create or |
| 346 // destroy the appropriate type of channel. |
| 347 virtual TransportChannelImpl* CreateTransportChannel(int component) = 0; |
| 348 virtual void DestroyTransportChannel(TransportChannelImpl* channel) = 0; |
| 349 |
| 350 // Pushes down the transport parameters from the local description, such |
| 351 // as the ICE ufrag and pwd. |
| 352 // Derived classes can override, but must call the base as well. |
| 353 virtual bool ApplyLocalTransportDescription(TransportChannelImpl* channel, |
| 354 std::string* error_desc); |
| 355 |
| 356 // Pushes down remote ice credentials from the remote description to the |
| 357 // transport channel. |
| 358 virtual bool ApplyRemoteTransportDescription(TransportChannelImpl* ch, |
| 359 std::string* error_desc); |
| 360 |
| 361 // Negotiates the transport parameters based on the current local and remote |
| 362 // transport description, such as the ICE role to use, and whether DTLS |
| 363 // should be activated. |
| 364 // Derived classes can negotiate their specific parameters here, but must call |
| 365 // the base as well. |
| 366 virtual bool NegotiateTransportDescription(ContentAction local_role, |
| 367 std::string* error_desc); |
| 368 |
| 369 // Pushes down the transport parameters obtained via negotiation. |
| 370 // Derived classes can set their specific parameters here, but must call the |
| 371 // base as well. |
| 372 virtual bool ApplyNegotiatedTransportDescription( |
| 373 TransportChannelImpl* channel, |
| 374 std::string* error_desc); |
| 375 |
| 376 // Returns false if the certificate's identity does not match the fingerprint, |
| 377 // or either is NULL. |
| 378 virtual bool VerifyCertificateFingerprint( |
| 379 const rtc::RTCCertificate* certificate, |
| 380 const rtc::SSLFingerprint* fingerprint, |
| 381 std::string* error_desc) const; |
| 382 |
| 383 // Negotiates the SSL role based off the offer and answer as specified by |
| 384 // RFC 4145, section-4.1. Returns false if the SSL role cannot be determined |
| 385 // from the local description and remote description. |
| 386 virtual bool NegotiateRole(ContentAction local_role, |
| 387 rtc::SSLRole* ssl_role, |
| 388 std::string* error_desc) const; |
| 389 |
| 390 private: |
| 391 // If a candidate is not acceptable, returns false and sets error. |
| 392 // Call this before calling OnRemoteCandidates. |
| 393 bool VerifyCandidate(const Candidate& candidate, std::string* error); |
| 394 bool VerifyCandidates(const Candidates& candidates, std::string* error); |
| 395 |
| 396 // Candidate component => TransportChannelImpl* |
| 397 typedef std::map<int, TransportChannelImpl*> ChannelMap; |
| 398 |
| 399 // Helper function that invokes the given function on every channel. |
| 400 typedef void (TransportChannelImpl::* TransportChannelFunc)(); |
| 401 void CallChannels(TransportChannelFunc func); |
| 402 |
| 403 const std::string name_; |
| 404 PortAllocator* const allocator_; |
| 405 bool channels_destroyed_ = false; |
| 406 IceRole ice_role_ = ICEROLE_UNKNOWN; |
| 407 uint64_t tiebreaker_ = 0; |
| 408 IceMode remote_ice_mode_ = ICEMODE_FULL; |
| 409 IceConfig ice_config_; |
| 410 std::unique_ptr<TransportDescription> local_description_; |
| 411 std::unique_ptr<TransportDescription> remote_description_; |
| 412 bool local_description_set_ = false; |
| 413 bool remote_description_set_ = false; |
| 414 |
| 415 ChannelMap channels_; |
| 416 |
| 417 RTC_DISALLOW_COPY_AND_ASSIGN(Transport); |
| 418 }; |
| 419 |
| 420 |
| 421 } // namespace cricket |
| 422 |
| 423 #endif // WEBRTC_P2P_BASE_TRANSPORT_H_ |
OLD | NEW |