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

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

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

Powered by Google App Engine
This is Rietveld 408576698