Home | History | Annotate | Download | only in base
      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 
    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 {
    143   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.
    208   rtc::Thread* signaling_thread() { return signaling_thread_; }
    209   // Returns the worker thread. The actual networking is done on this thread.
    210   rtc::Thread* worker_thread() { return worker_thread_; }
    211 
    212   // Returns the content_name of this transport.
    213   const std::string& content_name() const { return content_name_; }
    214   // Returns the type of this transport.
    215   const std::string& type() const { return type_; }
    216 
    217   // Returns the port allocator object for this transport.
    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().
    225   bool readable() const { return any_channels_readable(); }
    226   bool writable() const { return any_channels_writable(); }
    227   bool was_writable() const { return was_writable_; }
    228   bool any_channels_readable() const {
    229     return (readable_ == TRANSPORT_STATE_SOME ||
    230             readable_ == TRANSPORT_STATE_ALL);
    231   }
    232   bool any_channels_writable() const {
    233     return (writable_ == TRANSPORT_STATE_SOME ||
    234             writable_ == TRANSPORT_STATE_ALL);
    235   }
    236   bool all_channels_readable() const {
    237     return (readable_ == TRANSPORT_STATE_ALL);
    238   }
    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.
    248   bool connect_requested() const { return connect_requested_; }
    249 
    250   void SetIceRole(IceRole role);
    251   IceRole ice_role() const { return ice_role_; }
    252 
    253   void SetIceTiebreaker(uint64 IceTiebreaker) { tiebreaker_ = 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 
    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.
    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.
    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.
    353   virtual void OnTransportSignalingReady() {}
    354 
    355   // The current local transport description, for use by derived classes
    356   // when performing transport description negotiation.
    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.
    363   const TransportDescription* remote_description() const {
    364     return remote_description_.get();
    365   }
    366 
    367   virtual void SetIdentity_w(rtc::SSLIdentity* identity) {}
    368 
    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 
    398   virtual bool GetSslRole_w(rtc::SSLRole* ssl_role) const {
    399     return false;
    400   }
    401 
    402  private:
    403   struct ChannelMapEntry {
    404     ChannelMapEntry() : impl_(NULL), candidates_allocated_(false), ref_(0) {}
    405     explicit ChannelMapEntry(TransportChannelImpl *impl)
    406         : impl_(impl),
    407           candidates_allocated_(false),
    408           ref_(0) {
    409     }
    410 
    411     void AddRef() { ++ref_; }
    412     void DecRef() {
    413       ASSERT(ref_ > 0);
    414       --ref_;
    415     }
    416     int ref() const { return ref_; }
    417 
    418     TransportChannelImpl* get() const { return impl_; }
    419     TransportChannelImpl* operator->() const  { return impl_; }
    420     void set_candidates_allocated(bool status) {
    421       candidates_allocated_ = status;
    422     }
    423     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