aboutsummaryrefslogtreecommitdiff
path: root/webrtc/p2p/base/transport.h
blob: 955eb4209883e1c1def8f7b1b752bfc5ee7a73ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
/*
 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

// A Transport manages a set of named channels of the same type.
//
// Subclasses choose the appropriate class to instantiate for each channel;
// however, this base class keeps track of the channels by name, watches their
// state changes (in order to update the manager's state), and forwards
// requests to begin connecting or to reset to each of the channels.
//
// On Threading:  Transport performs work solely on the worker thread, and so
// its methods should only be called on the worker thread.
//
// Note: Subclasses must call DestroyChannels() in their own destructors.
// It is not possible to do so here because the subclass destructor will
// already have run.

#ifndef WEBRTC_P2P_BASE_TRANSPORT_H_
#define WEBRTC_P2P_BASE_TRANSPORT_H_

#include <map>
#include <string>
#include <vector>
#include "webrtc/p2p/base/candidate.h"
#include "webrtc/p2p/base/constants.h"
#include "webrtc/p2p/base/sessiondescription.h"
#include "webrtc/p2p/base/transportinfo.h"
#include "webrtc/base/messagequeue.h"
#include "webrtc/base/rtccertificate.h"
#include "webrtc/base/sigslot.h"
#include "webrtc/base/sslstreamadapter.h"

namespace cricket {

class PortAllocator;
class TransportChannel;
class TransportChannelImpl;

typedef std::vector<Candidate> Candidates;

// TODO(deadbeef): Unify with PeerConnectionInterface::IceConnectionState
// once /talk/ and /webrtc/ are combined, and also switch to ENUM_NAME naming
// style.
enum IceConnectionState {
  kIceConnectionConnecting = 0,
  kIceConnectionFailed,
  kIceConnectionConnected,  // Writable, but still checking one or more
                            // connections
  kIceConnectionCompleted,
};

enum DtlsTransportState {
  // Haven't started negotiating.
  DTLS_TRANSPORT_NEW = 0,
  // Have started negotiating.
  DTLS_TRANSPORT_CONNECTING,
  // Negotiated, and has a secure connection.
  DTLS_TRANSPORT_CONNECTED,
  // Transport is closed.
  DTLS_TRANSPORT_CLOSED,
  // Failed due to some error in the handshake process.
  DTLS_TRANSPORT_FAILED,
};

// TODO(deadbeef): Unify with PeerConnectionInterface::IceConnectionState
// once /talk/ and /webrtc/ are combined, and also switch to ENUM_NAME naming
// style.
enum IceGatheringState {
  kIceGatheringNew = 0,
  kIceGatheringGathering,
  kIceGatheringComplete,
};

// Stats that we can return about the connections for a transport channel.
// TODO(hta): Rename to ConnectionStats
struct ConnectionInfo {
  ConnectionInfo()
      : best_connection(false),
        writable(false),
        receiving(false),
        timeout(false),
        new_connection(false),
        rtt(0),
        sent_total_bytes(0),
        sent_bytes_second(0),
        sent_discarded_packets(0),
        sent_total_packets(0),
        recv_total_bytes(0),
        recv_bytes_second(0),
        key(NULL) {}

  bool best_connection;        // Is this the best connection we have?
  bool writable;               // Has this connection received a STUN response?
  bool receiving;              // Has this connection received anything?
  bool timeout;                // Has this connection timed out?
  bool new_connection;         // Is this a newly created connection?
  size_t rtt;                  // The STUN RTT for this connection.
  size_t sent_total_bytes;     // Total bytes sent on this connection.
  size_t sent_bytes_second;    // Bps over the last measurement interval.
  size_t sent_discarded_packets;  // Number of outgoing packets discarded due to
                                  // socket errors.
  size_t sent_total_packets;  // Number of total outgoing packets attempted for
                              // sending.

  size_t recv_total_bytes;     // Total bytes received on this connection.
  size_t recv_bytes_second;    // Bps over the last measurement interval.
  Candidate local_candidate;   // The local candidate for this connection.
  Candidate remote_candidate;  // The remote candidate for this connection.
  void* key;                   // A static value that identifies this conn.
};

// Information about all the connections of a channel.
typedef std::vector<ConnectionInfo> ConnectionInfos;

// Information about a specific channel
struct TransportChannelStats {
  int component = 0;
  ConnectionInfos connection_infos;
  std::string srtp_cipher;
  int ssl_cipher = 0;
};

// Information about all the channels of a transport.
// TODO(hta): Consider if a simple vector is as good as a map.
typedef std::vector<TransportChannelStats> TransportChannelStatsList;

// Information about the stats of a transport.
struct TransportStats {
  std::string transport_name;
  TransportChannelStatsList channel_stats;
};

// Information about ICE configuration.
struct IceConfig {
  // The ICE connection receiving timeout value.
  int receiving_timeout_ms = -1;
  // If true, the most recent port allocator session will keep on running.
  bool gather_continually = false;
};

bool BadTransportDescription(const std::string& desc, std::string* err_desc);

bool IceCredentialsChanged(const std::string& old_ufrag,
                           const std::string& old_pwd,
                           const std::string& new_ufrag,
                           const std::string& new_pwd);

class Transport : public sigslot::has_slots<> {
 public:
  Transport(const std::string& name, PortAllocator* allocator);
  virtual ~Transport();

  // Returns the name of this transport.
  const std::string& name() const { return name_; }

  // Returns the port allocator object for this transport.
  PortAllocator* port_allocator() { return allocator_; }

  bool ready_for_remote_candidates() const {
    return local_description_set_ && remote_description_set_;
  }

  // Returns whether the client has requested the channels to connect.
  bool connect_requested() const { return connect_requested_; }

  void SetIceRole(IceRole role);
  IceRole ice_role() const { return ice_role_; }

  void SetIceTiebreaker(uint64_t IceTiebreaker) { tiebreaker_ = IceTiebreaker; }
  uint64_t IceTiebreaker() { return tiebreaker_; }

  void SetIceConfig(const IceConfig& config);

  // Must be called before applying local session description.
  virtual void SetLocalCertificate(
      const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {}

  // Get a copy of the local certificate provided by SetLocalCertificate.
  virtual bool GetLocalCertificate(
      rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
    return false;
  }

  // Get a copy of the remote certificate in use by the specified channel.
  bool GetRemoteSSLCertificate(rtc::SSLCertificate** cert);

  // Create, destroy, and lookup the channels of this type by their components.
  TransportChannelImpl* CreateChannel(int component);

  TransportChannelImpl* GetChannel(int component);

  bool HasChannel(int component) {
    return (NULL != GetChannel(component));
  }
  bool HasChannels();

  void DestroyChannel(int component);

  // Set the local TransportDescription to be used by TransportChannels.
  bool SetLocalTransportDescription(const TransportDescription& description,
                                    ContentAction action,
                                    std::string* error_desc);

  // Set the remote TransportDescription to be used by TransportChannels.
  bool SetRemoteTransportDescription(const TransportDescription& description,
                                     ContentAction action,
                                     std::string* error_desc);

  // Tells all current and future channels to start connecting.
  void ConnectChannels();

  // Tells channels to start gathering candidates if necessary.
  // Should be called after ConnectChannels() has been called at least once,
  // which will happen in SetLocalTransportDescription.
  void MaybeStartGathering();

  // Resets all of the channels back to their initial state.  They are no
  // longer connecting.
  void ResetChannels();

  // Destroys every channel created so far.
  void DestroyAllChannels();

  bool GetStats(TransportStats* stats);

  // Called when one or more candidates are ready from the remote peer.
  bool AddRemoteCandidates(const std::vector<Candidate>& candidates,
                           std::string* error);

  // If candidate is not acceptable, returns false and sets error.
  // Call this before calling OnRemoteCandidates.
  virtual bool VerifyCandidate(const Candidate& candidate,
                               std::string* error);

  virtual bool GetSslRole(rtc::SSLRole* ssl_role) const { return false; }

  // Must be called before channel is starting to connect.
  virtual bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version) {
    return false;
  }

 protected:
  // These are called by Create/DestroyChannel above in order to create or
  // destroy the appropriate type of channel.
  virtual TransportChannelImpl* CreateTransportChannel(int component) = 0;
  virtual void DestroyTransportChannel(TransportChannelImpl* channel) = 0;

  // The current local transport description, for use by derived classes
  // when performing transport description negotiation.
  const TransportDescription* local_description() const {
    return local_description_.get();
  }

  // The current remote transport description, for use by derived classes
  // when performing transport description negotiation.
  const TransportDescription* remote_description() const {
    return remote_description_.get();
  }

  // Pushes down the transport parameters from the local description, such
  // as the ICE ufrag and pwd.
  // Derived classes can override, but must call the base as well.
  virtual bool ApplyLocalTransportDescription(TransportChannelImpl* channel,
                                              std::string* error_desc);

  // Pushes down remote ice credentials from the remote description to the
  // transport channel.
  virtual bool ApplyRemoteTransportDescription(TransportChannelImpl* ch,
                                               std::string* error_desc);

  // Negotiates the transport parameters based on the current local and remote
  // transport description, such as the ICE role to use, and whether DTLS
  // should be activated.
  // Derived classes can negotiate their specific parameters here, but must call
  // the base as well.
  virtual bool NegotiateTransportDescription(ContentAction local_role,
                                             std::string* error_desc);

  // Pushes down the transport parameters obtained via negotiation.
  // Derived classes can set their specific parameters here, but must call the
  // base as well.
  virtual bool ApplyNegotiatedTransportDescription(
      TransportChannelImpl* channel,
      std::string* error_desc);

 private:
  // Candidate component => TransportChannelImpl*
  typedef std::map<int, TransportChannelImpl*> ChannelMap;

  // Helper function that invokes the given function on every channel.
  typedef void (TransportChannelImpl::* TransportChannelFunc)();
  void CallChannels(TransportChannelFunc func);

  const std::string name_;
  PortAllocator* const allocator_;
  bool channels_destroyed_ = false;
  bool connect_requested_ = false;
  IceRole ice_role_ = ICEROLE_UNKNOWN;
  uint64_t tiebreaker_ = 0;
  IceMode remote_ice_mode_ = ICEMODE_FULL;
  IceConfig ice_config_;
  rtc::scoped_ptr<TransportDescription> local_description_;
  rtc::scoped_ptr<TransportDescription> remote_description_;
  bool local_description_set_ = false;
  bool remote_description_set_ = false;

  ChannelMap channels_;

  RTC_DISALLOW_COPY_AND_ASSIGN(Transport);
};


}  // namespace cricket

#endif  // WEBRTC_P2P_BASE_TRANSPORT_H_