diff options
11 files changed, 127 insertions, 46 deletions
diff --git a/chrome/browser/local_discovery/privet_http_asynchronous_factory.cc b/chrome/browser/local_discovery/privet_http_asynchronous_factory.cc index 16c9e93..94511f6 100644 --- a/chrome/browser/local_discovery/privet_http_asynchronous_factory.cc +++ b/chrome/browser/local_discovery/privet_http_asynchronous_factory.cc @@ -74,12 +74,20 @@ void PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::Start() { } void PrivetHTTPAsynchronousFactoryImpl::ResolutionImpl::ResolveComplete( - bool success, const net::IPAddressNumber& address) { + bool success, + const net::IPAddressNumber& address_ipv4, + const net::IPAddressNumber& address_ipv6) { if (!success) { callback_.Run(scoped_ptr<PrivetHTTPClient>()); return; } + net::IPAddressNumber address = address_ipv4; + if (address.empty()) + address = address_ipv6; + + DCHECK(!address.empty()); + net::HostPortPair new_address = net::HostPortPair( IPAddressToHostString(address), hostport_.port()); callback_.Run(scoped_ptr<PrivetHTTPClient>( diff --git a/chrome/browser/local_discovery/privet_http_asynchronous_factory.h b/chrome/browser/local_discovery/privet_http_asynchronous_factory.h index ac2552b..c02dbed 100644 --- a/chrome/browser/local_discovery/privet_http_asynchronous_factory.h +++ b/chrome/browser/local_discovery/privet_http_asynchronous_factory.h @@ -55,7 +55,9 @@ class PrivetHTTPAsynchronousFactoryImpl : public PrivetHTTPAsynchronousFactory { virtual void Start() OVERRIDE; private: - void ResolveComplete(bool success, const net::IPAddressNumber& address); + void ResolveComplete(bool success, + const net::IPAddressNumber& address_ipv4, + const net::IPAddressNumber& address_ipv6); std::string name_; scoped_ptr<LocalDomainResolver> resolver_; diff --git a/chrome/browser/local_discovery/service_discovery_host_client.cc b/chrome/browser/local_discovery/service_discovery_host_client.cc index 71ab0ce..0434d9c 100644 --- a/chrome/browser/local_discovery/service_discovery_host_client.cc +++ b/chrome/browser/local_discovery/service_discovery_host_client.cc @@ -293,12 +293,13 @@ void ServiceDiscoveryHostClient::OnResolverCallback( void ServiceDiscoveryHostClient::OnLocalDomainResolverCallback( uint64 id, bool success, - const net::IPAddressNumber& ip_address) { + const net::IPAddressNumber& ip_address_ipv4, + const net::IPAddressNumber& ip_address_ipv6) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); callback_runner_->PostTask( FROM_HERE, base::Bind(&ServiceDiscoveryHostClient::RunLocalDomainResolverCallback, - this, id, success, ip_address)); + this, id, success, ip_address_ipv4, ip_address_ipv6)); } void ServiceDiscoveryHostClient::RunWatcherCallback( @@ -324,11 +325,12 @@ void ServiceDiscoveryHostClient::RunResolverCallback( void ServiceDiscoveryHostClient::RunLocalDomainResolverCallback( uint64 id, bool success, - const net::IPAddressNumber& ip_address) { + const net::IPAddressNumber& ip_address_ipv4, + const net::IPAddressNumber& ip_address_ipv6) { DCHECK(CalledOnValidThread()); DomainResolverCallbacks::iterator it = domain_resolver_callbacks_.find(id); if (it != domain_resolver_callbacks_.end() && !it->second.is_null()) - it->second.Run(success, ip_address); + it->second.Run(success, ip_address_ipv4, ip_address_ipv6); } ServiceDiscoveryHostClientFactory::ServiceDiscoveryHostClientFactory() diff --git a/chrome/browser/local_discovery/service_discovery_host_client.h b/chrome/browser/local_discovery/service_discovery_host_client.h index 1a3278d..31f2a09 100644 --- a/chrome/browser/local_discovery/service_discovery_host_client.h +++ b/chrome/browser/local_discovery/service_discovery_host_client.h @@ -92,7 +92,8 @@ class ServiceDiscoveryHostClient : public base::NonThreadSafe, const ServiceDescription& description); void OnLocalDomainResolverCallback(uint64 id, bool success, - const net::IPAddressNumber& address); + const net::IPAddressNumber& address_ipv4, + const net::IPAddressNumber& address_ipv6); // Runs watcher callback on owning thread. @@ -106,7 +107,8 @@ class ServiceDiscoveryHostClient : public base::NonThreadSafe, // Runs local domain resolver callback on owning thread. void RunLocalDomainResolverCallback(uint64 id, bool success, - const net::IPAddressNumber& address); + const net::IPAddressNumber& address_ipv4, + const net::IPAddressNumber& address_ipv6); base::WeakPtr<content::UtilityProcessHost> utility_host_; diff --git a/chrome/common/local_discovery/local_discovery_messages.h b/chrome/common/local_discovery/local_discovery_messages.h index b98756e..4c75766 100644 --- a/chrome/common/local_discovery/local_discovery_messages.h +++ b/chrome/common/local_discovery/local_discovery_messages.h @@ -80,8 +80,9 @@ IPC_MESSAGE_CONTROL3( local_discovery::ServiceDescription /* description */) // Notifies browser process about local domain resolution results. -IPC_MESSAGE_CONTROL3( +IPC_MESSAGE_CONTROL4( LocalDiscoveryHostMsg_LocalDomainResolverCallback, uint64 /* id */, bool /* success */, - net::IPAddressNumber /* ip_address */) + net::IPAddressNumber /* ip_address_ipv4 */, + net::IPAddressNumber /* ip_address_ipv6 */) diff --git a/chrome/common/local_discovery/service_discovery_client.h b/chrome/common/local_discovery/service_discovery_client.h index 30dcbd2..94f5a9b 100644 --- a/chrome/common/local_discovery/service_discovery_client.h +++ b/chrome/common/local_discovery/service_discovery_client.h @@ -94,7 +94,9 @@ class ServiceResolver { class LocalDomainResolver { public: - typedef base::Callback<void(bool, const net::IPAddressNumber&)> + typedef base::Callback<void(bool /*success*/, + const net::IPAddressNumber& /*address_ipv4*/, + const net::IPAddressNumber& /*address_ipv6*/)> IPAddressCallback; virtual ~LocalDomainResolver() {} diff --git a/chrome/utility/local_discovery/local_domain_resolver_unittest.cc b/chrome/utility/local_discovery/local_domain_resolver_unittest.cc index 1dc9fc3..828af27 100644 --- a/chrome/utility/local_discovery/local_domain_resolver_unittest.cc +++ b/chrome/utility/local_discovery/local_domain_resolver_unittest.cc @@ -73,12 +73,17 @@ class LocalDomainResolverTest : public testing::Test { mdns_client_.StartListening(); } - void AddressCallback(bool resolved, const net::IPAddressNumber& address) { - if (address == net::IPAddressNumber()) { - AddressCallbackInternal(resolved, ""); - } else { - AddressCallbackInternal(resolved, net::IPAddressToString(address)); - } + std::string IPAddressToStringWithEmpty(const net::IPAddressNumber& address) { + if (address.empty()) return ""; + return net::IPAddressToString(address); + } + + void AddressCallback(bool resolved, + const net::IPAddressNumber& address_ipv4, + const net::IPAddressNumber& address_ipv6) { + AddressCallbackInternal(resolved, + IPAddressToStringWithEmpty(address_ipv4), + IPAddressToStringWithEmpty(address_ipv6)); } void RunFor(base::TimeDelta time_period) { @@ -92,8 +97,10 @@ class LocalDomainResolverTest : public testing::Test { callback.Cancel(); } - MOCK_METHOD2(AddressCallbackInternal, - void(bool resolved, std::string address)); + MOCK_METHOD3(AddressCallbackInternal, + void(bool resolved, + std::string address_ipv4, + std::string address_ipv6)); net::MockMDnsSocketFactory* socket_factory_; net::MDnsClientImpl mdns_client_; @@ -111,7 +118,7 @@ TEST_F(LocalDomainResolverTest, ResolveDomainA) { resolver.Start(); - EXPECT_CALL(*this, AddressCallbackInternal(true, "1.2.3.4")); + EXPECT_CALL(*this, AddressCallbackInternal(true, "1.2.3.4", "")); socket_factory_->SimulateReceive( kSamplePacketA, sizeof(kSamplePacketA)); @@ -128,13 +135,33 @@ TEST_F(LocalDomainResolverTest, ResolveDomainAAAA) { resolver.Start(); - EXPECT_CALL(*this, AddressCallbackInternal(true, "a::1:2:3:4")); + EXPECT_CALL(*this, AddressCallbackInternal(true, "", "a::1:2:3:4")); + + socket_factory_->SimulateReceive( + kSamplePacketAAAA, sizeof(kSamplePacketAAAA)); +} + +TEST_F(LocalDomainResolverTest, ResolveDomainAnyOneAvailable) { + LocalDomainResolverImpl resolver( + "myhello.local", net::ADDRESS_FAMILY_UNSPECIFIED, + base::Bind(&LocalDomainResolverTest::AddressCallback, + base::Unretained(this)), &mdns_client_); + + EXPECT_CALL(*socket_factory_, OnSendTo(_)) + .Times(4); // Twice per query + + resolver.Start(); socket_factory_->SimulateReceive( kSamplePacketAAAA, sizeof(kSamplePacketAAAA)); + + EXPECT_CALL(*this, AddressCallbackInternal(true, "", "a::1:2:3:4")); + + RunFor(base::TimeDelta::FromMilliseconds(150)); } -TEST_F(LocalDomainResolverTest, ResolveDomainAny) { + +TEST_F(LocalDomainResolverTest, ResolveDomainAnyBothAvailable) { LocalDomainResolverImpl resolver( "myhello.local", net::ADDRESS_FAMILY_UNSPECIFIED, base::Bind(&LocalDomainResolverTest::AddressCallback, @@ -145,10 +172,13 @@ TEST_F(LocalDomainResolverTest, ResolveDomainAny) { resolver.Start(); - EXPECT_CALL(*this, AddressCallbackInternal(true, "a::1:2:3:4")); + EXPECT_CALL(*this, AddressCallbackInternal(true, "1.2.3.4", "a::1:2:3:4")); socket_factory_->SimulateReceive( kSamplePacketAAAA, sizeof(kSamplePacketAAAA)); + + socket_factory_->SimulateReceive( + kSamplePacketA, sizeof(kSamplePacketA)); } TEST_F(LocalDomainResolverTest, ResolveDomainNone) { @@ -162,7 +192,7 @@ TEST_F(LocalDomainResolverTest, ResolveDomainNone) { resolver.Start(); - EXPECT_CALL(*this, AddressCallbackInternal(false, "")); + EXPECT_CALL(*this, AddressCallbackInternal(false, "", "")); RunFor(base::TimeDelta::FromSeconds(4)); } diff --git a/chrome/utility/local_discovery/service_discovery_client_impl.cc b/chrome/utility/local_discovery/service_discovery_client_impl.cc index 524f176..e8fc595 100644 --- a/chrome/utility/local_discovery/service_discovery_client_impl.cc +++ b/chrome/utility/local_discovery/service_discovery_client_impl.cc @@ -14,6 +14,12 @@ namespace local_discovery { +namespace { +// TODO(noamsml): Make this configurable through the LocalDomainResolver +// interface. +const int kLocalDomainSecondAddressTimeoutMs = 100; +} + ServiceDiscoveryClientImpl::ServiceDiscoveryClientImpl( net::MDnsClient* mdns_client) : mdns_client_(mdns_client) { } @@ -393,10 +399,11 @@ LocalDomainResolverImpl::LocalDomainResolverImpl( const IPAddressCallback& callback, net::MDnsClient* mdns_client) : domain_(domain), address_family_(address_family), callback_(callback), - transaction_failures_(0), mdns_client_(mdns_client) { + transactions_finished_(0), mdns_client_(mdns_client) { } LocalDomainResolverImpl::~LocalDomainResolverImpl() { + timeout_callback_.Cancel(); } void LocalDomainResolverImpl::Start() { @@ -425,31 +432,44 @@ scoped_ptr<net::MDnsTransaction> LocalDomainResolverImpl::CreateTransaction( void LocalDomainResolverImpl::OnTransactionComplete( net::MDnsTransaction::Result result, const net::RecordParsed* record) { - if (result != net::MDnsTransaction::RESULT_RECORD && - address_family_ == net::ADDRESS_FAMILY_UNSPECIFIED) { - transaction_failures_++; - - if (transaction_failures_ < 2) { - return; - } - } + transactions_finished_++; - transaction_a_.reset(); - transaction_aaaa_.reset(); - - net::IPAddressNumber address; if (result == net::MDnsTransaction::RESULT_RECORD) { if (record->type() == net::dns_protocol::kTypeA) { const net::ARecordRdata* rdata = record->rdata<net::ARecordRdata>(); - address = rdata->address(); + address_ipv4_ = rdata->address(); } else { DCHECK_EQ(net::dns_protocol::kTypeAAAA, record->type()); const net::AAAARecordRdata* rdata = record->rdata<net::AAAARecordRdata>(); - address = rdata->address(); + address_ipv6_ = rdata->address(); } } - callback_.Run(result == net::MDnsTransaction::RESULT_RECORD, address); + if (transactions_finished_ == 1 && + address_family_ == net::ADDRESS_FAMILY_UNSPECIFIED) { + timeout_callback_.Reset(base::Bind( + &LocalDomainResolverImpl::SendResolvedAddresses, + base::Unretained(this))); + + base::MessageLoop::current()->PostDelayedTask( + FROM_HERE, + timeout_callback_.callback(), + base::TimeDelta::FromMilliseconds(kLocalDomainSecondAddressTimeoutMs)); + } else if (transactions_finished_ == 2 + || address_family_ != net::ADDRESS_FAMILY_UNSPECIFIED) { + SendResolvedAddresses(); + } +} + +bool LocalDomainResolverImpl::IsSuccess() { + return !address_ipv4_.empty() || !address_ipv6_.empty(); +} + +void LocalDomainResolverImpl::SendResolvedAddresses() { + transaction_a_.reset(); + transaction_aaaa_.reset(); + timeout_callback_.Cancel(); + callback_.Run(IsSuccess(), address_ipv4_, address_ipv6_); } } // namespace local_discovery diff --git a/chrome/utility/local_discovery/service_discovery_client_impl.h b/chrome/utility/local_discovery/service_discovery_client_impl.h index f04f3112..efe0d43 100644 --- a/chrome/utility/local_discovery/service_discovery_client_impl.h +++ b/chrome/utility/local_discovery/service_discovery_client_impl.h @@ -212,6 +212,10 @@ class LocalDomainResolverImpl : public LocalDomainResolver { scoped_ptr<net::MDnsTransaction> CreateTransaction(uint16 type); + bool IsSuccess(); + + void SendResolvedAddresses(); + std::string domain_; net::AddressFamily address_family_; IPAddressCallback callback_; @@ -219,10 +223,15 @@ class LocalDomainResolverImpl : public LocalDomainResolver { scoped_ptr<net::MDnsTransaction> transaction_a_; scoped_ptr<net::MDnsTransaction> transaction_aaaa_; - int transaction_failures_; + int transactions_finished_; net::MDnsClient* mdns_client_; + net::IPAddressNumber address_ipv4_; + net::IPAddressNumber address_ipv6_; + + base::CancelableCallback<void()> timeout_callback_; + DISALLOW_COPY_AND_ASSIGN(LocalDomainResolverImpl); }; diff --git a/chrome/utility/local_discovery/service_discovery_message_handler.cc b/chrome/utility/local_discovery/service_discovery_message_handler.cc index e6c84dd..d506c2b 100644 --- a/chrome/utility/local_discovery/service_discovery_message_handler.cc +++ b/chrome/utility/local_discovery/service_discovery_message_handler.cc @@ -135,10 +135,11 @@ void SendServiceUpdated(uint64 id, ServiceWatcher::UpdateType update, } void SendLocalDomainResolved(uint64 id, bool success, - const net::IPAddressNumber& address) { + const net::IPAddressNumber& address_ipv4, + const net::IPAddressNumber& address_ipv6) { content::UtilityThread::Get()->Send( new LocalDiscoveryHostMsg_LocalDomainResolverCallback( - id, success, address)); + id, success, address_ipv4, address_ipv6)); } } // namespace @@ -381,10 +382,13 @@ void ServiceDiscoveryMessageHandler::OnServiceResolved( void ServiceDiscoveryMessageHandler::OnLocalDomainResolved( uint64 id, bool success, - const net::IPAddressNumber& address) { + const net::IPAddressNumber& address_ipv4, + const net::IPAddressNumber& address_ipv6) { DCHECK(service_discovery_client_); utility_task_runner_->PostTask(FROM_HERE, base::Bind(&SendLocalDomainResolved, - id, success, address)); + id, success, + address_ipv4, + address_ipv6)); } diff --git a/chrome/utility/local_discovery/service_discovery_message_handler.h b/chrome/utility/local_discovery/service_discovery_message_handler.h index 35c6b03..917d525 100644 --- a/chrome/utility/local_discovery/service_discovery_message_handler.h +++ b/chrome/utility/local_discovery/service_discovery_message_handler.h @@ -87,7 +87,8 @@ class ServiceDiscoveryMessageHandler : public chrome::UtilityMessageHandler { // Is called by LocalDomainResolver as callback. void OnLocalDomainResolved(uint64 id, bool success, - const net::IPAddressNumber& address); + const net::IPAddressNumber& address_ipv4, + const net::IPAddressNumber& address_ipv6); ServiceWatchers service_watchers_; ServiceResolvers service_resolvers_; |