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 // P2PTransportChannel wraps up the state management of the connection between
     12 // two P2P clients.  Clients have candidate ports for connecting, and
     13 // connections which are combinations of candidates from each end (Alice and
     14 // Bob each have candidates, one candidate from Alice and one candidate from
     15 // Bob are used to make a connection, repeat to make many connections).
     16 //
     17 // When all of the available connections become invalid (non-writable), we
     18 // kick off a process of determining more candidates and more connections.
     19 //
     20 #ifndef WEBRTC_P2P_BASE_P2PTRANSPORTCHANNEL_H_
     21 #define WEBRTC_P2P_BASE_P2PTRANSPORTCHANNEL_H_
     22 
     23 #include <map>
     24 #include <string>
     25 #include <vector>
     26 #include "webrtc/p2p/base/candidate.h"
     27 #include "webrtc/p2p/base/p2ptransport.h"
     28 #include "webrtc/p2p/base/portallocator.h"
     29 #include "webrtc/p2p/base/portinterface.h"
     30 #include "webrtc/p2p/base/transport.h"
     31 #include "webrtc/p2p/base/transportchannelimpl.h"
     32 #include "webrtc/base/asyncpacketsocket.h"
     33 #include "webrtc/base/sigslot.h"
     34 
     35 namespace cricket {
     36 
     37 extern const uint32_t WEAK_PING_DELAY;
     38 
     39 struct IceParameters {
     40   std::string ufrag;
     41   std::string pwd;
     42   IceParameters(const std::string& ice_ufrag, const std::string& ice_pwd)
     43       : ufrag(ice_ufrag), pwd(ice_pwd) {}
     44 
     45   bool operator==(const IceParameters& other) {
     46     return ufrag == other.ufrag && pwd == other.pwd;
     47   }
     48   bool operator!=(const IceParameters& other) { return !(*this == other); }
     49 };
     50 
     51 // Adds the port on which the candidate originated.
     52 class RemoteCandidate : public Candidate {
     53  public:
     54   RemoteCandidate(const Candidate& c, PortInterface* origin_port)
     55       : Candidate(c), origin_port_(origin_port) {}
     56 
     57   PortInterface* origin_port() { return origin_port_; }
     58 
     59  private:
     60   PortInterface* origin_port_;
     61 };
     62 
     63 // P2PTransportChannel manages the candidates and connection process to keep
     64 // two P2P clients connected to each other.
     65 class P2PTransportChannel : public TransportChannelImpl,
     66                             public rtc::MessageHandler {
     67  public:
     68   P2PTransportChannel(const std::string& transport_name,
     69                       int component,
     70                       P2PTransport* transport,
     71                       PortAllocator* allocator);
     72   virtual ~P2PTransportChannel();
     73 
     74   // From TransportChannelImpl:
     75   Transport* GetTransport() override { return transport_; }
     76   TransportChannelState GetState() const override;
     77   void SetIceRole(IceRole role) override;
     78   IceRole GetIceRole() const override { return ice_role_; }
     79   void SetIceTiebreaker(uint64_t tiebreaker) override;
     80   void SetIceCredentials(const std::string& ice_ufrag,
     81                          const std::string& ice_pwd) override;
     82   void SetRemoteIceCredentials(const std::string& ice_ufrag,
     83                                const std::string& ice_pwd) override;
     84   void SetRemoteIceMode(IceMode mode) override;
     85   void Connect() override;
     86   void MaybeStartGathering() override;
     87   IceGatheringState gathering_state() const override {
     88     return gathering_state_;
     89   }
     90   void AddRemoteCandidate(const Candidate& candidate) override;
     91   // Sets the receiving timeout and gather_continually.
     92   // This also sets the check_receiving_delay proportionally.
     93   void SetIceConfig(const IceConfig& config) override;
     94 
     95   // From TransportChannel:
     96   int SendPacket(const char* data,
     97                  size_t len,
     98                  const rtc::PacketOptions& options,
     99                  int flags) override;
    100   int SetOption(rtc::Socket::Option opt, int value) override;
    101   bool GetOption(rtc::Socket::Option opt, int* value) override;
    102   int GetError() override { return error_; }
    103   bool GetStats(std::vector<ConnectionInfo>* stats) override;
    104 
    105   const Connection* best_connection() const { return best_connection_; }
    106   void set_incoming_only(bool value) { incoming_only_ = value; }
    107 
    108   // Note: This is only for testing purpose.
    109   // |ports_| should not be changed from outside.
    110   const std::vector<PortInterface*>& ports() { return ports_; }
    111 
    112   IceMode remote_ice_mode() const { return remote_ice_mode_; }
    113 
    114   // DTLS methods.
    115   bool IsDtlsActive() const override { return false; }
    116 
    117   // Default implementation.
    118   bool GetSslRole(rtc::SSLRole* role) const override { return false; }
    119 
    120   bool SetSslRole(rtc::SSLRole role) override { return false; }
    121 
    122   // Set up the ciphers to use for DTLS-SRTP.
    123   bool SetSrtpCryptoSuites(const std::vector<int>& ciphers) override {
    124     return false;
    125   }
    126 
    127   // Find out which DTLS-SRTP cipher was negotiated.
    128   bool GetSrtpCryptoSuite(int* cipher) override { return false; }
    129 
    130   // Find out which DTLS cipher was negotiated.
    131   bool GetSslCipherSuite(int* cipher) override { return false; }
    132 
    133   // Returns null because the channel is not encrypted by default.
    134   rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate() const override {
    135     return nullptr;
    136   }
    137 
    138   bool GetRemoteSSLCertificate(rtc::SSLCertificate** cert) const override {
    139     return false;
    140   }
    141 
    142   // Allows key material to be extracted for external encryption.
    143   bool ExportKeyingMaterial(const std::string& label,
    144                             const uint8_t* context,
    145                             size_t context_len,
    146                             bool use_context,
    147                             uint8_t* result,
    148                             size_t result_len) override {
    149     return false;
    150   }
    151 
    152   bool SetLocalCertificate(
    153       const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) override {
    154     return false;
    155   }
    156 
    157   // Set DTLS Remote fingerprint. Must be after local identity set.
    158   bool SetRemoteFingerprint(const std::string& digest_alg,
    159                             const uint8_t* digest,
    160                             size_t digest_len) override {
    161     return false;
    162   }
    163 
    164   int receiving_timeout() const { return receiving_timeout_; }
    165   int check_receiving_delay() const { return check_receiving_delay_; }
    166 
    167   // Helper method used only in unittest.
    168   rtc::DiffServCodePoint DefaultDscpValue() const;
    169 
    170   // Public for unit tests.
    171   Connection* FindNextPingableConnection();
    172 
    173   // Public for unit tests.
    174   const std::vector<Connection*>& connections() const { return connections_; }
    175 
    176   // Public for unit tests.
    177   PortAllocatorSession* allocator_session() {
    178     return allocator_sessions_.back();
    179   }
    180 
    181   // Public for unit tests.
    182   const std::vector<RemoteCandidate>& remote_candidates() const {
    183     return remote_candidates_;
    184   }
    185 
    186  private:
    187   rtc::Thread* thread() { return worker_thread_; }
    188   bool IsGettingPorts() { return allocator_session()->IsGettingPorts(); }
    189 
    190   // A transport channel is weak if the current best connection is either
    191   // not receiving or not writable, or if there is no best connection at all.
    192   bool weak() const;
    193   void UpdateConnectionStates();
    194   void RequestSort();
    195   void SortConnections();
    196   void SwitchBestConnectionTo(Connection* conn);
    197   void UpdateState();
    198   void HandleAllTimedOut();
    199   void MaybeStopPortAllocatorSessions();
    200   TransportChannelState ComputeState() const;
    201 
    202   Connection* GetBestConnectionOnNetwork(rtc::Network* network) const;
    203   bool CreateConnections(const Candidate& remote_candidate,
    204                          PortInterface* origin_port);
    205   bool CreateConnection(PortInterface* port,
    206                         const Candidate& remote_candidate,
    207                         PortInterface* origin_port);
    208   bool FindConnection(cricket::Connection* connection) const;
    209 
    210   uint32_t GetRemoteCandidateGeneration(const Candidate& candidate);
    211   bool IsDuplicateRemoteCandidate(const Candidate& candidate);
    212   void RememberRemoteCandidate(const Candidate& remote_candidate,
    213                                PortInterface* origin_port);
    214   bool IsPingable(Connection* conn, uint32_t now);
    215   void PingConnection(Connection* conn);
    216   void AddAllocatorSession(PortAllocatorSession* session);
    217   void AddConnection(Connection* connection);
    218 
    219   void OnPortReady(PortAllocatorSession *session, PortInterface* port);
    220   void OnCandidatesReady(PortAllocatorSession *session,
    221                          const std::vector<Candidate>& candidates);
    222   void OnCandidatesAllocationDone(PortAllocatorSession* session);
    223   void OnUnknownAddress(PortInterface* port,
    224                         const rtc::SocketAddress& addr,
    225                         ProtocolType proto,
    226                         IceMessage* stun_msg,
    227                         const std::string& remote_username,
    228                         bool port_muxed);
    229   void OnPortDestroyed(PortInterface* port);
    230   void OnRoleConflict(PortInterface* port);
    231 
    232   void OnConnectionStateChange(Connection* connection);
    233   void OnReadPacket(Connection *connection, const char *data, size_t len,
    234                     const rtc::PacketTime& packet_time);
    235   void OnSentPacket(const rtc::SentPacket& sent_packet);
    236   void OnReadyToSend(Connection* connection);
    237   void OnConnectionDestroyed(Connection *connection);
    238 
    239   void OnNominated(Connection* conn);
    240 
    241   void OnMessage(rtc::Message* pmsg) override;
    242   void OnSort();
    243   void OnCheckAndPing();
    244 
    245   void PruneConnections();
    246   Connection* best_nominated_connection() const;
    247   bool IsBackupConnection(Connection* conn) const;
    248 
    249   // Returns the latest remote ICE parameters or nullptr if there are no remote
    250   // ICE parameters yet.
    251   IceParameters* remote_ice() {
    252     return remote_ice_parameters_.empty() ? nullptr
    253                                           : &remote_ice_parameters_.back();
    254   }
    255   // Returns the remote IceParameters and generation that match |ufrag|
    256   // if found, and returns nullptr otherwise.
    257   const IceParameters* FindRemoteIceFromUfrag(const std::string& ufrag,
    258                                               uint32_t* generation);
    259   // Returns the index of the latest remote ICE parameters, or 0 if no remote
    260   // ICE parameters have been received.
    261   uint32_t remote_ice_generation() {
    262     return remote_ice_parameters_.empty()
    263                ? 0
    264                : static_cast<uint32_t>(remote_ice_parameters_.size() - 1);
    265   }
    266 
    267   P2PTransport* transport_;
    268   PortAllocator* allocator_;
    269   rtc::Thread* worker_thread_;
    270   bool incoming_only_;
    271   int error_;
    272   std::vector<PortAllocatorSession*> allocator_sessions_;
    273   std::vector<PortInterface *> ports_;
    274   std::vector<Connection *> connections_;
    275   Connection* best_connection_;
    276   // Connection selected by the controlling agent. This should be used only
    277   // at controlled side when protocol type is RFC5245.
    278   Connection* pending_best_connection_;
    279   std::vector<RemoteCandidate> remote_candidates_;
    280   bool sort_dirty_;  // indicates whether another sort is needed right now
    281   bool had_connection_ = false;  // if connections_ has ever been nonempty
    282   typedef std::map<rtc::Socket::Option, int> OptionMap;
    283   OptionMap options_;
    284   std::string ice_ufrag_;
    285   std::string ice_pwd_;
    286   std::vector<IceParameters> remote_ice_parameters_;
    287   IceMode remote_ice_mode_;
    288   IceRole ice_role_;
    289   uint64_t tiebreaker_;
    290   IceGatheringState gathering_state_;
    291 
    292   int check_receiving_delay_;
    293   int receiving_timeout_;
    294   int backup_connection_ping_interval_;
    295   uint32_t last_ping_sent_ms_ = 0;
    296   bool gather_continually_ = false;
    297   int weak_ping_delay_ = WEAK_PING_DELAY;
    298   TransportChannelState state_ = TransportChannelState::STATE_INIT;
    299 
    300   RTC_DISALLOW_COPY_AND_ASSIGN(P2PTransportChannel);
    301 };
    302 
    303 }  // namespace cricket
    304 
    305 #endif  // WEBRTC_P2P_BASE_P2PTRANSPORTCHANNEL_H_
    306