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

Side by Side Diff: chrome/browser/extensions/api/dial/dial_service.cc

Issue 117853004: "Reland" of r241209. DialServiceImpl now binds to all ipv4 and interfaces instead of just the first (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years 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 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/api/dial/dial_service.h" 5 #include "chrome/browser/extensions/api/dial/dial_service.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set>
9 #include <utility>
8 10
9 #include "base/basictypes.h" 11 #include "base/basictypes.h"
10 #include "base/callback.h" 12 #include "base/callback.h"
11 #include "base/logging.h" 13 #include "base/logging.h"
12 #include "base/rand_util.h" 14 #include "base/rand_util.h"
13 #include "base/strings/string_number_conversions.h" 15 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/stringprintf.h" 16 #include "base/strings/stringprintf.h"
15 #include "base/time/time.h" 17 #include "base/time/time.h"
16 #include "chrome/browser/extensions/api/dial/dial_device_data.h" 18 #include "chrome/browser/extensions/api/dial/dial_device_data.h"
17 #include "chrome/common/chrome_version_info.h" 19 #include "chrome/common/chrome_version_info.h"
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 #else 464 #else
463 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind( 465 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind(
464 &GetNetworkListOnFileThread, 466 &GetNetworkListOnFileThread,
465 base::MessageLoopProxy::current(), base::Bind( 467 base::MessageLoopProxy::current(), base::Bind(
466 &DialServiceImpl::SendNetworkList, AsWeakPtr()))); 468 &DialServiceImpl::SendNetworkList, AsWeakPtr())));
467 #endif 469 #endif
468 } 470 }
469 471
470 void DialServiceImpl::SendNetworkList(const NetworkInterfaceList& networks) { 472 void DialServiceImpl::SendNetworkList(const NetworkInterfaceList& networks) {
471 DCHECK(thread_checker_.CalledOnValidThread()); 473 DCHECK(thread_checker_.CalledOnValidThread());
474 typedef std::pair<uint32, net::AddressFamily> InterfaceIndexAddressFamily;
475 std::set<InterfaceIndexAddressFamily> interface_index_addr_family_seen;
472 std::vector<IPAddressNumber> ip_addresses; 476 std::vector<IPAddressNumber> ip_addresses;
473 477
474 // Returns the first IPv4 address found. If there is a need for discovery 478 // Binds a socket to each IPv4 network interface found. Note that
475 // across multiple networks, we could manage multiple sockets. 479 // there may be duplicates in |networks|, so address family + interface index
480 // is used to identify unique interfaces.
476 // TODO(mfoltz): Support IPV6 multicast. http://crbug.com/165286 481 // TODO(mfoltz): Support IPV6 multicast. http://crbug.com/165286
477 for (NetworkInterfaceList::const_iterator iter = networks.begin(); 482 for (NetworkInterfaceList::const_iterator iter = networks.begin();
478 iter != networks.end(); ++iter) { 483 iter != networks.end(); ++iter) {
484 net::AddressFamily addr_family = net::GetAddressFamily(iter->address);
479 DVLOG(1) << "Found " << iter->name << ", " 485 DVLOG(1) << "Found " << iter->name << ", "
480 << net::IPAddressToString(iter->address); 486 << net::IPAddressToString(iter->address)
481 if (iter->address.size() == net::kIPv4AddressSize) { 487 << ", address family: " << addr_family;
482 ip_addresses.push_back(iter->address); 488 if (addr_family == net::ADDRESS_FAMILY_IPV4) {
483 break; 489 InterfaceIndexAddressFamily interface_index_addr_family =
490 std::make_pair(iter->interface_index, addr_family);
491 bool inserted = interface_index_addr_family_seen
492 .insert(interface_index_addr_family)
493 .second;
494 // We have not seen this interface before, so add its IP address to the
495 // discovery list.
496 if (inserted) {
497 VLOG(2) << "Encountered "
498 << "interface index: " << iter->interface_index << ", "
499 << "address family: " << addr_family << " for the first time, "
500 << "adding IP address " << net::IPAddressToString(iter->address)
501 << " to list.";
502 ip_addresses.push_back(iter->address);
503 } else {
504 VLOG(2) << "Already encountered "
505 << "interface index: " << iter->interface_index << ", "
506 << "address family: " << addr_family << " before, not adding.";
507 }
484 } 508 }
485 } 509 }
486 510
487 DiscoverOnAddresses(ip_addresses); 511 DiscoverOnAddresses(ip_addresses);
488 } 512 }
489 513
490 void DialServiceImpl::DiscoverOnAddresses( 514 void DialServiceImpl::DiscoverOnAddresses(
491 const std::vector<IPAddressNumber>& ip_addresses) { 515 const std::vector<IPAddressNumber>& ip_addresses) {
492 if (ip_addresses.size() == 0) { 516 if (ip_addresses.empty()) {
493 DVLOG(1) << "Could not find a valid interface to bind. Finishing discovery"; 517 DVLOG(1) << "Could not find a valid interface to bind. Finishing discovery";
494 FinishDiscovery(); 518 FinishDiscovery();
495 return; 519 return;
496 } 520 }
497 521
498 // Schedule a timer to finish the discovery process (and close the sockets). 522 // Schedule a timer to finish the discovery process (and close the sockets).
499 if (finish_delay_ > TimeDelta::FromSeconds(0)) { 523 if (finish_delay_ > TimeDelta::FromSeconds(0)) {
500 VLOG(2) << "Starting timer to finish discovery."; 524 VLOG(2) << "Starting timer to finish discovery.";
501 finish_timer_.Start(FROM_HERE, 525 finish_timer_.Start(FROM_HERE,
502 finish_delay_, 526 finish_delay_,
503 this, 527 this,
504 &DialServiceImpl::FinishDiscovery); 528 &DialServiceImpl::FinishDiscovery);
505 } 529 }
506 530
507 for (std::vector<IPAddressNumber>::const_iterator iter = ip_addresses.begin(); 531 for (std::vector<IPAddressNumber>::const_iterator iter = ip_addresses.begin();
508 iter != ip_addresses.end(); 532 iter != ip_addresses.end();
509 ++iter) { 533 ++iter)
510 BindAndAddSocket(*iter); 534 BindAndAddSocket(*iter);
511 }
512 535
513 SendOneRequest(); 536 SendOneRequest();
514 } 537 }
515 538
516 void DialServiceImpl::BindAndAddSocket(const IPAddressNumber& bind_ip_address) { 539 void DialServiceImpl::BindAndAddSocket(const IPAddressNumber& bind_ip_address) {
517 scoped_ptr<DialServiceImpl::DialSocket> dial_socket(CreateDialSocket()); 540 scoped_ptr<DialServiceImpl::DialSocket> dial_socket(CreateDialSocket());
518 if (dial_socket->CreateAndBindSocket(bind_ip_address, net_log_, 541 if (dial_socket->CreateAndBindSocket(bind_ip_address, net_log_,
519 net_log_source_)) 542 net_log_source_))
520 dial_sockets_.push_back(dial_socket.release()); 543 dial_sockets_.push_back(dial_socket.release());
521 } 544 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 if (!discovery_active_) { 577 if (!discovery_active_) {
555 VLOG(2) << "Request sent after discovery finished. Ignoring."; 578 VLOG(2) << "Request sent after discovery finished. Ignoring.";
556 return; 579 return;
557 } 580 }
558 581
559 VLOG(2) << "Notifying observers of discovery request"; 582 VLOG(2) << "Notifying observers of discovery request";
560 FOR_EACH_OBSERVER(Observer, observer_list_, OnDiscoveryRequest(this)); 583 FOR_EACH_OBSERVER(Observer, observer_list_, OnDiscoveryRequest(this));
561 // If we need to send additional requests, schedule a timer to do so. 584 // If we need to send additional requests, schedule a timer to do so.
562 if (num_requests_sent_ < max_requests_ && num_requests_sent_ == 1) { 585 if (num_requests_sent_ < max_requests_ && num_requests_sent_ == 1) {
563 VLOG(2) << "Scheduling timer to send additional requests"; 586 VLOG(2) << "Scheduling timer to send additional requests";
587 // TODO(imcheng): Move this to SendOneRequest() once the implications are
588 // understood.
564 request_timer_.Start(FROM_HERE, 589 request_timer_.Start(FROM_HERE,
565 request_interval_, 590 request_interval_,
566 this, 591 this,
567 &DialServiceImpl::SendOneRequest); 592 &DialServiceImpl::SendOneRequest);
568 } 593 }
569 } 594 }
570 595
571 void DialServiceImpl::NotifyOnDeviceDiscovered( 596 void DialServiceImpl::NotifyOnDeviceDiscovered(
572 const DialDeviceData& device_data) { 597 const DialDeviceData& device_data) {
573 DCHECK(thread_checker_.CalledOnValidThread()); 598 DCHECK(thread_checker_.CalledOnValidThread());
574 if (!discovery_active_) { 599 if (!discovery_active_) {
575 VLOG(2) << "Got response after discovery finished. Ignoring."; 600 VLOG(2) << "Got response after discovery finished. Ignoring.";
576 return; 601 return;
577 } 602 }
578 FOR_EACH_OBSERVER(Observer, observer_list_, 603 FOR_EACH_OBSERVER(Observer, observer_list_,
579 OnDeviceDiscovered(this, device_data)); 604 OnDeviceDiscovered(this, device_data));
580 } 605 }
581 606
582 void DialServiceImpl::NotifyOnError() { 607 void DialServiceImpl::NotifyOnError() {
583 DCHECK(thread_checker_.CalledOnValidThread()); 608 DCHECK(thread_checker_.CalledOnValidThread());
609 // TODO(imcheng): Modify upstream so that the device list is not cleared
610 // when it could still potentially discover devices on other sockets.
584 FOR_EACH_OBSERVER(Observer, observer_list_, 611 FOR_EACH_OBSERVER(Observer, observer_list_,
585 OnError(this, DIAL_SERVICE_SOCKET_ERROR)); 612 OnError(this,
613 HasOpenSockets() ? DIAL_SERVICE_SOCKET_ERROR
614 : DIAL_SERVICE_NO_INTERFACES));
586 } 615 }
587 616
588 void DialServiceImpl::FinishDiscovery() { 617 void DialServiceImpl::FinishDiscovery() {
589 DCHECK(thread_checker_.CalledOnValidThread()); 618 DCHECK(thread_checker_.CalledOnValidThread());
590 DCHECK(discovery_active_); 619 DCHECK(discovery_active_);
591 VLOG(2) << "Discovery finished."; 620 VLOG(2) << "Discovery finished.";
592 // Close all open sockets. 621 // Close all open sockets.
593 dial_sockets_.clear(); 622 dial_sockets_.clear();
594 finish_timer_.Stop(); 623 finish_timer_.Stop();
595 request_timer_.Stop(); 624 request_timer_.Stop();
596 discovery_active_ = false; 625 discovery_active_ = false;
597 num_requests_sent_ = 0; 626 num_requests_sent_ = 0;
598 FOR_EACH_OBSERVER(Observer, observer_list_, OnDiscoveryFinished(this)); 627 FOR_EACH_OBSERVER(Observer, observer_list_, OnDiscoveryFinished(this));
599 } 628 }
600 629
601 bool DialServiceImpl::HasOpenSockets() { 630 bool DialServiceImpl::HasOpenSockets() {
602 for (ScopedVector<DialSocket>::const_iterator iter = dial_sockets_.begin(); 631 for (ScopedVector<DialSocket>::const_iterator iter = dial_sockets_.begin();
603 iter != dial_sockets_.end(); 632 iter != dial_sockets_.end();
604 ++iter) { 633 ++iter) {
605 if (!((*iter)->IsClosed())) 634 if (!((*iter)->IsClosed()))
606 return true; 635 return true;
607 } 636 }
608 return false; 637 return false;
609 } 638 }
610 639
611 } // namespace extensions 640 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698