OLD | NEW |
---|---|
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 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 ASSERT(channels_destroyed_); |
73 } | 73 } |
74 | 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 } | |
112 | |
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& iter : channels_) { |
116 iter.second->SetIceRole(ice_role_); | 78 iter.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; |
123 | 85 |
124 ChannelMap::iterator iter = channels_.begin(); | 86 ChannelMap::iterator iter = channels_.begin(); |
125 return iter->second->GetRemoteSSLCertificate(cert); | 87 return iter->second->GetRemoteSSLCertificate(cert); |
126 } | 88 } |
127 | 89 |
128 void Transport::SetIceConfig(const IceConfig& config) { | 90 void Transport::SetIceConfig(const IceConfig& config) { |
129 ice_config_ = config; | 91 ice_config_ = config; |
130 for (const auto& kv : channels_) { | 92 for (const auto& iter : channels_) { |
131 kv.second->SetIceConfig(ice_config_); | 93 iter.second->SetIceConfig(ice_config_); |
132 } | 94 } |
133 } | 95 } |
134 | 96 |
135 bool Transport::SetLocalTransportDescription( | 97 bool Transport::SetLocalTransportDescription( |
136 const TransportDescription& description, | 98 const TransportDescription& description, |
137 ContentAction action, | 99 ContentAction action, |
138 std::string* error_desc) { | 100 std::string* error_desc) { |
139 bool ret = true; | 101 bool ret = true; |
140 | 102 |
141 if (!VerifyIceParams(description)) { | 103 if (!VerifyIceParams(description)) { |
142 return BadTransportDescription("Invalid ice-ufrag or ice-pwd length", | 104 return BadTransportDescription("Invalid ice-ufrag or ice-pwd length", |
143 error_desc); | 105 error_desc); |
144 } | 106 } |
145 | 107 |
146 if (local_description_ && | 108 if (local_description_ && |
147 IceCredentialsChanged(*local_description_, description)) { | 109 IceCredentialsChanged(*local_description_, description)) { |
148 IceRole new_ice_role = | 110 IceRole new_ice_role = |
149 (action == CA_OFFER) ? ICEROLE_CONTROLLING : ICEROLE_CONTROLLED; | 111 (action == CA_OFFER) ? ICEROLE_CONTROLLING : ICEROLE_CONTROLLED; |
150 | 112 |
151 // It must be called before ApplyLocalTransportDescription, which may | 113 // It must be called before ApplyLocalTransportDescription, which may |
152 // trigger an ICE restart and depends on the new ICE role. | 114 // trigger an ICE restart and depends on the new ICE role. |
153 SetIceRole(new_ice_role); | 115 SetIceRole(new_ice_role); |
154 } | 116 } |
155 | 117 |
156 local_description_.reset(new TransportDescription(description)); | 118 local_description_.reset(new TransportDescription(description)); |
157 | 119 |
158 for (auto& iter : channels_) { | 120 for (const auto& iter : channels_) { |
159 ret &= ApplyLocalTransportDescription(iter.second.get(), error_desc); | 121 ret &= ApplyLocalTransportDescription(iter.second, error_desc); |
160 } | 122 } |
161 if (!ret) { | 123 if (!ret) { |
162 return false; | 124 return false; |
163 } | 125 } |
164 | 126 |
165 // If PRANSWER/ANSWER is set, we should decide transport protocol type. | 127 // If PRANSWER/ANSWER is set, we should decide transport protocol type. |
166 if (action == CA_PRANSWER || action == CA_ANSWER) { | 128 if (action == CA_PRANSWER || action == CA_ANSWER) { |
167 ret &= NegotiateTransportDescription(action, error_desc); | 129 ret &= NegotiateTransportDescription(action, error_desc); |
168 } | 130 } |
169 if (ret) { | 131 if (ret) { |
170 local_description_set_ = true; | 132 local_description_set_ = true; |
171 ConnectChannels(); | 133 ConnectChannels(); |
172 } | 134 } |
173 | 135 |
174 return ret; | 136 return ret; |
175 } | 137 } |
176 | 138 |
177 bool Transport::SetRemoteTransportDescription( | 139 bool Transport::SetRemoteTransportDescription( |
178 const TransportDescription& description, | 140 const TransportDescription& description, |
179 ContentAction action, | 141 ContentAction action, |
180 std::string* error_desc) { | 142 std::string* error_desc) { |
181 bool ret = true; | 143 bool ret = true; |
182 | 144 |
183 if (!VerifyIceParams(description)) { | 145 if (!VerifyIceParams(description)) { |
184 return BadTransportDescription("Invalid ice-ufrag or ice-pwd length", | 146 return BadTransportDescription("Invalid ice-ufrag or ice-pwd length", |
185 error_desc); | 147 error_desc); |
186 } | 148 } |
187 | 149 |
188 remote_description_.reset(new TransportDescription(description)); | 150 remote_description_.reset(new TransportDescription(description)); |
189 for (auto& iter : channels_) { | 151 for (const auto& iter : channels_) { |
190 ret &= ApplyRemoteTransportDescription(iter.second.get(), error_desc); | 152 ret &= ApplyRemoteTransportDescription(iter.second, error_desc); |
191 } | 153 } |
192 | 154 |
193 // If PRANSWER/ANSWER is set, we should decide transport protocol type. | 155 // If PRANSWER/ANSWER is set, we should decide transport protocol type. |
194 if (action == CA_PRANSWER || action == CA_ANSWER) { | 156 if (action == CA_PRANSWER || action == CA_ANSWER) { |
195 ret = NegotiateTransportDescription(CA_OFFER, error_desc); | 157 ret = NegotiateTransportDescription(CA_OFFER, error_desc); |
196 } | 158 } |
197 if (ret) { | 159 if (ret) { |
198 remote_description_set_ = true; | 160 remote_description_set_ = true; |
199 } | 161 } |
200 | 162 |
201 return ret; | 163 return ret; |
202 } | 164 } |
203 | 165 |
204 TransportChannelImpl* Transport::CreateChannel(int component) { | 166 TransportChannelImpl* Transport::CreateChannel(int component) { |
205 TransportChannelImpl* impl; | 167 TransportChannelImpl* impl; |
pthatcher1
2015/09/29 23:50:58
Can you rename "impl" to "channel"?
Here and belo
Taylor Brandstetter
2015/09/30 01:01:20
Done.
| |
206 | 168 |
207 // Create the entry if it does not exist. | 169 // Create the entry if it does not exist. |
208 bool impl_exists = false; | 170 bool impl_exists = false; |
209 auto iterator = channels_.find(component); | 171 auto iterator = channels_.find(component); |
210 if (iterator == channels_.end()) { | 172 if (iterator == channels_.end()) { |
211 impl = CreateTransportChannel(component); | 173 impl = CreateTransportChannel(component); |
212 iterator = channels_.insert(std::pair<int, ChannelMapEntry>( | 174 iterator = |
213 component, ChannelMapEntry(impl))).first; | 175 channels_.insert(std::pair<int, TransportChannelImpl*>(component, impl)) |
176 .first; | |
pthatcher1
2015/09/29 23:50:58
Is iterator even used in this function? Can we ju
Taylor Brandstetter
2015/09/30 01:01:20
Done.
| |
214 } else { | 177 } else { |
215 impl = iterator->second.get(); | 178 impl = iterator->second; |
216 impl_exists = true; | 179 impl_exists = true; |
217 } | 180 } |
218 | 181 |
219 // Increase the ref count. | |
220 iterator->second.AddRef(); | |
221 channels_destroyed_ = false; | 182 channels_destroyed_ = false; |
222 | 183 |
223 if (impl_exists) { | 184 if (impl_exists) { |
224 // If this is an existing channel, we should just return it without | 185 // If this is an existing channel, we should just return it. |
225 // connecting to all the signal again. | |
226 return impl; | 186 return impl; |
227 } | 187 } |
228 | 188 |
229 // Push down our transport state to the new channel. | 189 // Push down our transport state to the new channel. |
230 impl->SetIceRole(ice_role_); | 190 impl->SetIceRole(ice_role_); |
231 impl->SetIceTiebreaker(tiebreaker_); | 191 impl->SetIceTiebreaker(tiebreaker_); |
232 impl->SetIceConfig(ice_config_); | 192 impl->SetIceConfig(ice_config_); |
233 // TODO(ronghuawu): Change CreateChannel to be able to return error since | 193 // TODO(ronghuawu): Change CreateChannel to be able to return error since |
234 // below Apply**Description calls can fail. | 194 // below Apply**Description calls can fail. |
235 if (local_description_) | 195 if (local_description_) |
236 ApplyLocalTransportDescription(impl, NULL); | 196 ApplyLocalTransportDescription(impl, NULL); |
237 if (remote_description_) | 197 if (remote_description_) |
238 ApplyRemoteTransportDescription(impl, NULL); | 198 ApplyRemoteTransportDescription(impl, NULL); |
239 if (local_description_ && remote_description_) | 199 if (local_description_ && remote_description_) |
240 ApplyNegotiatedTransportDescription(impl, NULL); | 200 ApplyNegotiatedTransportDescription(impl, NULL); |
241 | 201 |
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 | |
252 if (connect_requested_) { | 202 if (connect_requested_) { |
253 impl->Connect(); | 203 impl->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 } | 204 } |
260 return impl; | 205 return impl; |
261 } | 206 } |
262 | 207 |
263 TransportChannelImpl* Transport::GetChannel(int component) { | 208 TransportChannelImpl* Transport::GetChannel(int component) { |
264 ChannelMap::iterator iter = channels_.find(component); | 209 ChannelMap::iterator iter = channels_.find(component); |
265 return (iter != channels_.end()) ? iter->second.get() : NULL; | 210 return (iter != channels_.end()) ? iter->second : NULL; |
266 } | 211 } |
267 | 212 |
268 bool Transport::HasChannels() { | 213 bool Transport::HasChannels() { |
269 return !channels_.empty(); | 214 return !channels_.empty(); |
270 } | 215 } |
271 | 216 |
272 void Transport::DestroyChannel(int component) { | 217 void Transport::DestroyChannel(int component) { |
273 ChannelMap::iterator iter = channels_.find(component); | 218 ChannelMap::iterator iter = channels_.find(component); |
274 if (iter == channels_.end()) | 219 if (iter == channels_.end()) |
275 return; | 220 return; |
276 | 221 |
277 TransportChannelImpl* impl = NULL; | 222 TransportChannelImpl* impl = iter->second; |
278 | 223 channels_.erase(iter); |
279 iter->second.DecRef(); | 224 DestroyTransportChannel(impl); |
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 } | 225 } |
300 | 226 |
301 void Transport::ConnectChannels() { | 227 void Transport::ConnectChannels() { |
302 if (connect_requested_ || channels_.empty()) | 228 if (connect_requested_ || channels_.empty()) |
303 return; | 229 return; |
304 | 230 |
305 connect_requested_ = true; | 231 connect_requested_ = true; |
306 | 232 |
307 if (!local_description_) { | 233 if (!local_description_) { |
308 // TOOD(mallinath) : TransportDescription(TD) shouldn't be generated here. | 234 // TOOD(mallinath) : TransportDescription(TD) shouldn't be generated here. |
309 // As Transport must know TD is offer or answer and cricket::Transport | 235 // 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 | 236 // doesn't have the capability to decide it. This should be set by the |
311 // Session. | 237 // Session. |
312 // Session must generate local TD before remote candidates pushed when | 238 // Session must generate local TD before remote candidates pushed when |
313 // initiate request initiated by the remote. | 239 // initiate request initiated by the remote. |
314 LOG(LS_INFO) << "Transport::ConnectChannels: No local description has " | 240 LOG(LS_INFO) << "Transport::ConnectChannels: No local description has " |
315 << "been set. Will generate one."; | 241 << "been set. Will generate one."; |
316 TransportDescription desc( | 242 TransportDescription desc( |
317 std::vector<std::string>(), rtc::CreateRandomString(ICE_UFRAG_LENGTH), | 243 std::vector<std::string>(), rtc::CreateRandomString(ICE_UFRAG_LENGTH), |
318 rtc::CreateRandomString(ICE_PWD_LENGTH), ICEMODE_FULL, | 244 rtc::CreateRandomString(ICE_PWD_LENGTH), ICEMODE_FULL, |
319 CONNECTIONROLE_NONE, NULL, Candidates()); | 245 CONNECTIONROLE_NONE, NULL, Candidates()); |
320 SetLocalTransportDescription(desc, CA_OFFER, NULL); | 246 SetLocalTransportDescription(desc, CA_OFFER, NULL); |
321 } | 247 } |
322 | 248 |
323 CallChannels(&TransportChannelImpl::Connect); | 249 CallChannels(&TransportChannelImpl::Connect); |
324 if (HasChannels()) { | |
325 SignalConnecting(this); | |
326 } | |
327 } | 250 } |
328 | 251 |
329 void Transport::MaybeStartGathering() { | 252 void Transport::MaybeStartGathering() { |
330 if (connect_requested_) { | 253 if (connect_requested_) { |
331 CallChannels(&TransportChannelImpl::MaybeStartGathering); | 254 CallChannels(&TransportChannelImpl::MaybeStartGathering); |
332 } | 255 } |
333 } | 256 } |
334 | 257 |
335 void Transport::DestroyAllChannels() { | 258 void Transport::DestroyAllChannels() { |
336 std::vector<TransportChannelImpl*> impls; | 259 for (const auto& iter : channels_) { |
337 for (auto& iter : channels_) { | 260 DestroyTransportChannel(iter.second); |
338 iter.second.DecRef(); | |
339 if (!iter.second.ref()) | |
340 impls.push_back(iter.second.get()); | |
341 } | 261 } |
342 | |
343 channels_.clear(); | 262 channels_.clear(); |
344 | |
345 for (TransportChannelImpl* impl : impls) { | |
346 DestroyTransportChannel(impl); | |
347 } | |
348 channels_destroyed_ = true; | 263 channels_destroyed_ = true; |
349 } | 264 } |
350 | 265 |
351 void Transport::CallChannels(TransportChannelFunc func) { | 266 void Transport::CallChannels(TransportChannelFunc func) { |
352 for (const auto& iter : channels_) { | 267 for (const auto& iter : channels_) { |
353 ((iter.second.get())->*func)(); | 268 (iter.second->*func)(); |
354 } | 269 } |
355 } | 270 } |
356 | 271 |
357 bool Transport::VerifyCandidate(const Candidate& cand, std::string* error) { | 272 bool Transport::VerifyCandidate(const Candidate& cand, std::string* error) { |
358 // No address zero. | 273 // No address zero. |
359 if (cand.address().IsNil() || cand.address().IsAny()) { | 274 if (cand.address().IsNil() || cand.address().IsAny()) { |
360 *error = "candidate has address of zero"; | 275 *error = "candidate has address of zero"; |
361 return false; | 276 return false; |
362 } | 277 } |
363 | 278 |
(...skipping 19 matching lines...) Expand all Loading... | |
383 } | 298 } |
384 | 299 |
385 return true; | 300 return true; |
386 } | 301 } |
387 | 302 |
388 | 303 |
389 bool Transport::GetStats(TransportStats* stats) { | 304 bool Transport::GetStats(TransportStats* stats) { |
390 stats->transport_name = name(); | 305 stats->transport_name = name(); |
391 stats->channel_stats.clear(); | 306 stats->channel_stats.clear(); |
392 for (auto iter : channels_) { | 307 for (auto iter : channels_) { |
393 ChannelMapEntry& entry = iter.second; | 308 TransportChannelImpl* impl = iter.second; |
394 TransportChannelStats substats; | 309 TransportChannelStats substats; |
395 substats.component = entry->component(); | 310 substats.component = impl->component(); |
396 entry->GetSrtpCipher(&substats.srtp_cipher); | 311 impl->GetSrtpCipher(&substats.srtp_cipher); |
397 entry->GetSslCipher(&substats.ssl_cipher); | 312 impl->GetSslCipher(&substats.ssl_cipher); |
398 if (!entry->GetStats(&substats.connection_infos)) { | 313 if (!impl->GetStats(&substats.connection_infos)) { |
399 return false; | 314 return false; |
400 } | 315 } |
401 stats->channel_stats.push_back(substats); | 316 stats->channel_stats.push_back(substats); |
402 } | 317 } |
403 return true; | 318 return true; |
404 } | 319 } |
405 | 320 |
406 bool Transport::AddRemoteCandidates(const std::vector<Candidate>& candidates, | 321 bool Transport::AddRemoteCandidates(const std::vector<Candidate>& candidates, |
407 std::string* error) { | 322 std::string* error) { |
408 ASSERT(!channels_destroyed_); | 323 ASSERT(!channels_destroyed_); |
(...skipping 13 matching lines...) Expand all Loading... | |
422 iter != candidates.end(); | 337 iter != candidates.end(); |
423 ++iter) { | 338 ++iter) { |
424 TransportChannelImpl* channel = GetChannel(iter->component()); | 339 TransportChannelImpl* channel = GetChannel(iter->component()); |
425 if (channel != NULL) { | 340 if (channel != NULL) { |
426 channel->AddRemoteCandidate(*iter); | 341 channel->AddRemoteCandidate(*iter); |
427 } | 342 } |
428 } | 343 } |
429 return true; | 344 return true; |
430 } | 345 } |
431 | 346 |
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, | 347 bool Transport::ApplyLocalTransportDescription(TransportChannelImpl* ch, |
586 std::string* error_desc) { | 348 std::string* error_desc) { |
587 ch->SetIceCredentials(local_description_->ice_ufrag, | 349 ch->SetIceCredentials(local_description_->ice_ufrag, |
588 local_description_->ice_pwd); | 350 local_description_->ice_pwd); |
589 return true; | 351 return true; |
590 } | 352 } |
591 | 353 |
592 bool Transport::ApplyRemoteTransportDescription(TransportChannelImpl* ch, | 354 bool Transport::ApplyRemoteTransportDescription(TransportChannelImpl* ch, |
593 std::string* error_desc) { | 355 std::string* error_desc) { |
594 ch->SetRemoteIceCredentials(remote_description_->ice_ufrag, | 356 ch->SetRemoteIceCredentials(remote_description_->ice_ufrag, |
(...skipping 21 matching lines...) Expand all Loading... | |
616 } | 378 } |
617 | 379 |
618 // Update remote ice_mode to all existing channels. | 380 // Update remote ice_mode to all existing channels. |
619 remote_ice_mode_ = remote_description_->ice_mode; | 381 remote_ice_mode_ = remote_description_->ice_mode; |
620 | 382 |
621 // Now that we have negotiated everything, push it downward. | 383 // Now that we have negotiated everything, push it downward. |
622 // Note that we cache the result so that if we have race conditions | 384 // Note that we cache the result so that if we have race conditions |
623 // between future SetRemote/SetLocal invocations and new channel | 385 // between future SetRemote/SetLocal invocations and new channel |
624 // creation, we have the negotiation state saved until a new | 386 // creation, we have the negotiation state saved until a new |
625 // negotiation happens. | 387 // negotiation happens. |
626 for (auto& iter : channels_) { | 388 for (const auto& iter : channels_) { |
627 if (!ApplyNegotiatedTransportDescription(iter.second.get(), error_desc)) | 389 if (!ApplyNegotiatedTransportDescription(iter.second, error_desc)) { |
628 return false; | 390 return false; |
391 } | |
629 } | 392 } |
630 return true; | 393 return true; |
631 } | 394 } |
632 | 395 |
633 } // namespace cricket | 396 } // namespace cricket |
OLD | NEW |