3 * Copyright 2004--2005, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
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.
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.
28 // A Transport manages a set of named channels of the same type.
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.
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).
42 // Note: Subclasses must call DestroyChannels() in their own constructors.
43 // It is not possible to do so here because the subclass constructor will
46 #ifndef WEBRTC_P2P_BASE_TRANSPORT_H_
47 #define WEBRTC_P2P_BASE_TRANSPORT_H_
52 #include "webrtc/p2p/base/candidate.h"
53 #include "webrtc/p2p/base/constants.h"
54 #include "webrtc/p2p/base/sessiondescription.h"
55 #include "webrtc/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"
74 class CandidateTranslator;
78 class TransportChannel;
79 class TransportChannelImpl;
81 typedef std::vector<buzz::XmlElement*> XmlElements;
82 typedef std::vector<Candidate> Candidates;
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
88 class TransportParser {
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.
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;
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;
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,
129 virtual ~TransportParser() {}
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,
140 // Stats that we can return about the connections for a transport channel.
141 // TODO(hta): Rename to ConnectionStats
142 struct ConnectionInfo {
144 : best_connection(false),
148 new_connection(false),
151 sent_bytes_second(0),
153 recv_bytes_second(0),
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.
171 // Information about all the connections of a channel.
172 typedef std::vector<ConnectionInfo> ConnectionInfos;
174 // Information about a specific channel
175 struct TransportChannelStats {
177 ConnectionInfos connection_infos;
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;
184 // Information about the stats of a transport.
185 struct TransportStats {
186 std::string content_name;
187 TransportChannelStatsList channel_stats;
190 bool BadTransportDescription(const std::string& desc, std::string* err_desc);
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);
197 class Transport : public rtc::MessageHandler,
198 public sigslot::has_slots<> {
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();
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_; }
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_; }
217 // Returns the port allocator object for this transport.
218 PortAllocator* port_allocator() { return allocator_; }
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);
232 bool any_channels_writable() const {
233 return (writable_ == TRANSPORT_STATE_SOME ||
234 writable_ == TRANSPORT_STATE_ALL);
236 bool all_channels_readable() const {
237 return (readable_ == TRANSPORT_STATE_ALL);
239 bool all_channels_writable() const {
240 return (writable_ == TRANSPORT_STATE_ALL);
242 sigslot::signal1<Transport*> SignalReadableState;
243 sigslot::signal1<Transport*> SignalWritableState;
244 sigslot::signal1<Transport*> SignalCompleted;
245 sigslot::signal1<Transport*> SignalFailed;
247 // Returns whether the client has requested the channels to connect.
248 bool connect_requested() const { return connect_requested_; }
250 void SetIceRole(IceRole role);
251 IceRole ice_role() const { return ice_role_; }
253 void SetIceTiebreaker(uint64 IceTiebreaker) { tiebreaker_ = IceTiebreaker; }
254 uint64 IceTiebreaker() { return tiebreaker_; }
256 // Must be called before applying local session description.
257 void SetIdentity(rtc::SSLIdentity* identity);
259 // Get a copy of the local identity provided by SetIdentity.
260 bool GetIdentity(rtc::SSLIdentity** identity);
262 // Get a copy of the remote certificate in use by the specified channel.
263 bool GetRemoteCertificate(rtc::SSLCertificate** cert);
265 TransportProtocol protocol() const { return protocol_; }
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));
277 void DestroyChannel(int component);
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);
285 // Set the remote TransportDescription to be used by TransportChannels.
286 bool SetRemoteTransportDescription(const TransportDescription& description,
287 ContentAction action,
288 std::string* error_desc);
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;
295 // Resets all of the channels back to their initial state. They are no
296 // longer connecting.
297 void ResetChannels();
299 // Destroys every channel created so far.
300 void DestroyAllChannels();
302 bool GetStats(TransportStats* stats);
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();
312 // Handles sending of ready candidates and receiving of remote candidates.
313 sigslot::signal2<Transport*,
314 const std::vector<Candidate>&> SignalCandidatesReady;
316 sigslot::signal1<Transport*> SignalCandidatesAllocationDone;
317 void OnRemoteCandidates(const std::vector<Candidate>& candidates);
319 // If candidate is not acceptable, returns false and sets error.
320 // Call this before calling OnRemoteCandidates.
321 virtual bool VerifyCandidate(const Candidate& candidate,
324 // Signals when the best connection for a channel changes.
325 sigslot::signal3<Transport*,
327 const Candidate&> SignalRouteChange;
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
333 // TODO(juberti): Remove these obsolete functions once Session no longer
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;
341 // Forwards the signal from TransportChannel to BaseSession.
342 sigslot::signal0<> SignalRoleConflict;
344 virtual bool GetSslRole(rtc::SSLRole* ssl_role) const;
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;
352 // Informs the subclass that we received the signaling ready message.
353 virtual void OnTransportSignalingReady() {}
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();
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();
367 virtual void SetIdentity_w(rtc::SSLIdentity* identity) {}
369 virtual bool GetIdentity_w(rtc::SSLIdentity** identity) {
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);
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);
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
389 virtual bool NegotiateTransportDescription_w(ContentAction local_role,
390 std::string* error_desc);
392 // Pushes down the transport parameters obtained via negotiation.
393 // Derived classes can set their specific parameters here, but must call the
395 virtual bool ApplyNegotiatedTransportDescription_w(
396 TransportChannelImpl* channel, std::string* error_desc);
398 virtual bool GetSslRole_w(rtc::SSLRole* ssl_role) const {
403 struct ChannelMapEntry {
404 ChannelMapEntry() : impl_(NULL), candidates_allocated_(false), ref_(0) {}
405 explicit ChannelMapEntry(TransportChannelImpl *impl)
407 candidates_allocated_(false),
411 void AddRef() { ++ref_; }
416 int ref() const { return ref_; }
418 TransportChannelImpl* get() const { return impl_; }
419 TransportChannelImpl* operator->() const { return impl_; }
420 void set_candidates_allocated(bool status) {
421 candidates_allocated_ = status;
423 bool candidates_allocated() const { return candidates_allocated_; }
426 TransportChannelImpl *impl_;
427 bool candidates_allocated_;
431 // Candidate component => ChannelMapEntry
432 typedef std::map<int, ChannelMapEntry> ChannelMap;
434 // Called when the state of a channel changes.
435 void OnChannelReadableState(TransportChannel* channel);
436 void OnChannelWritableState(TransportChannel* channel);
438 // Called when a channel requests signaling.
439 void OnChannelRequestSignaling(TransportChannelImpl* channel);
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);
454 // Dispatches messages to the appropriate handler (below).
455 void OnMessage(rtc::Message* msg);
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();
474 // Helper function that invokes the given function on every channel.
475 typedef void (TransportChannelImpl::* TransportChannelFunc)();
476 void CallChannels_w(TransportChannelFunc func);
478 // Computes the OR of the channel's read or write state (argument picks).
479 TransportState GetTransportState_s(bool read);
481 void OnChannelCandidateReady_s();
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);
494 // Sends SignalCompleted if we are now in that state.
495 void MaybeCompleted_w();
497 rtc::Thread* signaling_thread_;
498 rtc::Thread* worker_thread_;
499 std::string content_name_;
501 PortAllocator* allocator_;
503 TransportState readable_;
504 TransportState writable_;
506 bool connect_requested_;
509 TransportProtocol protocol_;
510 IceMode remote_ice_mode_;
511 rtc::scoped_ptr<TransportDescription> local_description_;
512 rtc::scoped_ptr<TransportDescription> remote_description_;
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_;
521 DISALLOW_EVIL_CONSTRUCTORS(Transport);
524 // Extract a TransportProtocol from a TransportDescription.
525 TransportProtocol TransportProtocolFromDescription(
526 const TransportDescription* desc);
528 } // namespace cricket
530 #endif // WEBRTC_P2P_BASE_TRANSPORT_H_