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/base/sslstreamadapter.h"
     56 #include "talk/p2p/base/candidate.h"
     57 #include "talk/p2p/base/constants.h"
     58 #include "talk/p2p/base/sessiondescription.h"
     59 #include "talk/p2p/base/transportinfo.h"
     60 
     61 namespace talk_base {
     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                     talk_base::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 class Transport : public talk_base::MessageHandler,
    193                   public sigslot::has_slots<> {
    194  public:
    195   Transport(talk_base::Thread* signaling_thread,
    196             talk_base::Thread* worker_thread,
    197             const std::string& content_name,
    198             const std::string& type,
    199             PortAllocator* allocator);
    200   virtual ~Transport();
    201 
    202   // Returns the signaling thread. The app talks to Transport on this thread.
    203   talk_base::Thread* signaling_thread() { return signaling_thread_; }
    204   // Returns the worker thread. The actual networking is done on this thread.
    205   talk_base::Thread* worker_thread() { return worker_thread_; }
    206 
    207   // Returns the content_name of this transport.
    208   const std::string& content_name() const { return content_name_; }
    209   // Returns the type of this transport.
    210   const std::string& type() const { return type_; }
    211 
    212   // Returns the port allocator object for this transport.
    213   PortAllocator* port_allocator() { return allocator_; }
    214 
    215   // Returns the readable and states of this manager.  These bits are the ORs
    216   // of the corresponding bits on the managed channels.  Each time one of these
    217   // states changes, a signal is raised.
    218   // TODO: Replace uses of readable() and writable() with
    219   // any_channels_readable() and any_channels_writable().
    220   bool readable() const { return any_channels_readable(); }
    221   bool writable() const { return any_channels_writable(); }
    222   bool was_writable() const { return was_writable_; }
    223   bool any_channels_readable() const {
    224     return (readable_ == TRANSPORT_STATE_SOME ||
    225             readable_ == TRANSPORT_STATE_ALL);
    226   }
    227   bool any_channels_writable() const {
    228     return (writable_ == TRANSPORT_STATE_SOME ||
    229             writable_ == TRANSPORT_STATE_ALL);
    230   }
    231   bool all_channels_readable() const {
    232     return (readable_ == TRANSPORT_STATE_ALL);
    233   }
    234   bool all_channels_writable() const {
    235     return (writable_ == TRANSPORT_STATE_ALL);
    236   }
    237   sigslot::signal1<Transport*> SignalReadableState;
    238   sigslot::signal1<Transport*> SignalWritableState;
    239   sigslot::signal1<Transport*> SignalCompleted;
    240   sigslot::signal1<Transport*> SignalFailed;
    241 
    242   // Returns whether the client has requested the channels to connect.
    243   bool connect_requested() const { return connect_requested_; }
    244 
    245   void SetIceRole(IceRole role);
    246   IceRole ice_role() const { return ice_role_; }
    247 
    248   void SetIceTiebreaker(uint64 IceTiebreaker) { tiebreaker_ = IceTiebreaker; }
    249   uint64 IceTiebreaker() { return tiebreaker_; }
    250 
    251   // Must be called before applying local session description.
    252   void SetIdentity(talk_base::SSLIdentity* identity);
    253 
    254   // Get a copy of the local identity provided by SetIdentity.
    255   bool GetIdentity(talk_base::SSLIdentity** identity);
    256 
    257   // Get a copy of the remote certificate in use by the specified channel.
    258   bool GetRemoteCertificate(talk_base::SSLCertificate** cert);
    259 
    260   TransportProtocol protocol() const { return protocol_; }
    261 
    262   // Create, destroy, and lookup the channels of this type by their components.
    263   TransportChannelImpl* CreateChannel(int component);
    264   // Note: GetChannel may lead to race conditions, since the mutex is not held
    265   // after the pointer is returned.
    266   TransportChannelImpl* GetChannel(int component);
    267   // Note: HasChannel does not lead to race conditions, unlike GetChannel.
    268   bool HasChannel(int component) {
    269     return (NULL != GetChannel(component));
    270   }
    271   bool HasChannels();
    272   void DestroyChannel(int component);
    273 
    274   // Set the local TransportDescription to be used by TransportChannels.
    275   // This should be called before ConnectChannels().
    276   bool SetLocalTransportDescription(const TransportDescription& description,
    277                                     ContentAction action,
    278                                     std::string* error_desc);
    279 
    280   // Set the remote TransportDescription to be used by TransportChannels.
    281   bool SetRemoteTransportDescription(const TransportDescription& description,
    282                                      ContentAction action,
    283                                      std::string* error_desc);
    284 
    285   // Tells all current and future channels to start connecting.  When the first
    286   // channel begins connecting, the following signal is raised.
    287   void ConnectChannels();
    288   sigslot::signal1<Transport*> SignalConnecting;
    289 
    290   // Resets all of the channels back to their initial state.  They are no
    291   // longer connecting.
    292   void ResetChannels();
    293 
    294   // Destroys every channel created so far.
    295   void DestroyAllChannels();
    296 
    297   bool GetStats(TransportStats* stats);
    298 
    299   // Before any stanza is sent, the manager will request signaling.  Once
    300   // signaling is available, the client should call OnSignalingReady.  Once
    301   // this occurs, the transport (or its channels) can send any waiting stanzas.
    302   // OnSignalingReady invokes OnTransportSignalingReady and then forwards this
    303   // signal to each channel.
    304   sigslot::signal1<Transport*> SignalRequestSignaling;
    305   void OnSignalingReady();
    306 
    307   // Handles sending of ready candidates and receiving of remote candidates.
    308   sigslot::signal2<Transport*,
    309                    const std::vector<Candidate>&> SignalCandidatesReady;
    310 
    311   sigslot::signal1<Transport*> SignalCandidatesAllocationDone;
    312   void OnRemoteCandidates(const std::vector<Candidate>& candidates);
    313 
    314   // If candidate is not acceptable, returns false and sets error.
    315   // Call this before calling OnRemoteCandidates.
    316   virtual bool VerifyCandidate(const Candidate& candidate,
    317                                std::string* error);
    318 
    319   // Signals when the best connection for a channel changes.
    320   sigslot::signal3<Transport*,
    321                    int,  // component
    322                    const Candidate&> SignalRouteChange;
    323 
    324   // A transport message has generated an transport-specific error.  The
    325   // stanza that caused the error is available in session_msg.  If false is
    326   // returned, the error is considered unrecoverable, and the session is
    327   // terminated.
    328   // TODO(juberti): Remove these obsolete functions once Session no longer
    329   // references them.
    330   virtual void OnTransportError(const buzz::XmlElement* error) {}
    331   sigslot::signal6<Transport*, const buzz::XmlElement*, const buzz::QName&,
    332                    const std::string&, const std::string&,
    333                    const buzz::XmlElement*>
    334       SignalTransportError;
    335 
    336   // Forwards the signal from TransportChannel to BaseSession.
    337   sigslot::signal0<> SignalRoleConflict;
    338 
    339   virtual bool GetSslRole(talk_base::SSLRole* ssl_role) const;
    340 
    341  protected:
    342   // These are called by Create/DestroyChannel above in order to create or
    343   // destroy the appropriate type of channel.
    344   virtual TransportChannelImpl* CreateTransportChannel(int component) = 0;
    345   virtual void DestroyTransportChannel(TransportChannelImpl* channel) = 0;
    346 
    347   // Informs the subclass that we received the signaling ready message.
    348   virtual void OnTransportSignalingReady() {}
    349 
    350   // The current local transport description, for use by derived classes
    351   // when performing transport description negotiation.
    352   const TransportDescription* local_description() const {
    353     return local_description_.get();
    354   }
    355 
    356   // The current remote transport description, for use by derived classes
    357   // when performing transport description negotiation.
    358   const TransportDescription* remote_description() const {
    359     return remote_description_.get();
    360   }
    361 
    362   virtual void SetIdentity_w(talk_base::SSLIdentity* identity) {}
    363 
    364   virtual bool GetIdentity_w(talk_base::SSLIdentity** identity) {
    365     return false;
    366   }
    367 
    368   // Pushes down the transport parameters from the local description, such
    369   // as the ICE ufrag and pwd.
    370   // Derived classes can override, but must call the base as well.
    371   virtual bool ApplyLocalTransportDescription_w(TransportChannelImpl* channel,
    372                                                 std::string* error_desc);
    373 
    374   // Pushes down remote ice credentials from the remote description to the
    375   // transport channel.
    376   virtual bool ApplyRemoteTransportDescription_w(TransportChannelImpl* ch,
    377                                                  std::string* error_desc);
    378 
    379   // Negotiates the transport parameters based on the current local and remote
    380   // transport description, such at the version of ICE to use, and whether DTLS
    381   // should be activated.
    382   // Derived classes can negotiate their specific parameters here, but must call
    383   // the base as well.
    384   virtual bool NegotiateTransportDescription_w(ContentAction local_role,
    385                                                std::string* error_desc);
    386 
    387   // Pushes down the transport parameters obtained via negotiation.
    388   // Derived classes can set their specific parameters here, but must call the
    389   // base as well.
    390   virtual bool ApplyNegotiatedTransportDescription_w(
    391       TransportChannelImpl* channel, std::string* error_desc);
    392 
    393   virtual bool GetSslRole_w(talk_base::SSLRole* ssl_role) const {
    394     return false;
    395   }
    396 
    397  private:
    398   struct ChannelMapEntry {
    399     ChannelMapEntry() : impl_(NULL), candidates_allocated_(false), ref_(0) {}
    400     explicit ChannelMapEntry(TransportChannelImpl *impl)
    401         : impl_(impl),
    402           candidates_allocated_(false),
    403           ref_(0) {
    404     }
    405 
    406     void AddRef() { ++ref_; }
    407     void DecRef() {
    408       ASSERT(ref_ > 0);
    409       --ref_;
    410     }
    411     int ref() const { return ref_; }
    412 
    413     TransportChannelImpl* get() const { return impl_; }
    414     TransportChannelImpl* operator->() const  { return impl_; }
    415     void set_candidates_allocated(bool status) {
    416       candidates_allocated_ = status;
    417     }
    418     bool candidates_allocated() const { return candidates_allocated_; }
    419 
    420   private:
    421     TransportChannelImpl *impl_;
    422     bool candidates_allocated_;
    423     int ref_;
    424   };
    425 
    426   // Candidate component => ChannelMapEntry
    427   typedef std::map<int, ChannelMapEntry> ChannelMap;
    428 
    429   // Called when the state of a channel changes.
    430   void OnChannelReadableState(TransportChannel* channel);
    431   void OnChannelWritableState(TransportChannel* channel);
    432 
    433   // Called when a channel requests signaling.
    434   void OnChannelRequestSignaling(TransportChannelImpl* channel);
    435 
    436   // Called when a candidate is ready from remote peer.
    437   void OnRemoteCandidate(const Candidate& candidate);
    438   // Called when a candidate is ready from channel.
    439   void OnChannelCandidateReady(TransportChannelImpl* channel,
    440                                const Candidate& candidate);
    441   void OnChannelRouteChange(TransportChannel* channel,
    442                             const Candidate& remote_candidate);
    443   void OnChannelCandidatesAllocationDone(TransportChannelImpl* channel);
    444   // Called when there is ICE role change.
    445   void OnRoleConflict(TransportChannelImpl* channel);
    446   // Called when the channel removes a connection.
    447   void OnChannelConnectionRemoved(TransportChannelImpl* channel);
    448 
    449   // Dispatches messages to the appropriate handler (below).
    450   void OnMessage(talk_base::Message* msg);
    451 
    452   // These are versions of the above methods that are called only on a
    453   // particular thread (s = signaling, w = worker).  The above methods post or
    454   // send a message to invoke this version.
    455   TransportChannelImpl* CreateChannel_w(int component);
    456   void DestroyChannel_w(int component);
    457   void ConnectChannels_w();
    458   void ResetChannels_w();
    459   void DestroyAllChannels_w();
    460   void OnRemoteCandidate_w(const Candidate& candidate);
    461   void OnChannelReadableState_s();
    462   void OnChannelWritableState_s();
    463   void OnChannelRequestSignaling_s(int component);
    464   void OnConnecting_s();
    465   void OnChannelRouteChange_s(const TransportChannel* channel,
    466                               const Candidate& remote_candidate);
    467   void OnChannelCandidatesAllocationDone_s();
    468 
    469   // Helper function that invokes the given function on every channel.
    470   typedef void (TransportChannelImpl::* TransportChannelFunc)();
    471   void CallChannels_w(TransportChannelFunc func);
    472 
    473   // Computes the OR of the channel's read or write state (argument picks).
    474   TransportState GetTransportState_s(bool read);
    475 
    476   void OnChannelCandidateReady_s();
    477 
    478   void SetIceRole_w(IceRole role);
    479   void SetRemoteIceMode_w(IceMode mode);
    480   bool SetLocalTransportDescription_w(const TransportDescription& desc,
    481                                       ContentAction action,
    482                                       std::string* error_desc);
    483   bool SetRemoteTransportDescription_w(const TransportDescription& desc,
    484                                        ContentAction action,
    485                                        std::string* error_desc);
    486   bool GetStats_w(TransportStats* infos);
    487   bool GetRemoteCertificate_w(talk_base::SSLCertificate** cert);
    488 
    489   // Sends SignalCompleted if we are now in that state.
    490   void MaybeCompleted_w();
    491 
    492   talk_base::Thread* signaling_thread_;
    493   talk_base::Thread* worker_thread_;
    494   std::string content_name_;
    495   std::string type_;
    496   PortAllocator* allocator_;
    497   bool destroyed_;
    498   TransportState readable_;
    499   TransportState writable_;
    500   bool was_writable_;
    501   bool connect_requested_;
    502   IceRole ice_role_;
    503   uint64 tiebreaker_;
    504   TransportProtocol protocol_;
    505   IceMode remote_ice_mode_;
    506   talk_base::scoped_ptr<TransportDescription> local_description_;
    507   talk_base::scoped_ptr<TransportDescription> remote_description_;
    508 
    509   ChannelMap channels_;
    510   // Buffers the ready_candidates so that SignalCanidatesReady can
    511   // provide them in multiples.
    512   std::vector<Candidate> ready_candidates_;
    513   // Protects changes to channels and messages
    514   talk_base::CriticalSection crit_;
    515 
    516   DISALLOW_EVIL_CONSTRUCTORS(Transport);
    517 };
    518 
    519 // Extract a TransportProtocol from a TransportDescription.
    520 TransportProtocol TransportProtocolFromDescription(
    521     const TransportDescription* desc);
    522 
    523 }  // namespace cricket
    524 
    525 #endif  // TALK_P2P_BASE_TRANSPORT_H_
    526