Index: webrtc/p2p/base/transport.h |
diff --git a/webrtc/p2p/base/transport.h b/webrtc/p2p/base/transport.h |
index cd763ab3bcf1404c441e29a6b326c1e5a9c0631d..72a089501e6007d51c61be121efbef1e1178fa25 100644 |
--- a/webrtc/p2p/base/transport.h |
+++ b/webrtc/p2p/base/transport.h |
@@ -15,11 +15,15 @@ |
// 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. |
+// On Threading: Transport performs work on both the signaling and worker |
+// threads. For subclasses, the rule is that all signaling related calls will |
+// be made on the signaling thread and all channel related calls (including |
+// signaling for a channel) will be made on the worker thread. When |
+// information needs to be sent between the two threads, this class should do |
+// the work (e.g., OnRemoteCandidate). |
// |
-// Note: Subclasses must call DestroyChannels() in their own destructors. |
-// It is not possible to do so here because the subclass destructor will |
+// Note: Subclasses must call DestroyChannels() in their own constructors. |
+// It is not possible to do so here because the subclass constructor will |
// already have run. |
#ifndef WEBRTC_P2P_BASE_TRANSPORT_H_ |
@@ -32,11 +36,16 @@ |
#include "webrtc/p2p/base/constants.h" |
#include "webrtc/p2p/base/sessiondescription.h" |
#include "webrtc/p2p/base/transportinfo.h" |
+#include "webrtc/base/criticalsection.h" |
#include "webrtc/base/messagequeue.h" |
#include "webrtc/base/rtccertificate.h" |
#include "webrtc/base/sigslot.h" |
#include "webrtc/base/sslstreamadapter.h" |
+namespace rtc { |
+class Thread; |
+} |
+ |
namespace cricket { |
class PortAllocator; |
@@ -44,26 +53,6 @@ |
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, |
-}; |
- |
-// 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, |
-}; |
// For "writable" and "receiving", we need to differentiate between |
// none, all, and some. |
@@ -135,7 +124,7 @@ |
// Information about the stats of a transport. |
struct TransportStats { |
- std::string transport_name; |
+ std::string content_name; |
TransportChannelStatsList channel_stats; |
}; |
@@ -146,13 +135,22 @@ |
const std::string& new_ufrag, |
const std::string& new_pwd); |
-class Transport : public sigslot::has_slots<> { |
+class Transport : public rtc::MessageHandler, |
+ public sigslot::has_slots<> { |
public: |
- Transport(const std::string& name, PortAllocator* allocator); |
+ Transport(rtc::Thread* signaling_thread, |
+ rtc::Thread* worker_thread, |
+ const std::string& content_name, |
+ PortAllocator* allocator); |
virtual ~Transport(); |
- // Returns the name of this transport. |
- const std::string& name() const { return name_; } |
+ // Returns the signaling thread. The app talks to Transport on this thread. |
+ rtc::Thread* signaling_thread() const { return signaling_thread_; } |
+ // Returns the worker thread. The actual networking is done on this thread. |
+ rtc::Thread* worker_thread() const { return worker_thread_; } |
+ |
+ // Returns the content_name of this transport. |
+ const std::string& content_name() const { return content_name_; } |
// Returns the port allocator object for this transport. |
PortAllocator* port_allocator() { return allocator_; } |
@@ -174,14 +172,6 @@ |
return (receiving_ == TRANSPORT_STATE_SOME || |
receiving_ == TRANSPORT_STATE_ALL); |
} |
- bool ready_for_remote_candidates() const { |
- return local_description_set_ && remote_description_set_; |
- } |
- |
- bool AllChannelsCompleted() const; |
- bool AnyChannelFailed() const; |
- |
- IceGatheringState gathering_state() const { return gathering_state_; } |
sigslot::signal1<Transport*> SignalWritableState; |
sigslot::signal1<Transport*> SignalReceivingState; |
@@ -200,23 +190,21 @@ |
void SetChannelReceivingTimeout(int timeout_ms); |
// 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; |
- } |
+ void SetCertificate( |
+ const rtc::scoped_refptr<rtc::RTCCertificate>& certificate); |
+ |
+ // Get a copy of the local identity provided by SetIdentity. |
+ bool GetCertificate(rtc::scoped_refptr<rtc::RTCCertificate>* certificate); |
// 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); |
- |
+ // Note: GetChannel may lead to race conditions, since the mutex is not held |
+ // after the pointer is returned. |
TransportChannelImpl* GetChannel(int component); |
- |
+ // Note: HasChannel does not lead to race conditions, unlike GetChannel. |
bool HasChannel(int component) { |
return (NULL != GetChannel(component)); |
} |
@@ -224,6 +212,7 @@ |
void DestroyChannel(int component); |
// Set the local TransportDescription to be used by TransportChannels. |
+ // This should be called before ConnectChannels(). |
bool SetLocalTransportDescription(const TransportDescription& description, |
ContentAction action, |
std::string* error_desc); |
@@ -238,11 +227,6 @@ |
void ConnectChannels(); |
sigslot::signal1<Transport*> SignalConnecting; |
- // 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(); |
@@ -252,15 +236,20 @@ |
bool GetStats(TransportStats* stats); |
- sigslot::signal1<Transport*> SignalGatheringState; |
+ // Before any stanza is sent, the manager will request signaling. Once |
+ // signaling is available, the client should call OnSignalingReady. Once |
+ // this occurs, the transport (or its channels) can send any waiting stanzas. |
+ // OnSignalingReady invokes OnTransportSignalingReady and then forwards this |
+ // signal to each channel. |
+ sigslot::signal1<Transport*> SignalRequestSignaling; |
+ void OnSignalingReady(); |
// Handles sending of ready candidates and receiving of remote candidates. |
- sigslot::signal2<Transport*, const std::vector<Candidate>&> |
- SignalCandidatesGathered; |
- |
- // Called when one or more candidates are ready from the remote peer. |
- bool AddRemoteCandidates(const std::vector<Candidate>& candidates, |
- std::string* error); |
+ sigslot::signal2<Transport*, |
+ const std::vector<Candidate>&> SignalCandidatesReady; |
+ |
+ sigslot::signal1<Transport*> SignalCandidatesAllocationDone; |
+ void OnRemoteCandidates(const std::vector<Candidate>& candidates); |
// If candidate is not acceptable, returns false and sets error. |
// Call this before calling OnRemoteCandidates. |
@@ -275,12 +264,10 @@ |
// Forwards the signal from TransportChannel to BaseSession. |
sigslot::signal0<> SignalRoleConflict; |
- virtual bool GetSslRole(rtc::SSLRole* ssl_role) const { return false; } |
+ virtual bool GetSslRole(rtc::SSLRole* ssl_role) const; |
// Must be called before channel is starting to connect. |
- virtual bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version) { |
- return false; |
- } |
+ virtual bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version); |
protected: |
// These are called by Create/DestroyChannel above in order to create or |
@@ -288,6 +275,9 @@ |
virtual TransportChannelImpl* CreateTransportChannel(int component) = 0; |
virtual void DestroyTransportChannel(TransportChannelImpl* channel) = 0; |
+ // Informs the subclass that we received the signaling ready message. |
+ virtual void OnTransportSignalingReady() {} |
+ |
// The current local transport description, for use by derived classes |
// when performing transport description negotiation. |
const TransportDescription* local_description() const { |
@@ -300,37 +290,53 @@ |
return remote_description_.get(); |
} |
+ virtual void SetCertificate_w( |
+ const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {} |
+ |
+ virtual bool GetCertificate_w( |
+ rtc::scoped_refptr<rtc::RTCCertificate>* certificate) { |
+ return false; |
+ } |
+ |
// 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); |
+ virtual bool ApplyLocalTransportDescription_w(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); |
+ virtual bool ApplyRemoteTransportDescription_w(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); |
+ virtual bool NegotiateTransportDescription_w(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); |
+ virtual bool ApplyNegotiatedTransportDescription_w( |
+ TransportChannelImpl* channel, std::string* error_desc); |
+ |
+ virtual bool GetSslRole_w(rtc::SSLRole* ssl_role) const { |
+ return false; |
+ } |
+ |
+ virtual bool SetSslMaxProtocolVersion_w(rtc::SSLProtocolVersion version) { |
+ return false; |
+ } |
private: |
struct ChannelMapEntry { |
- ChannelMapEntry() : impl_(NULL), ref_(0) {} |
+ ChannelMapEntry() : impl_(NULL), candidates_allocated_(false), ref_(0) {} |
explicit ChannelMapEntry(TransportChannelImpl *impl) |
: impl_(impl), |
+ candidates_allocated_(false), |
ref_(0) { |
} |
@@ -343,9 +349,14 @@ |
TransportChannelImpl* get() const { return impl_; } |
TransportChannelImpl* operator->() const { return impl_; } |
- |
- private: |
- TransportChannelImpl* impl_; |
+ void set_candidates_allocated(bool status) { |
+ candidates_allocated_ = status; |
+ } |
+ bool candidates_allocated() const { return candidates_allocated_; } |
+ |
+ private: |
+ TransportChannelImpl *impl_; |
+ bool candidates_allocated_; |
int ref_; |
}; |
@@ -358,55 +369,92 @@ |
// Called when the receiving state of a channel changes. |
void OnChannelReceivingState(TransportChannel* channel); |
- // Called when a channel starts finishes gathering candidates |
- void OnChannelGatheringState(TransportChannelImpl* channel); |
- |
+ // Called when a channel requests signaling. |
+ void OnChannelRequestSignaling(TransportChannelImpl* channel); |
+ |
+ // Called when a candidate is ready from remote peer. |
+ void OnRemoteCandidate(const Candidate& candidate); |
// Called when a candidate is ready from channel. |
- void OnChannelCandidateGathered(TransportChannelImpl* channel, |
- const Candidate& candidate); |
+ void OnChannelCandidateReady(TransportChannelImpl* channel, |
+ const Candidate& candidate); |
void OnChannelRouteChange(TransportChannel* channel, |
const Candidate& remote_candidate); |
+ void OnChannelCandidatesAllocationDone(TransportChannelImpl* channel); |
// Called when there is ICE role change. |
void OnRoleConflict(TransportChannelImpl* channel); |
// Called when the channel removes a connection. |
void OnChannelConnectionRemoved(TransportChannelImpl* channel); |
+ // Dispatches messages to the appropriate handler (below). |
+ void OnMessage(rtc::Message* msg); |
+ |
+ // These are versions of the above methods that are called only on a |
+ // particular thread (s = signaling, w = worker). The above methods post or |
+ // send a message to invoke this version. |
+ TransportChannelImpl* CreateChannel_w(int component); |
+ void DestroyChannel_w(int component); |
+ void ConnectChannels_w(); |
+ void ResetChannels_w(); |
+ void DestroyAllChannels_w(); |
+ void OnRemoteCandidate_w(const Candidate& candidate); |
+ void OnChannelWritableState_s(); |
+ void OnChannelReceivingState_s(); |
+ void OnChannelRequestSignaling_s(); |
+ void OnConnecting_s(); |
+ void OnChannelRouteChange_s(const TransportChannel* channel, |
+ const Candidate& remote_candidate); |
+ void OnChannelCandidatesAllocationDone_s(); |
+ |
// Helper function that invokes the given function on every channel. |
typedef void (TransportChannelImpl::* TransportChannelFunc)(); |
- void CallChannels(TransportChannelFunc func); |
+ void CallChannels_w(TransportChannelFunc func); |
// Computes the AND and OR of the channel's read/write/receiving state |
// (argument picks the operation). |
- TransportState GetTransportState(TransportStateType type); |
+ TransportState GetTransportState_s(TransportStateType type); |
+ |
+ void OnChannelCandidateReady_s(); |
+ |
+ void SetIceRole_w(IceRole role); |
+ void SetRemoteIceMode_w(IceMode mode); |
+ bool SetLocalTransportDescription_w(const TransportDescription& desc, |
+ ContentAction action, |
+ std::string* error_desc); |
+ bool SetRemoteTransportDescription_w(const TransportDescription& desc, |
+ ContentAction action, |
+ std::string* error_desc); |
+ bool GetStats_w(TransportStats* infos); |
+ bool GetRemoteSSLCertificate_w(rtc::SSLCertificate** cert); |
+ |
+ void SetChannelReceivingTimeout_w(int timeout_ms); |
// Sends SignalCompleted if we are now in that state. |
- void MaybeSignalCompleted(); |
- |
- // Sends SignalGatheringState if gathering state changed |
- void UpdateGatheringState(); |
- |
- void UpdateWritableState(); |
- void UpdateReceivingState(); |
- |
- const std::string name_; |
+ void MaybeCompleted_w(); |
+ |
+ rtc::Thread* const signaling_thread_; |
+ rtc::Thread* const worker_thread_; |
+ const std::string content_name_; |
PortAllocator* const allocator_; |
- bool channels_destroyed_ = false; |
- TransportState readable_ = TRANSPORT_STATE_NONE; |
- TransportState writable_ = TRANSPORT_STATE_NONE; |
- TransportState receiving_ = TRANSPORT_STATE_NONE; |
- bool was_writable_ = false; |
- bool connect_requested_ = false; |
- IceRole ice_role_ = ICEROLE_UNKNOWN; |
- uint64 tiebreaker_ = 0; |
- IceMode remote_ice_mode_ = ICEMODE_FULL; |
- int channel_receiving_timeout_ = -1; |
+ bool destroyed_; |
+ TransportState readable_; |
+ TransportState writable_; |
+ TransportState receiving_; |
+ bool was_writable_; |
+ bool connect_requested_; |
+ IceRole ice_role_; |
+ uint64 tiebreaker_; |
+ IceMode remote_ice_mode_; |
+ int channel_receiving_timeout_; |
rtc::scoped_ptr<TransportDescription> local_description_; |
rtc::scoped_ptr<TransportDescription> remote_description_; |
- bool local_description_set_ = false; |
- bool remote_description_set_ = false; |
- IceGatheringState gathering_state_ = kIceGatheringNew; |
- |
+ |
+ // TODO(tommi): Make sure we only use this on the worker thread. |
ChannelMap channels_; |
+ // Buffers the ready_candidates so that SignalCanidatesReady can |
+ // provide them in multiples. |
+ std::vector<Candidate> ready_candidates_; |
+ // Protects changes to channels and messages |
+ rtc::CriticalSection crit_; |
RTC_DISALLOW_COPY_AND_ASSIGN(Transport); |
}; |