1 /* 2 * libjingle 3 * Copyright 2004--2005, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 // A Transport manages a set of named channels of the same type. 29 // 30 // Subclasses choose the appropriate class to instantiate for each channel; 31 // however, this base class keeps track of the channels by name, watches their 32 // state changes (in order to update the manager's state), and forwards 33 // requests to begin connecting or to reset to each of the channels. 34 // 35 // On Threading: Transport performs work on both the signaling and worker 36 // threads. For subclasses, the rule is that all signaling related calls will 37 // be made on the signaling thread and all channel related calls (including 38 // signaling for a channel) will be made on the worker thread. When 39 // information needs to be sent between the two threads, this class should do 40 // the work (e.g., OnRemoteCandidate). 41 // 42 // Note: Subclasses must call DestroyChannels() in their own constructors. 43 // It is not possible to do so here because the subclass constructor will 44 // already have run. 45 46 #ifndef TALK_P2P_BASE_TRANSPORT_H_ 47 #define TALK_P2P_BASE_TRANSPORT_H_ 48 49 #include <map> 50 #include <string> 51 #include <vector> 52 #include "talk/p2p/base/candidate.h" 53 #include "talk/p2p/base/constants.h" 54 #include "talk/p2p/base/sessiondescription.h" 55 #include "talk/p2p/base/transportinfo.h" 56 #include "webrtc/base/criticalsection.h" 57 #include "webrtc/base/messagequeue.h" 58 #include "webrtc/base/sigslot.h" 59 #include "webrtc/base/sslstreamadapter.h" 60 61 namespace rtc { 62 class Thread; 63 } 64 65 namespace buzz { 66 class QName; 67 class XmlElement; 68 } 69 70 namespace cricket { 71 72 struct ParseError; 73 struct WriteError; 74 class CandidateTranslator; 75 class PortAllocator; 76 class SessionManager; 77 class Session; 78 class TransportChannel; 79 class TransportChannelImpl; 80 81 typedef std::vector<buzz::XmlElement*> XmlElements; 82 typedef std::vector<Candidate> Candidates; 83 84 // Used to parse and serialize (write) transport candidates. For 85 // convenience of old code, Transports will implement TransportParser. 86 // Parse/Write seems better than Serialize/Deserialize or 87 // Create/Translate. 88 class TransportParser { 89 public: 90 // The incoming Translator value may be null, in which case 91 // ParseCandidates should return false if there are candidates to 92 // parse (indicating a failure to parse). If the Translator is null 93 // and there are no candidates to parse, then return true, 94 // indicating a successful parse of 0 candidates. 95 96 // Parse or write a transport description, including ICE credentials and 97 // any DTLS fingerprint. Since only Jingle has transport descriptions, these 98 // functions are only used when serializing to Jingle. 99 virtual bool ParseTransportDescription(const buzz::XmlElement* elem, 100 const CandidateTranslator* translator, 101 TransportDescription* tdesc, 102 ParseError* error) = 0; 103 virtual bool WriteTransportDescription(const TransportDescription& tdesc, 104 const CandidateTranslator* translator, 105 buzz::XmlElement** tdesc_elem, 106 WriteError* error) = 0; 107 108 109 // Parse a single candidate. This must be used when parsing Gingle 110 // candidates, since there is no enclosing transport description. 111 virtual bool ParseGingleCandidate(const buzz::XmlElement* elem, 112 const CandidateTranslator* translator, 113 Candidate* candidates, 114 ParseError* error) = 0; 115 virtual bool WriteGingleCandidate(const Candidate& candidate, 116 const CandidateTranslator* translator, 117 buzz::XmlElement** candidate_elem, 118 WriteError* error) = 0; 119 120 // Helper function to parse an element describing an address. This 121 // retrieves the IP and port from the given element and verifies 122 // that they look like plausible values. 123 bool ParseAddress(const buzz::XmlElement* elem, 124 const buzz::QName& address_name, 125 const buzz::QName& port_name, 126 rtc::SocketAddress* address, 127 ParseError* error); 128 ~TransportParser()129 virtual ~TransportParser() {} 130 }; 131 132 // For "writable" and "readable", we need to differentiate between 133 // none, all, and some. 134 enum TransportState { 135 TRANSPORT_STATE_NONE = 0, 136 TRANSPORT_STATE_SOME, 137 TRANSPORT_STATE_ALL 138 }; 139 140 // Stats that we can return about the connections for a transport channel. 141 // TODO(hta): Rename to ConnectionStats 142 struct ConnectionInfo { ConnectionInfoConnectionInfo143 ConnectionInfo() 144 : best_connection(false), 145 writable(false), 146 readable(false), 147 timeout(false), 148 new_connection(false), 149 rtt(0), 150 sent_total_bytes(0), 151 sent_bytes_second(0), 152 recv_total_bytes(0), 153 recv_bytes_second(0), 154 key(NULL) {} 155 156 bool best_connection; // Is this the best connection we have? 157 bool writable; // Has this connection received a STUN response? 158 bool readable; // Has this connection received a STUN request? 159 bool timeout; // Has this connection timed out? 160 bool new_connection; // Is this a newly created connection? 161 size_t rtt; // The STUN RTT for this connection. 162 size_t sent_total_bytes; // Total bytes sent on this connection. 163 size_t sent_bytes_second; // Bps over the last measurement interval. 164 size_t recv_total_bytes; // Total bytes received on this connection. 165 size_t recv_bytes_second; // Bps over the last measurement interval. 166 Candidate local_candidate; // The local candidate for this connection. 167 Candidate remote_candidate; // The remote candidate for this connection. 168 void* key; // A static value that identifies this conn. 169 }; 170 171 // Information about all the connections of a channel. 172 typedef std::vector<ConnectionInfo> ConnectionInfos; 173 174 // Information about a specific channel 175 struct TransportChannelStats { 176 int component; 177 ConnectionInfos connection_infos; 178 }; 179 180 // Information about all the channels of a transport. 181 // TODO(hta): Consider if a simple vector is as good as a map. 182 typedef std::vector<TransportChannelStats> TransportChannelStatsList; 183 184 // Information about the stats of a transport. 185 struct TransportStats { 186 std::string content_name; 187 TransportChannelStatsList channel_stats; 188 }; 189 190 bool BadTransportDescription(const std::string& desc, std::string* err_desc); 191 192 bool IceCredentialsChanged(const std::string& old_ufrag, 193 const std::string& old_pwd, 194 const std::string& new_ufrag, 195 const std::string& new_pwd); 196 197 class Transport : public rtc::MessageHandler, 198 public sigslot::has_slots<> { 199 public: 200 Transport(rtc::Thread* signaling_thread, 201 rtc::Thread* worker_thread, 202 const std::string& content_name, 203 const std::string& type, 204 PortAllocator* allocator); 205 virtual ~Transport(); 206 207 // Returns the signaling thread. The app talks to Transport on this thread. signaling_thread()208 rtc::Thread* signaling_thread() { return signaling_thread_; } 209 // Returns the worker thread. The actual networking is done on this thread. worker_thread()210 rtc::Thread* worker_thread() { return worker_thread_; } 211 212 // Returns the content_name of this transport. content_name()213 const std::string& content_name() const { return content_name_; } 214 // Returns the type of this transport. type()215 const std::string& type() const { return type_; } 216 217 // Returns the port allocator object for this transport. port_allocator()218 PortAllocator* port_allocator() { return allocator_; } 219 220 // Returns the readable and states of this manager. These bits are the ORs 221 // of the corresponding bits on the managed channels. Each time one of these 222 // states changes, a signal is raised. 223 // TODO: Replace uses of readable() and writable() with 224 // any_channels_readable() and any_channels_writable(). readable()225 bool readable() const { return any_channels_readable(); } writable()226 bool writable() const { return any_channels_writable(); } was_writable()227 bool was_writable() const { return was_writable_; } any_channels_readable()228 bool any_channels_readable() const { 229 return (readable_ == TRANSPORT_STATE_SOME || 230 readable_ == TRANSPORT_STATE_ALL); 231 } any_channels_writable()232 bool any_channels_writable() const { 233 return (writable_ == TRANSPORT_STATE_SOME || 234 writable_ == TRANSPORT_STATE_ALL); 235 } all_channels_readable()236 bool all_channels_readable() const { 237 return (readable_ == TRANSPORT_STATE_ALL); 238 } all_channels_writable()239 bool all_channels_writable() const { 240 return (writable_ == TRANSPORT_STATE_ALL); 241 } 242 sigslot::signal1<Transport*> SignalReadableState; 243 sigslot::signal1<Transport*> SignalWritableState; 244 sigslot::signal1<Transport*> SignalCompleted; 245 sigslot::signal1<Transport*> SignalFailed; 246 247 // Returns whether the client has requested the channels to connect. connect_requested()248 bool connect_requested() const { return connect_requested_; } 249 250 void SetIceRole(IceRole role); ice_role()251 IceRole ice_role() const { return ice_role_; } 252 SetIceTiebreaker(uint64 IceTiebreaker)253 void SetIceTiebreaker(uint64 IceTiebreaker) { tiebreaker_ = IceTiebreaker; } IceTiebreaker()254 uint64 IceTiebreaker() { return tiebreaker_; } 255 256 // Must be called before applying local session description. 257 void SetIdentity(rtc::SSLIdentity* identity); 258 259 // Get a copy of the local identity provided by SetIdentity. 260 bool GetIdentity(rtc::SSLIdentity** identity); 261 262 // Get a copy of the remote certificate in use by the specified channel. 263 bool GetRemoteCertificate(rtc::SSLCertificate** cert); 264 protocol()265 TransportProtocol protocol() const { return protocol_; } 266 267 // Create, destroy, and lookup the channels of this type by their components. 268 TransportChannelImpl* CreateChannel(int component); 269 // Note: GetChannel may lead to race conditions, since the mutex is not held 270 // after the pointer is returned. 271 TransportChannelImpl* GetChannel(int component); 272 // Note: HasChannel does not lead to race conditions, unlike GetChannel. HasChannel(int component)273 bool HasChannel(int component) { 274 return (NULL != GetChannel(component)); 275 } 276 bool HasChannels(); 277 void DestroyChannel(int component); 278 279 // Set the local TransportDescription to be used by TransportChannels. 280 // This should be called before ConnectChannels(). 281 bool SetLocalTransportDescription(const TransportDescription& description, 282 ContentAction action, 283 std::string* error_desc); 284 285 // Set the remote TransportDescription to be used by TransportChannels. 286 bool SetRemoteTransportDescription(const TransportDescription& description, 287 ContentAction action, 288 std::string* error_desc); 289 290 // Tells all current and future channels to start connecting. When the first 291 // channel begins connecting, the following signal is raised. 292 void ConnectChannels(); 293 sigslot::signal1<Transport*> SignalConnecting; 294 295 // Resets all of the channels back to their initial state. They are no 296 // longer connecting. 297 void ResetChannels(); 298 299 // Destroys every channel created so far. 300 void DestroyAllChannels(); 301 302 bool GetStats(TransportStats* stats); 303 304 // Before any stanza is sent, the manager will request signaling. Once 305 // signaling is available, the client should call OnSignalingReady. Once 306 // this occurs, the transport (or its channels) can send any waiting stanzas. 307 // OnSignalingReady invokes OnTransportSignalingReady and then forwards this 308 // signal to each channel. 309 sigslot::signal1<Transport*> SignalRequestSignaling; 310 void OnSignalingReady(); 311 312 // Handles sending of ready candidates and receiving of remote candidates. 313 sigslot::signal2<Transport*, 314 const std::vector<Candidate>&> SignalCandidatesReady; 315 316 sigslot::signal1<Transport*> SignalCandidatesAllocationDone; 317 void OnRemoteCandidates(const std::vector<Candidate>& candidates); 318 319 // If candidate is not acceptable, returns false and sets error. 320 // Call this before calling OnRemoteCandidates. 321 virtual bool VerifyCandidate(const Candidate& candidate, 322 std::string* error); 323 324 // Signals when the best connection for a channel changes. 325 sigslot::signal3<Transport*, 326 int, // component 327 const Candidate&> SignalRouteChange; 328 329 // A transport message has generated an transport-specific error. The 330 // stanza that caused the error is available in session_msg. If false is 331 // returned, the error is considered unrecoverable, and the session is 332 // terminated. 333 // TODO(juberti): Remove these obsolete functions once Session no longer 334 // references them. OnTransportError(const buzz::XmlElement * error)335 virtual void OnTransportError(const buzz::XmlElement* error) {} 336 sigslot::signal6<Transport*, const buzz::XmlElement*, const buzz::QName&, 337 const std::string&, const std::string&, 338 const buzz::XmlElement*> 339 SignalTransportError; 340 341 // Forwards the signal from TransportChannel to BaseSession. 342 sigslot::signal0<> SignalRoleConflict; 343 344 virtual bool GetSslRole(rtc::SSLRole* ssl_role) const; 345 346 protected: 347 // These are called by Create/DestroyChannel above in order to create or 348 // destroy the appropriate type of channel. 349 virtual TransportChannelImpl* CreateTransportChannel(int component) = 0; 350 virtual void DestroyTransportChannel(TransportChannelImpl* channel) = 0; 351 352 // Informs the subclass that we received the signaling ready message. OnTransportSignalingReady()353 virtual void OnTransportSignalingReady() {} 354 355 // The current local transport description, for use by derived classes 356 // when performing transport description negotiation. local_description()357 const TransportDescription* local_description() const { 358 return local_description_.get(); 359 } 360 361 // The current remote transport description, for use by derived classes 362 // when performing transport description negotiation. remote_description()363 const TransportDescription* remote_description() const { 364 return remote_description_.get(); 365 } 366 SetIdentity_w(rtc::SSLIdentity * identity)367 virtual void SetIdentity_w(rtc::SSLIdentity* identity) {} 368 GetIdentity_w(rtc::SSLIdentity ** identity)369 virtual bool GetIdentity_w(rtc::SSLIdentity** identity) { 370 return false; 371 } 372 373 // Pushes down the transport parameters from the local description, such 374 // as the ICE ufrag and pwd. 375 // Derived classes can override, but must call the base as well. 376 virtual bool ApplyLocalTransportDescription_w(TransportChannelImpl* channel, 377 std::string* error_desc); 378 379 // Pushes down remote ice credentials from the remote description to the 380 // transport channel. 381 virtual bool ApplyRemoteTransportDescription_w(TransportChannelImpl* ch, 382 std::string* error_desc); 383 384 // Negotiates the transport parameters based on the current local and remote 385 // transport description, such at the version of ICE to use, and whether DTLS 386 // should be activated. 387 // Derived classes can negotiate their specific parameters here, but must call 388 // the base as well. 389 virtual bool NegotiateTransportDescription_w(ContentAction local_role, 390 std::string* error_desc); 391 392 // Pushes down the transport parameters obtained via negotiation. 393 // Derived classes can set their specific parameters here, but must call the 394 // base as well. 395 virtual bool ApplyNegotiatedTransportDescription_w( 396 TransportChannelImpl* channel, std::string* error_desc); 397 GetSslRole_w(rtc::SSLRole * ssl_role)398 virtual bool GetSslRole_w(rtc::SSLRole* ssl_role) const { 399 return false; 400 } 401 402 private: 403 struct ChannelMapEntry { ChannelMapEntryChannelMapEntry404 ChannelMapEntry() : impl_(NULL), candidates_allocated_(false), ref_(0) {} ChannelMapEntryChannelMapEntry405 explicit ChannelMapEntry(TransportChannelImpl *impl) 406 : impl_(impl), 407 candidates_allocated_(false), 408 ref_(0) { 409 } 410 AddRefChannelMapEntry411 void AddRef() { ++ref_; } DecRefChannelMapEntry412 void DecRef() { 413 ASSERT(ref_ > 0); 414 --ref_; 415 } refChannelMapEntry416 int ref() const { return ref_; } 417 getChannelMapEntry418 TransportChannelImpl* get() const { return impl_; } 419 TransportChannelImpl* operator->() const { return impl_; } set_candidates_allocatedChannelMapEntry420 void set_candidates_allocated(bool status) { 421 candidates_allocated_ = status; 422 } candidates_allocatedChannelMapEntry423 bool candidates_allocated() const { return candidates_allocated_; } 424 425 private: 426 TransportChannelImpl *impl_; 427 bool candidates_allocated_; 428 int ref_; 429 }; 430 431 // Candidate component => ChannelMapEntry 432 typedef std::map<int, ChannelMapEntry> ChannelMap; 433 434 // Called when the state of a channel changes. 435 void OnChannelReadableState(TransportChannel* channel); 436 void OnChannelWritableState(TransportChannel* channel); 437 438 // Called when a channel requests signaling. 439 void OnChannelRequestSignaling(TransportChannelImpl* channel); 440 441 // Called when a candidate is ready from remote peer. 442 void OnRemoteCandidate(const Candidate& candidate); 443 // Called when a candidate is ready from channel. 444 void OnChannelCandidateReady(TransportChannelImpl* channel, 445 const Candidate& candidate); 446 void OnChannelRouteChange(TransportChannel* channel, 447 const Candidate& remote_candidate); 448 void OnChannelCandidatesAllocationDone(TransportChannelImpl* channel); 449 // Called when there is ICE role change. 450 void OnRoleConflict(TransportChannelImpl* channel); 451 // Called when the channel removes a connection. 452 void OnChannelConnectionRemoved(TransportChannelImpl* channel); 453 454 // Dispatches messages to the appropriate handler (below). 455 void OnMessage(rtc::Message* msg); 456 457 // These are versions of the above methods that are called only on a 458 // particular thread (s = signaling, w = worker). The above methods post or 459 // send a message to invoke this version. 460 TransportChannelImpl* CreateChannel_w(int component); 461 void DestroyChannel_w(int component); 462 void ConnectChannels_w(); 463 void ResetChannels_w(); 464 void DestroyAllChannels_w(); 465 void OnRemoteCandidate_w(const Candidate& candidate); 466 void OnChannelReadableState_s(); 467 void OnChannelWritableState_s(); 468 void OnChannelRequestSignaling_s(int component); 469 void OnConnecting_s(); 470 void OnChannelRouteChange_s(const TransportChannel* channel, 471 const Candidate& remote_candidate); 472 void OnChannelCandidatesAllocationDone_s(); 473 474 // Helper function that invokes the given function on every channel. 475 typedef void (TransportChannelImpl::* TransportChannelFunc)(); 476 void CallChannels_w(TransportChannelFunc func); 477 478 // Computes the OR of the channel's read or write state (argument picks). 479 TransportState GetTransportState_s(bool read); 480 481 void OnChannelCandidateReady_s(); 482 483 void SetIceRole_w(IceRole role); 484 void SetRemoteIceMode_w(IceMode mode); 485 bool SetLocalTransportDescription_w(const TransportDescription& desc, 486 ContentAction action, 487 std::string* error_desc); 488 bool SetRemoteTransportDescription_w(const TransportDescription& desc, 489 ContentAction action, 490 std::string* error_desc); 491 bool GetStats_w(TransportStats* infos); 492 bool GetRemoteCertificate_w(rtc::SSLCertificate** cert); 493 494 // Sends SignalCompleted if we are now in that state. 495 void MaybeCompleted_w(); 496 497 rtc::Thread* signaling_thread_; 498 rtc::Thread* worker_thread_; 499 std::string content_name_; 500 std::string type_; 501 PortAllocator* allocator_; 502 bool destroyed_; 503 TransportState readable_; 504 TransportState writable_; 505 bool was_writable_; 506 bool connect_requested_; 507 IceRole ice_role_; 508 uint64 tiebreaker_; 509 TransportProtocol protocol_; 510 IceMode remote_ice_mode_; 511 rtc::scoped_ptr<TransportDescription> local_description_; 512 rtc::scoped_ptr<TransportDescription> remote_description_; 513 514 ChannelMap channels_; 515 // Buffers the ready_candidates so that SignalCanidatesReady can 516 // provide them in multiples. 517 std::vector<Candidate> ready_candidates_; 518 // Protects changes to channels and messages 519 rtc::CriticalSection crit_; 520 521 DISALLOW_EVIL_CONSTRUCTORS(Transport); 522 }; 523 524 // Extract a TransportProtocol from a TransportDescription. 525 TransportProtocol TransportProtocolFromDescription( 526 const TransportDescription* desc); 527 528 } // namespace cricket 529 530 #endif // TALK_P2P_BASE_TRANSPORT_H_ 531