• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
61 namespace rtc {
62 class Thread;
63 }
64 
65 namespace buzz {
66 class QName;
67 class XmlElement;
68 }
69 
70 namespace cricket {
71 
72 struct ParseError;
73 struct WriteError;
74 class CandidateTranslator;
75 class PortAllocator;
76 class SessionManager;
77 class Session;
78 class TransportChannel;
79 class TransportChannelImpl;
80 
81 typedef std::vector<buzz::XmlElement*> XmlElements;
82 typedef 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.
88 class 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 
~TransportParser()129   virtual ~TransportParser() {}
130 };
131 
132 // For "writable" and "readable", we need to differentiate between
133 // none, all, and some.
134 enum 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
142 struct ConnectionInfo {
ConnectionInfoConnectionInfo143   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.
172 typedef std::vector<ConnectionInfo> ConnectionInfos;
173 
174 // Information about a specific channel
175 struct 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.
182 typedef std::vector<TransportChannelStats> TransportChannelStatsList;
183 
184 // Information about the stats of a transport.
185 struct TransportStats {
186   std::string content_name;
187   TransportChannelStatsList channel_stats;
188 };
189 
190 bool BadTransportDescription(const std::string& desc, std::string* err_desc);
191 
192 bool 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 
197 class 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.
signaling_thread()208   rtc::Thread* signaling_thread() { return signaling_thread_; }
209   // Returns the worker thread. The actual networking is done on this thread.
worker_thread()210   rtc::Thread* worker_thread() { return worker_thread_; }
211 
212   // Returns the content_name of this transport.
content_name()213   const std::string& content_name() const { return content_name_; }
214   // Returns the type of this transport.
type()215   const std::string& type() const { return type_; }
216 
217   // Returns the port allocator object for this transport.
port_allocator()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().
readable()225   bool readable() const { return any_channels_readable(); }
writable()226   bool writable() const { return any_channels_writable(); }
was_writable()227   bool was_writable() const { return was_writable_; }
any_channels_readable()228   bool any_channels_readable() const {
229     return (readable_ == TRANSPORT_STATE_SOME ||
230             readable_ == TRANSPORT_STATE_ALL);
231   }
any_channels_writable()232   bool any_channels_writable() const {
233     return (writable_ == TRANSPORT_STATE_SOME ||
234             writable_ == TRANSPORT_STATE_ALL);
235   }
all_channels_readable()236   bool all_channels_readable() const {
237     return (readable_ == TRANSPORT_STATE_ALL);
238   }
all_channels_writable()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.
connect_requested()248   bool connect_requested() const { return connect_requested_; }
249 
250   void SetIceRole(IceRole role);
ice_role()251   IceRole ice_role() const { return ice_role_; }
252 
SetIceTiebreaker(uint64 IceTiebreaker)253   void SetIceTiebreaker(uint64 IceTiebreaker) { tiebreaker_ = IceTiebreaker; }
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 
protocol()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.
HasChannel(int component)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.
OnTransportError(const buzz::XmlElement * error)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.
OnTransportSignalingReady()353   virtual void OnTransportSignalingReady() {}
354 
355   // The current local transport description, for use by derived classes
356   // when performing transport description negotiation.
local_description()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.
remote_description()363   const TransportDescription* remote_description() const {
364     return remote_description_.get();
365   }
366 
SetIdentity_w(rtc::SSLIdentity * identity)367   virtual void SetIdentity_w(rtc::SSLIdentity* identity) {}
368 
GetIdentity_w(rtc::SSLIdentity ** identity)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 
GetSslRole_w(rtc::SSLRole * ssl_role)398   virtual bool GetSslRole_w(rtc::SSLRole* ssl_role) const {
399     return false;
400   }
401 
402  private:
403   struct ChannelMapEntry {
ChannelMapEntryChannelMapEntry404     ChannelMapEntry() : impl_(NULL), candidates_allocated_(false), ref_(0) {}
ChannelMapEntryChannelMapEntry405     explicit ChannelMapEntry(TransportChannelImpl *impl)
406         : impl_(impl),
407           candidates_allocated_(false),
408           ref_(0) {
409     }
410 
AddRefChannelMapEntry411     void AddRef() { ++ref_; }
DecRefChannelMapEntry412     void DecRef() {
413       ASSERT(ref_ > 0);
414       --ref_;
415     }
refChannelMapEntry416     int ref() const { return ref_; }
417 
getChannelMapEntry418     TransportChannelImpl* get() const { return impl_; }
419     TransportChannelImpl* operator->() const  { return impl_; }
set_candidates_allocatedChannelMapEntry420     void set_candidates_allocated(bool status) {
421       candidates_allocated_ = status;
422     }
candidates_allocatedChannelMapEntry423     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.
525 TransportProtocol TransportProtocolFromDescription(
526     const TransportDescription* desc);
527 
528 }  // namespace cricket
529 
530 #endif  // TALK_P2P_BASE_TRANSPORT_H_
531