Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(483)

Unified Diff: webrtc/p2p/base/p2ptransportchannel.cc

Issue 1336553003: Revert change which removes GICE (Closed) Base URL: https://chromium.googlesource.com/external/webrtc@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/p2p/base/p2ptransportchannel.h ('k') | webrtc/p2p/base/p2ptransportchannel_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/p2p/base/p2ptransportchannel.cc
diff --git a/webrtc/p2p/base/p2ptransportchannel.cc b/webrtc/p2p/base/p2ptransportchannel.cc
index 094a8dcc8f1ffc937a436dc85890633c62d60760..51f4736e24cf4311d5ed6eb43ad6fe0618ad6c98 100644
--- a/webrtc/p2p/base/p2ptransportchannel.cc
+++ b/webrtc/p2p/base/p2ptransportchannel.cc
@@ -124,6 +124,14 @@ class ConnectionCompare {
cricket::Connection* a = const_cast<cricket::Connection*>(ca);
cricket::Connection* b = const_cast<cricket::Connection*>(cb);
+ // The IceProtocol is initialized to ICEPROTO_HYBRID and can be updated to
+ // GICE or RFC5245 when an answer SDP is set, or when a STUN message is
+ // received. So the port receiving the STUN message may have a different
+ // IceProtocol if the answer SDP is not set yet.
+ ASSERT(a->port()->IceProtocol() == b->port()->IceProtocol() ||
+ a->port()->IceProtocol() == cricket::ICEPROTO_HYBRID ||
+ b->port()->IceProtocol() == cricket::ICEPROTO_HYBRID);
+
// Compare first on writability and static preferences.
int cmp = CompareConnections(a, b);
if (cmp > 0)
@@ -184,6 +192,7 @@ P2PTransportChannel::P2PTransportChannel(const std::string& content_name,
pending_best_connection_(NULL),
sort_dirty_(false),
was_writable_(false),
+ protocol_type_(ICEPROTO_HYBRID),
remote_ice_mode_(ICEMODE_FULL),
ice_role_(ICEROLE_UNKNOWN),
tiebreaker_(0),
@@ -284,6 +293,21 @@ TransportChannelState P2PTransportChannel::GetState() const {
return TransportChannelState::STATE_COMPLETED;
}
+bool P2PTransportChannel::GetIceProtocolType(IceProtocolType* type) const {
+ *type = protocol_type_;
+ return true;
+}
+
+void P2PTransportChannel::SetIceProtocolType(IceProtocolType type) {
+ ASSERT(worker_thread_ == rtc::Thread::Current());
+
+ protocol_type_ = type;
+ for (std::vector<PortInterface *>::iterator it = ports_.begin();
+ it != ports_.end(); ++it) {
+ (*it)->SetIceProtocolType(protocol_type_);
+ }
+}
+
void P2PTransportChannel::SetIceCredentials(const std::string& ice_ufrag,
const std::string& ice_pwd) {
ASSERT(worker_thread_ == rtc::Thread::Current());
@@ -323,8 +347,9 @@ void P2PTransportChannel::SetRemoteIceCredentials(const std::string& ice_ufrag,
}
if (ice_restart) {
- // We need to keep track of the remote ice restart so newer
- // connections are prioritized over the older.
+ // |candidate.generation()| is not signaled in ICEPROTO_RFC5245.
+ // Therefore we need to keep track of the remote ice restart so
+ // newer connections are prioritized over the older.
++remote_candidate_generation_;
}
}
@@ -385,6 +410,7 @@ void P2PTransportChannel::OnPortReady(PortAllocatorSession *session,
// The session will handle this, and send an initiate/accept/modify message
// if one is pending.
+ port->SetIceProtocolType(protocol_type_);
port->SetIceRole(ice_role_);
port->SetIceTiebreaker(tiebreaker_);
ports_.push_back(port);
@@ -479,30 +505,46 @@ void P2PTransportChannel::OnUnknownAddress(
}
} else {
// Create a new candidate with this address.
+ std::string type;
int remote_candidate_priority;
-
- // The priority of the candidate is set to the PRIORITY attribute
- // from the request.
- const StunUInt32Attribute* priority_attr =
- stun_msg->GetUInt32(STUN_ATTR_PRIORITY);
- if (!priority_attr) {
- LOG(LS_WARNING) << "P2PTransportChannel::OnUnknownAddress - "
- << "No STUN_ATTR_PRIORITY found in the "
- << "stun request message";
- port->SendBindingErrorResponse(stun_msg, address,
- STUN_ERROR_BAD_REQUEST,
- STUN_ERROR_REASON_BAD_REQUEST);
- return;
+ if (port->IceProtocol() == ICEPROTO_RFC5245) {
+ // RFC 5245
+ // If the source transport address of the request does not match any
+ // existing remote candidates, it represents a new peer reflexive remote
+ // candidate.
+ type = PRFLX_PORT_TYPE;
+
+ // The priority of the candidate is set to the PRIORITY attribute
+ // from the request.
+ const StunUInt32Attribute* priority_attr =
+ stun_msg->GetUInt32(STUN_ATTR_PRIORITY);
+ if (!priority_attr) {
+ LOG(LS_WARNING) << "P2PTransportChannel::OnUnknownAddress - "
+ << "No STUN_ATTR_PRIORITY found in the "
+ << "stun request message";
+ port->SendBindingErrorResponse(stun_msg, address,
+ STUN_ERROR_BAD_REQUEST,
+ STUN_ERROR_REASON_BAD_REQUEST);
+ return;
+ }
+ remote_candidate_priority = priority_attr->value();
+ } else {
+ // G-ICE doesn't support prflx candidate.
+ // We set candidate type to STUN_PORT_TYPE if the binding request comes
+ // from a relay port or the shared socket is used. Otherwise we use the
+ // port's type as the candidate type.
+ if (port->Type() == RELAY_PORT_TYPE || port->SharedSocket()) {
+ type = STUN_PORT_TYPE;
+ } else {
+ type = port->Type();
+ }
+ remote_candidate_priority = remote_candidate.GetPriority(
+ ICE_TYPE_PREFERENCE_PRFLX, port->Network()->preference(), 0);
}
- remote_candidate_priority = priority_attr->value();
- // RFC 5245
- // If the source transport address of the request does not match any
- // existing remote candidates, it represents a new peer reflexive remote
- // candidate.
remote_candidate =
Candidate(component(), ProtoToString(proto), address, 0,
- remote_username, remote_password, PRFLX_PORT_TYPE, 0U, "");
+ remote_username, remote_password, type, 0U, "");
// From RFC 5245, section-7.2.1.3:
// The foundation of the candidate is set to an arbitrary value, different
@@ -513,56 +555,81 @@ void P2PTransportChannel::OnUnknownAddress(
remote_candidate.set_priority(remote_candidate_priority);
}
- // RFC5245, the agent constructs a pair whose local candidate is equal to
- // the transport address on which the STUN request was received, and a
- // remote candidate equal to the source transport address where the
- // request came from.
+ if (port->IceProtocol() == ICEPROTO_RFC5245) {
+ // RFC5245, the agent constructs a pair whose local candidate is equal to
+ // the transport address on which the STUN request was received, and a
+ // remote candidate equal to the source transport address where the
+ // request came from.
+
+ // There shouldn't be an existing connection with this remote address.
+ // When ports are muxed, this channel might get multiple unknown address
+ // signals. In that case if the connection is already exists, we should
+ // simply ignore the signal otherwise send server error.
+ if (port->GetConnection(remote_candidate.address())) {
+ if (port_muxed) {
+ LOG(LS_INFO) << "Connection already exists for peer reflexive "
+ << "candidate: " << remote_candidate.ToString();
+ return;
+ } else {
+ ASSERT(false);
+ port->SendBindingErrorResponse(stun_msg, address,
+ STUN_ERROR_SERVER_ERROR,
+ STUN_ERROR_REASON_SERVER_ERROR);
+ return;
+ }
+ }
- // There shouldn't be an existing connection with this remote address.
- // When ports are muxed, this channel might get multiple unknown address
- // signals. In that case if the connection is already exists, we should
- // simply ignore the signal otherwise send server error.
- if (port->GetConnection(remote_candidate.address())) {
- if (port_muxed) {
- LOG(LS_INFO) << "Connection already exists for peer reflexive "
- << "candidate: " << remote_candidate.ToString();
- return;
- } else {
+ Connection* connection = port->CreateConnection(
+ remote_candidate, cricket::PortInterface::ORIGIN_THIS_PORT);
+ if (!connection) {
ASSERT(false);
port->SendBindingErrorResponse(stun_msg, address,
STUN_ERROR_SERVER_ERROR,
STUN_ERROR_REASON_SERVER_ERROR);
return;
}
- }
- Connection* connection = port->CreateConnection(
- remote_candidate, cricket::PortInterface::ORIGIN_THIS_PORT);
- if (!connection) {
- ASSERT(false);
- port->SendBindingErrorResponse(stun_msg, address,
- STUN_ERROR_SERVER_ERROR,
- STUN_ERROR_REASON_SERVER_ERROR);
- return;
- }
+ LOG(LS_INFO) << "Adding connection from "
+ << (remote_candidate_is_new ? "peer reflexive" : "resurrected")
+ << " candidate: " << remote_candidate.ToString();
+ AddConnection(connection);
+ connection->ReceivedPing();
- LOG(LS_INFO) << "Adding connection from "
- << (remote_candidate_is_new ? "peer reflexive" : "resurrected")
- << " candidate: " << remote_candidate.ToString();
- AddConnection(connection);
- connection->ReceivedPing();
+ // Send the pinger a successful stun response.
+ port->SendBindingResponse(stun_msg, address);
- bool received_use_candidate =
- stun_msg->GetByteString(STUN_ATTR_USE_CANDIDATE) != nullptr;
- if (received_use_candidate && ice_role_ == ICEROLE_CONTROLLED) {
- connection->set_nominated(true);
- OnNominated(connection);
- }
+ bool received_use_candidate =
+ stun_msg->GetByteString(STUN_ATTR_USE_CANDIDATE) != nullptr;
+ if (received_use_candidate && ice_role_ == ICEROLE_CONTROLLED) {
+ connection->set_nominated(true);
+ OnNominated(connection);
+ }
- // Update the list of connections since we just added another. We do this
- // after sending the response since it could (in principle) delete the
- // connection in question.
- SortConnections();
+ // Update the list of connections since we just added another. We do this
+ // after sending the response since it could (in principle) delete the
+ // connection in question.
+ SortConnections();
+ } else {
+ // Check for connectivity to this address. Create connections
+ // to this address across all local ports. First, add this as a new remote
+ // address
+ if (!CreateConnections(remote_candidate, port, true)) {
+ // Hopefully this won't occur, because changing a destination address
+ // shouldn't cause a new connection to fail
+ ASSERT(false);
+ port->SendBindingErrorResponse(stun_msg, address, STUN_ERROR_SERVER_ERROR,
+ STUN_ERROR_REASON_SERVER_ERROR);
+ return;
+ }
+
+ // Send the pinger a successful stun response.
+ port->SendBindingResponse(stun_msg, address);
+
+ // Update the list of connections since we just added another. We do this
+ // after sending the response since it could (in principle) delete the
+ // connection in question.
+ SortConnections();
+ }
}
void P2PTransportChannel::OnRoleConflict(PortInterface* port) {
@@ -583,6 +650,7 @@ void P2PTransportChannel::OnSignalingReady() {
void P2PTransportChannel::OnNominated(Connection* conn) {
ASSERT(worker_thread_ == rtc::Thread::Current());
ASSERT(ice_role_ == ICEROLE_CONTROLLED);
+ ASSERT(protocol_type_ == ICEPROTO_RFC5245);
if (conn->write_state() == Connection::STATE_WRITABLE) {
if (best_connection_ != conn) {
@@ -741,8 +809,13 @@ bool P2PTransportChannel::FindConnection(
uint32 P2PTransportChannel::GetRemoteCandidateGeneration(
const Candidate& candidate) {
- // We need to keep track of the remote ice restart so newer
- // connections are prioritized over the older.
+ if (protocol_type_ == ICEPROTO_GOOGLE) {
+ // The Candidate.generation() can be trusted. Nothing needs to be done.
+ return candidate.generation();
+ }
+ // |candidate.generation()| is not signaled in ICEPROTO_RFC5245.
+ // Therefore we need to keep track of the remote ice restart so
+ // newer connections are prioritized over the older.
ASSERT(candidate.generation() == 0 ||
candidate.generation() == remote_candidate_generation_);
return remote_candidate_generation_;
@@ -920,6 +993,15 @@ void P2PTransportChannel::SortConnections() {
// will be sorted.
UpdateConnectionStates();
+ if (protocol_type_ == ICEPROTO_HYBRID) {
+ // If we are in hybrid mode, we are not sending any ping requests, so there
+ // is no point in sorting the connections. In hybrid state, ports can have
+ // different protocol than hybrid and protocol may differ from one another.
+ // Instead just update the state of this channel
+ UpdateChannelState();
+ return;
+ }
+
// Any changes after this point will require a re-sort.
sort_dirty_ = false;
@@ -942,7 +1024,10 @@ void P2PTransportChannel::SortConnections() {
// connection although it will have higher priority if it is writable.
// The controlled side can switch the best connection only if the current
// |best connection_| has not been nominated by the controlling side yet.
- if ((ice_role_ == ICEROLE_CONTROLLING || !best_nominated_connection()) &&
+
+ // We don't want to pick the best connections if channel is using RFC5245.
+ if ((protocol_type_ != ICEPROTO_RFC5245 || ice_role_ == ICEROLE_CONTROLLING ||
+ !best_nominated_connection()) &&
ShouldSwitch(best_connection_, top_connection)) {
LOG(LS_INFO) << "Switching best connection: " << top_connection->ToString();
SwitchBestConnectionTo(top_connection);
@@ -951,7 +1036,8 @@ void P2PTransportChannel::SortConnections() {
// Controlled side can prune only if the best connection has been nominated.
// because otherwise it may delete the connection that will be selected by
// the controlling side.
- if (ice_role_ == ICEROLE_CONTROLLING || best_nominated_connection()) {
+ if (protocol_type_ != ICEPROTO_RFC5245 || ice_role_ == ICEROLE_CONTROLLING ||
+ best_nominated_connection()) {
PruneConnections();
}
@@ -1216,7 +1302,8 @@ Connection* P2PTransportChannel::FindNextPingableConnection() {
continue;
}
bool needs_triggered_check =
- (!conn->writable() &&
+ (protocol_type_ == ICEPROTO_RFC5245 &&
+ !conn->writable() &&
conn->last_ping_received() > conn->last_ping_sent());
if (needs_triggered_check &&
(!oldest_needing_triggered_check ||
@@ -1251,13 +1338,15 @@ Connection* P2PTransportChannel::FindNextPingableConnection() {
// b.2) |conn| is writable.
void P2PTransportChannel::PingConnection(Connection* conn) {
bool use_candidate = false;
- if (remote_ice_mode_ == ICEMODE_FULL && ice_role_ == ICEROLE_CONTROLLING) {
- use_candidate = (conn == best_connection_) ||
- (best_connection_ == NULL) ||
- (!best_connection_->writable()) ||
- (conn->priority() > best_connection_->priority());
- } else if (remote_ice_mode_ == ICEMODE_LITE && conn == best_connection_) {
- use_candidate = best_connection_->writable();
+ if (protocol_type_ == ICEPROTO_RFC5245) {
+ if (remote_ice_mode_ == ICEMODE_FULL && ice_role_ == ICEROLE_CONTROLLING) {
+ use_candidate = (conn == best_connection_) ||
+ (best_connection_ == NULL) ||
+ (!best_connection_->writable()) ||
+ (conn->priority() > best_connection_->priority());
+ } else if (remote_ice_mode_ == ICEMODE_LITE && conn == best_connection_) {
+ use_candidate = best_connection_->writable();
+ }
}
conn->set_use_candidate_attr(use_candidate);
conn->Ping(rtc::Time());
@@ -1270,7 +1359,7 @@ void P2PTransportChannel::OnConnectionStateChange(Connection* connection) {
// Update the best connection if the state change is from pending best
// connection and role is controlled.
- if (ice_role_ == ICEROLE_CONTROLLED) {
+ if (protocol_type_ == ICEPROTO_RFC5245 && ice_role_ == ICEROLE_CONTROLLED) {
if (connection == pending_best_connection_ && connection->writable()) {
pending_best_connection_ = NULL;
LOG(LS_INFO) << "Switching best connection on controlled side"
« no previous file with comments | « webrtc/p2p/base/p2ptransportchannel.h ('k') | webrtc/p2p/base/p2ptransportchannel_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698