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 on both the signaling and worker 19 // threads. For subclasses, the rule is that all signaling related calls will 20 // be made on the signaling thread and all channel related calls (including 21 // signaling for a channel) will be made on the worker thread. When 22 // information needs to be sent between the two threads, this class should do 23 // the work (e.g., OnRemoteCandidate). 24 // 25 // Note: Subclasses must call DestroyChannels() in their own constructors. 26 // It is not possible to do so here because the subclass constructor will 27 // already have run. 28 29 #ifndef WEBRTC_P2P_BASE_TRANSPORT_H_ 30 #define WEBRTC_P2P_BASE_TRANSPORT_H_ 31 32 #include <map> 33 #include <string> 34 #include <vector> 35 #include "webrtc/p2p/base/candidate.h" 36 #include "webrtc/p2p/base/constants.h" 37 #include "webrtc/p2p/base/sessiondescription.h" 38 #include "webrtc/p2p/base/transportinfo.h" 39 #include "webrtc/base/criticalsection.h" 40 #include "webrtc/base/messagequeue.h" 41 #include "webrtc/base/sigslot.h" 42 #include "webrtc/base/sslstreamadapter.h" 43 44 namespace rtc { 45 class Thread; 46 } 47 48 namespace cricket { 49 50 class PortAllocator; 51 class TransportChannel; 52 class TransportChannelImpl; 53 54 typedef std::vector<Candidate> Candidates; 55 56 // For "writable" and "readable", we need to differentiate between 57 // none, all, and some. 58 enum TransportState { 59 TRANSPORT_STATE_NONE = 0, 60 TRANSPORT_STATE_SOME, 61 TRANSPORT_STATE_ALL 62 }; 63 64 // Stats that we can return about the connections for a transport channel. 65 // TODO(hta): Rename to ConnectionStats 66 struct ConnectionInfo { ConnectionInfoConnectionInfo67 ConnectionInfo() 68 : best_connection(false), 69 writable(false), 70 readable(false), 71 timeout(false), 72 new_connection(false), 73 rtt(0), 74 sent_total_bytes(0), 75 sent_bytes_second(0), 76 sent_discarded_packets(0), 77 sent_total_packets(0), 78 recv_total_bytes(0), 79 recv_bytes_second(0), 80 key(NULL) {} 81 82 bool best_connection; // Is this the best connection we have? 83 bool writable; // Has this connection received a STUN response? 84 bool readable; // Has this connection received a STUN request? 85 bool timeout; // Has this connection timed out? 86 bool new_connection; // Is this a newly created connection? 87 size_t rtt; // The STUN RTT for this connection. 88 size_t sent_total_bytes; // Total bytes sent on this connection. 89 size_t sent_bytes_second; // Bps over the last measurement interval. 90 size_t sent_discarded_packets; // Number of outgoing packets discarded due to 91 // socket errors. 92 size_t sent_total_packets; // Number of total outgoing packets attempted for 93 // sending. 94 95 size_t recv_total_bytes; // Total bytes received on this connection. 96 size_t recv_bytes_second; // Bps over the last measurement interval. 97 Candidate local_candidate; // The local candidate for this connection. 98 Candidate remote_candidate; // The remote candidate for this connection. 99 void* key; // A static value that identifies this conn. 100 }; 101 102 // Information about all the connections of a channel. 103 typedef std::vector<ConnectionInfo> ConnectionInfos; 104 105 // Information about a specific channel 106 struct TransportChannelStats { 107 int component; 108 ConnectionInfos connection_infos; 109 std::string srtp_cipher; 110 std::string ssl_cipher; 111 }; 112 113 // Information about all the channels of a transport. 114 // TODO(hta): Consider if a simple vector is as good as a map. 115 typedef std::vector<TransportChannelStats> TransportChannelStatsList; 116 117 // Information about the stats of a transport. 118 struct TransportStats { 119 std::string content_name; 120 TransportChannelStatsList channel_stats; 121 }; 122 123 bool BadTransportDescription(const std::string& desc, std::string* err_desc); 124 125 bool IceCredentialsChanged(const std::string& old_ufrag, 126 const std::string& old_pwd, 127 const std::string& new_ufrag, 128 const std::string& new_pwd); 129 130 class Transport : public rtc::MessageHandler, 131 public sigslot::has_slots<> { 132 public: 133 Transport(rtc::Thread* signaling_thread, 134 rtc::Thread* worker_thread, 135 const std::string& content_name, 136 const std::string& type, 137 PortAllocator* allocator); 138 virtual ~Transport(); 139 140 // Returns the signaling thread. The app talks to Transport on this thread. signaling_thread()141 rtc::Thread* signaling_thread() { return signaling_thread_; } 142 // Returns the worker thread. The actual networking is done on this thread. worker_thread()143 rtc::Thread* worker_thread() { return worker_thread_; } 144 145 // Returns the content_name of this transport. content_name()146 const std::string& content_name() const { return content_name_; } 147 // Returns the type of this transport. type()148 const std::string& type() const { return type_; } 149 150 // Returns the port allocator object for this transport. port_allocator()151 PortAllocator* port_allocator() { return allocator_; } 152 153 // Returns the readable and states of this manager. These bits are the ORs 154 // of the corresponding bits on the managed channels. Each time one of these 155 // states changes, a signal is raised. 156 // TODO: Replace uses of readable() and writable() with 157 // any_channels_readable() and any_channels_writable(). readable()158 bool readable() const { return any_channels_readable(); } writable()159 bool writable() const { return any_channels_writable(); } was_writable()160 bool was_writable() const { return was_writable_; } any_channels_readable()161 bool any_channels_readable() const { 162 return (readable_ == TRANSPORT_STATE_SOME || 163 readable_ == TRANSPORT_STATE_ALL); 164 } any_channels_writable()165 bool any_channels_writable() const { 166 return (writable_ == TRANSPORT_STATE_SOME || 167 writable_ == TRANSPORT_STATE_ALL); 168 } all_channels_readable()169 bool all_channels_readable() const { 170 return (readable_ == TRANSPORT_STATE_ALL); 171 } all_channels_writable()172 bool all_channels_writable() const { 173 return (writable_ == TRANSPORT_STATE_ALL); 174 } 175 sigslot::signal1<Transport*> SignalReadableState; 176 sigslot::signal1<Transport*> SignalWritableState; 177 sigslot::signal1<Transport*> SignalCompleted; 178 sigslot::signal1<Transport*> SignalFailed; 179 180 // Returns whether the client has requested the channels to connect. connect_requested()181 bool connect_requested() const { return connect_requested_; } 182 183 void SetIceRole(IceRole role); ice_role()184 IceRole ice_role() const { return ice_role_; } 185 SetIceTiebreaker(uint64 IceTiebreaker)186 void SetIceTiebreaker(uint64 IceTiebreaker) { tiebreaker_ = IceTiebreaker; } IceTiebreaker()187 uint64 IceTiebreaker() { return tiebreaker_; } 188 189 // Must be called before applying local session description. 190 void SetIdentity(rtc::SSLIdentity* identity); 191 192 // Get a copy of the local identity provided by SetIdentity. 193 bool GetIdentity(rtc::SSLIdentity** identity); 194 195 // Get a copy of the remote certificate in use by the specified channel. 196 bool GetRemoteCertificate(rtc::SSLCertificate** cert); 197 protocol()198 TransportProtocol protocol() const { return protocol_; } 199 200 // Create, destroy, and lookup the channels of this type by their components. 201 TransportChannelImpl* CreateChannel(int component); 202 // Note: GetChannel may lead to race conditions, since the mutex is not held 203 // after the pointer is returned. 204 TransportChannelImpl* GetChannel(int component); 205 // Note: HasChannel does not lead to race conditions, unlike GetChannel. HasChannel(int component)206 bool HasChannel(int component) { 207 return (NULL != GetChannel(component)); 208 } 209 bool HasChannels(); 210 void DestroyChannel(int component); 211 212 // Set the local TransportDescription to be used by TransportChannels. 213 // This should be called before ConnectChannels(). 214 bool SetLocalTransportDescription(const TransportDescription& description, 215 ContentAction action, 216 std::string* error_desc); 217 218 // Set the remote TransportDescription to be used by TransportChannels. 219 bool SetRemoteTransportDescription(const TransportDescription& description, 220 ContentAction action, 221 std::string* error_desc); 222 223 // Tells all current and future channels to start connecting. When the first 224 // channel begins connecting, the following signal is raised. 225 void ConnectChannels(); 226 sigslot::signal1<Transport*> SignalConnecting; 227 228 // Resets all of the channels back to their initial state. They are no 229 // longer connecting. 230 void ResetChannels(); 231 232 // Destroys every channel created so far. 233 void DestroyAllChannels(); 234 235 bool GetStats(TransportStats* stats); 236 237 // Before any stanza is sent, the manager will request signaling. Once 238 // signaling is available, the client should call OnSignalingReady. Once 239 // this occurs, the transport (or its channels) can send any waiting stanzas. 240 // OnSignalingReady invokes OnTransportSignalingReady and then forwards this 241 // signal to each channel. 242 sigslot::signal1<Transport*> SignalRequestSignaling; 243 void OnSignalingReady(); 244 245 // Handles sending of ready candidates and receiving of remote candidates. 246 sigslot::signal2<Transport*, 247 const std::vector<Candidate>&> SignalCandidatesReady; 248 249 sigslot::signal1<Transport*> SignalCandidatesAllocationDone; 250 void OnRemoteCandidates(const std::vector<Candidate>& candidates); 251 252 // If candidate is not acceptable, returns false and sets error. 253 // Call this before calling OnRemoteCandidates. 254 virtual bool VerifyCandidate(const Candidate& candidate, 255 std::string* error); 256 257 // Signals when the best connection for a channel changes. 258 sigslot::signal3<Transport*, 259 int, // component 260 const Candidate&> SignalRouteChange; 261 262 // Forwards the signal from TransportChannel to BaseSession. 263 sigslot::signal0<> SignalRoleConflict; 264 265 virtual bool GetSslRole(rtc::SSLRole* ssl_role) const; 266 267 protected: 268 // These are called by Create/DestroyChannel above in order to create or 269 // destroy the appropriate type of channel. 270 virtual TransportChannelImpl* CreateTransportChannel(int component) = 0; 271 virtual void DestroyTransportChannel(TransportChannelImpl* channel) = 0; 272 273 // Informs the subclass that we received the signaling ready message. OnTransportSignalingReady()274 virtual void OnTransportSignalingReady() {} 275 276 // The current local transport description, for use by derived classes 277 // when performing transport description negotiation. local_description()278 const TransportDescription* local_description() const { 279 return local_description_.get(); 280 } 281 282 // The current remote transport description, for use by derived classes 283 // when performing transport description negotiation. remote_description()284 const TransportDescription* remote_description() const { 285 return remote_description_.get(); 286 } 287 SetIdentity_w(rtc::SSLIdentity * identity)288 virtual void SetIdentity_w(rtc::SSLIdentity* identity) {} 289 GetIdentity_w(rtc::SSLIdentity ** identity)290 virtual bool GetIdentity_w(rtc::SSLIdentity** identity) { 291 return false; 292 } 293 294 // Pushes down the transport parameters from the local description, such 295 // as the ICE ufrag and pwd. 296 // Derived classes can override, but must call the base as well. 297 virtual bool ApplyLocalTransportDescription_w(TransportChannelImpl* channel, 298 std::string* error_desc); 299 300 // Pushes down remote ice credentials from the remote description to the 301 // transport channel. 302 virtual bool ApplyRemoteTransportDescription_w(TransportChannelImpl* ch, 303 std::string* error_desc); 304 305 // Negotiates the transport parameters based on the current local and remote 306 // transport description, such at the version of ICE to use, and whether DTLS 307 // should be activated. 308 // Derived classes can negotiate their specific parameters here, but must call 309 // the base as well. 310 virtual bool NegotiateTransportDescription_w(ContentAction local_role, 311 std::string* error_desc); 312 313 // Pushes down the transport parameters obtained via negotiation. 314 // Derived classes can set their specific parameters here, but must call the 315 // base as well. 316 virtual bool ApplyNegotiatedTransportDescription_w( 317 TransportChannelImpl* channel, std::string* error_desc); 318 GetSslRole_w(rtc::SSLRole * ssl_role)319 virtual bool GetSslRole_w(rtc::SSLRole* ssl_role) const { 320 return false; 321 } 322 323 private: 324 struct ChannelMapEntry { ChannelMapEntryChannelMapEntry325 ChannelMapEntry() : impl_(NULL), candidates_allocated_(false), ref_(0) {} ChannelMapEntryChannelMapEntry326 explicit ChannelMapEntry(TransportChannelImpl *impl) 327 : impl_(impl), 328 candidates_allocated_(false), 329 ref_(0) { 330 } 331 AddRefChannelMapEntry332 void AddRef() { ++ref_; } DecRefChannelMapEntry333 void DecRef() { 334 ASSERT(ref_ > 0); 335 --ref_; 336 } refChannelMapEntry337 int ref() const { return ref_; } 338 getChannelMapEntry339 TransportChannelImpl* get() const { return impl_; } 340 TransportChannelImpl* operator->() const { return impl_; } set_candidates_allocatedChannelMapEntry341 void set_candidates_allocated(bool status) { 342 candidates_allocated_ = status; 343 } candidates_allocatedChannelMapEntry344 bool candidates_allocated() const { return candidates_allocated_; } 345 346 private: 347 TransportChannelImpl *impl_; 348 bool candidates_allocated_; 349 int ref_; 350 }; 351 352 // Candidate component => ChannelMapEntry 353 typedef std::map<int, ChannelMapEntry> ChannelMap; 354 355 // Called when the state of a channel changes. 356 void OnChannelReadableState(TransportChannel* channel); 357 void OnChannelWritableState(TransportChannel* channel); 358 359 // Called when a channel requests signaling. 360 void OnChannelRequestSignaling(TransportChannelImpl* channel); 361 362 // Called when a candidate is ready from remote peer. 363 void OnRemoteCandidate(const Candidate& candidate); 364 // Called when a candidate is ready from channel. 365 void OnChannelCandidateReady(TransportChannelImpl* channel, 366 const Candidate& candidate); 367 void OnChannelRouteChange(TransportChannel* channel, 368 const Candidate& remote_candidate); 369 void OnChannelCandidatesAllocationDone(TransportChannelImpl* channel); 370 // Called when there is ICE role change. 371 void OnRoleConflict(TransportChannelImpl* channel); 372 // Called when the channel removes a connection. 373 void OnChannelConnectionRemoved(TransportChannelImpl* channel); 374 375 // Dispatches messages to the appropriate handler (below). 376 void OnMessage(rtc::Message* msg); 377 378 // These are versions of the above methods that are called only on a 379 // particular thread (s = signaling, w = worker). The above methods post or 380 // send a message to invoke this version. 381 TransportChannelImpl* CreateChannel_w(int component); 382 void DestroyChannel_w(int component); 383 void ConnectChannels_w(); 384 void ResetChannels_w(); 385 void DestroyAllChannels_w(); 386 void OnRemoteCandidate_w(const Candidate& candidate); 387 void OnChannelReadableState_s(); 388 void OnChannelWritableState_s(); 389 void OnChannelRequestSignaling_s(); 390 void OnConnecting_s(); 391 void OnChannelRouteChange_s(const TransportChannel* channel, 392 const Candidate& remote_candidate); 393 void OnChannelCandidatesAllocationDone_s(); 394 395 // Helper function that invokes the given function on every channel. 396 typedef void (TransportChannelImpl::* TransportChannelFunc)(); 397 void CallChannels_w(TransportChannelFunc func); 398 399 // Computes the OR of the channel's read or write state (argument picks). 400 TransportState GetTransportState_s(bool read); 401 402 void OnChannelCandidateReady_s(); 403 404 void SetIceRole_w(IceRole role); 405 void SetRemoteIceMode_w(IceMode mode); 406 bool SetLocalTransportDescription_w(const TransportDescription& desc, 407 ContentAction action, 408 std::string* error_desc); 409 bool SetRemoteTransportDescription_w(const TransportDescription& desc, 410 ContentAction action, 411 std::string* error_desc); 412 bool GetStats_w(TransportStats* infos); 413 bool GetRemoteCertificate_w(rtc::SSLCertificate** cert); 414 415 // Sends SignalCompleted if we are now in that state. 416 void MaybeCompleted_w(); 417 418 rtc::Thread* const signaling_thread_; 419 rtc::Thread* const worker_thread_; 420 const std::string content_name_; 421 const std::string type_; 422 PortAllocator* const allocator_; 423 bool destroyed_; 424 TransportState readable_; 425 TransportState writable_; 426 bool was_writable_; 427 bool connect_requested_; 428 IceRole ice_role_; 429 uint64 tiebreaker_; 430 TransportProtocol protocol_; 431 IceMode remote_ice_mode_; 432 rtc::scoped_ptr<TransportDescription> local_description_; 433 rtc::scoped_ptr<TransportDescription> remote_description_; 434 435 // TODO(tommi): Make sure we only use this on the worker thread. 436 ChannelMap channels_; 437 // Buffers the ready_candidates so that SignalCanidatesReady can 438 // provide them in multiples. 439 std::vector<Candidate> ready_candidates_; 440 // Protects changes to channels and messages 441 rtc::CriticalSection crit_; 442 443 DISALLOW_EVIL_CONSTRUCTORS(Transport); 444 }; 445 446 // Extract a TransportProtocol from a TransportDescription. 447 TransportProtocol TransportProtocolFromDescription( 448 const TransportDescription* desc); 449 450 } // namespace cricket 451 452 #endif // WEBRTC_P2P_BASE_TRANSPORT_H_ 453