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

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

Issue 1350523003: TransportController refactoring. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fixing Mac test. 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
12
11 #include "webrtc/p2p/base/transport.h" 13 #include "webrtc/p2p/base/transport.h"
12 14
13 #include "webrtc/p2p/base/candidate.h" 15 #include "webrtc/p2p/base/candidate.h"
14 #include "webrtc/p2p/base/constants.h" 16 #include "webrtc/p2p/base/constants.h"
15 #include "webrtc/p2p/base/port.h" 17 #include "webrtc/p2p/base/port.h"
16 #include "webrtc/p2p/base/transportchannelimpl.h" 18 #include "webrtc/p2p/base/transportchannelimpl.h"
17 #include "webrtc/base/bind.h" 19 #include "webrtc/base/bind.h"
18 #include "webrtc/base/common.h" 20 #include "webrtc/base/common.h"
19 #include "webrtc/base/logging.h" 21 #include "webrtc/base/logging.h"
20 22
21 namespace cricket { 23 namespace cricket {
22 24
23 using rtc::Bind; 25 using rtc::Bind;
24 26
25 enum {
26 MSG_ONSIGNALINGREADY = 1,
27 MSG_ONREMOTECANDIDATE,
28 MSG_WRITESTATE,
29 MSG_REQUESTSIGNALING,
30 MSG_CANDIDATEREADY,
31 MSG_ROUTECHANGE,
32 MSG_CONNECTING,
33 MSG_CANDIDATEALLOCATIONCOMPLETE,
34 MSG_ROLECONFLICT,
35 MSG_COMPLETED,
36 MSG_FAILED,
37 MSG_RECEIVINGSTATE,
38 };
39
40 struct ChannelParams : public rtc::MessageData {
41 ChannelParams() : channel(NULL), candidate(NULL) {}
42 explicit ChannelParams(int component)
43 : component(component), channel(NULL), candidate(NULL) {}
44 explicit ChannelParams(Candidate* candidate)
45 : channel(NULL), candidate(candidate) {
46 }
47
48 ~ChannelParams() {
49 delete candidate;
50 }
51
52 std::string name;
53 int component;
54 TransportChannelImpl* channel;
55 Candidate* candidate;
56 };
57
58 static bool VerifyIceParams(const TransportDescription& desc) { 27 static bool VerifyIceParams(const TransportDescription& desc) {
59 // For legacy protocols. 28 // For legacy protocols.
60 if (desc.ice_ufrag.empty() && desc.ice_pwd.empty()) 29 if (desc.ice_ufrag.empty() && desc.ice_pwd.empty())
61 return true; 30 return true;
62 31
63 if (desc.ice_ufrag.length() < ICE_UFRAG_MIN_LENGTH || 32 if (desc.ice_ufrag.length() < ICE_UFRAG_MIN_LENGTH ||
64 desc.ice_ufrag.length() > ICE_UFRAG_MAX_LENGTH) { 33 desc.ice_ufrag.length() > ICE_UFRAG_MAX_LENGTH) {
65 return false; 34 return false;
66 } 35 }
67 if (desc.ice_pwd.length() < ICE_PWD_MIN_LENGTH || 36 if (desc.ice_pwd.length() < ICE_PWD_MIN_LENGTH ||
(...skipping 21 matching lines...) Expand all
89 // should clean this up when GICE is no longer used. 58 // should clean this up when GICE is no longer used.
90 return (old_ufrag != new_ufrag) || (old_pwd != new_pwd); 59 return (old_ufrag != new_ufrag) || (old_pwd != new_pwd);
91 } 60 }
92 61
93 static bool IceCredentialsChanged(const TransportDescription& old_desc, 62 static bool IceCredentialsChanged(const TransportDescription& old_desc,
94 const TransportDescription& new_desc) { 63 const TransportDescription& new_desc) {
95 return IceCredentialsChanged(old_desc.ice_ufrag, old_desc.ice_pwd, 64 return IceCredentialsChanged(old_desc.ice_ufrag, old_desc.ice_pwd,
96 new_desc.ice_ufrag, new_desc.ice_pwd); 65 new_desc.ice_ufrag, new_desc.ice_pwd);
97 } 66 }
98 67
99 Transport::Transport(rtc::Thread* signaling_thread, 68 Transport::Transport(const std::string& name, PortAllocator* allocator)
100 rtc::Thread* worker_thread, 69 : name_(name), allocator_(allocator) {}
101 const std::string& content_name, 70
102 PortAllocator* allocator) 71 Transport::~Transport() {
103 : signaling_thread_(signaling_thread), 72 ASSERT(channels_destroyed_);
104 worker_thread_(worker_thread),
105 content_name_(content_name),
106 allocator_(allocator),
107 destroyed_(false),
108 readable_(TRANSPORT_STATE_NONE),
109 writable_(TRANSPORT_STATE_NONE),
110 receiving_(TRANSPORT_STATE_NONE),
111 was_writable_(false),
112 connect_requested_(false),
113 ice_role_(ICEROLE_UNKNOWN),
114 tiebreaker_(0),
115 remote_ice_mode_(ICEMODE_FULL),
116 channel_receiving_timeout_(-1) {
117 } 73 }
118 74
119 Transport::~Transport() { 75 bool Transport::AllChannelsCompleted() const {
120 ASSERT(signaling_thread_->IsCurrent()); 76 // We aren't completed until at least one channel is complete, so if there
121 ASSERT(destroyed_); 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;
122 } 111 }
123 112
124 void Transport::SetIceRole(IceRole role) { 113 void Transport::SetIceRole(IceRole role) {
125 worker_thread_->Invoke<void>(Bind(&Transport::SetIceRole_w, this, role)); 114 ice_role_ = role;
126 } 115 for (auto& iter : channels_) {
127 116 iter.second->SetIceRole(ice_role_);
128 void Transport::SetCertificate( 117 }
129 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {
130 worker_thread_->Invoke<void>(Bind(&Transport::SetCertificate_w, this,
131 certificate));
132 }
133
134 bool Transport::GetCertificate(
135 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
136 // The identity is set on the worker thread, so for safety it must also be
137 // acquired on the worker thread.
138 return worker_thread_->Invoke<bool>(
139 Bind(&Transport::GetCertificate_w, this, certificate));
140 } 118 }
141 119
142 bool Transport::GetRemoteSSLCertificate(rtc::SSLCertificate** cert) { 120 bool Transport::GetRemoteSSLCertificate(rtc::SSLCertificate** cert) {
143 // Channels can be deleted on the worker thread, so for safety the remote
144 // certificate is acquired on the worker thread.
145 return worker_thread_->Invoke<bool>(
146 Bind(&Transport::GetRemoteSSLCertificate_w, this, cert));
147 }
148
149 bool Transport::GetRemoteSSLCertificate_w(rtc::SSLCertificate** cert) {
150 ASSERT(worker_thread()->IsCurrent());
151 if (channels_.empty()) 121 if (channels_.empty())
152 return false; 122 return false;
153 123
154 ChannelMap::iterator iter = channels_.begin(); 124 ChannelMap::iterator iter = channels_.begin();
155 return iter->second->GetRemoteSSLCertificate(cert); 125 return iter->second->GetRemoteSSLCertificate(cert);
156 } 126 }
157 127
158 void Transport::SetChannelReceivingTimeout(int timeout_ms) { 128 void Transport::SetChannelReceivingTimeout(int timeout_ms) {
159 worker_thread_->Invoke<void>(
160 Bind(&Transport::SetChannelReceivingTimeout_w, this, timeout_ms));
161 }
162
163 void Transport::SetChannelReceivingTimeout_w(int timeout_ms) {
164 ASSERT(worker_thread()->IsCurrent());
165 channel_receiving_timeout_ = timeout_ms; 129 channel_receiving_timeout_ = timeout_ms;
166 for (const auto& kv : channels_) { 130 for (const auto& kv : channels_) {
167 kv.second->SetReceivingTimeout(timeout_ms); 131 kv.second->SetReceivingTimeout(timeout_ms);
168 } 132 }
169 } 133 }
170 134
171 bool Transport::SetLocalTransportDescription( 135 bool Transport::SetLocalTransportDescription(
172 const TransportDescription& description, 136 const TransportDescription& description,
173 ContentAction action, 137 ContentAction action,
174 std::string* error_desc) { 138 std::string* error_desc) {
175 return worker_thread_->Invoke<bool>(Bind( 139 bool ret = true;
176 &Transport::SetLocalTransportDescription_w, this, 140
177 description, action, error_desc)); 141 if (!VerifyIceParams(description)) {
142 return BadTransportDescription("Invalid ice-ufrag or ice-pwd length",
143 error_desc);
144 }
145
146 if (local_description_ &&
147 IceCredentialsChanged(*local_description_, description)) {
148 IceRole new_ice_role =
149 (action == CA_OFFER) ? ICEROLE_CONTROLLING : ICEROLE_CONTROLLED;
150
151 // It must be called before ApplyLocalTransportDescription, which may
152 // trigger an ICE restart and depends on the new ICE role.
153 SetIceRole(new_ice_role);
154 }
155
156 local_description_.reset(new TransportDescription(description));
157
158 for (auto& iter : channels_) {
159 ret &= ApplyLocalTransportDescription(iter.second.get(), error_desc);
160 }
161 if (!ret) {
162 return false;
163 }
164
165 // If PRANSWER/ANSWER is set, we should decide transport protocol type.
166 if (action == CA_PRANSWER || action == CA_ANSWER) {
167 ret &= NegotiateTransportDescription(action, error_desc);
168 }
169 if (ret) {
170 local_description_set_ = true;
171 ConnectChannels();
172 }
173
174 return ret;
178 } 175 }
179 176
180 bool Transport::SetRemoteTransportDescription( 177 bool Transport::SetRemoteTransportDescription(
181 const TransportDescription& description, 178 const TransportDescription& description,
182 ContentAction action, 179 ContentAction action,
183 std::string* error_desc) { 180 std::string* error_desc) {
184 return worker_thread_->Invoke<bool>(Bind( 181 bool ret = true;
185 &Transport::SetRemoteTransportDescription_w, this, 182
186 description, action, error_desc)); 183 if (!VerifyIceParams(description)) {
184 return BadTransportDescription("Invalid ice-ufrag or ice-pwd length",
185 error_desc);
186 }
187
188 remote_description_.reset(new TransportDescription(description));
189 for (auto& iter : channels_) {
190 ret &= ApplyRemoteTransportDescription(iter.second.get(), error_desc);
191 }
192
193 // If PRANSWER/ANSWER is set, we should decide transport protocol type.
194 if (action == CA_PRANSWER || action == CA_ANSWER) {
195 ret = NegotiateTransportDescription(CA_OFFER, error_desc);
196 }
197 if (ret) {
198 remote_description_set_ = true;
199 }
200
201 return ret;
187 } 202 }
188 203
189 TransportChannelImpl* Transport::CreateChannel(int component) { 204 TransportChannelImpl* Transport::CreateChannel(int component) {
190 return worker_thread_->Invoke<TransportChannelImpl*>(Bind(
191 &Transport::CreateChannel_w, this, component));
192 }
193
194 TransportChannelImpl* Transport::CreateChannel_w(int component) {
195 ASSERT(worker_thread()->IsCurrent());
196 TransportChannelImpl* impl; 205 TransportChannelImpl* impl;
197 // TODO(tommi): We don't really need to grab the lock until the actual call
198 // to insert() below and presumably hold it throughout initialization of
199 // |impl| after the impl_exists check. Maybe we can factor that out to
200 // a separate function and not grab the lock in this function.
201 // Actually, we probably don't need to hold the lock while initializing
202 // |impl| since we can just do the insert when that's done.
203 rtc::CritScope cs(&crit_);
204 206
205 // Create the entry if it does not exist. 207 // Create the entry if it does not exist.
206 bool impl_exists = false; 208 bool impl_exists = false;
207 auto iterator = channels_.find(component); 209 auto iterator = channels_.find(component);
208 if (iterator == channels_.end()) { 210 if (iterator == channels_.end()) {
209 impl = CreateTransportChannel(component); 211 impl = CreateTransportChannel(component);
210 iterator = channels_.insert(std::pair<int, ChannelMapEntry>( 212 iterator = channels_.insert(std::pair<int, ChannelMapEntry>(
211 component, ChannelMapEntry(impl))).first; 213 component, ChannelMapEntry(impl))).first;
212 } else { 214 } else {
213 impl = iterator->second.get(); 215 impl = iterator->second.get();
214 impl_exists = true; 216 impl_exists = true;
215 } 217 }
216 218
217 // Increase the ref count. 219 // Increase the ref count.
218 iterator->second.AddRef(); 220 iterator->second.AddRef();
219 destroyed_ = false; 221 channels_destroyed_ = false;
220 222
221 if (impl_exists) { 223 if (impl_exists) {
222 // If this is an existing channel, we should just return it without 224 // If this is an existing channel, we should just return it without
223 // connecting to all the signal again. 225 // connecting to all the signal again.
224 return impl; 226 return impl;
225 } 227 }
226 228
227 // Push down our transport state to the new channel. 229 // Push down our transport state to the new channel.
228 impl->SetIceRole(ice_role_); 230 impl->SetIceRole(ice_role_);
229 impl->SetIceTiebreaker(tiebreaker_); 231 impl->SetIceTiebreaker(tiebreaker_);
230 impl->SetReceivingTimeout(channel_receiving_timeout_); 232 impl->SetReceivingTimeout(channel_receiving_timeout_);
231 // TODO(ronghuawu): Change CreateChannel_w to be able to return error since 233 // TODO(ronghuawu): Change CreateChannel to be able to return error since
232 // below Apply**Description_w calls can fail. 234 // below Apply**Description calls can fail.
233 if (local_description_) 235 if (local_description_)
234 ApplyLocalTransportDescription_w(impl, NULL); 236 ApplyLocalTransportDescription(impl, NULL);
235 if (remote_description_) 237 if (remote_description_)
236 ApplyRemoteTransportDescription_w(impl, NULL); 238 ApplyRemoteTransportDescription(impl, NULL);
237 if (local_description_ && remote_description_) 239 if (local_description_ && remote_description_)
238 ApplyNegotiatedTransportDescription_w(impl, NULL); 240 ApplyNegotiatedTransportDescription(impl, NULL);
239 241
240 impl->SignalWritableState.connect(this, &Transport::OnChannelWritableState); 242 impl->SignalWritableState.connect(this, &Transport::OnChannelWritableState);
241 impl->SignalReceivingState.connect(this, &Transport::OnChannelReceivingState); 243 impl->SignalReceivingState.connect(this, &Transport::OnChannelReceivingState);
242 impl->SignalRequestSignaling.connect( 244 impl->SignalGatheringState.connect(this, &Transport::OnChannelGatheringState);
243 this, &Transport::OnChannelRequestSignaling); 245 impl->SignalCandidateGathered.connect(this,
244 impl->SignalCandidateReady.connect(this, &Transport::OnChannelCandidateReady); 246 &Transport::OnChannelCandidateGathered);
245 impl->SignalRouteChange.connect(this, &Transport::OnChannelRouteChange); 247 impl->SignalRouteChange.connect(this, &Transport::OnChannelRouteChange);
246 impl->SignalCandidatesAllocationDone.connect(
247 this, &Transport::OnChannelCandidatesAllocationDone);
248 impl->SignalRoleConflict.connect(this, &Transport::OnRoleConflict); 248 impl->SignalRoleConflict.connect(this, &Transport::OnRoleConflict);
249 impl->SignalConnectionRemoved.connect( 249 impl->SignalConnectionRemoved.connect(
250 this, &Transport::OnChannelConnectionRemoved); 250 this, &Transport::OnChannelConnectionRemoved);
251 251
252 if (connect_requested_) { 252 if (connect_requested_) {
253 impl->Connect(); 253 impl->Connect();
254 if (channels_.size() == 1) { 254 if (channels_.size() == 1) {
255 // If this is the first channel, then indicate that we have started 255 // If this is the first channel, then indicate that we have started
256 // connecting. 256 // connecting.
257 signaling_thread()->Post(this, MSG_CONNECTING, NULL); 257 SignalConnecting(this);
258 } 258 }
259 } 259 }
260 return impl; 260 return impl;
261 } 261 }
262 262
263 TransportChannelImpl* Transport::GetChannel(int component) { 263 TransportChannelImpl* Transport::GetChannel(int component) {
264 // TODO(tommi,pthatcher): Since we're returning a pointer from the channels_
265 // map, shouldn't we assume that we're on the worker thread? (The pointer
266 // will be used outside of the lock).
267 // And if we're on the worker thread, which is the only thread that modifies
268 // channels_, can we skip grabbing the lock?
269 rtc::CritScope cs(&crit_);
270 ChannelMap::iterator iter = channels_.find(component); 264 ChannelMap::iterator iter = channels_.find(component);
271 return (iter != channels_.end()) ? iter->second.get() : NULL; 265 return (iter != channels_.end()) ? iter->second.get() : NULL;
272 } 266 }
273 267
274 bool Transport::HasChannels() { 268 bool Transport::HasChannels() {
275 rtc::CritScope cs(&crit_);
276 return !channels_.empty(); 269 return !channels_.empty();
277 } 270 }
278 271
279 void Transport::DestroyChannel(int component) { 272 void Transport::DestroyChannel(int component) {
280 worker_thread_->Invoke<void>(Bind(
281 &Transport::DestroyChannel_w, this, component));
282 }
283
284 void Transport::DestroyChannel_w(int component) {
285 ASSERT(worker_thread()->IsCurrent());
286
287 ChannelMap::iterator iter = channels_.find(component); 273 ChannelMap::iterator iter = channels_.find(component);
288 if (iter == channels_.end()) 274 if (iter == channels_.end())
289 return; 275 return;
290 276
291 TransportChannelImpl* impl = NULL; 277 TransportChannelImpl* impl = NULL;
292 278
293 iter->second.DecRef(); 279 iter->second.DecRef();
294 if (!iter->second.ref()) { 280 if (!iter->second.ref()) {
295 impl = iter->second.get(); 281 impl = iter->second.get();
296 rtc::CritScope cs(&crit_);
297 channels_.erase(iter); 282 channels_.erase(iter);
298 } 283 }
299 284
300 if (connect_requested_ && channels_.empty()) { 285 if (connect_requested_ && channels_.empty()) {
301 // We're no longer attempting to connect. 286 // We're no longer attempting to connect.
302 signaling_thread()->Post(this, MSG_CONNECTING, NULL); 287 SignalConnecting(this);
303 } 288 }
304 289
305 if (impl) { 290 if (impl) {
306 // Check in case the deleted channel was the only non-writable channel.
307 OnChannelWritableState(impl);
308 DestroyTransportChannel(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();
309 } 298 }
310 } 299 }
311 300
312 void Transport::ConnectChannels() { 301 void Transport::ConnectChannels() {
313 ASSERT(signaling_thread()->IsCurrent());
314 worker_thread_->Invoke<void>(Bind(&Transport::ConnectChannels_w, this));
315 }
316
317 void Transport::ConnectChannels_w() {
318 ASSERT(worker_thread()->IsCurrent());
319 if (connect_requested_ || channels_.empty()) 302 if (connect_requested_ || channels_.empty())
320 return; 303 return;
321 304
322 connect_requested_ = true; 305 connect_requested_ = true;
323 signaling_thread()->Post(this, MSG_CANDIDATEREADY, NULL);
324 306
325 if (!local_description_) { 307 if (!local_description_) {
326 // TOOD(mallinath) : TransportDescription(TD) shouldn't be generated here. 308 // TOOD(mallinath) : TransportDescription(TD) shouldn't be generated here.
327 // As Transport must know TD is offer or answer and cricket::Transport 309 // As Transport must know TD is offer or answer and cricket::Transport
328 // doesn't have the capability to decide it. This should be set by the 310 // doesn't have the capability to decide it. This should be set by the
329 // Session. 311 // Session.
330 // Session must generate local TD before remote candidates pushed when 312 // Session must generate local TD before remote candidates pushed when
331 // initiate request initiated by the remote. 313 // initiate request initiated by the remote.
332 LOG(LS_INFO) << "Transport::ConnectChannels_w: No local description has " 314 LOG(LS_INFO) << "Transport::ConnectChannels: No local description has "
333 << "been set. Will generate one."; 315 << "been set. Will generate one.";
334 TransportDescription desc(std::vector<std::string>(), 316 TransportDescription desc(
335 rtc::CreateRandomString(ICE_UFRAG_LENGTH), 317 std::vector<std::string>(), rtc::CreateRandomString(ICE_UFRAG_LENGTH),
336 rtc::CreateRandomString(ICE_PWD_LENGTH), 318 rtc::CreateRandomString(ICE_PWD_LENGTH), ICEMODE_FULL,
337 ICEMODE_FULL, CONNECTIONROLE_NONE, NULL, 319 CONNECTIONROLE_NONE, NULL, Candidates());
338 Candidates()); 320 SetLocalTransportDescription(desc, CA_OFFER, NULL);
339 SetLocalTransportDescription_w(desc, CA_OFFER, NULL);
340 } 321 }
341 322
342 CallChannels_w(&TransportChannelImpl::Connect); 323 CallChannels(&TransportChannelImpl::Connect);
343 if (!channels_.empty()) { 324 if (HasChannels()) {
344 signaling_thread()->Post(this, MSG_CONNECTING, NULL); 325 SignalConnecting(this);
345 } 326 }
346 } 327 }
347 328
348 void Transport::OnConnecting_s() { 329 void Transport::MaybeStartGathering() {
349 ASSERT(signaling_thread()->IsCurrent()); 330 if (connect_requested_) {
350 SignalConnecting(this); 331 CallChannels(&TransportChannelImpl::MaybeStartGathering);
332 }
351 } 333 }
352 334
353 void Transport::DestroyAllChannels() { 335 void Transport::DestroyAllChannels() {
354 ASSERT(signaling_thread()->IsCurrent());
355 worker_thread_->Invoke<void>(Bind(&Transport::DestroyAllChannels_w, this));
356 worker_thread()->Clear(this);
357 signaling_thread()->Clear(this);
358 destroyed_ = true;
359 }
360
361 void Transport::DestroyAllChannels_w() {
362 ASSERT(worker_thread()->IsCurrent());
363
364 std::vector<TransportChannelImpl*> impls; 336 std::vector<TransportChannelImpl*> impls;
365 for (auto& iter : channels_) { 337 for (auto& iter : channels_) {
366 iter.second.DecRef(); 338 iter.second.DecRef();
367 if (!iter.second.ref()) 339 if (!iter.second.ref())
368 impls.push_back(iter.second.get()); 340 impls.push_back(iter.second.get());
369 } 341 }
370 342
371 { 343 channels_.clear();
372 rtc::CritScope cs(&crit_); 344
373 channels_.clear(); 345 for (TransportChannelImpl* impl : impls) {
346 DestroyTransportChannel(impl);
374 } 347 }
375 348 channels_destroyed_ = true;
376 for (size_t i = 0; i < impls.size(); ++i)
377 DestroyTransportChannel(impls[i]);
378 } 349 }
379 350
380 void Transport::OnSignalingReady() { 351 void Transport::CallChannels(TransportChannelFunc func) {
381 ASSERT(signaling_thread()->IsCurrent());
382 if (destroyed_) return;
383
384 worker_thread()->Post(this, MSG_ONSIGNALINGREADY, NULL);
385
386 // Notify the subclass.
387 OnTransportSignalingReady();
388 }
389
390 void Transport::CallChannels_w(TransportChannelFunc func) {
391 ASSERT(worker_thread()->IsCurrent());
392 for (const auto& iter : channels_) { 352 for (const auto& iter : channels_) {
393 ((iter.second.get())->*func)(); 353 ((iter.second.get())->*func)();
394 } 354 }
395 } 355 }
396 356
397 bool Transport::VerifyCandidate(const Candidate& cand, std::string* error) { 357 bool Transport::VerifyCandidate(const Candidate& cand, std::string* error) {
398 // No address zero. 358 // No address zero.
399 if (cand.address().IsNil() || cand.address().IsAny()) { 359 if (cand.address().IsNil() || cand.address().IsAny()) {
400 *error = "candidate has address of zero"; 360 *error = "candidate has address of zero";
401 return false; 361 return false;
(...skipping 18 matching lines...) Expand all
420 *error = "candidate has port of 80 or 443 with private IP address"; 380 *error = "candidate has port of 80 or 443 with private IP address";
421 return false; 381 return false;
422 } 382 }
423 } 383 }
424 384
425 return true; 385 return true;
426 } 386 }
427 387
428 388
429 bool Transport::GetStats(TransportStats* stats) { 389 bool Transport::GetStats(TransportStats* stats) {
430 ASSERT(signaling_thread()->IsCurrent()); 390 stats->transport_name = name();
431 return worker_thread_->Invoke<bool>(Bind(
432 &Transport::GetStats_w, this, stats));
433 }
434
435 bool Transport::GetStats_w(TransportStats* stats) {
436 ASSERT(worker_thread()->IsCurrent());
437 stats->content_name = content_name();
438 stats->channel_stats.clear(); 391 stats->channel_stats.clear();
439 for (auto iter : channels_) { 392 for (auto iter : channels_) {
440 ChannelMapEntry& entry = iter.second; 393 ChannelMapEntry& entry = iter.second;
441 TransportChannelStats substats; 394 TransportChannelStats substats;
442 substats.component = entry->component(); 395 substats.component = entry->component();
443 entry->GetSrtpCipher(&substats.srtp_cipher); 396 entry->GetSrtpCipher(&substats.srtp_cipher);
444 entry->GetSslCipher(&substats.ssl_cipher); 397 entry->GetSslCipher(&substats.ssl_cipher);
445 if (!entry->GetStats(&substats.connection_infos)) { 398 if (!entry->GetStats(&substats.connection_infos)) {
446 return false; 399 return false;
447 } 400 }
448 stats->channel_stats.push_back(substats); 401 stats->channel_stats.push_back(substats);
449 } 402 }
450 return true; 403 return true;
451 } 404 }
452 405
453 bool Transport::GetSslRole(rtc::SSLRole* ssl_role) const { 406 bool Transport::AddRemoteCandidates(const std::vector<Candidate>& candidates,
454 return worker_thread_->Invoke<bool>(Bind( 407 std::string* error) {
455 &Transport::GetSslRole_w, this, ssl_role)); 408 ASSERT(!channels_destroyed_);
456 } 409 // Verify each candidate before passing down to transport layer.
410 for (const Candidate& cand : candidates) {
411 if (!VerifyCandidate(cand, error)) {
412 return false;
413 }
414 if (!HasChannel(cand.component())) {
415 *error = "Candidate has unknown component: " + cand.ToString() +
416 " for content: " + name();
417 return false;
418 }
419 }
457 420
458 bool Transport::SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version) {
459 return worker_thread_->Invoke<bool>(Bind(
460 &Transport::SetSslMaxProtocolVersion_w, this, version));
461 }
462
463 void Transport::OnRemoteCandidates(const std::vector<Candidate>& candidates) {
464 for (std::vector<Candidate>::const_iterator iter = candidates.begin(); 421 for (std::vector<Candidate>::const_iterator iter = candidates.begin();
465 iter != candidates.end(); 422 iter != candidates.end();
466 ++iter) { 423 ++iter) {
467 OnRemoteCandidate(*iter); 424 TransportChannelImpl* channel = GetChannel(iter->component());
425 if (channel != NULL) {
426 channel->AddRemoteCandidate(*iter);
427 }
468 } 428 }
469 } 429 return true;
470
471 void Transport::OnRemoteCandidate(const Candidate& candidate) {
472 ASSERT(signaling_thread()->IsCurrent());
473 if (destroyed_) return;
474
475 if (!HasChannel(candidate.component())) {
476 LOG(LS_WARNING) << "Ignoring candidate for unknown component "
477 << candidate.component();
478 return;
479 }
480
481 ChannelParams* params = new ChannelParams(new Candidate(candidate));
482 worker_thread()->Post(this, MSG_ONREMOTECANDIDATE, params);
483 }
484
485 void Transport::OnRemoteCandidate_w(const Candidate& candidate) {
486 ASSERT(worker_thread()->IsCurrent());
487 ChannelMap::iterator iter = channels_.find(candidate.component());
488 // It's ok for a channel to go away while this message is in transit.
489 if (iter != channels_.end()) {
490 iter->second->OnCandidate(candidate);
491 }
492 } 430 }
493 431
494 void Transport::OnChannelWritableState(TransportChannel* channel) { 432 void Transport::OnChannelWritableState(TransportChannel* channel) {
495 ASSERT(worker_thread()->IsCurrent()); 433 LOG(LS_INFO) << name() << " TransportChannel " << channel->component()
496 signaling_thread()->Post(this, MSG_WRITESTATE, NULL); 434 << " writability changed to " << channel->writable()
497 435 << ". Check if transport is complete.";
498 MaybeCompleted_w(); 436 UpdateWritableState();
499 } 437 MaybeSignalCompleted();
500
501 void Transport::OnChannelWritableState_s() {
502 ASSERT(signaling_thread()->IsCurrent());
503 TransportState writable = GetTransportState_s(TRANSPORT_WRITABLE_STATE);
504 if (writable_ != writable) {
505 was_writable_ = (writable_ == TRANSPORT_STATE_ALL);
506 writable_ = writable;
507 SignalWritableState(this);
508 }
509 } 438 }
510 439
511 void Transport::OnChannelReceivingState(TransportChannel* channel) { 440 void Transport::OnChannelReceivingState(TransportChannel* channel) {
512 ASSERT(worker_thread()->IsCurrent()); 441 UpdateReceivingState();
513 signaling_thread()->Post(this, MSG_RECEIVINGSTATE);
514 } 442 }
515 443
516 void Transport::OnChannelReceivingState_s() { 444 TransportState Transport::GetTransportState(TransportStateType state_type) {
517 ASSERT(signaling_thread()->IsCurrent());
518 TransportState receiving = GetTransportState_s(TRANSPORT_RECEIVING_STATE);
519 if (receiving_ != receiving) {
520 receiving_ = receiving;
521 SignalReceivingState(this);
522 }
523 }
524
525 TransportState Transport::GetTransportState_s(TransportStateType state_type) {
526 ASSERT(signaling_thread()->IsCurrent());
527
528 rtc::CritScope cs(&crit_);
529 bool any = false; 445 bool any = false;
530 bool all = !channels_.empty(); 446 bool all = !channels_.empty();
531 for (const auto iter : channels_) { 447 for (const auto iter : channels_) {
532 bool b = false; 448 bool b = false;
533 switch (state_type) { 449 switch (state_type) {
534 case TRANSPORT_WRITABLE_STATE: 450 case TRANSPORT_WRITABLE_STATE:
535 b = iter.second->writable(); 451 b = iter.second->writable();
536 break; 452 break;
537 case TRANSPORT_RECEIVING_STATE: 453 case TRANSPORT_RECEIVING_STATE:
538 b = iter.second->receiving(); 454 b = iter.second->receiving();
539 break; 455 break;
540 default: 456 default:
541 ASSERT(false); 457 ASSERT(false);
542 } 458 }
543 any |= b; 459 any |= b;
544 all &= b; 460 all &= b;
545 } 461 }
546 462
547 if (all) { 463 if (all) {
548 return TRANSPORT_STATE_ALL; 464 return TRANSPORT_STATE_ALL;
549 } else if (any) { 465 } else if (any) {
550 return TRANSPORT_STATE_SOME; 466 return TRANSPORT_STATE_SOME;
551 } 467 }
552 468
553 return TRANSPORT_STATE_NONE; 469 return TRANSPORT_STATE_NONE;
554 } 470 }
555 471
556 void Transport::OnChannelRequestSignaling(TransportChannelImpl* channel) { 472 void Transport::OnChannelGatheringState(TransportChannelImpl* channel) {
557 ASSERT(worker_thread()->IsCurrent()); 473 ASSERT(channels_.find(channel->component()) != channels_.end());
558 // Resetting ICE state for the channel. 474 UpdateGatheringState();
559 ChannelMap::iterator iter = channels_.find(channel->component()); 475 if (gathering_state_ == kIceGatheringComplete) {
560 if (iter != channels_.end()) 476 // If UpdateGatheringState brought us to kIceGatheringComplete, check if
561 iter->second.set_candidates_allocated(false); 477 // our connection state is also "Completed". Otherwise, there's no point in
562 signaling_thread()->Post(this, MSG_REQUESTSIGNALING, nullptr); 478 // checking (since it would only produce log messages).
479 MaybeSignalCompleted();
480 }
563 } 481 }
564 482
565 void Transport::OnChannelRequestSignaling_s() { 483 void Transport::OnChannelCandidateGathered(TransportChannelImpl* channel,
566 ASSERT(signaling_thread()->IsCurrent()); 484 const Candidate& candidate) {
567 LOG(LS_INFO) << "Transport: " << content_name_ << ", allocating candidates";
568 SignalRequestSignaling(this);
569 }
570
571 void Transport::OnChannelCandidateReady(TransportChannelImpl* channel,
572 const Candidate& candidate) {
573 // We should never signal peer-reflexive candidates. 485 // We should never signal peer-reflexive candidates.
574 if (candidate.type() == PRFLX_PORT_TYPE) { 486 if (candidate.type() == PRFLX_PORT_TYPE) {
575 ASSERT(false); 487 ASSERT(false);
576 return; 488 return;
577 } 489 }
578 490
579 ASSERT(worker_thread()->IsCurrent());
580 rtc::CritScope cs(&crit_);
581 ready_candidates_.push_back(candidate);
582
583 // We hold any messages until the client lets us connect.
584 if (connect_requested_) {
585 signaling_thread()->Post(
586 this, MSG_CANDIDATEREADY, NULL);
587 }
588 }
589
590 void Transport::OnChannelCandidateReady_s() {
591 ASSERT(signaling_thread()->IsCurrent());
592 ASSERT(connect_requested_); 491 ASSERT(connect_requested_);
593
594 std::vector<Candidate> candidates; 492 std::vector<Candidate> candidates;
595 { 493 candidates.push_back(candidate);
596 rtc::CritScope cs(&crit_); 494 SignalCandidatesGathered(this, candidates);
597 candidates.swap(ready_candidates_);
598 }
599
600 // we do the deleting of Candidate* here to keep the new above and
601 // delete below close to each other
602 if (!candidates.empty()) {
603 SignalCandidatesReady(this, candidates);
604 }
605 } 495 }
606 496
607 void Transport::OnChannelRouteChange(TransportChannel* channel, 497 void Transport::OnChannelRouteChange(TransportChannel* channel,
608 const Candidate& remote_candidate) { 498 const Candidate& remote_candidate) {
609 ASSERT(worker_thread()->IsCurrent());
610 ChannelParams* params = new ChannelParams(new Candidate(remote_candidate));
611 params->channel = static_cast<cricket::TransportChannelImpl*>(channel);
612 signaling_thread()->Post(this, MSG_ROUTECHANGE, params);
613 }
614
615 void Transport::OnChannelRouteChange_s(const TransportChannel* channel,
616 const Candidate& remote_candidate) {
617 ASSERT(signaling_thread()->IsCurrent());
618 SignalRouteChange(this, remote_candidate.component(), remote_candidate); 499 SignalRouteChange(this, remote_candidate.component(), remote_candidate);
619 } 500 }
620 501
621 void Transport::OnChannelCandidatesAllocationDone(
622 TransportChannelImpl* channel) {
623 ASSERT(worker_thread()->IsCurrent());
624 ChannelMap::iterator iter = channels_.find(channel->component());
625 ASSERT(iter != channels_.end());
626 LOG(LS_INFO) << "Transport: " << content_name_ << ", component "
627 << channel->component() << " allocation complete";
628
629 iter->second.set_candidates_allocated(true);
630
631 // If all channels belonging to this Transport got signal, then
632 // forward this signal to upper layer.
633 // Can this signal arrive before all transport channels are created?
634 for (auto& iter : channels_) {
635 if (!iter.second.candidates_allocated())
636 return;
637 }
638 signaling_thread_->Post(this, MSG_CANDIDATEALLOCATIONCOMPLETE);
639
640 MaybeCompleted_w();
641 }
642
643 void Transport::OnChannelCandidatesAllocationDone_s() {
644 ASSERT(signaling_thread()->IsCurrent());
645 LOG(LS_INFO) << "Transport: " << content_name_ << " allocation complete";
646 SignalCandidatesAllocationDone(this);
647 }
648
649 void Transport::OnRoleConflict(TransportChannelImpl* channel) { 502 void Transport::OnRoleConflict(TransportChannelImpl* channel) {
650 signaling_thread_->Post(this, MSG_ROLECONFLICT); 503 SignalRoleConflict();
651 } 504 }
652 505
653 void Transport::OnChannelConnectionRemoved(TransportChannelImpl* channel) { 506 void Transport::OnChannelConnectionRemoved(TransportChannelImpl* channel) {
654 ASSERT(worker_thread()->IsCurrent()); 507 LOG(LS_INFO) << name() << " TransportChannel " << channel->component()
655 MaybeCompleted_w(); 508 << " connection removed. Check if transport is complete.";
509 MaybeSignalCompleted();
656 510
657 // Check if the state is now Failed. 511 // Check if the state is now Failed.
658 // Failed is only available in the Controlling ICE role. 512 // Failed is only available in the Controlling ICE role.
659 if (channel->GetIceRole() != ICEROLE_CONTROLLING) { 513 if (channel->GetIceRole() != ICEROLE_CONTROLLING) {
660 return; 514 return;
661 } 515 }
662 516
663 ChannelMap::iterator iter = channels_.find(channel->component()); 517 // Failed can only occur after candidate gathering has stopped.
664 ASSERT(iter != channels_.end()); 518 if (channel->gathering_state() != kIceGatheringComplete) {
665 // Failed can only occur after candidate allocation has stopped.
666 if (!iter->second.candidates_allocated()) {
667 return; 519 return;
668 } 520 }
669 521
670 if (channel->GetState() == TransportChannelState::STATE_FAILED) { 522 if (channel->GetState() == TransportChannelState::STATE_FAILED) {
671 // A Transport has failed if any of its channels have no remaining 523 // A Transport has failed if any of its channels have no remaining
672 // connections. 524 // connections.
673 signaling_thread_->Post(this, MSG_FAILED); 525 SignalFailed(this);
674 } 526 }
675 } 527 }
676 528
677 void Transport::MaybeCompleted_w() { 529 void Transport::MaybeSignalCompleted() {
678 ASSERT(worker_thread()->IsCurrent()); 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 }
679 538
680 // When there is no channel created yet, calling this function could fire an 539 void Transport::UpdateGatheringState() {
681 // IceConnectionCompleted event prematurely. 540 IceGatheringState new_state = kIceGatheringNew;
682 if (channels_.empty()) { 541 bool any_gathering = false;
683 return; 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;
684 } 553 }
685 554
686 // A Transport's ICE process is completed if all of its channels are writable, 555 if (gathering_state_ != new_state) {
687 // have finished allocating candidates, and have pruned all but one of their 556 gathering_state_ = new_state;
688 // connections. 557 if (gathering_state_ == kIceGatheringGathering) {
689 for (const auto& iter : channels_) { 558 LOG(LS_INFO) << "Transport: " << name_ << ", gathering candidates";
690 const TransportChannelImpl* channel = iter.second.get(); 559 } else if (gathering_state_ == kIceGatheringComplete) {
691 if (!(channel->writable() && 560 LOG(LS_INFO) << "Transport " << name() << " gathering complete.";
692 channel->GetState() == TransportChannelState::STATE_COMPLETED &&
693 channel->GetIceRole() == ICEROLE_CONTROLLING &&
694 iter.second.candidates_allocated())) {
695 return;
696 } 561 }
697 } 562 SignalGatheringState(this);
698
699 signaling_thread_->Post(this, MSG_COMPLETED);
700 }
701
702 void Transport::SetIceRole_w(IceRole role) {
703 ASSERT(worker_thread()->IsCurrent());
704 rtc::CritScope cs(&crit_);
705 ice_role_ = role;
706 for (auto& iter : channels_) {
707 iter.second->SetIceRole(ice_role_);
708 } 563 }
709 } 564 }
710 565
711 void Transport::SetRemoteIceMode_w(IceMode mode) { 566 void Transport::UpdateReceivingState() {
712 ASSERT(worker_thread()->IsCurrent()); 567 TransportState receiving = GetTransportState(TRANSPORT_RECEIVING_STATE);
713 remote_ice_mode_ = mode; 568 if (receiving_ != receiving) {
714 // Shouldn't channels be created after this method executed? 569 receiving_ = receiving;
715 for (auto& iter : channels_) { 570 SignalReceivingState(this);
716 iter.second->SetRemoteIceMode(remote_ice_mode_);
717 } 571 }
718 } 572 }
719 573
720 bool Transport::SetLocalTransportDescription_w( 574 void Transport::UpdateWritableState() {
721 const TransportDescription& desc, 575 TransportState writable = GetTransportState(TRANSPORT_WRITABLE_STATE);
722 ContentAction action, 576 LOG(LS_INFO) << name() << " transport writable state changed? " << writable_
723 std::string* error_desc) { 577 << " => " << writable;
724 ASSERT(worker_thread()->IsCurrent()); 578 if (writable_ != writable) {
725 bool ret = true; 579 was_writable_ = (writable_ == TRANSPORT_STATE_ALL);
726 580 writable_ = writable;
727 if (!VerifyIceParams(desc)) { 581 SignalWritableState(this);
728 return BadTransportDescription("Invalid ice-ufrag or ice-pwd length",
729 error_desc);
730 } 582 }
731
732 // TODO(tommi,pthatcher): I'm not sure why we need to grab this lock at this
733 // point. |local_description_| seems to always be modified on the worker
734 // thread, so we should be able to use it here without grabbing the lock.
735 // However, we _might_ need it before the call to reset() below?
736 // Raw access to |local_description_| is granted to derived transports outside
737 // of locking (see local_description() in the header file).
738 // The contract is that the derived implementations must be aware of when the
739 // description might change and do appropriate synchronization.
740 rtc::CritScope cs(&crit_);
741 if (local_description_ && IceCredentialsChanged(*local_description_, desc)) {
742 IceRole new_ice_role = (action == CA_OFFER) ? ICEROLE_CONTROLLING
743 : ICEROLE_CONTROLLED;
744
745 // It must be called before ApplyLocalTransportDescription_w, which may
746 // trigger an ICE restart and depends on the new ICE role.
747 SetIceRole_w(new_ice_role);
748 }
749
750 local_description_.reset(new TransportDescription(desc));
751
752 for (auto& iter : channels_) {
753 ret &= ApplyLocalTransportDescription_w(iter.second.get(), error_desc);
754 }
755 if (!ret)
756 return false;
757
758 // If PRANSWER/ANSWER is set, we should decide transport protocol type.
759 if (action == CA_PRANSWER || action == CA_ANSWER) {
760 ret &= NegotiateTransportDescription_w(action, error_desc);
761 }
762 return ret;
763 } 583 }
764 584
765 bool Transport::SetRemoteTransportDescription_w( 585 bool Transport::ApplyLocalTransportDescription(TransportChannelImpl* ch,
766 const TransportDescription& desc, 586 std::string* error_desc) {
767 ContentAction action,
768 std::string* error_desc) {
769 bool ret = true;
770
771 if (!VerifyIceParams(desc)) {
772 return BadTransportDescription("Invalid ice-ufrag or ice-pwd length",
773 error_desc);
774 }
775
776 // TODO(tommi,pthatcher): See todo for local_description_ above.
777 rtc::CritScope cs(&crit_);
778 remote_description_.reset(new TransportDescription(desc));
779 for (auto& iter : channels_) {
780 ret &= ApplyRemoteTransportDescription_w(iter.second.get(), error_desc);
781 }
782
783 // If PRANSWER/ANSWER is set, we should decide transport protocol type.
784 if (action == CA_PRANSWER || action == CA_ANSWER) {
785 ret = NegotiateTransportDescription_w(CA_OFFER, error_desc);
786 }
787 return ret;
788 }
789
790 bool Transport::ApplyLocalTransportDescription_w(TransportChannelImpl* ch,
791 std::string* error_desc) {
792 ASSERT(worker_thread()->IsCurrent());
793 ch->SetIceCredentials(local_description_->ice_ufrag, 587 ch->SetIceCredentials(local_description_->ice_ufrag,
794 local_description_->ice_pwd); 588 local_description_->ice_pwd);
795 return true; 589 return true;
796 } 590 }
797 591
798 bool Transport::ApplyRemoteTransportDescription_w(TransportChannelImpl* ch, 592 bool Transport::ApplyRemoteTransportDescription(TransportChannelImpl* ch,
799 std::string* error_desc) { 593 std::string* error_desc) {
800 ch->SetRemoteIceCredentials(remote_description_->ice_ufrag, 594 ch->SetRemoteIceCredentials(remote_description_->ice_ufrag,
801 remote_description_->ice_pwd); 595 remote_description_->ice_pwd);
802 return true; 596 return true;
803 } 597 }
804 598
805 bool Transport::ApplyNegotiatedTransportDescription_w( 599 bool Transport::ApplyNegotiatedTransportDescription(
806 TransportChannelImpl* channel, std::string* error_desc) { 600 TransportChannelImpl* channel,
807 ASSERT(worker_thread()->IsCurrent()); 601 std::string* error_desc) {
808 channel->SetRemoteIceMode(remote_ice_mode_); 602 channel->SetRemoteIceMode(remote_ice_mode_);
809 return true; 603 return true;
810 } 604 }
811 605
812 bool Transport::NegotiateTransportDescription_w(ContentAction local_role, 606 bool Transport::NegotiateTransportDescription(ContentAction local_role,
813 std::string* error_desc) { 607 std::string* error_desc) {
814 ASSERT(worker_thread()->IsCurrent());
815 // TODO(ekr@rtfm.com): This is ICE-specific stuff. Refactor into 608 // TODO(ekr@rtfm.com): This is ICE-specific stuff. Refactor into
816 // P2PTransport. 609 // P2PTransport.
817 610
818 // If transport is in ICEROLE_CONTROLLED and remote end point supports only 611 // If transport is in ICEROLE_CONTROLLED and remote end point supports only
819 // ice_lite, this local end point should take CONTROLLING role. 612 // ice_lite, this local end point should take CONTROLLING role.
820 if (ice_role_ == ICEROLE_CONTROLLED && 613 if (ice_role_ == ICEROLE_CONTROLLED &&
821 remote_description_->ice_mode == ICEMODE_LITE) { 614 remote_description_->ice_mode == ICEMODE_LITE) {
822 SetIceRole_w(ICEROLE_CONTROLLING); 615 SetIceRole(ICEROLE_CONTROLLING);
823 } 616 }
824 617
825 // Update remote ice_mode to all existing channels. 618 // Update remote ice_mode to all existing channels.
826 remote_ice_mode_ = remote_description_->ice_mode; 619 remote_ice_mode_ = remote_description_->ice_mode;
827 620
828 // Now that we have negotiated everything, push it downward. 621 // Now that we have negotiated everything, push it downward.
829 // Note that we cache the result so that if we have race conditions 622 // Note that we cache the result so that if we have race conditions
830 // between future SetRemote/SetLocal invocations and new channel 623 // between future SetRemote/SetLocal invocations and new channel
831 // creation, we have the negotiation state saved until a new 624 // creation, we have the negotiation state saved until a new
832 // negotiation happens. 625 // negotiation happens.
833 for (auto& iter : channels_) { 626 for (auto& iter : channels_) {
834 if (!ApplyNegotiatedTransportDescription_w(iter.second.get(), error_desc)) 627 if (!ApplyNegotiatedTransportDescription(iter.second.get(), error_desc))
835 return false; 628 return false;
836 } 629 }
837 return true; 630 return true;
838 } 631 }
839 632
840 void Transport::OnMessage(rtc::Message* msg) {
841 switch (msg->message_id) {
842 case MSG_ONSIGNALINGREADY:
843 CallChannels_w(&TransportChannelImpl::OnSignalingReady);
844 break;
845 case MSG_ONREMOTECANDIDATE: {
846 ChannelParams* params = static_cast<ChannelParams*>(msg->pdata);
847 OnRemoteCandidate_w(*params->candidate);
848 delete params;
849 }
850 break;
851 case MSG_CONNECTING:
852 OnConnecting_s();
853 break;
854 case MSG_WRITESTATE:
855 OnChannelWritableState_s();
856 break;
857 case MSG_RECEIVINGSTATE:
858 OnChannelReceivingState_s();
859 break;
860 case MSG_REQUESTSIGNALING:
861 OnChannelRequestSignaling_s();
862 break;
863 case MSG_CANDIDATEREADY:
864 OnChannelCandidateReady_s();
865 break;
866 case MSG_ROUTECHANGE: {
867 ChannelParams* params = static_cast<ChannelParams*>(msg->pdata);
868 OnChannelRouteChange_s(params->channel, *params->candidate);
869 delete params;
870 }
871 break;
872 case MSG_CANDIDATEALLOCATIONCOMPLETE:
873 OnChannelCandidatesAllocationDone_s();
874 break;
875 case MSG_ROLECONFLICT:
876 SignalRoleConflict();
877 break;
878 case MSG_COMPLETED:
879 SignalCompleted(this);
880 break;
881 case MSG_FAILED:
882 SignalFailed(this);
883 break;
884 }
885 }
886
887 } // namespace cricket 633 } // 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