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

Side by Side Diff: webrtc/p2p/base/transport.cc

Issue 1380563002: Thinning out the Transport class. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fixing code style and naming. Created 5 years, 2 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 unified diff | Download patch
« no previous file with comments | « webrtc/p2p/base/transport.h ('k') | webrtc/p2p/base/transport_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include <utility> // for std::pair 11 #include <utility> // for std::pair
12 12
13 #include "webrtc/p2p/base/transport.h" 13 #include "webrtc/p2p/base/transport.h"
14 14
15 #include "webrtc/p2p/base/candidate.h" 15 #include "webrtc/p2p/base/candidate.h"
16 #include "webrtc/p2p/base/constants.h" 16 #include "webrtc/p2p/base/constants.h"
17 #include "webrtc/p2p/base/port.h" 17 #include "webrtc/p2p/base/port.h"
18 #include "webrtc/p2p/base/transportchannelimpl.h" 18 #include "webrtc/p2p/base/transportchannelimpl.h"
19 #include "webrtc/base/bind.h" 19 #include "webrtc/base/bind.h"
20 #include "webrtc/base/common.h" 20 #include "webrtc/base/checks.h"
21 #include "webrtc/base/logging.h" 21 #include "webrtc/base/logging.h"
22 22
23 namespace cricket { 23 namespace cricket {
24 24
25 using rtc::Bind; 25 using rtc::Bind;
26 26
27 static bool VerifyIceParams(const TransportDescription& desc) { 27 static bool VerifyIceParams(const TransportDescription& desc) {
28 // For legacy protocols. 28 // For legacy protocols.
29 if (desc.ice_ufrag.empty() && desc.ice_pwd.empty()) 29 if (desc.ice_ufrag.empty() && desc.ice_pwd.empty())
30 return true; 30 return true;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 static bool IceCredentialsChanged(const TransportDescription& old_desc, 62 static bool IceCredentialsChanged(const TransportDescription& old_desc,
63 const TransportDescription& new_desc) { 63 const TransportDescription& new_desc) {
64 return IceCredentialsChanged(old_desc.ice_ufrag, old_desc.ice_pwd, 64 return IceCredentialsChanged(old_desc.ice_ufrag, old_desc.ice_pwd,
65 new_desc.ice_ufrag, new_desc.ice_pwd); 65 new_desc.ice_ufrag, new_desc.ice_pwd);
66 } 66 }
67 67
68 Transport::Transport(const std::string& name, PortAllocator* allocator) 68 Transport::Transport(const std::string& name, PortAllocator* allocator)
69 : name_(name), allocator_(allocator) {} 69 : name_(name), allocator_(allocator) {}
70 70
71 Transport::~Transport() { 71 Transport::~Transport() {
72 ASSERT(channels_destroyed_); 72 RTC_DCHECK(channels_destroyed_);
73 }
74
75 bool Transport::AllChannelsCompleted() const {
76 // We aren't completed until at least one channel is complete, so if there
77 // are no channels, we aren't complete yet.
78 if (channels_.empty()) {
79 LOG(LS_INFO) << name() << " transport is not complete"
80 << " because it has no TransportChannels";
81 return false;
82 }
83
84 // A Transport's ICE process is completed if all of its channels are writable,
85 // have finished allocating candidates, and have pruned all but one of their
86 // connections.
87 for (const auto& iter : channels_) {
88 const TransportChannelImpl* channel = iter.second.get();
89 bool complete =
90 channel->writable() &&
91 channel->GetState() == TransportChannelState::STATE_COMPLETED &&
92 channel->GetIceRole() == ICEROLE_CONTROLLING &&
93 channel->gathering_state() == kIceGatheringComplete;
94 if (!complete) {
95 LOG(LS_INFO) << name() << " transport is not complete"
96 << " because a channel is still incomplete.";
97 return false;
98 }
99 }
100
101 return true;
102 }
103
104 bool Transport::AnyChannelFailed() const {
105 for (const auto& iter : channels_) {
106 if (iter.second->GetState() == TransportChannelState::STATE_FAILED) {
107 return true;
108 }
109 }
110 return false;
111 } 73 }
112 74
113 void Transport::SetIceRole(IceRole role) { 75 void Transport::SetIceRole(IceRole role) {
114 ice_role_ = role; 76 ice_role_ = role;
115 for (auto& iter : channels_) { 77 for (const auto& kv : channels_) {
116 iter.second->SetIceRole(ice_role_); 78 kv.second->SetIceRole(ice_role_);
117 } 79 }
118 } 80 }
119 81
120 bool Transport::GetRemoteSSLCertificate(rtc::SSLCertificate** cert) { 82 bool Transport::GetRemoteSSLCertificate(rtc::SSLCertificate** cert) {
121 if (channels_.empty()) 83 if (channels_.empty()) {
122 return false; 84 return false;
85 }
123 86
124 ChannelMap::iterator iter = channels_.begin(); 87 auto iter = channels_.begin();
125 return iter->second->GetRemoteSSLCertificate(cert); 88 return iter->second->GetRemoteSSLCertificate(cert);
126 } 89 }
127 90
128 void Transport::SetIceConfig(const IceConfig& config) { 91 void Transport::SetIceConfig(const IceConfig& config) {
129 ice_config_ = config; 92 ice_config_ = config;
130 for (const auto& kv : channels_) { 93 for (const auto& kv : channels_) {
131 kv.second->SetIceConfig(ice_config_); 94 kv.second->SetIceConfig(ice_config_);
132 } 95 }
133 } 96 }
134 97
(...skipping 13 matching lines...) Expand all
148 IceRole new_ice_role = 111 IceRole new_ice_role =
149 (action == CA_OFFER) ? ICEROLE_CONTROLLING : ICEROLE_CONTROLLED; 112 (action == CA_OFFER) ? ICEROLE_CONTROLLING : ICEROLE_CONTROLLED;
150 113
151 // It must be called before ApplyLocalTransportDescription, which may 114 // It must be called before ApplyLocalTransportDescription, which may
152 // trigger an ICE restart and depends on the new ICE role. 115 // trigger an ICE restart and depends on the new ICE role.
153 SetIceRole(new_ice_role); 116 SetIceRole(new_ice_role);
154 } 117 }
155 118
156 local_description_.reset(new TransportDescription(description)); 119 local_description_.reset(new TransportDescription(description));
157 120
158 for (auto& iter : channels_) { 121 for (const auto& kv : channels_) {
159 ret &= ApplyLocalTransportDescription(iter.second.get(), error_desc); 122 ret &= ApplyLocalTransportDescription(kv.second, error_desc);
160 } 123 }
161 if (!ret) { 124 if (!ret) {
162 return false; 125 return false;
163 } 126 }
164 127
165 // If PRANSWER/ANSWER is set, we should decide transport protocol type. 128 // If PRANSWER/ANSWER is set, we should decide transport protocol type.
166 if (action == CA_PRANSWER || action == CA_ANSWER) { 129 if (action == CA_PRANSWER || action == CA_ANSWER) {
167 ret &= NegotiateTransportDescription(action, error_desc); 130 ret &= NegotiateTransportDescription(action, error_desc);
168 } 131 }
169 if (ret) { 132 if (ret) {
170 local_description_set_ = true; 133 local_description_set_ = true;
171 ConnectChannels(); 134 ConnectChannels();
172 } 135 }
173 136
174 return ret; 137 return ret;
175 } 138 }
176 139
177 bool Transport::SetRemoteTransportDescription( 140 bool Transport::SetRemoteTransportDescription(
178 const TransportDescription& description, 141 const TransportDescription& description,
179 ContentAction action, 142 ContentAction action,
180 std::string* error_desc) { 143 std::string* error_desc) {
181 bool ret = true; 144 bool ret = true;
182 145
183 if (!VerifyIceParams(description)) { 146 if (!VerifyIceParams(description)) {
184 return BadTransportDescription("Invalid ice-ufrag or ice-pwd length", 147 return BadTransportDescription("Invalid ice-ufrag or ice-pwd length",
185 error_desc); 148 error_desc);
186 } 149 }
187 150
188 remote_description_.reset(new TransportDescription(description)); 151 remote_description_.reset(new TransportDescription(description));
189 for (auto& iter : channels_) { 152 for (const auto& kv : channels_) {
190 ret &= ApplyRemoteTransportDescription(iter.second.get(), error_desc); 153 ret &= ApplyRemoteTransportDescription(kv.second, error_desc);
191 } 154 }
192 155
193 // If PRANSWER/ANSWER is set, we should decide transport protocol type. 156 // If PRANSWER/ANSWER is set, we should decide transport protocol type.
194 if (action == CA_PRANSWER || action == CA_ANSWER) { 157 if (action == CA_PRANSWER || action == CA_ANSWER) {
195 ret = NegotiateTransportDescription(CA_OFFER, error_desc); 158 ret = NegotiateTransportDescription(CA_OFFER, error_desc);
196 } 159 }
197 if (ret) { 160 if (ret) {
198 remote_description_set_ = true; 161 remote_description_set_ = true;
199 } 162 }
200 163
201 return ret; 164 return ret;
202 } 165 }
203 166
204 TransportChannelImpl* Transport::CreateChannel(int component) { 167 TransportChannelImpl* Transport::CreateChannel(int component) {
205 TransportChannelImpl* impl; 168 TransportChannelImpl* channel;
206 169
207 // Create the entry if it does not exist. 170 // Create the entry if it does not exist.
208 bool impl_exists = false; 171 bool channel_exists = false;
209 auto iterator = channels_.find(component); 172 auto iter = channels_.find(component);
210 if (iterator == channels_.end()) { 173 if (iter == channels_.end()) {
211 impl = CreateTransportChannel(component); 174 channel = CreateTransportChannel(component);
212 iterator = channels_.insert(std::pair<int, ChannelMapEntry>( 175 channels_.insert(std::pair<int, TransportChannelImpl*>(component, channel));
213 component, ChannelMapEntry(impl))).first;
214 } else { 176 } else {
215 impl = iterator->second.get(); 177 channel = iter->second;
216 impl_exists = true; 178 channel_exists = true;
217 } 179 }
218 180
219 // Increase the ref count.
220 iterator->second.AddRef();
221 channels_destroyed_ = false; 181 channels_destroyed_ = false;
222 182
223 if (impl_exists) { 183 if (channel_exists) {
224 // If this is an existing channel, we should just return it without 184 // If this is an existing channel, we should just return it.
225 // connecting to all the signal again. 185 return channel;
226 return impl;
227 } 186 }
228 187
229 // Push down our transport state to the new channel. 188 // Push down our transport state to the new channel.
230 impl->SetIceRole(ice_role_); 189 channel->SetIceRole(ice_role_);
231 impl->SetIceTiebreaker(tiebreaker_); 190 channel->SetIceTiebreaker(tiebreaker_);
232 impl->SetIceConfig(ice_config_); 191 channel->SetIceConfig(ice_config_);
233 // TODO(ronghuawu): Change CreateChannel to be able to return error since 192 // TODO(ronghuawu): Change CreateChannel to be able to return error since
234 // below Apply**Description calls can fail. 193 // below Apply**Description calls can fail.
235 if (local_description_) 194 if (local_description_)
236 ApplyLocalTransportDescription(impl, NULL); 195 ApplyLocalTransportDescription(channel, nullptr);
237 if (remote_description_) 196 if (remote_description_)
238 ApplyRemoteTransportDescription(impl, NULL); 197 ApplyRemoteTransportDescription(channel, nullptr);
239 if (local_description_ && remote_description_) 198 if (local_description_ && remote_description_)
240 ApplyNegotiatedTransportDescription(impl, NULL); 199 ApplyNegotiatedTransportDescription(channel, nullptr);
241
242 impl->SignalWritableState.connect(this, &Transport::OnChannelWritableState);
243 impl->SignalReceivingState.connect(this, &Transport::OnChannelReceivingState);
244 impl->SignalGatheringState.connect(this, &Transport::OnChannelGatheringState);
245 impl->SignalCandidateGathered.connect(this,
246 &Transport::OnChannelCandidateGathered);
247 impl->SignalRouteChange.connect(this, &Transport::OnChannelRouteChange);
248 impl->SignalRoleConflict.connect(this, &Transport::OnRoleConflict);
249 impl->SignalConnectionRemoved.connect(
250 this, &Transport::OnChannelConnectionRemoved);
251 200
252 if (connect_requested_) { 201 if (connect_requested_) {
253 impl->Connect(); 202 channel->Connect();
254 if (channels_.size() == 1) {
255 // If this is the first channel, then indicate that we have started
256 // connecting.
257 SignalConnecting(this);
258 }
259 } 203 }
260 return impl; 204 return channel;
261 } 205 }
262 206
263 TransportChannelImpl* Transport::GetChannel(int component) { 207 TransportChannelImpl* Transport::GetChannel(int component) {
264 ChannelMap::iterator iter = channels_.find(component); 208 auto iter = channels_.find(component);
265 return (iter != channels_.end()) ? iter->second.get() : NULL; 209 return (iter != channels_.end()) ? iter->second : nullptr;
266 } 210 }
267 211
268 bool Transport::HasChannels() { 212 bool Transport::HasChannels() {
269 return !channels_.empty(); 213 return !channels_.empty();
270 } 214 }
271 215
272 void Transport::DestroyChannel(int component) { 216 void Transport::DestroyChannel(int component) {
273 ChannelMap::iterator iter = channels_.find(component); 217 auto iter = channels_.find(component);
274 if (iter == channels_.end()) 218 if (iter == channels_.end())
275 return; 219 return;
276 220
277 TransportChannelImpl* impl = NULL; 221 TransportChannelImpl* channel = iter->second;
278 222 channels_.erase(iter);
279 iter->second.DecRef(); 223 DestroyTransportChannel(channel);
280 if (!iter->second.ref()) {
281 impl = iter->second.get();
282 channels_.erase(iter);
283 }
284
285 if (connect_requested_ && channels_.empty()) {
286 // We're no longer attempting to connect.
287 SignalConnecting(this);
288 }
289
290 if (impl) {
291 DestroyTransportChannel(impl);
292 // Need to update aggregate state after destroying a channel,
293 // for example if it was the only one that wasn't yet writable.
294 UpdateWritableState();
295 UpdateReceivingState();
296 UpdateGatheringState();
297 MaybeSignalCompleted();
298 }
299 } 224 }
300 225
301 void Transport::ConnectChannels() { 226 void Transport::ConnectChannels() {
302 if (connect_requested_ || channels_.empty()) 227 if (connect_requested_ || channels_.empty())
303 return; 228 return;
304 229
305 connect_requested_ = true; 230 connect_requested_ = true;
306 231
307 if (!local_description_) { 232 if (!local_description_) {
308 // TOOD(mallinath) : TransportDescription(TD) shouldn't be generated here. 233 // TOOD(mallinath) : TransportDescription(TD) shouldn't be generated here.
309 // As Transport must know TD is offer or answer and cricket::Transport 234 // As Transport must know TD is offer or answer and cricket::Transport
310 // doesn't have the capability to decide it. This should be set by the 235 // doesn't have the capability to decide it. This should be set by the
311 // Session. 236 // Session.
312 // Session must generate local TD before remote candidates pushed when 237 // Session must generate local TD before remote candidates pushed when
313 // initiate request initiated by the remote. 238 // initiate request initiated by the remote.
314 LOG(LS_INFO) << "Transport::ConnectChannels: No local description has " 239 LOG(LS_INFO) << "Transport::ConnectChannels: No local description has "
315 << "been set. Will generate one."; 240 << "been set. Will generate one.";
316 TransportDescription desc( 241 TransportDescription desc(
317 std::vector<std::string>(), rtc::CreateRandomString(ICE_UFRAG_LENGTH), 242 std::vector<std::string>(), rtc::CreateRandomString(ICE_UFRAG_LENGTH),
318 rtc::CreateRandomString(ICE_PWD_LENGTH), ICEMODE_FULL, 243 rtc::CreateRandomString(ICE_PWD_LENGTH), ICEMODE_FULL,
319 CONNECTIONROLE_NONE, NULL, Candidates()); 244 CONNECTIONROLE_NONE, nullptr, Candidates());
320 SetLocalTransportDescription(desc, CA_OFFER, NULL); 245 SetLocalTransportDescription(desc, CA_OFFER, nullptr);
321 } 246 }
322 247
323 CallChannels(&TransportChannelImpl::Connect); 248 CallChannels(&TransportChannelImpl::Connect);
324 if (HasChannels()) {
325 SignalConnecting(this);
326 }
327 } 249 }
328 250
329 void Transport::MaybeStartGathering() { 251 void Transport::MaybeStartGathering() {
330 if (connect_requested_) { 252 if (connect_requested_) {
331 CallChannels(&TransportChannelImpl::MaybeStartGathering); 253 CallChannels(&TransportChannelImpl::MaybeStartGathering);
332 } 254 }
333 } 255 }
334 256
335 void Transport::DestroyAllChannels() { 257 void Transport::DestroyAllChannels() {
336 std::vector<TransportChannelImpl*> impls; 258 for (const auto& kv : channels_) {
337 for (auto& iter : channels_) { 259 DestroyTransportChannel(kv.second);
338 iter.second.DecRef();
339 if (!iter.second.ref())
340 impls.push_back(iter.second.get());
341 } 260 }
342
343 channels_.clear(); 261 channels_.clear();
344
345 for (TransportChannelImpl* impl : impls) {
346 DestroyTransportChannel(impl);
347 }
348 channels_destroyed_ = true; 262 channels_destroyed_ = true;
349 } 263 }
350 264
351 void Transport::CallChannels(TransportChannelFunc func) { 265 void Transport::CallChannels(TransportChannelFunc func) {
352 for (const auto& iter : channels_) { 266 for (const auto& kv : channels_) {
353 ((iter.second.get())->*func)(); 267 (kv.second->*func)();
354 } 268 }
355 } 269 }
356 270
357 bool Transport::VerifyCandidate(const Candidate& cand, std::string* error) { 271 bool Transport::VerifyCandidate(const Candidate& cand, std::string* error) {
358 // No address zero. 272 // No address zero.
359 if (cand.address().IsNil() || cand.address().IsAny()) { 273 if (cand.address().IsNil() || cand.address().IsAny()) {
360 *error = "candidate has address of zero"; 274 *error = "candidate has address of zero";
361 return false; 275 return false;
362 } 276 }
363 277
(...skipping 18 matching lines...) Expand all
382 } 296 }
383 } 297 }
384 298
385 return true; 299 return true;
386 } 300 }
387 301
388 302
389 bool Transport::GetStats(TransportStats* stats) { 303 bool Transport::GetStats(TransportStats* stats) {
390 stats->transport_name = name(); 304 stats->transport_name = name();
391 stats->channel_stats.clear(); 305 stats->channel_stats.clear();
392 for (auto iter : channels_) { 306 for (auto kv : channels_) {
393 ChannelMapEntry& entry = iter.second; 307 TransportChannelImpl* channel = kv.second;
394 TransportChannelStats substats; 308 TransportChannelStats substats;
395 substats.component = entry->component(); 309 substats.component = channel->component();
396 entry->GetSrtpCipher(&substats.srtp_cipher); 310 channel->GetSrtpCipher(&substats.srtp_cipher);
397 entry->GetSslCipher(&substats.ssl_cipher); 311 channel->GetSslCipher(&substats.ssl_cipher);
398 if (!entry->GetStats(&substats.connection_infos)) { 312 if (!channel->GetStats(&substats.connection_infos)) {
399 return false; 313 return false;
400 } 314 }
401 stats->channel_stats.push_back(substats); 315 stats->channel_stats.push_back(substats);
402 } 316 }
403 return true; 317 return true;
404 } 318 }
405 319
406 bool Transport::AddRemoteCandidates(const std::vector<Candidate>& candidates, 320 bool Transport::AddRemoteCandidates(const std::vector<Candidate>& candidates,
407 std::string* error) { 321 std::string* error) {
408 ASSERT(!channels_destroyed_); 322 ASSERT(!channels_destroyed_);
409 // Verify each candidate before passing down to transport layer. 323 // Verify each candidate before passing down to transport layer.
410 for (const Candidate& cand : candidates) { 324 for (const Candidate& cand : candidates) {
411 if (!VerifyCandidate(cand, error)) { 325 if (!VerifyCandidate(cand, error)) {
412 return false; 326 return false;
413 } 327 }
414 if (!HasChannel(cand.component())) { 328 if (!HasChannel(cand.component())) {
415 *error = "Candidate has unknown component: " + cand.ToString() + 329 *error = "Candidate has unknown component: " + cand.ToString() +
416 " for content: " + name(); 330 " for content: " + name();
417 return false; 331 return false;
418 } 332 }
419 } 333 }
420 334
421 for (std::vector<Candidate>::const_iterator iter = candidates.begin(); 335 for (const Candidate& candidate : candidates) {
422 iter != candidates.end(); 336 TransportChannelImpl* channel = GetChannel(candidate.component());
423 ++iter) { 337 if (channel != nullptr) {
424 TransportChannelImpl* channel = GetChannel(iter->component()); 338 channel->AddRemoteCandidate(candidate);
425 if (channel != NULL) {
426 channel->AddRemoteCandidate(*iter);
427 } 339 }
428 } 340 }
429 return true; 341 return true;
430 } 342 }
431 343
432 void Transport::OnChannelWritableState(TransportChannel* channel) {
433 LOG(LS_INFO) << name() << " TransportChannel " << channel->component()
434 << " writability changed to " << channel->writable()
435 << ". Check if transport is complete.";
436 UpdateWritableState();
437 MaybeSignalCompleted();
438 }
439
440 void Transport::OnChannelReceivingState(TransportChannel* channel) {
441 UpdateReceivingState();
442 }
443
444 TransportState Transport::GetTransportState(TransportStateType state_type) {
445 bool any = false;
446 bool all = !channels_.empty();
447 for (const auto iter : channels_) {
448 bool b = false;
449 switch (state_type) {
450 case TRANSPORT_WRITABLE_STATE:
451 b = iter.second->writable();
452 break;
453 case TRANSPORT_RECEIVING_STATE:
454 b = iter.second->receiving();
455 break;
456 default:
457 ASSERT(false);
458 }
459 any |= b;
460 all &= b;
461 }
462
463 if (all) {
464 return TRANSPORT_STATE_ALL;
465 } else if (any) {
466 return TRANSPORT_STATE_SOME;
467 }
468
469 return TRANSPORT_STATE_NONE;
470 }
471
472 void Transport::OnChannelGatheringState(TransportChannelImpl* channel) {
473 ASSERT(channels_.find(channel->component()) != channels_.end());
474 UpdateGatheringState();
475 if (gathering_state_ == kIceGatheringComplete) {
476 // If UpdateGatheringState brought us to kIceGatheringComplete, check if
477 // our connection state is also "Completed". Otherwise, there's no point in
478 // checking (since it would only produce log messages).
479 MaybeSignalCompleted();
480 }
481 }
482
483 void Transport::OnChannelCandidateGathered(TransportChannelImpl* channel,
484 const Candidate& candidate) {
485 // We should never signal peer-reflexive candidates.
486 if (candidate.type() == PRFLX_PORT_TYPE) {
487 ASSERT(false);
488 return;
489 }
490
491 ASSERT(connect_requested_);
492 std::vector<Candidate> candidates;
493 candidates.push_back(candidate);
494 SignalCandidatesGathered(this, candidates);
495 }
496
497 void Transport::OnChannelRouteChange(TransportChannel* channel,
498 const Candidate& remote_candidate) {
499 SignalRouteChange(this, remote_candidate.component(), remote_candidate);
500 }
501
502 void Transport::OnRoleConflict(TransportChannelImpl* channel) {
503 SignalRoleConflict();
504 }
505
506 void Transport::OnChannelConnectionRemoved(TransportChannelImpl* channel) {
507 LOG(LS_INFO) << name() << " TransportChannel " << channel->component()
508 << " connection removed. Check if transport is complete.";
509 MaybeSignalCompleted();
510
511 // Check if the state is now Failed.
512 // Failed is only available in the Controlling ICE role.
513 if (channel->GetIceRole() != ICEROLE_CONTROLLING) {
514 return;
515 }
516
517 // Failed can only occur after candidate gathering has stopped.
518 if (channel->gathering_state() != kIceGatheringComplete) {
519 return;
520 }
521
522 if (channel->GetState() == TransportChannelState::STATE_FAILED) {
523 // A Transport has failed if any of its channels have no remaining
524 // connections.
525 SignalFailed(this);
526 }
527 }
528
529 void Transport::MaybeSignalCompleted() {
530 if (AllChannelsCompleted()) {
531 LOG(LS_INFO) << name() << " transport is complete"
532 << " because all the channels are complete.";
533 SignalCompleted(this);
534 }
535 // TODO(deadbeef): Should we do anything if we previously were completed,
536 // but now are not (if, for example, a new remote candidate is added)?
537 }
538
539 void Transport::UpdateGatheringState() {
540 IceGatheringState new_state = kIceGatheringNew;
541 bool any_gathering = false;
542 bool all_complete = !channels_.empty();
543 for (const auto& kv : channels_) {
544 any_gathering =
545 any_gathering || kv.second->gathering_state() != kIceGatheringNew;
546 all_complete =
547 all_complete && kv.second->gathering_state() == kIceGatheringComplete;
548 }
549 if (all_complete) {
550 new_state = kIceGatheringComplete;
551 } else if (any_gathering) {
552 new_state = kIceGatheringGathering;
553 }
554
555 if (gathering_state_ != new_state) {
556 gathering_state_ = new_state;
557 if (gathering_state_ == kIceGatheringGathering) {
558 LOG(LS_INFO) << "Transport: " << name_ << ", gathering candidates";
559 } else if (gathering_state_ == kIceGatheringComplete) {
560 LOG(LS_INFO) << "Transport " << name() << " gathering complete.";
561 }
562 SignalGatheringState(this);
563 }
564 }
565
566 void Transport::UpdateReceivingState() {
567 TransportState receiving = GetTransportState(TRANSPORT_RECEIVING_STATE);
568 if (receiving_ != receiving) {
569 receiving_ = receiving;
570 SignalReceivingState(this);
571 }
572 }
573
574 void Transport::UpdateWritableState() {
575 TransportState writable = GetTransportState(TRANSPORT_WRITABLE_STATE);
576 LOG(LS_INFO) << name() << " transport writable state changed? " << writable_
577 << " => " << writable;
578 if (writable_ != writable) {
579 was_writable_ = (writable_ == TRANSPORT_STATE_ALL);
580 writable_ = writable;
581 SignalWritableState(this);
582 }
583 }
584
585 bool Transport::ApplyLocalTransportDescription(TransportChannelImpl* ch, 344 bool Transport::ApplyLocalTransportDescription(TransportChannelImpl* ch,
586 std::string* error_desc) { 345 std::string* error_desc) {
587 ch->SetIceCredentials(local_description_->ice_ufrag, 346 ch->SetIceCredentials(local_description_->ice_ufrag,
588 local_description_->ice_pwd); 347 local_description_->ice_pwd);
589 return true; 348 return true;
590 } 349 }
591 350
592 bool Transport::ApplyRemoteTransportDescription(TransportChannelImpl* ch, 351 bool Transport::ApplyRemoteTransportDescription(TransportChannelImpl* ch,
593 std::string* error_desc) { 352 std::string* error_desc) {
594 ch->SetRemoteIceCredentials(remote_description_->ice_ufrag, 353 ch->SetRemoteIceCredentials(remote_description_->ice_ufrag,
(...skipping 21 matching lines...) Expand all
616 } 375 }
617 376
618 // Update remote ice_mode to all existing channels. 377 // Update remote ice_mode to all existing channels.
619 remote_ice_mode_ = remote_description_->ice_mode; 378 remote_ice_mode_ = remote_description_->ice_mode;
620 379
621 // Now that we have negotiated everything, push it downward. 380 // Now that we have negotiated everything, push it downward.
622 // Note that we cache the result so that if we have race conditions 381 // Note that we cache the result so that if we have race conditions
623 // between future SetRemote/SetLocal invocations and new channel 382 // between future SetRemote/SetLocal invocations and new channel
624 // creation, we have the negotiation state saved until a new 383 // creation, we have the negotiation state saved until a new
625 // negotiation happens. 384 // negotiation happens.
626 for (auto& iter : channels_) { 385 for (const auto& kv : channels_) {
627 if (!ApplyNegotiatedTransportDescription(iter.second.get(), error_desc)) 386 if (!ApplyNegotiatedTransportDescription(kv.second, error_desc)) {
628 return false; 387 return false;
388 }
629 } 389 }
630 return true; 390 return true;
631 } 391 }
632 392
633 } // namespace cricket 393 } // namespace cricket
OLDNEW
« no previous file with comments | « webrtc/p2p/base/transport.h ('k') | webrtc/p2p/base/transport_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698