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
35namespace cricket {
36
37extern const uint32_t WEAK_PING_DELAY;
38
39struct 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.
52class 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.
65class 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