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 <string>
     50 #include <map>
     51 #include <vector>
     52 #include "talk/base/criticalsection.h"
     53 #include "talk/base/messagequeue.h"
     54 #include "talk/base/sigslot.h"
     55 #include "talk/p2p/base/candidate.h"
     56 #include "talk/p2p/base/constants.h"
     57 #include "talk/p2p/base/sessiondescription.h"
     58 #include "talk/p2p/base/transportinfo.h"
     59 
     60 namespace talk_base {
     61 class Thread;
     62 }
     63 
     64 namespace buzz {
     65 class QName;
     66 class XmlElement;
     67 }
     68 
     69 namespace cricket {
     70 
     71 struct ParseError;
     72 struct WriteError;
     73 class CandidateTranslator;
     74 class PortAllocator;
     75 class SessionManager;
     76 class Session;
     77 class TransportChannel;
     78 class TransportChannelImpl;
     79 
     80 typedef std::vector<buzz::XmlElement*> XmlElements;
     81 typedef std::vector<Candidate> Candidates;
     82 
     83 // Used to parse and serialize (write) transport candidates.  For
     84 // convenience of old code, Transports will implement TransportParser.
     85 // Parse/Write seems better than Serialize/Deserialize or
     86 // Create/Translate.
     87 class TransportParser {
     88  public:
     89   // The incoming Translator value may be null, in which case
     90   // ParseCandidates should return false if there are candidates to
     91   // parse (indicating a failure to parse).  If the Translator is null
     92   // and there are no candidates to parse, then return true,
     93   // indicating a successful parse of 0 candidates.
     94 
     95   // Parse or write a transport description, including ICE credentials and
     96   // any DTLS fingerprint. Since only Jingle has transport descriptions, these
     97   // functions are only used when serializing to Jingle.
     98   virtual bool ParseTransportDescription(const buzz::XmlElement* elem,
     99                                          const CandidateTranslator* translator,
    100                                          TransportDescription* tdesc,
    101                                          ParseError* error) = 0;
    102   virtual bool WriteTransportDescription(const TransportDescription& tdesc,
    103                                          const CandidateTranslator* translator,
    104                                          buzz::XmlElement** tdesc_elem,
    105                                          WriteError* error) = 0;
    106 
    107 
    108   // Parse a single candidate. This must be used when parsing Gingle
    109   // candidates, since there is no enclosing transport description.
    110   virtual bool ParseGingleCandidate(const buzz::XmlElement* elem,
    111                                     const CandidateTranslator* translator,
    112                                     Candidate* candidates,
    113                                     ParseError* error) = 0;
    114   virtual bool WriteGingleCandidate(const Candidate& candidate,
    115                                     const CandidateTranslator* translator,
    116                                     buzz::XmlElement** candidate_elem,
    117                                     WriteError* error) = 0;
    118 
    119   // Helper function to parse an element describing an address.  This
    120   // retrieves the IP and port from the given element and verifies
    121   // that they look like plausible values.
    122   bool ParseAddress(const buzz::XmlElement* elem,
    123                     const buzz::QName& address_name,
    124                     const buzz::QName& port_name,
    125                     talk_base::SocketAddress* address,
    126                     ParseError* error);
    127 
    128   virtual ~TransportParser() {}
    129 };
    130 
    131 // For "writable" and "readable", we need to differentiate between
    132 // none, all, and some.
    133 enum TransportState {
    134   TRANSPORT_STATE_NONE = 0,
    135   TRANSPORT_STATE_SOME,
    136   TRANSPORT_STATE_ALL
    137 };
    138 
    139 // Stats that we can return about the connections for a transport channel.
    140 // TODO(hta): Rename to ConnectionStats
    141 struct ConnectionInfo {
    142   ConnectionInfo()
    143       : best_connection(false),
    144         writable(false),
    145         readable(false),
    146         timeout(false),
    147         new_connection(false),
    148         rtt(0),
    149         sent_total_bytes(0),
    150         sent_bytes_second(0),
    151         recv_total_bytes(0),
    152         recv_bytes_second(0),
    153         key(NULL) {}
    154 
    155   bool best_connection;        // Is this the best connection we have?
    156   bool writable;               // Has this connection received a STUN response?
    157   bool readable;               // Has this connection received a STUN request?
    158   bool timeout;                // Has this connection timed out?
    159   bool new_connection;         // Is this a newly created connection?
    160   size_t rtt;                  // The STUN RTT for this connection.
    161   size_t sent_total_bytes;     // Total bytes sent on this connection.
    162   size_t sent_bytes_second;    // Bps over the last measurement interval.
    163   size_t recv_total_bytes;     // Total bytes received on this connection.
    164   size_t recv_bytes_second;    // Bps over the last measurement interval.
    165   Candidate local_candidate;   // The local candidate for this connection.
    166   Candidate remote_candidate;  // The remote candidate for this connection.
    167   void* key;                   // A static value that identifies this conn.
    168 };
    169 
    170 // Information about all the connections of a channel.
    171 typedef std::vector<ConnectionInfo> ConnectionInfos;
    172 
    173 // Information about a specific channel
    174 struct TransportChannelStats {
    175   int component;
    176   ConnectionInfos connection_infos;
    177 };
    178 
    179 // Information about all the channels of a transport.
    180 // TODO(hta): Consider if a simple vector is as good as a map.
    181 typedef std::vector<TransportChannelStats> TransportChannelStatsList;
    182 
    183 // Information about the stats of a transport.
    184 struct TransportStats {
    185   std::string content_name;
    186   TransportChannelStatsList channel_stats;
    187 };
    188 
    189 class Transport : public talk_base::MessageHandler,
    190                   public sigslot::has_slots<> {
    191  public:
    192   Transport(talk_base::Thread* signaling_thread,
    193             talk_base::Thread* worker_thread,
    194             const std::string& content_name,
    195             const std::string& type,
    196             PortAllocator* allocator);
    197   virtual ~Transport();
    198 
    199   // Returns the signaling thread. The app talks to Transport on this thread.
    200   talk_base::Thread* signaling_thread() { return signaling_thread_; }
    201   // Returns the worker thread. The actual networking is done on this thread.
    202   talk_base::Thread* worker_thread() { return worker_thread_; }
    203 
    204   // Returns the content_name of this transport.
    205   const std::string& content_name() const { return content_name_; }
    206   // Returns the type of this transport.
    207   const std::string& type() const { return type_; }
    208 
    209   // Returns the port allocator object for this transport.
    210   PortAllocator* port_allocator() { return allocator_; }
    211 
    212   // Returns the readable and states of this manager.  These bits are the ORs
    213   // of the corresponding bits on the managed channels.  Each time one of these
    214   // states changes, a signal is raised.
    215   // TODO: Replace uses of readable() and writable() with
    216   // any_channels_readable() and any_channels_writable().
    217   bool readable() const { return any_channels_readable(); }
    218   bool writable() const { return any_channels_writable(); }
    219   bool was_writable() const { return was_writable_; }
    220   bool any_channels_readable() const {
    221     return (readable_ == TRANSPORT_STATE_SOME ||
    222             readable_ == TRANSPORT_STATE_ALL);
    223   }
    224   bool any_channels_writable() const {
    225     return (writable_ == TRANSPORT_STATE_SOME ||
    226             writable_ == TRANSPORT_STATE_ALL);
    227   }
    228   bool all_channels_readable() const {
    229     return (readable_ == TRANSPORT_STATE_ALL);
    230   }
    231   bool all_channels_writable() const {
    232     return (writable_ == TRANSPORT_STATE_ALL);
    233   }
    234   sigslot::signal1<Transport*> SignalReadableState;
    235   sigslot::signal1<Transport*> SignalWritableState;
    236 
    237   // Returns whether the client has requested the channels to connect.
    238   bool connect_requested() const { return connect_requested_; }
    239 
    240   void SetIceRole(IceRole role);
    241   IceRole ice_role() const { return ice_role_; }
    242 
    243   void SetIceTiebreaker(uint64 IceTiebreaker) { tiebreaker_ = IceTiebreaker; }
    244   uint64 IceTiebreaker() { return tiebreaker_; }
    245 
    246   // Must be called before applying local session description.
    247   void SetIdentity(talk_base::SSLIdentity* identity);
    248 
    249   TransportProtocol protocol() const { return protocol_; }
    250 
    251   // Create, destroy, and lookup the channels of this type by their components.
    252   TransportChannelImpl* CreateChannel(int component);
    253   // Note: GetChannel may lead to race conditions, since the mutex is not held
    254   // after the pointer is returned.
    255   TransportChannelImpl* GetChannel(int component);
    256   // Note: HasChannel does not lead to race conditions, unlike GetChannel.
    257   bool HasChannel(int component) {
    258     return (NULL != GetChannel(component));
    259   }
    260   bool HasChannels();
    261   void DestroyChannel(int component);
    262 
    263   // Set the local TransportDescription to be used by TransportChannels.
    264   // This should be called before ConnectChannels().
    265   bool SetLocalTransportDescription(const TransportDescription& description,
    266                                     ContentAction action);
    267 
    268   // Set the remote TransportDescription to be used by TransportChannels.
    269   bool SetRemoteTransportDescription(const TransportDescription& description,
    270                                      ContentAction action);
    271 
    272   // Tells all current and future channels to start connecting.  When the first
    273   // channel begins connecting, the following signal is raised.
    274   void ConnectChannels();
    275   sigslot::signal1<Transport*> SignalConnecting;
    276 
    277   // Resets all of the channels back to their initial state.  They are no
    278   // longer connecting.
    279   void ResetChannels();
    280 
    281   // Destroys every channel created so far.
    282   void DestroyAllChannels();
    283 
    284   bool GetStats(TransportStats* stats);
    285 
    286   // Before any stanza is sent, the manager will request signaling.  Once
    287   // signaling is available, the client should call OnSignalingReady.  Once
    288   // this occurs, the transport (or its channels) can send any waiting stanzas.
    289   // OnSignalingReady invokes OnTransportSignalingReady and then forwards this
    290   // signal to each channel.
    291   sigslot::signal1<Transport*> SignalRequestSignaling;
    292   void OnSignalingReady();
    293 
    294   // Handles sending of ready candidates and receiving of remote candidates.
    295   sigslot::signal2<Transport*,
    296                    const std::vector<Candidate>&> SignalCandidatesReady;
    297 
    298   sigslot::signal1<Transport*> SignalCandidatesAllocationDone;
    299   void OnRemoteCandidates(const std::vector<Candidate>& candidates);
    300 
    301   // If candidate is not acceptable, returns false and sets error.
    302   // Call this before calling OnRemoteCandidates.
    303   virtual bool VerifyCandidate(const Candidate& candidate,
    304                                std::string* error);
    305 
    306   // Signals when the best connection for a channel changes.
    307   sigslot::signal3<Transport*,
    308                    int,  // component
    309                    const Candidate&> SignalRouteChange;
    310 
    311   // A transport message has generated an transport-specific error.  The
    312   // stanza that caused the error is available in session_msg.  If false is
    313   // returned, the error is considered unrecoverable, and the session is
    314   // terminated.
    315   // TODO(juberti): Remove these obsolete functions once Session no longer
    316   // references them.
    317   virtual void OnTransportError(const buzz::XmlElement* error) {}
    318   sigslot::signal6<Transport*, const buzz::XmlElement*, const buzz::QName&,
    319                    const std::string&, const std::string&,
    320                    const buzz::XmlElement*>
    321       SignalTransportError;
    322 
    323   // Forwards the signal from TransportChannel to BaseSession.
    324   sigslot::signal0<> SignalRoleConflict;
    325 
    326  protected:
    327   // These are called by Create/DestroyChannel above in order to create or
    328   // destroy the appropriate type of channel.
    329   virtual TransportChannelImpl* CreateTransportChannel(int component) = 0;
    330   virtual void DestroyTransportChannel(TransportChannelImpl* channel) = 0;
    331 
    332   // Informs the subclass that we received the signaling ready message.
    333   virtual void OnTransportSignalingReady() {}
    334 
    335   // The current local transport description, for use by derived classes
    336   // when performing transport description negotiation.
    337   const TransportDescription* local_description() const {
    338     return local_description_.get();
    339   }
    340 
    341   // The current remote transport description, for use by derived classes
    342   // when performing transport description negotiation.
    343   const TransportDescription* remote_description() const {
    344     return remote_description_.get();
    345   }
    346 
    347   virtual void SetIdentity_w(talk_base::SSLIdentity* identity) {}
    348 
    349   // Pushes down the transport parameters from the local description, such
    350   // as the ICE ufrag and pwd.
    351   // Derived classes can override, but must call the base as well.
    352   virtual bool ApplyLocalTransportDescription_w(TransportChannelImpl*
    353                                                 channel);
    354 
    355   // Pushes down remote ice credentials from the remote description to the
    356   // transport channel.
    357   virtual bool ApplyRemoteTransportDescription_w(TransportChannelImpl* ch);
    358 
    359   // Negotiates the transport parameters based on the current local and remote
    360   // transport description, such at the version of ICE to use, and whether DTLS
    361   // should be activated.
    362   // Derived classes can negotiate their specific parameters here, but must call
    363   // the base as well.
    364   virtual bool NegotiateTransportDescription_w(ContentAction local_role);
    365 
    366   // Pushes down the transport parameters obtained via negotiation.
    367   // Derived classes can set their specific parameters here, but must call the
    368   // base as well.
    369   virtual void ApplyNegotiatedTransportDescription_w(
    370       TransportChannelImpl* channel);
    371 
    372  private:
    373   struct ChannelMapEntry {
    374     ChannelMapEntry() : impl_(NULL), candidates_allocated_(false), ref_(0) {}
    375     explicit ChannelMapEntry(TransportChannelImpl *impl)
    376         : impl_(impl),
    377           candidates_allocated_(false),
    378           ref_(0) {
    379     }
    380 
    381     void AddRef() { ++ref_; }
    382     void DecRef() {
    383       ASSERT(ref_ > 0);
    384       --ref_;
    385     }
    386     int ref() const { return ref_; }
    387 
    388     TransportChannelImpl* get() const { return impl_; }
    389     TransportChannelImpl* operator->() const  { return impl_; }
    390     void set_candidates_allocated(bool status) {
    391       candidates_allocated_ = status;
    392     }
    393     bool candidates_allocated() const { return candidates_allocated_; }
    394 
    395   private:
    396     TransportChannelImpl *impl_;
    397     bool candidates_allocated_;
    398     int ref_;
    399   };
    400 
    401   // Candidate component => ChannelMapEntry
    402   typedef std::map<int, ChannelMapEntry> ChannelMap;
    403 
    404   // Called when the state of a channel changes.
    405   void OnChannelReadableState(TransportChannel* channel);
    406   void OnChannelWritableState(TransportChannel* channel);
    407 
    408   // Called when a channel requests signaling.
    409   void OnChannelRequestSignaling(TransportChannelImpl* channel);
    410 
    411   // Called when a candidate is ready from remote peer.
    412   void OnRemoteCandidate(const Candidate& candidate);
    413   // Called when a candidate is ready from channel.
    414   void OnChannelCandidateReady(TransportChannelImpl* channel,
    415                                const Candidate& candidate);
    416   void OnChannelRouteChange(TransportChannel* channel,
    417                             const Candidate& remote_candidate);
    418   void OnChannelCandidatesAllocationDone(TransportChannelImpl* channel);
    419   // Called when there is ICE role change.
    420   void OnRoleConflict(TransportChannelImpl* channel);
    421 
    422   // Dispatches messages to the appropriate handler (below).
    423   void OnMessage(talk_base::Message* msg);
    424 
    425   // These are versions of the above methods that are called only on a
    426   // particular thread (s = signaling, w = worker).  The above methods post or
    427   // send a message to invoke this version.
    428   TransportChannelImpl* CreateChannel_w(int component);
    429   void DestroyChannel_w(int component);
    430   void ConnectChannels_w();
    431   void ResetChannels_w();
    432   void DestroyAllChannels_w();
    433   void OnRemoteCandidate_w(const Candidate& candidate);
    434   void OnChannelReadableState_s();
    435   void OnChannelWritableState_s();
    436   void OnChannelRequestSignaling_s(int component);
    437   void OnConnecting_s();
    438   void OnChannelRouteChange_s(const TransportChannel* channel,
    439                               const Candidate& remote_candidate);
    440   void OnChannelCandidatesAllocationDone_s();
    441 
    442   // Helper function that invokes the given function on every channel.
    443   typedef void (TransportChannelImpl::* TransportChannelFunc)();
    444   void CallChannels_w(TransportChannelFunc func);
    445 
    446   // Computes the OR of the channel's read or write state (argument picks).
    447   TransportState GetTransportState_s(bool read);
    448 
    449   void OnChannelCandidateReady_s();
    450 
    451   void SetIceRole_w(IceRole role);
    452   void SetRemoteIceMode_w(IceMode mode);
    453   bool SetLocalTransportDescription_w(const TransportDescription& desc,
    454                                       ContentAction action);
    455   bool SetRemoteTransportDescription_w(const TransportDescription& desc,
    456                                        ContentAction action);
    457   bool GetStats_w(TransportStats* infos);
    458 
    459   talk_base::Thread* signaling_thread_;
    460   talk_base::Thread* worker_thread_;
    461   std::string content_name_;
    462   std::string type_;
    463   PortAllocator* allocator_;
    464   bool destroyed_;
    465   TransportState readable_;
    466   TransportState writable_;
    467   bool was_writable_;
    468   bool connect_requested_;
    469   IceRole ice_role_;
    470   uint64 tiebreaker_;
    471   TransportProtocol protocol_;
    472   IceMode remote_ice_mode_;
    473   talk_base::scoped_ptr<TransportDescription> local_description_;
    474   talk_base::scoped_ptr<TransportDescription> remote_description_;
    475 
    476   ChannelMap channels_;
    477   // Buffers the ready_candidates so that SignalCanidatesReady can
    478   // provide them in multiples.
    479   std::vector<Candidate> ready_candidates_;
    480   // Protects changes to channels and messages
    481   talk_base::CriticalSection crit_;
    482 
    483   DISALLOW_EVIL_CONSTRUCTORS(Transport);
    484 };
    485 
    486 // Extract a TransportProtocol from a TransportDescription.
    487 TransportProtocol TransportProtocolFromDescription(
    488     const TransportDescription* desc);
    489 
    490 }  // namespace cricket
    491 
    492 #endif  // TALK_P2P_BASE_TRANSPORT_H_
    493