summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions
diff options
context:
space:
mode:
authorwez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-07 11:48:45 +0000
committerwez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-07 11:48:45 +0000
commit25499833bc2a02a665c211c208af8da17bc31191 (patch)
treeb0f727e98336b8e05f4132194e3b37031e8702ec /chrome/browser/extensions
parentf8c47b92b86783a6df24b593f6237f5fb0b78eec (diff)
downloadchromium_src-25499833bc2a02a665c211c208af8da17bc31191.zip
chromium_src-25499833bc2a02a665c211c208af8da17bc31191.tar.gz
chromium_src-25499833bc2a02a665c211c208af8da17bc31191.tar.bz2
Revert "Bind to all interfaces for chrome.dial."
We suspect that crrev.com/227854 may be responsible for a regression in DIAL discovery. TBR=mfoltz BUG=315258 Review URL: https://codereview.chromium.org/63083003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@233581 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions')
-rw-r--r--chrome/browser/extensions/api/dial/dial_service.cc93
-rw-r--r--chrome/browser/extensions/api/dial/dial_service.h5
-rw-r--r--chrome/browser/extensions/api/dial/dial_service_unittest.cc2
3 files changed, 92 insertions, 8 deletions
diff --git a/chrome/browser/extensions/api/dial/dial_service.cc b/chrome/browser/extensions/api/dial/dial_service.cc
index 75c6aee..2caf51c 100644
--- a/chrome/browser/extensions/api/dial/dial_service.cc
+++ b/chrome/browser/extensions/api/dial/dial_service.cc
@@ -91,19 +91,64 @@ std::string BuildRequest() {
"MAN:\"ssdp:discover\"\r\n"
"MX:%d\r\n"
"ST:%s\r\n"
- "USER-AGENT:%s %s\r\n"
+ "USER-AGENT:%s/%s %s\r\n"
"\r\n",
kDialRequestAddress,
kDialRequestPort,
kDialResponseTimeoutSecs,
kDialSearchType,
- version.ProductNameAndVersionForUserAgent().c_str(),
+ version.Name().c_str(),
+ version.Version().c_str(),
version.OSType().c_str()));
// 1500 is a good MTU value for most Ethernet LANs.
DCHECK(request.size() <= 1500);
return request;
}
+void GetNetworkListOnFileThread(
+ const scoped_refptr<base::MessageLoopProxy>& loop,
+ const base::Callback<void(const NetworkInterfaceList& networks)>& cb) {
+ NetworkInterfaceList list;
+ bool success = net::GetNetworkList(&list);
+ if (!success)
+ DVLOG(1) << "Could not retrieve network list!";
+
+ loop->PostTask(FROM_HERE, base::Bind(cb, list));
+}
+
+#if defined(OS_CHROMEOS)
+IPAddressNumber GetBestBindAddressByType(
+ const chromeos::NetworkTypePattern& type) {
+ const chromeos::NetworkState* state = chromeos::NetworkHandler::Get()
+ ->network_state_handler()->ConnectedNetworkByType(type);
+ IPAddressNumber bind_ip_address;
+ if (!state ||
+ !net::ParseIPLiteralToNumber(state->ip_address(), &bind_ip_address)) {
+ return IPAddressNumber();
+ }
+ if (bind_ip_address.size() != net::kIPv4AddressSize) {
+ LOG(ERROR) << "Default network is not using IPv4.";
+ return IPAddressNumber();
+ }
+
+ DVLOG(1) << "Found " << state->type() << ", " << state->name() << ":"
+ << state->ip_address();
+ return bind_ip_address;
+}
+
+// Returns the IP address of the preferred interface to bind the socket. This
+// ChromeOS version can prioritize wifi and ethernet interfaces.
+IPAddressNumber GetBestBindAddressChromeOS() {
+ IPAddressNumber bind_ip_address =
+ GetBestBindAddressByType(chromeos::NetworkTypePattern::Ethernet());
+ if (bind_ip_address.empty()) {
+ bind_ip_address =
+ GetBestBindAddressByType(chromeos::NetworkTypePattern::WiFi());
+ }
+ return bind_ip_address;
+}
+#endif
+
} // namespace
DialServiceImpl::DialServiceImpl(net::NetLog* net_log)
@@ -163,20 +208,36 @@ void DialServiceImpl::StartDiscovery() {
if (socket_.get())
return;
- BindSocketAndSendRequest();
+#if defined(OS_CHROMEOS)
+ // The ChromeOS specific version of getting network interfaces does not
+ // require trampolining to another thread, and contains additional interface
+ // information such as interface types (i.e. wifi vs cellular).
+ BindSocketAndSendRequest(GetBestBindAddressChromeOS());
+#else
+ BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind(
+ &GetNetworkListOnFileThread,
+ base::MessageLoopProxy::current(), base::Bind(
+ &DialServiceImpl::SendNetworkList, AsWeakPtr())));
+#endif
}
-bool DialServiceImpl::BindSocketAndSendRequest() {
+bool DialServiceImpl::BindSocketAndSendRequest(
+ const IPAddressNumber& bind_ip_address) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(!socket_.get());
+ if (bind_ip_address.size() == 0) {
+ DVLOG(1) << "Could not find a valid interface to bind.";
+ FinishDiscovery();
+ return false;
+ }
+
net::RandIntCallback rand_cb = base::Bind(&base::RandInt);
socket_.reset(new UDPSocket(net::DatagramSocket::RANDOM_BIND,
rand_cb,
net_log_,
net_log_source_));
socket_->AllowBroadcast();
- socket_->AllowAddressReuse();
// Schedule a timer to finish the discovery process (and close the socket).
if (finish_delay_ > TimeDelta::FromSeconds(0)) {
@@ -187,7 +248,7 @@ bool DialServiceImpl::BindSocketAndSendRequest() {
}
// 0 means bind a random port
- IPEndPoint address(IPAddressNumber(net::kIPv4AddressSize), 0);
+ IPEndPoint address(bind_ip_address, 0);
if (!CheckResult("Bind", socket_->Bind(address)))
return false;
@@ -381,6 +442,26 @@ bool DialServiceImpl::ParseResponse(const std::string& response,
return true;
}
+void DialServiceImpl::SendNetworkList(const NetworkInterfaceList& networks) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ IPAddressNumber bind_ip_address;
+ // Returns the first IPv4 address found. If there is a need for discovery
+ // across multiple networks, we could manage multiple sockets.
+
+ // TODO(mfoltz): Support IPV6 multicast. http://crbug.com/165286
+ for (NetworkInterfaceList::const_iterator iter = networks.begin();
+ iter != networks.end(); ++iter) {
+ DVLOG(1) << "Found " << iter->name << ", "
+ << net::IPAddressToString(iter->address);
+ if (iter->address.size() == net::kIPv4AddressSize) {
+ bind_ip_address = (*iter).address;
+ break;
+ }
+ }
+
+ BindSocketAndSendRequest(bind_ip_address);
+}
+
void DialServiceImpl::FinishDiscovery() {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(discovery_active_);
diff --git a/chrome/browser/extensions/api/dial/dial_service.h b/chrome/browser/extensions/api/dial/dial_service.h
index 830d3fa..5c0dc0d 100644
--- a/chrome/browser/extensions/api/dial/dial_service.h
+++ b/chrome/browser/extensions/api/dial/dial_service.h
@@ -116,7 +116,7 @@ class DialServiceImpl : public DialService,
// Establishes the UDP socket that is used for requests and responses,
// establishes a read callback on the socket, and sends the first discovery
// request. Returns true if successful.
- bool BindSocketAndSendRequest();
+ bool BindSocketAndSendRequest(const net::IPAddressNumber& bind_ip_address);
// Sends a single discovery request over the socket.
void SendOneRequest();
@@ -124,6 +124,9 @@ class DialServiceImpl : public DialService,
// Callback invoked for socket writes.
void OnSocketWrite(int result);
+ // Send the network list to IO thread.
+ void SendNetworkList(const net::NetworkInterfaceList& list);
+
// Establishes the callback to read from the socket. Returns true if
// successful.
bool ReadSocket();
diff --git a/chrome/browser/extensions/api/dial/dial_service_unittest.cc b/chrome/browser/extensions/api/dial/dial_service_unittest.cc
index 8d80753..4a23d93 100644
--- a/chrome/browser/extensions/api/dial/dial_service_unittest.cc
+++ b/chrome/browser/extensions/api/dial/dial_service_unittest.cc
@@ -62,7 +62,7 @@ TEST_F(DialServiceTest, TestSendMultipleRequests) {
dial_service_.discovery_active_ = true;
EXPECT_CALL(mock_observer_, OnDiscoveryRequest(A<DialService*>())).Times(4);
EXPECT_CALL(mock_observer_, OnDiscoveryFinished(A<DialService*>())).Times(1);
- dial_service_.BindSocketAndSendRequest();
+ dial_service_.BindSocketAndSendRequest(mock_ip_);
loop.RunUntilIdle();
dial_service_.FinishDiscovery();
}