| Index: chrome/browser/extensions/api/dial/dial_service.cc
|
| diff --git a/chrome/browser/extensions/api/dial/dial_service.cc b/chrome/browser/extensions/api/dial/dial_service.cc
|
| index c1bbcff030f52b75e72b24a34695bc491a1e4e3f..a11fabdc5f3955577f5ac9c9093edb6d910a97d6 100644
|
| --- a/chrome/browser/extensions/api/dial/dial_service.cc
|
| +++ b/chrome/browser/extensions/api/dial/dial_service.cc
|
| @@ -5,6 +5,8 @@
|
| #include "chrome/browser/extensions/api/dial/dial_service.h"
|
|
|
| #include <algorithm>
|
| +#include <set>
|
| +#include <utility>
|
|
|
| #include "base/basictypes.h"
|
| #include "base/callback.h"
|
| @@ -469,18 +471,40 @@ void DialServiceImpl::StartDiscovery() {
|
|
|
| void DialServiceImpl::SendNetworkList(const NetworkInterfaceList& networks) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| + typedef std::pair<uint32, net::AddressFamily> InterfaceIndexAddressFamily;
|
| + std::set<InterfaceIndexAddressFamily> interface_index_addr_family_seen;
|
| std::vector<IPAddressNumber> ip_addresses;
|
|
|
| - // Returns the first IPv4 address found. If there is a need for discovery
|
| - // across multiple networks, we could manage multiple sockets.
|
| + // Binds a socket to each IPv4 network interface found. Note that
|
| + // there may be duplicates in |networks|, so address family + interface index
|
| + // is used to identify unique interfaces.
|
| // TODO(mfoltz): Support IPV6 multicast. http://crbug.com/165286
|
| for (NetworkInterfaceList::const_iterator iter = networks.begin();
|
| iter != networks.end(); ++iter) {
|
| + net::AddressFamily addr_family = net::GetAddressFamily(iter->address);
|
| DVLOG(1) << "Found " << iter->name << ", "
|
| - << net::IPAddressToString(iter->address);
|
| - if (iter->address.size() == net::kIPv4AddressSize) {
|
| - ip_addresses.push_back(iter->address);
|
| - break;
|
| + << net::IPAddressToString(iter->address)
|
| + << ", address family: " << addr_family;
|
| + if (addr_family == net::ADDRESS_FAMILY_IPV4) {
|
| + InterfaceIndexAddressFamily interface_index_addr_family =
|
| + std::make_pair(iter->interface_index, addr_family);
|
| + bool inserted = interface_index_addr_family_seen
|
| + .insert(interface_index_addr_family)
|
| + .second;
|
| + // We have not seen this interface before, so add its IP address to the
|
| + // discovery list.
|
| + if (inserted) {
|
| + VLOG(2) << "Encountered "
|
| + << "interface index: " << iter->interface_index << ", "
|
| + << "address family: " << addr_family << " for the first time, "
|
| + << "adding IP address " << net::IPAddressToString(iter->address)
|
| + << " to list.";
|
| + ip_addresses.push_back(iter->address);
|
| + } else {
|
| + VLOG(2) << "Already encountered "
|
| + << "interface index: " << iter->interface_index << ", "
|
| + << "address family: " << addr_family << " before, not adding.";
|
| + }
|
| }
|
| }
|
|
|
| @@ -489,7 +513,7 @@ void DialServiceImpl::SendNetworkList(const NetworkInterfaceList& networks) {
|
|
|
| void DialServiceImpl::DiscoverOnAddresses(
|
| const std::vector<IPAddressNumber>& ip_addresses) {
|
| - if (ip_addresses.size() == 0) {
|
| + if (ip_addresses.empty()) {
|
| DVLOG(1) << "Could not find a valid interface to bind. Finishing discovery";
|
| FinishDiscovery();
|
| return;
|
| @@ -506,9 +530,8 @@ void DialServiceImpl::DiscoverOnAddresses(
|
|
|
| for (std::vector<IPAddressNumber>::const_iterator iter = ip_addresses.begin();
|
| iter != ip_addresses.end();
|
| - ++iter) {
|
| + ++iter)
|
| BindAndAddSocket(*iter);
|
| - }
|
|
|
| SendOneRequest();
|
| }
|
| @@ -561,6 +584,8 @@ void DialServiceImpl::NotifyOnDiscoveryRequest() {
|
| // If we need to send additional requests, schedule a timer to do so.
|
| if (num_requests_sent_ < max_requests_ && num_requests_sent_ == 1) {
|
| VLOG(2) << "Scheduling timer to send additional requests";
|
| + // TODO(imcheng): Move this to SendOneRequest() once the implications are
|
| + // understood.
|
| request_timer_.Start(FROM_HERE,
|
| request_interval_,
|
| this,
|
| @@ -581,8 +606,12 @@ void DialServiceImpl::NotifyOnDeviceDiscovered(
|
|
|
| void DialServiceImpl::NotifyOnError() {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| + // TODO(imcheng): Modify upstream so that the device list is not cleared
|
| + // when it could still potentially discover devices on other sockets.
|
| FOR_EACH_OBSERVER(Observer, observer_list_,
|
| - OnError(this, DIAL_SERVICE_SOCKET_ERROR));
|
| + OnError(this,
|
| + HasOpenSockets() ? DIAL_SERVICE_SOCKET_ERROR
|
| + : DIAL_SERVICE_NO_INTERFACES));
|
| }
|
|
|
| void DialServiceImpl::FinishDiscovery() {
|
|
|