Index: remoting/protocol/jingle_session.cc |
diff --git a/remoting/protocol/jingle_session.cc b/remoting/protocol/jingle_session.cc |
index 0f4f0a2ea6092236162ff8c7dfbfa5dcc8eb302b..edc48eea6b6649d4de693cab122266516821dc0b 100644 |
--- a/remoting/protocol/jingle_session.cc |
+++ b/remoting/protocol/jingle_session.cc |
@@ -32,11 +32,12 @@ |
namespace protocol { |
namespace { |
- |
-// Delay after candidate creation before sending transport-info message to |
-// accumulate multiple candidates. This is an optimization to reduce number of |
-// transport-info messages. |
-const int kTransportInfoSendDelayMs = 20; |
+// Delay after candidate creation before sending transport-info |
+// message. This is neccessary to be able to pack multiple candidates |
+// into one transport-info messages. The value needs to be greater |
+// than zero because ports are opened asynchronously in the browser |
+// process. |
+const int kTransportInfoSendDelayMs = 2; |
// How long we should wait for a response from the other end. This value is used |
// for all requests except |transport-info|. |
@@ -73,6 +74,7 @@ |
event_handler_(nullptr), |
state_(INITIALIZING), |
error_(OK), |
+ config_is_set_(false), |
weak_factory_(this) { |
} |
@@ -147,7 +149,7 @@ |
void JingleSession::AcceptIncomingConnection( |
const JingleMessage& initiate_message) { |
- DCHECK(config_); |
+ DCHECK(config_is_set_); |
// Process the first authentication message. |
const buzz::XmlElement* first_auth_message = |
@@ -182,7 +184,7 @@ |
auth_message = authenticator_->GetNextMessage(); |
message.description.reset( |
- new ContentDescription(CandidateSessionConfig::CreateFrom(*config_), |
+ new ContentDescription(CandidateSessionConfig::CreateFrom(config_), |
auth_message.Pass())); |
SendMessage(message); |
@@ -211,13 +213,14 @@ |
const SessionConfig& JingleSession::config() { |
DCHECK(CalledOnValidThread()); |
- return *config_; |
-} |
- |
-void JingleSession::set_config(scoped_ptr<SessionConfig> config) { |
- DCHECK(CalledOnValidThread()); |
- DCHECK(!config_); |
- config_ = config.Pass(); |
+ return config_; |
+} |
+ |
+void JingleSession::set_config(const SessionConfig& config) { |
+ DCHECK(CalledOnValidThread()); |
+ DCHECK(!config_is_set_); |
+ config_ = config; |
+ config_is_set_ = true; |
} |
StreamChannelFactory* JingleSession::GetTransportChannelFactory() { |
@@ -240,26 +243,16 @@ |
CloseInternal(OK); |
} |
-void JingleSession::AddPendingRemoteTransportInfo(Transport* channel) { |
- std::list<JingleMessage::IceCredentials>::iterator credentials = |
- pending_remote_ice_credentials_.begin(); |
- while (credentials != pending_remote_ice_credentials_.end()) { |
- if (credentials->channel == channel->name()) { |
- channel->SetRemoteCredentials(credentials->ufrag, credentials->password); |
- credentials = pending_remote_ice_credentials_.erase(credentials); |
+void JingleSession::AddPendingRemoteCandidates(Transport* channel, |
+ const std::string& name) { |
+ std::list<JingleMessage::NamedCandidate>::iterator it = |
+ pending_remote_candidates_.begin(); |
+ while(it != pending_remote_candidates_.end()) { |
+ if (it->name == name) { |
+ channel->AddRemoteCandidate(it->candidate); |
+ it = pending_remote_candidates_.erase(it); |
} else { |
- ++credentials; |
- } |
- } |
- |
- std::list<JingleMessage::NamedCandidate>::iterator candidate = |
- pending_remote_candidates_.begin(); |
- while (candidate != pending_remote_candidates_.end()) { |
- if (candidate->name == channel->name()) { |
- channel->AddRemoteCandidate(candidate->candidate); |
- candidate = pending_remote_candidates_.erase(candidate); |
- } else { |
- ++candidate; |
+ ++it; |
} |
} |
} |
@@ -270,9 +263,8 @@ |
scoped_ptr<Transport> channel = |
session_manager_->transport_factory_->CreateTransport(); |
- channel->SetUseStandardIce(config_->standard_ice()); |
channel->Connect(name, this, callback); |
- AddPendingRemoteTransportInfo(channel.get()); |
+ AddPendingRemoteCandidates(channel.get(), name); |
channels_[name] = channel.release(); |
} |
@@ -285,19 +277,18 @@ |
} |
} |
-void JingleSession::OnTransportIceCredentials(Transport* transport, |
- const std::string& ufrag, |
- const std::string& password) { |
- EnsurePendingTransportInfoMessage(); |
- pending_transport_info_message_->ice_credentials.push_back( |
- JingleMessage::IceCredentials(transport->name(), ufrag, password)); |
-} |
- |
void JingleSession::OnTransportCandidate(Transport* transport, |
const cricket::Candidate& candidate) { |
- EnsurePendingTransportInfoMessage(); |
- pending_transport_info_message_->candidates.push_back( |
- JingleMessage::NamedCandidate(transport->name(), candidate)); |
+ pending_candidates_.push_back(JingleMessage::NamedCandidate( |
+ transport->name(), candidate)); |
+ |
+ if (!transport_infos_timer_.IsRunning()) { |
+ // Delay sending the new candidates in case we get more candidates |
+ // that we can send in one message. |
+ transport_infos_timer_.Start( |
+ FROM_HERE, base::TimeDelta::FromMilliseconds(kTransportInfoSendDelayMs), |
+ this, &JingleSession::SendTransportInfo); |
+ } |
} |
void JingleSession::OnTransportRouteChange(Transport* transport, |
@@ -371,33 +362,14 @@ |
} |
} |
-void JingleSession::EnsurePendingTransportInfoMessage() { |
- // |transport_info_timer_| must be running iff |
- // |pending_transport_info_message_| exists. |
- DCHECK_EQ(pending_transport_info_message_ != nullptr, |
- transport_info_timer_.IsRunning()); |
- |
- if (!pending_transport_info_message_) { |
- pending_transport_info_message_.reset(new JingleMessage( |
- peer_jid_, JingleMessage::TRANSPORT_INFO, session_id_)); |
- pending_transport_info_message_->standard_ice = config_->standard_ice(); |
- |
- // Delay sending the new candidates in case we get more candidates |
- // that we can send in one message. |
- transport_info_timer_.Start( |
- FROM_HERE, base::TimeDelta::FromMilliseconds(kTransportInfoSendDelayMs), |
- this, &JingleSession::SendTransportInfo); |
- } |
-} |
- |
void JingleSession::SendTransportInfo() { |
- DCHECK(pending_transport_info_message_); |
+ JingleMessage message(peer_jid_, JingleMessage::TRANSPORT_INFO, session_id_); |
+ message.candidates.swap(pending_candidates_); |
scoped_ptr<IqRequest> request = session_manager_->iq_sender()->SendIq( |
- pending_transport_info_message_->ToXml(), |
+ message.ToXml(), |
base::Bind(&JingleSession::OnTransportInfoResponse, |
base::Unretained(this))); |
- pending_transport_info_message_.reset(); |
if (request) { |
request->SetTimeout(base::TimeDelta::FromSeconds(kTransportInfoTimeout)); |
transport_info_requests_.push_back(request.release()); |
@@ -490,6 +462,9 @@ |
CloseInternal(INCOMPATIBLE_PROTOCOL); |
return; |
} |
+ |
+ // In case there is transport information in the accept message. |
+ ProcessTransportInfo(message); |
SetState(CONNECTED); |
@@ -522,27 +497,6 @@ |
} |
void JingleSession::ProcessTransportInfo(const JingleMessage& message) { |
- // Check if the transport information version matches what was negotiated. |
- if (message.standard_ice != config_->standard_ice()) { |
- LOG(ERROR) << "Received transport-info message in format different from " |
- "negotiated."; |
- CloseInternal(INCOMPATIBLE_PROTOCOL); |
- return; |
- } |
- |
- for (std::list<JingleMessage::IceCredentials>::const_iterator it = |
- message.ice_credentials.begin(); |
- it != message.ice_credentials.end(); ++it) { |
- ChannelsMap::iterator channel = channels_.find(it->channel); |
- if (channel != channels_.end()) { |
- channel->second->SetRemoteCredentials(it->ufrag, it->password); |
- } else { |
- // Transport info was received before the channel was created. |
- // This could happen due to messages being reordered on the wire. |
- pending_remote_ice_credentials_.push_back(*it); |
- } |
- } |
- |
for (std::list<JingleMessage::NamedCandidate>::const_iterator it = |
message.candidates.begin(); |
it != message.candidates.end(); ++it) { |
@@ -601,12 +555,12 @@ |
bool JingleSession::InitializeConfigFromDescription( |
const ContentDescription* description) { |
DCHECK(description); |
- config_ = SessionConfig::GetFinalConfig(description->config()); |
- if (!config_) { |
+ |
+ if (!description->config()->GetFinalConfig(&config_)) { |
LOG(ERROR) << "session-accept does not specify configuration"; |
return false; |
} |
- if (!candidate_config()->IsSupported(*config_)) { |
+ if (!candidate_config()->IsSupported(config_)) { |
LOG(ERROR) << "session-accept specifies an invalid configuration"; |
return false; |
} |