Home | History | Annotate | Download | only in base
      1 /*
      2  *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 // A Transport manages a set of named channels of the same type.
     12 //
     13 // Subclasses choose the appropriate class to instantiate for each channel;
     14 // however, this base class keeps track of the channels by name, watches their
     15 // state changes (in order to update the manager's state), and forwards
     16 // requests to begin connecting or to reset to each of the channels.
     17 //
     18 // On Threading:  Transport performs work solely on the worker thread, and so
     19 // its methods should only be called on the worker thread.
     20 //
     21 // Note: Subclasses must call DestroyChannels() in their own destructors.
     22 // It is not possible to do so here because the subclass destructor will
     23 // already have run.
     24 
     25 #ifndef WEBRTC_P2P_BASE_TRANSPORT_H_
     26 #define WEBRTC_P2P_BASE_TRANSPORT_H_
     27 
     28 #include <map>
     29 #include <string>
     30 #include <vector>
     31 #include "webrtc/p2p/base/candidate.h"
     32 #include "webrtc/p2p/base/constants.h"
     33 #include "webrtc/p2p/base/sessiondescription.h"
     34 #include "webrtc/p2p/base/transportinfo.h"
     35 #include "webrtc/base/messagequeue.h"
     36 #include "webrtc/base/rtccertificate.h"
     37 #include "webrtc/base/sigslot.h"
     38 #include "webrtc/base/sslstreamadapter.h"
     39 
     40 namespace cricket {
     41 
     42 class PortAllocator;
     43 class TransportChannel;
     44 class TransportChannelImpl;
     45 
     46 typedef std::vector<Candidate> Candidates;
     47 
     48 // TODO(deadbeef): Unify with PeerConnectionInterface::IceConnectionState
     49 // once /talk/ and /webrtc/ are combined, and also switch to ENUM_NAME naming
     50 // style.
     51 enum IceConnectionState {
     52   kIceConnectionConnecting = 0,
     53   kIceConnectionFailed,
     54   kIceConnectionConnected,  // Writable, but still checking one or more
     55                             // connections
     56   kIceConnectionCompleted,
     57 };
     58 
     59 enum DtlsTransportState {
     60   // Haven't started negotiating.
     61   DTLS_TRANSPORT_NEW = 0,
     62   // Have started negotiating.
     63   DTLS_TRANSPORT_CONNECTING,
     64   // Negotiated, and has a secure connection.
     65   DTLS_TRANSPORT_CONNECTED,
     66   // Transport is closed.
     67   DTLS_TRANSPORT_CLOSED,
     68   // Failed due to some error in the handshake process.
     69   DTLS_TRANSPORT_FAILED,
     70 };
     71 
     72 // TODO(deadbeef): Unify with PeerConnectionInterface::IceConnectionState
     73 // once /talk/ and /webrtc/ are combined, and also switch to ENUM_NAME naming
     74 // style.
     75 enum IceGatheringState {
     76   kIceGatheringNew = 0,
     77   kIceGatheringGathering,
     78   kIceGatheringComplete,
     79 };
     80 
     81 // Stats that we can return about the connections for a transport channel.
     82 // TODO(hta): Rename to ConnectionStats
     83 struct ConnectionInfo {
     84   ConnectionInfo()
     85       : best_connection(false),
     86         writable(false),
     87         receiving(false),
     88         timeout(false),
     89         new_connection(false),
     90         rtt(0),
     91         sent_total_bytes(0),
     92         sent_bytes_second(0),
     93         sent_discarded_packets(0),
     94         sent_total_packets(0),
     95         recv_total_bytes(0),
     96         recv_bytes_second(0),
     97         key(NULL) {}
     98 
     99   bool best_connection;        // Is this the best connection we have?
    100   bool writable;               // Has this connection received a STUN response?
    101   bool receiving;              // Has this connection received anything?
    102   bool timeout;                // Has this connection timed out?
    103   bool new_connection;         // Is this a newly created connection?
    104   size_t rtt;                  // The STUN RTT for this connection.
    105   size_t sent_total_bytes;     // Total bytes sent on this connection.
    106   size_t sent_bytes_second;    // Bps over the last measurement interval.
    107   size_t sent_discarded_packets;  // Number of outgoing packets discarded due to
    108                                   // socket errors.
    109   size_t sent_total_packets;  // Number of total outgoing packets attempted for
    110                               // sending.
    111 
    112   size_t recv_total_bytes;     // Total bytes received on this connection.
    113   size_t recv_bytes_second;    // Bps over the last measurement interval.
    114   Candidate local_candidate;   // The local candidate for this connection.
    115   Candidate remote_candidate;  // The remote candidate for this connection.
    116   void* key;                   // A static value that identifies this conn.
    117 };
    118 
    119 // Information about all the connections of a channel.
    120 typedef std::vector<ConnectionInfo> ConnectionInfos;
    121 
    122 // Information about a specific channel
    123 struct TransportChannelStats {
    124   int component = 0;
    125   ConnectionInfos connection_infos;
    126   int srtp_crypto_suite = rtc::SRTP_INVALID_CRYPTO_SUITE;
    127   int ssl_cipher_suite = rtc::TLS_NULL_WITH_NULL_NULL;
    128 };
    129 
    130 // Information about all the channels of a transport.
    131 // TODO(hta): Consider if a simple vector is as good as a map.
    132 typedef std::vector<TransportChannelStats> TransportChannelStatsList;
    133 
    134 // Information about the stats of a transport.
    135 struct TransportStats {
    136   std::string transport_name;
    137   TransportChannelStatsList channel_stats;
    138 };
    139 
    140 // Information about ICE configuration.
    141 struct IceConfig {
    142   // The ICE connection receiving timeout value.
    143   // TODO(honghaiz): Remove suffix _ms to be consistent.
    144   int receiving_timeout_ms = -1;
    145   // Time interval in milliseconds to ping a backup connection when the ICE
    146   // channel is strongly connected.
    147   int backup_connection_ping_interval = -1;
    148   // If true, the most recent port allocator session will keep on running.
    149   bool gather_continually = false;
    150 };
    151 
    152 bool BadTransportDescription(const std::string& desc, std::string* err_desc);
    153 
    154 bool IceCredentialsChanged(const std::string& old_ufrag,
    155                            const std::string& old_pwd,
    156                            const std::string& new_ufrag,
    157                            const std::string& new_pwd);
    158 
    159 class Transport : public sigslot::has_slots<> {
    160  public:
    161   Transport(const std::string& name, PortAllocator* allocator);
    162   virtual ~Transport();
    163 
    164   // Returns the name of this transport.
    165   const std::string& name() const { return name_; }
    166 
    167   // Returns the port allocator object for this transport.
    168   PortAllocator* port_allocator() { return allocator_; }
    169 
    170   bool ready_for_remote_candidates() const {
    171     return local_description_set_ && remote_description_set_;
    172   }
    173 
    174   // Returns whether the client has requested the channels to connect.
    175   bool connect_requested() const { return connect_requested_; }
    176 
    177   void SetIceRole(IceRole role);
    178   IceRole ice_role() const { return ice_role_; }
    179 
    180   void SetIceTiebreaker(uint64_t IceTiebreaker) { tiebreaker_ = IceTiebreaker; }
    181   uint64_t IceTiebreaker() { return tiebreaker_; }
    182 
    183   void SetIceConfig(const IceConfig& config);
    184 
    185   // Must be called before applying local session description.
    186   virtual void SetLocalCertificate(
    187       const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {}
    188 
    189   // Get a copy of the local certificate provided by SetLocalCertificate.
    190   virtual bool GetLocalCertificate(
    191       rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
    192     return false;
    193   }
    194 
    195   // Get a copy of the remote certificate in use by the specified channel.
    196   bool GetRemoteSSLCertificate(rtc::SSLCertificate** cert);
    197 
    198   // Create, destroy, and lookup the channels of this type by their components.
    199   TransportChannelImpl* CreateChannel(int component);
    200 
    201   TransportChannelImpl* GetChannel(int component);
    202 
    203   bool HasChannel(int component) {
    204     return (NULL != GetChannel(component));
    205   }
    206   bool HasChannels();
    207 
    208   void DestroyChannel(int component);
    209 
    210   // Set the local TransportDescription to be used by TransportChannels.
    211   bool SetLocalTransportDescription(const TransportDescription& description,
    212                                     ContentAction action,
    213                                     std::string* error_desc);
    214 
    215   // Set the remote TransportDescription to be used by TransportChannels.
    216   bool SetRemoteTransportDescription(const TransportDescription& description,
    217                                      ContentAction action,
    218                                      std::string* error_desc);
    219 
    220   // Tells all current and future channels to start connecting.
    221   void ConnectChannels();
    222 
    223   // Tells channels to start gathering candidates if necessary.
    224   // Should be called after ConnectChannels() has been called at least once,
    225   // which will happen in SetLocalTransportDescription.
    226   void MaybeStartGathering();
    227 
    228   // Resets all of the channels back to their initial state.  They are no
    229   // longer connecting.
    230   void ResetChannels();
    231 
    232   // Destroys every channel created so far.
    233   void DestroyAllChannels();
    234 
    235   bool GetStats(TransportStats* stats);
    236 
    237   // Called when one or more candidates are ready from the remote peer.
    238   bool AddRemoteCandidates(const std::vector<Candidate>& candidates,
    239                            std::string* error);
    240 
    241   // If candidate is not acceptable, returns false and sets error.
    242   // Call this before calling OnRemoteCandidates.
    243   virtual bool VerifyCandidate(const Candidate& candidate,
    244                                std::string* error);
    245 
    246   virtual bool GetSslRole(rtc::SSLRole* ssl_role) const { return false; }
    247 
    248   // Must be called before channel is starting to connect.
    249   virtual bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version) {
    250     return false;
    251   }
    252 
    253  protected:
    254   // These are called by Create/DestroyChannel above in order to create or
    255   // destroy the appropriate type of channel.
    256   virtual TransportChannelImpl* CreateTransportChannel(int component) = 0;
    257   virtual void DestroyTransportChannel(TransportChannelImpl* channel) = 0;
    258 
    259   // The current local transport description, for use by derived classes
    260   // when performing transport description negotiation.
    261   const TransportDescription* local_description() const {
    262     return local_description_.get();
    263   }
    264 
    265   // The current remote transport description, for use by derived classes
    266   // when performing transport description negotiation.
    267   const TransportDescription* remote_description() const {
    268     return remote_description_.get();
    269   }
    270 
    271   // Pushes down the transport parameters from the local description, such
    272   // as the ICE ufrag and pwd.
    273   // Derived classes can override, but must call the base as well.
    274   virtual bool ApplyLocalTransportDescription(TransportChannelImpl* channel,
    275                                               std::string* error_desc);
    276 
    277   // Pushes down remote ice credentials from the remote description to the
    278   // transport channel.
    279   virtual bool ApplyRemoteTransportDescription(TransportChannelImpl* ch,
    280                                                std::string* error_desc);
    281 
    282   // Negotiates the transport parameters based on the current local and remote
    283   // transport description, such as the ICE role to use, and whether DTLS
    284   // should be activated.
    285   // Derived classes can negotiate their specific parameters here, but must call
    286   // the base as well.
    287   virtual bool NegotiateTransportDescription(ContentAction local_role,
    288                                              std::string* error_desc);
    289 
    290   // Pushes down the transport parameters obtained via negotiation.
    291   // Derived classes can set their specific parameters here, but must call the
    292   // base as well.
    293   virtual bool ApplyNegotiatedTransportDescription(
    294       TransportChannelImpl* channel,
    295       std::string* error_desc);
    296 
    297  private:
    298   // Candidate component => TransportChannelImpl*
    299   typedef std::map<int, TransportChannelImpl*> ChannelMap;
    300 
    301   // Helper function that invokes the given function on every channel.
    302   typedef void (TransportChannelImpl::* TransportChannelFunc)();
    303   void CallChannels(TransportChannelFunc func);
    304 
    305   const std::string name_;
    306   PortAllocator* const allocator_;
    307   bool channels_destroyed_ = false;
    308   bool connect_requested_ = false;
    309   IceRole ice_role_ = ICEROLE_UNKNOWN;
    310   uint64_t tiebreaker_ = 0;
    311   IceMode remote_ice_mode_ = ICEMODE_FULL;
    312   IceConfig ice_config_;
    313   rtc::scoped_ptr<TransportDescription> local_description_;
    314   rtc::scoped_ptr<TransportDescription> remote_description_;
    315   bool local_description_set_ = false;
    316   bool remote_description_set_ = false;
    317 
    318   ChannelMap channels_;
    319 
    320   RTC_DISALLOW_COPY_AND_ASSIGN(Transport);
    321 };
    322 
    323 
    324 }  // namespace cricket
    325 
    326 #endif  // WEBRTC_P2P_BASE_TRANSPORT_H_
    327