The previous change causes a build issue as there is subclass of TransportChannel in chromium. To break the circular dependency, a stub of implementation for GetState() is provided and will be removed once the jingle_glue::MockTransportChannel has the function defined.

TBR=pthatcher@webrtc.org

BUG=411086

Review URL: https://webrtc-codereview.appspot.com/34369004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@7806 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
guoweis@webrtc.org 2014-12-04 07:56:02 +00:00
parent fd8422938c
commit 8c9ff203c5
12 changed files with 94 additions and 15 deletions

View File

@ -109,9 +109,6 @@ class DtlsTransportChannelWrapper : public TransportChannelImpl {
virtual IceRole GetIceRole() const { virtual IceRole GetIceRole() const {
return channel_->GetIceRole(); return channel_->GetIceRole();
} }
virtual size_t GetConnectionCount() const {
return channel_->GetConnectionCount();
}
virtual bool SetLocalIdentity(rtc::SSLIdentity *identity); virtual bool SetLocalIdentity(rtc::SSLIdentity *identity);
virtual bool GetLocalIdentity(rtc::SSLIdentity** identity) const; virtual bool GetLocalIdentity(rtc::SSLIdentity** identity) const;
@ -175,6 +172,10 @@ class DtlsTransportChannelWrapper : public TransportChannelImpl {
virtual Transport* GetTransport() { virtual Transport* GetTransport() {
return transport_; return transport_;
} }
virtual TransportChannelState GetState() const {
return channel_->GetState();
}
virtual void SetIceTiebreaker(uint64 tiebreaker) { virtual void SetIceTiebreaker(uint64 tiebreaker) {
channel_->SetIceTiebreaker(tiebreaker); channel_->SetIceTiebreaker(tiebreaker);
} }

View File

@ -82,9 +82,20 @@ class FakeTransportChannel : public TransportChannelImpl,
return transport_; return transport_;
} }
virtual TransportChannelState GetState() const {
if (connection_count_ == 0) {
return TransportChannelState::STATE_FAILED;
}
if (connection_count_ == 1) {
return TransportChannelState::STATE_COMPLETED;
}
return TransportChannelState::STATE_FAILED;
}
virtual void SetIceRole(IceRole role) { role_ = role; } virtual void SetIceRole(IceRole role) { role_ = role; }
virtual IceRole GetIceRole() const { return role_; } virtual IceRole GetIceRole() const { return role_; }
virtual size_t GetConnectionCount() const { return connection_count_; }
virtual void SetIceTiebreaker(uint64 tiebreaker) { tiebreaker_ = tiebreaker; } virtual void SetIceTiebreaker(uint64 tiebreaker) { tiebreaker_ = tiebreaker; }
virtual bool GetIceProtocolType(IceProtocolType* type) const { virtual bool GetIceProtocolType(IceProtocolType* type) const {
*type = ice_proto_; *type = ice_proto_;

View File

@ -226,6 +226,36 @@ void P2PTransportChannel::SetIceTiebreaker(uint64 tiebreaker) {
tiebreaker_ = tiebreaker; tiebreaker_ = tiebreaker;
} }
// Currently a channel is considered ICE completed once there is no
// more than one connection per Network. This works for a single NIC
// with both IPv4 and IPv6 enabled. However, this condition won't
// happen when there are multiple NICs and all of them have
// connectivity.
// TODO(guoweis): Change Completion to be driven by a channel level
// timer.
TransportChannelState P2PTransportChannel::GetState() const {
std::set<rtc::Network*> networks;
if (connections_.size() == 0) {
return TransportChannelState::STATE_FAILED;
}
for (uint32 i = 0; i < connections_.size(); ++i) {
rtc::Network* network = connections_[i]->port()->Network();
if (networks.find(network) == networks.end()) {
networks.insert(network);
} else {
LOG_J(LS_VERBOSE, this) << "Ice not completed yet for this channel as "
<< network->ToString()
<< " has more than 1 connection.";
return TransportChannelState::STATE_CONNECTING;
}
}
LOG_J(LS_VERBOSE, this) << "Ice is completed for this channel.";
return TransportChannelState::STATE_COMPLETED;
}
bool P2PTransportChannel::GetIceProtocolType(IceProtocolType* type) const { bool P2PTransportChannel::GetIceProtocolType(IceProtocolType* type) const {
*type = protocol_type_; *type = protocol_type_;
return true; return true;
@ -1065,7 +1095,7 @@ void P2PTransportChannel::HandleAllTimedOut() {
// If we have a best connection, return it, otherwise return top one in the // If we have a best connection, return it, otherwise return top one in the
// list (later we will mark it best). // list (later we will mark it best).
Connection* P2PTransportChannel::GetBestConnectionOnNetwork( Connection* P2PTransportChannel::GetBestConnectionOnNetwork(
rtc::Network* network) { rtc::Network* network) const {
// If the best connection is on this network, then it wins. // If the best connection is on this network, then it wins.
if (best_connection_ && (best_connection_->port()->Network() == network)) if (best_connection_ && (best_connection_->port()->Network() == network))
return best_connection_; return best_connection_;

View File

@ -59,10 +59,10 @@ class P2PTransportChannel : public TransportChannelImpl,
// From TransportChannelImpl: // From TransportChannelImpl:
virtual Transport* GetTransport() { return transport_; } virtual Transport* GetTransport() { return transport_; }
virtual TransportChannelState GetState() const;
virtual void SetIceRole(IceRole role); virtual void SetIceRole(IceRole role);
virtual IceRole GetIceRole() const { return ice_role_; } virtual IceRole GetIceRole() const { return ice_role_; }
virtual void SetIceTiebreaker(uint64 tiebreaker); virtual void SetIceTiebreaker(uint64 tiebreaker);
virtual size_t GetConnectionCount() const { return connections_.size(); }
virtual bool GetIceProtocolType(IceProtocolType* type) const; virtual bool GetIceProtocolType(IceProtocolType* type) const;
virtual void SetIceProtocolType(IceProtocolType type); virtual void SetIceProtocolType(IceProtocolType type);
virtual void SetIceCredentials(const std::string& ice_ufrag, virtual void SetIceCredentials(const std::string& ice_ufrag,
@ -164,7 +164,7 @@ class P2PTransportChannel : public TransportChannelImpl,
void HandleNotWritable(); void HandleNotWritable();
void HandleAllTimedOut(); void HandleAllTimedOut();
Connection* GetBestConnectionOnNetwork(rtc::Network* network); Connection* GetBestConnectionOnNetwork(rtc::Network* network) const;
bool CreateConnections(const Candidate &remote_candidate, bool CreateConnections(const Candidate &remote_candidate,
PortInterface* origin_port, bool readable); PortInterface* origin_port, bool readable);
bool CreateConnection(PortInterface* port, const Candidate& remote_candidate, bool CreateConnection(PortInterface* port, const Candidate& remote_candidate,

View File

@ -927,7 +927,8 @@ void Connection::set_write_state(WriteState value) {
WriteState old_value = write_state_; WriteState old_value = write_state_;
write_state_ = value; write_state_ = value;
if (value != old_value) { if (value != old_value) {
LOG_J(LS_VERBOSE, this) << "set_write_state"; LOG_J(LS_VERBOSE, this) << "set_write_state from: " << old_value << " to "
<< value;
SignalStateChange(this); SignalStateChange(this);
CheckTimeout(); CheckTimeout();
} }
@ -1102,8 +1103,10 @@ void Connection::UpdateState(uint32 now) {
pings_since_last_response_[i]); pings_since_last_response_[i]);
pings.append(buf).append(" "); pings.append(buf).append(" ");
} }
LOG_J(LS_VERBOSE, this) << "UpdateState(): pings_since_last_response_=" << LOG_J(LS_VERBOSE, this) << "UpdateState(): pings_since_last_response_="
pings << ", rtt=" << rtt << ", now=" << now; << pings << ", rtt=" << rtt << ", now=" << now
<< ", last ping received: " << last_ping_received_
<< ", last data_received: " << last_data_received_;
// Check the readable state. // Check the readable state.
// //
@ -1187,6 +1190,12 @@ void Connection::ReceivedPing() {
set_read_state(STATE_READABLE); set_read_state(STATE_READABLE);
} }
std::string Connection::ToDebugId() const {
std::stringstream ss;
ss << std::hex << this;
return ss.str();
}
std::string Connection::ToString() const { std::string Connection::ToString() const {
const char CONNECT_STATE_ABBREV[2] = { const char CONNECT_STATE_ABBREV[2] = {
'-', // not connected (false) '-', // not connected (false)
@ -1212,7 +1221,8 @@ std::string Connection::ToString() const {
const Candidate& local = local_candidate(); const Candidate& local = local_candidate();
const Candidate& remote = remote_candidate(); const Candidate& remote = remote_candidate();
std::stringstream ss; std::stringstream ss;
ss << "Conn[" << port_->content_name() ss << "Conn[" << ToDebugId()
<< ":" << port_->content_name()
<< ":" << local.id() << ":" << local.component() << ":" << local.id() << ":" << local.component()
<< ":" << local.generation() << ":" << local.generation()
<< ":" << local.type() << ":" << local.protocol() << ":" << local.type() << ":" << local.protocol()

View File

@ -517,6 +517,7 @@ class Connection : public rtc::MessageHandler,
void ReceivedPing(); void ReceivedPing();
// Debugging description of this connection // Debugging description of this connection
std::string ToDebugId() const;
std::string ToString() const; std::string ToString() const;
std::string ToSensitiveString() const; std::string ToSensitiveString() const;

View File

@ -54,6 +54,9 @@ class RawTransportChannel : public TransportChannelImpl,
// Implements TransportChannelImpl. // Implements TransportChannelImpl.
virtual Transport* GetTransport() { return raw_transport_; } virtual Transport* GetTransport() { return raw_transport_; }
virtual TransportChannelState GetState() const {
return TransportChannelState::STATE_COMPLETED;
}
virtual void SetIceCredentials(const std::string& ice_ufrag, virtual void SetIceCredentials(const std::string& ice_ufrag,
const std::string& ice_pwd) {} const std::string& ice_pwd) {}
virtual void SetRemoteIceCredentials(const std::string& ice_ufrag, virtual void SetRemoteIceCredentials(const std::string& ice_ufrag,

View File

@ -669,8 +669,7 @@ void Transport::OnChannelConnectionRemoved(TransportChannelImpl* channel) {
return; return;
} }
size_t connections = channel->GetConnectionCount(); if (channel->GetState() == TransportChannelState::STATE_FAILED) {
if (connections == 0) {
// A Transport has failed if any of its channels have no remaining // A Transport has failed if any of its channels have no remaining
// connections. // connections.
signaling_thread_->Post(this, MSG_FAILED); signaling_thread_->Post(this, MSG_FAILED);
@ -680,6 +679,12 @@ void Transport::OnChannelConnectionRemoved(TransportChannelImpl* channel) {
void Transport::MaybeCompleted_w() { void Transport::MaybeCompleted_w() {
ASSERT(worker_thread()->IsCurrent()); ASSERT(worker_thread()->IsCurrent());
// When there is no channel created yet, calling this function could fire an
// IceConnectionCompleted event prematurely.
if (channels_.size() == 0) {
return;
}
// A Transport's ICE process is completed if all of its channels are writable, // A Transport's ICE process is completed if all of its channels are writable,
// have finished allocating candidates, and have pruned all but one of their // have finished allocating candidates, and have pruned all but one of their
// connections. // connections.
@ -687,7 +692,7 @@ void Transport::MaybeCompleted_w() {
for (iter = channels_.begin(); iter != channels_.end(); ++iter) { for (iter = channels_.begin(); iter != channels_.end(); ++iter) {
const TransportChannelImpl* channel = iter->second.get(); const TransportChannelImpl* channel = iter->second.get();
if (!(channel->writable() && if (!(channel->writable() &&
channel->GetConnectionCount() == 1 && channel->GetState() == TransportChannelState::STATE_COMPLETED &&
channel->GetIceRole() == ICEROLE_CONTROLLING && channel->GetIceRole() == ICEROLE_CONTROLLING &&
iter->second.candidates_allocated())) { iter->second.candidates_allocated())) {
return; return;

View File

@ -36,6 +36,9 @@ enum PacketFlags {
// crypto provided by the transport (e.g. DTLS) // crypto provided by the transport (e.g. DTLS)
}; };
// Used to indicate channel's connection state.
enum TransportChannelState { STATE_CONNECTING, STATE_COMPLETED, STATE_FAILED };
// A TransportChannel represents one logical stream of packets that are sent // A TransportChannel represents one logical stream of packets that are sent
// between the two sides of a session. // between the two sides of a session.
class TransportChannel : public sigslot::has_slots<> { class TransportChannel : public sigslot::has_slots<> {
@ -46,6 +49,12 @@ class TransportChannel : public sigslot::has_slots<> {
readable_(false), writable_(false) {} readable_(false), writable_(false) {}
virtual ~TransportChannel() {} virtual ~TransportChannel() {}
// TODO(guoweis) - Make this pure virtual once all subclasses of
// TransportChannel have this defined.
virtual TransportChannelState GetState() const {
return TransportChannelState::STATE_CONNECTING;
}
// TODO(mallinath) - Remove this API, as it's no longer useful. // TODO(mallinath) - Remove this API, as it's no longer useful.
// Returns the session id of this channel. // Returns the session id of this channel.
virtual const std::string SessionId() const { return std::string(); } virtual const std::string SessionId() const { return std::string(); }

View File

@ -36,7 +36,6 @@ class TransportChannelImpl : public TransportChannel {
virtual IceRole GetIceRole() const = 0; virtual IceRole GetIceRole() const = 0;
virtual void SetIceRole(IceRole role) = 0; virtual void SetIceRole(IceRole role) = 0;
virtual void SetIceTiebreaker(uint64 tiebreaker) = 0; virtual void SetIceTiebreaker(uint64 tiebreaker) = 0;
virtual size_t GetConnectionCount() const = 0;
// To toggle G-ICE/ICE. // To toggle G-ICE/ICE.
virtual bool GetIceProtocolType(IceProtocolType* type) const = 0; virtual bool GetIceProtocolType(IceProtocolType* type) const = 0;
virtual void SetIceProtocolType(IceProtocolType type) = 0; virtual void SetIceProtocolType(IceProtocolType type) = 0;

View File

@ -111,6 +111,14 @@ int TransportChannelProxy::GetError() {
return impl_->GetError(); return impl_->GetError();
} }
TransportChannelState TransportChannelProxy::GetState() const {
ASSERT(rtc::Thread::Current() == worker_thread_);
if (!impl_) {
return TransportChannelState::STATE_CONNECTING;
}
return impl_->GetState();
}
bool TransportChannelProxy::GetStats(ConnectionInfos* infos) { bool TransportChannelProxy::GetStats(ConnectionInfos* infos) {
ASSERT(rtc::Thread::Current() == worker_thread_); ASSERT(rtc::Thread::Current() == worker_thread_);
if (!impl_) { if (!impl_) {

View File

@ -41,6 +41,8 @@ class TransportChannelProxy : public TransportChannel,
const std::string& name() const { return name_; } const std::string& name() const { return name_; }
TransportChannelImpl* impl() { return impl_; } TransportChannelImpl* impl() { return impl_; }
virtual TransportChannelState GetState() const;
// Sets the implementation to which we will proxy. // Sets the implementation to which we will proxy.
void SetImplementation(TransportChannelImpl* impl); void SetImplementation(TransportChannelImpl* impl);