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

Side by Side Diff: webrtc/p2p/stunprober/stunprober.cc

Issue 1422593002: Separate StunProber::Start into Prepare and Run so we could create multiple of them and send out ST… (Closed) Base URL: https://chromium.googlesource.com/external/webrtc@master
Patch Set: 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
OLDNEW
1 /* 1 /*
2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2015 The WebRTC Project Authors. All rights reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 10 matching lines...) Expand all
21 #include "webrtc/base/timeutils.h" 21 #include "webrtc/base/timeutils.h"
22 #include "webrtc/base/thread.h" 22 #include "webrtc/base/thread.h"
23 #include "webrtc/p2p/base/packetsocketfactory.h" 23 #include "webrtc/p2p/base/packetsocketfactory.h"
24 #include "webrtc/p2p/base/stun.h" 24 #include "webrtc/p2p/base/stun.h"
25 #include "webrtc/p2p/stunprober/stunprober.h" 25 #include "webrtc/p2p/stunprober/stunprober.h"
26 26
27 namespace stunprober { 27 namespace stunprober {
28 28
29 namespace { 29 namespace {
30 30
31 const int thread_wake_up_interval_ms = 5; 31 const int THREAD_WAKE_UP_INTERVAL_MS = 5;
32 32
33 template <typename T> 33 template <typename T>
34 void IncrementCounterByAddress(std::map<T, int>* counter_per_ip, const T& ip) { 34 void IncrementCounterByAddress(std::map<T, int>* counter_per_ip, const T& ip) {
35 counter_per_ip->insert(std::make_pair(ip, 0)).first->second++; 35 counter_per_ip->insert(std::make_pair(ip, 0)).first->second++;
36 } 36 }
37 37
38 } // namespace 38 } // namespace
39 39
40 // A requester tracks the requests and responses from a single socket to many 40 // A requester tracks the requests and responses from a single socket to many
41 // STUN servers 41 // STUN servers
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 cricket::StunMessage message; 136 cricket::StunMessage message;
137 137
138 // Random transaction ID, STUN_BINDING_REQUEST 138 // Random transaction ID, STUN_BINDING_REQUEST
139 message.SetTransactionID( 139 message.SetTransactionID(
140 rtc::CreateRandomString(cricket::kStunTransactionIdLength)); 140 rtc::CreateRandomString(cricket::kStunTransactionIdLength));
141 message.SetType(cricket::STUN_BINDING_REQUEST); 141 message.SetType(cricket::STUN_BINDING_REQUEST);
142 142
143 rtc::scoped_ptr<rtc::ByteBuffer> request_packet( 143 rtc::scoped_ptr<rtc::ByteBuffer> request_packet(
144 new rtc::ByteBuffer(nullptr, kMaxUdpBufferSize)); 144 new rtc::ByteBuffer(nullptr, kMaxUdpBufferSize));
145 if (!message.Write(request_packet.get())) { 145 if (!message.Write(request_packet.get())) {
146 prober_->End(WRITE_FAILED); 146 prober_->ReportOnFinished(WRITE_FAILED);
147 return; 147 return;
148 } 148 }
149 149
150 auto addr = server_ips_[num_request_sent_]; 150 auto addr = server_ips_[num_request_sent_];
151 request.server_addr = addr.ipaddr(); 151 request.server_addr = addr.ipaddr();
152 152
153 // The write must succeed immediately. Otherwise, the calculating of the STUN 153 // The write must succeed immediately. Otherwise, the calculating of the STUN
154 // request timing could become too complicated. Callback is ignored by passing 154 // request timing could become too complicated. Callback is ignored by passing
155 // empty AsyncCallback. 155 // empty AsyncCallback.
156 rtc::PacketOptions options; 156 rtc::PacketOptions options;
157 int rv = socket_->SendTo(const_cast<char*>(request_packet->Data()), 157 int rv = socket_->SendTo(const_cast<char*>(request_packet->Data()),
158 request_packet->Length(), addr, options); 158 request_packet->Length(), addr, options);
159 if (rv < 0) { 159 if (rv < 0) {
160 prober_->End(WRITE_FAILED); 160 prober_->ReportOnFinished(WRITE_FAILED);
161 return; 161 return;
162 } 162 }
163 163
164 request.sent_time_ms = rtc::Time(); 164 request.sent_time_ms = rtc::Time();
165 165
166 num_request_sent_++; 166 num_request_sent_++;
167 RTC_DCHECK(static_cast<size_t>(num_request_sent_) <= server_ips_.size()); 167 RTC_DCHECK(static_cast<size_t>(num_request_sent_) <= server_ips_.size());
168 } 168 }
169 169
170 void StunProber::Requester::Request::ProcessResponse(const char* buf, 170 void StunProber::Requester::Request::ProcessResponse(const char* buf,
(...skipping 29 matching lines...) Expand all
200 rtc::AsyncPacketSocket* socket, 200 rtc::AsyncPacketSocket* socket,
201 const char* buf, 201 const char* buf,
202 size_t size, 202 size_t size,
203 const rtc::SocketAddress& addr, 203 const rtc::SocketAddress& addr,
204 const rtc::PacketTime& time) { 204 const rtc::PacketTime& time) {
205 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 205 RTC_DCHECK(thread_checker_.CalledOnValidThread());
206 RTC_DCHECK(socket_); 206 RTC_DCHECK(socket_);
207 Request* request = GetRequestByAddress(addr.ipaddr()); 207 Request* request = GetRequestByAddress(addr.ipaddr());
208 if (!request) { 208 if (!request) {
209 // Something is wrong, finish the test. 209 // Something is wrong, finish the test.
210 prober_->End(GENERIC_FAILURE); 210 prober_->ReportOnFinished(GENERIC_FAILURE);
211 return; 211 return;
212 } 212 }
213 213
214 num_response_received_++; 214 num_response_received_++;
215 request->ProcessResponse(buf, size); 215 request->ProcessResponse(buf, size);
216 } 216 }
217 217
218 StunProber::Requester::Request* StunProber::Requester::GetRequestByAddress( 218 StunProber::Requester::Request* StunProber::Requester::GetRequestByAddress(
219 const rtc::IPAddress& ipaddr) { 219 const rtc::IPAddress& ipaddr) {
220 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 220 RTC_DCHECK(thread_checker_.CalledOnValidThread());
(...skipping 27 matching lines...) Expand all
248 } 248 }
249 } 249 }
250 } 250 }
251 251
252 bool StunProber::Start(const std::vector<rtc::SocketAddress>& servers, 252 bool StunProber::Start(const std::vector<rtc::SocketAddress>& servers,
253 bool shared_socket_mode, 253 bool shared_socket_mode,
254 int interval_ms, 254 int interval_ms,
255 int num_request_per_ip, 255 int num_request_per_ip,
256 int timeout_ms, 256 int timeout_ms,
257 const AsyncCallback callback) { 257 const AsyncCallback callback) {
258 observer_adapter_.set_callback(callback);
259 return Prepare(servers, shared_socket_mode, interval_ms, num_request_per_ip,
260 timeout_ms, &observer_adapter_);
261 }
262
263 bool StunProber::Prepare(const std::vector<rtc::SocketAddress>& servers,
264 bool shared_socket_mode,
265 int interval_ms,
266 int num_request_per_ip,
267 int timeout_ms,
268 StunProber::Observer* observer) {
258 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 269 RTC_DCHECK(thread_checker_.CalledOnValidThread());
259 interval_ms_ = interval_ms; 270 interval_ms_ = interval_ms;
260 shared_socket_mode_ = shared_socket_mode; 271 shared_socket_mode_ = shared_socket_mode;
261 272
262 requests_per_ip_ = num_request_per_ip; 273 requests_per_ip_ = num_request_per_ip;
263 if (requests_per_ip_ == 0 || servers.size() == 0) { 274 if (requests_per_ip_ == 0 || servers.size() == 0) {
264 return false; 275 return false;
265 } 276 }
266 277
267 timeout_ms_ = timeout_ms; 278 timeout_ms_ = timeout_ms;
268 servers_ = servers; 279 servers_ = servers;
269 finished_callback_ = callback; 280 observer_ = observer;
270 return ResolveServerName(servers_.back()); 281 return ResolveServerName(servers_.back());
271 } 282 }
272 283
284 bool StunProber::Run(StunProber::Observer* observer) {
285 observer_ = observer;
286 if (total_ready_sockets_ != total_socket_required()) {
287 return false;
288 }
289 MaybeScheduleStunRequests();
290 return true;
291 }
292
273 bool StunProber::ResolveServerName(const rtc::SocketAddress& addr) { 293 bool StunProber::ResolveServerName(const rtc::SocketAddress& addr) {
274 rtc::AsyncResolverInterface* resolver = 294 rtc::AsyncResolverInterface* resolver =
275 socket_factory_->CreateAsyncResolver(); 295 socket_factory_->CreateAsyncResolver();
276 if (!resolver) { 296 if (!resolver) {
277 return false; 297 return false;
278 } 298 }
279 resolver->SignalDone.connect(this, &StunProber::OnServerResolved); 299 resolver->SignalDone.connect(this, &StunProber::OnServerResolved);
280 resolver->Start(addr); 300 resolver->Start(addr);
281 return true; 301 return true;
282 } 302 }
283 303
284 void StunProber::OnSocketReady(rtc::AsyncPacketSocket* socket, 304 void StunProber::OnSocketReady(rtc::AsyncPacketSocket* socket,
285 const rtc::SocketAddress& addr) { 305 const rtc::SocketAddress& addr) {
286 total_ready_sockets_++; 306 total_ready_sockets_++;
287 if (total_ready_sockets_ == total_socket_required()) { 307 if (total_ready_sockets_ == total_socket_required()) {
288 MaybeScheduleStunRequests(); 308 ReportOnPrepared(SUCCESS);
289 } 309 }
290 } 310 }
291 311
292 void StunProber::OnServerResolved(rtc::AsyncResolverInterface* resolver) { 312 void StunProber::OnServerResolved(rtc::AsyncResolverInterface* resolver) {
293 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 313 RTC_DCHECK(thread_checker_.CalledOnValidThread());
294 314
295 if (resolver->GetError() == 0) { 315 if (resolver->GetError() == 0) {
296 rtc::SocketAddress addr(resolver->address().ipaddr(), 316 rtc::SocketAddress addr(resolver->address().ipaddr(),
297 resolver->address().port()); 317 resolver->address().port());
298 all_servers_addrs_.push_back(addr); 318 all_servers_addrs_.push_back(addr);
299 } 319 }
300 320
301 // Deletion of AsyncResolverInterface can't be done in OnResolveResult which 321 // Deletion of AsyncResolverInterface can't be done in OnResolveResult which
302 // handles SignalDone. 322 // handles SignalDone.
303 invoker_.AsyncInvoke<void>( 323 invoker_.AsyncInvoke<void>(
304 thread_, 324 thread_,
305 rtc::Bind(&rtc::AsyncResolverInterface::Destroy, resolver, false)); 325 rtc::Bind(&rtc::AsyncResolverInterface::Destroy, resolver, false));
306 servers_.pop_back(); 326 servers_.pop_back();
307 327
308 if (servers_.size()) { 328 if (servers_.size()) {
309 if (!ResolveServerName(servers_.back())) { 329 if (!ResolveServerName(servers_.back())) {
310 End(RESOLVE_FAILED); 330 ReportOnPrepared(RESOLVE_FAILED);
311 } 331 }
312 return; 332 return;
313 } 333 }
314 334
315 if (all_servers_addrs_.size() == 0) { 335 if (all_servers_addrs_.size() == 0) {
316 End(RESOLVE_FAILED); 336 ReportOnPrepared(RESOLVE_FAILED);
317 return; 337 return;
318 } 338 }
319 339
320 // Dedupe. 340 // Dedupe.
321 std::set<rtc::SocketAddress> addrs(all_servers_addrs_.begin(), 341 std::set<rtc::SocketAddress> addrs(all_servers_addrs_.begin(),
322 all_servers_addrs_.end()); 342 all_servers_addrs_.end());
323 all_servers_addrs_.assign(addrs.begin(), addrs.end()); 343 all_servers_addrs_.assign(addrs.begin(), addrs.end());
324 344
325 // Prepare all the sockets beforehand. All of them will bind to "any" address. 345 // Prepare all the sockets beforehand. All of them will bind to "any" address.
326 while (sockets_.size() < total_socket_required()) { 346 while (sockets_.size() < total_socket_required()) {
327 rtc::scoped_ptr<rtc::AsyncPacketSocket> socket( 347 rtc::scoped_ptr<rtc::AsyncPacketSocket> socket(
328 socket_factory_->CreateUdpSocket(rtc::SocketAddress(INADDR_ANY, 0), 0, 348 socket_factory_->CreateUdpSocket(rtc::SocketAddress(INADDR_ANY, 0), 0,
329 0)); 349 0));
330 if (!socket) { 350 if (!socket) {
331 End(GENERIC_FAILURE); 351 ReportOnPrepared(GENERIC_FAILURE);
332 return; 352 return;
333 } 353 }
334 // Chrome and WebRTC behave differently in terms of the state of a socket 354 // Chrome and WebRTC behave differently in terms of the state of a socket
335 // once returned from PacketSocketFactory::CreateUdpSocket. 355 // once returned from PacketSocketFactory::CreateUdpSocket.
336 if (socket->GetState() == rtc::AsyncPacketSocket::STATE_BINDING) { 356 if (socket->GetState() == rtc::AsyncPacketSocket::STATE_BINDING) {
337 socket->SignalAddressReady.connect(this, &StunProber::OnSocketReady); 357 socket->SignalAddressReady.connect(this, &StunProber::OnSocketReady);
338 } else { 358 } else {
339 OnSocketReady(socket.get(), rtc::SocketAddress(INADDR_ANY, 0)); 359 OnSocketReady(socket.get(), rtc::SocketAddress(INADDR_ANY, 0));
340 } 360 }
341 sockets_.push_back(socket.release()); 361 sockets_.push_back(socket.release());
(...skipping 25 matching lines...) Expand all
367 requesters_.push_back(current_requester_); 387 requesters_.push_back(current_requester_);
368 } 388 }
369 if (!current_requester_) { 389 if (!current_requester_) {
370 return false; 390 return false;
371 } 391 }
372 current_requester_->SendStunRequest(); 392 current_requester_->SendStunRequest();
373 num_request_sent_++; 393 num_request_sent_++;
374 return true; 394 return true;
375 } 395 }
376 396
397 bool StunProber::should_send_next_request(uint32_t now) {
398 if (interval_ms_ < THREAD_WAKE_UP_INTERVAL_MS) {
399 return now >= next_request_time_ms_;
400 } else {
401 return (now + (THREAD_WAKE_UP_INTERVAL_MS / 2)) >= next_request_time_ms_;
402 }
403 }
404
405 int StunProber::get_wake_up_interval_ms() {
406 if (interval_ms_ < THREAD_WAKE_UP_INTERVAL_MS) {
407 return 1;
408 } else {
409 return THREAD_WAKE_UP_INTERVAL_MS;
410 }
411 }
412
377 void StunProber::MaybeScheduleStunRequests() { 413 void StunProber::MaybeScheduleStunRequests() {
378 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 414 RTC_DCHECK(thread_checker_.CalledOnValidThread());
379 uint32_t now = rtc::Time(); 415 uint32_t now = rtc::Time();
380 416
381 if (Done()) { 417 if (Done()) {
382 invoker_.AsyncInvokeDelayed<void>( 418 invoker_.AsyncInvokeDelayed<void>(
383 thread_, rtc::Bind(&StunProber::End, this, SUCCESS), timeout_ms_); 419 thread_, rtc::Bind(&StunProber::ReportOnFinished, this, SUCCESS),
420 timeout_ms_);
384 return; 421 return;
385 } 422 }
386 if ((now + (thread_wake_up_interval_ms / 2)) >= next_request_time_ms_) { 423 if (should_send_next_request(now)) {
387 if (!SendNextRequest()) { 424 if (!SendNextRequest()) {
388 End(GENERIC_FAILURE); 425 ReportOnFinished(GENERIC_FAILURE);
389 return; 426 return;
390 } 427 }
391 next_request_time_ms_ = now + interval_ms_; 428 next_request_time_ms_ = now + interval_ms_;
392 } 429 }
393 invoker_.AsyncInvokeDelayed<void>( 430 invoker_.AsyncInvokeDelayed<void>(
394 thread_, rtc::Bind(&StunProber::MaybeScheduleStunRequests, this), 431 thread_, rtc::Bind(&StunProber::MaybeScheduleStunRequests, this),
395 thread_wake_up_interval_ms /* ms */); 432 get_wake_up_interval_ms());
396 } 433 }
397 434
398 bool StunProber::GetStats(StunProber::Stats* prob_stats) const { 435 bool StunProber::GetStats(StunProber::Stats* prob_stats) const {
399 // No need to be on the same thread. 436 // No need to be on the same thread.
400 if (!prob_stats) { 437 if (!prob_stats) {
401 return false; 438 return false;
402 } 439 }
403 440
404 StunProber::Stats stats; 441 StunProber::Stats stats;
405 442
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 } 550 }
514 551
515 if (num_received) { 552 if (num_received) {
516 stats.average_rtt_ms = static_cast<int>((rtt_sum / num_received)); 553 stats.average_rtt_ms = static_cast<int>((rtt_sum / num_received));
517 } 554 }
518 555
519 *prob_stats = stats; 556 *prob_stats = stats;
520 return true; 557 return true;
521 } 558 }
522 559
523 void StunProber::End(StunProber::Status status) { 560 void StunProber::ReportOnPrepared(StunProber::Status status) {
524 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 561 if (observer_) {
525 if (!finished_callback_.empty()) { 562 observer_->OnPrepared(this, status);
526 AsyncCallback callback = finished_callback_;
527 finished_callback_ = AsyncCallback();
528
529 // Callback at the last since the prober might be deleted in the callback.
530 callback(this, status);
531 } 563 }
532 } 564 }
533 565
566 void StunProber::ReportOnFinished(StunProber::Status status) {
567 if (observer_) {
568 observer_->OnFinished(this, status);
569 }
570 }
571
534 } // namespace stunprober 572 } // namespace stunprober
OLDNEW
« webrtc/p2p/stunprober/stunprober.h ('K') | « webrtc/p2p/stunprober/stunprober.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698