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