shill: resolver: Use (even) smaller DNS timeout

Use the new glibc facility for sub-second timeouts, and choose
300 milliseconds for the timeout.  However, only do this by
default for Ethernet and WiFi networks, since VPN networks
in particular have trouble with this configuration (due to many
name servers and search domains, as well as the additional
latency inherent to such networks).  Also, increase the number
of attempts, so we still spend a reasonable amount of time
overall waiting for a DNS response.

Provide a means to change which technologies are setup in this
manner.

BUG=chromium-os:29124
TEST=Manual: Install connection manager, verify via strace that
gethostbyname now waits 300 ms, and retries 15 times per trial (*).
Ensure Chromium continues to work correctly under light loads.
Also, connect via Verizon and VPN and ensure DNS parameters
are back to the long timeout.
List manager properties and ensure it says "ethernet,wifi" for
ShortDNSTimeoutTechnologies and that this is saved out to the
profile.
New unit tests.
CQ-DEPENDS=Ib9ffc59bbfcd5bf3f57d146965c5a43a936348f8

*: Each trial consists of a nameserver / IP address pair, so
for example, if we have IPv6 connectivity and have two "server"
entries in resolv.conf, we first do 30 tries of IPv6 requests,
alternating between the two servers, then another 30 alternating
IPv4 requests between them.  This was tested by intentionally
making the DNS server unreachable and instrumenting the gethostbyname
request via strace.

Change-Id: Idd331b4a9fcf96d457ab9959537aefcb86328e12
Reviewed-on: https://gerrit.chromium.org/gerrit/26493
Commit-Ready: Paul Stewart <pstew@chromium.org>
Reviewed-by: Paul Stewart <pstew@chromium.org>
Tested-by: Paul Stewart <pstew@chromium.org>
diff --git a/resolver_unittest.cc b/resolver_unittest.cc
index 0885e44..31501e2 100644
--- a/resolver_unittest.cc
+++ b/resolver_unittest.cc
@@ -29,7 +29,12 @@
   "nameserver 8.8.8.8\n"
   "nameserver 8.8.9.9\n"
   "search chromium.org google.com\n"
-  "options single-request timeout:1\n";
+  "options single-request timeout:1 attempts:3\n";
+const char kExpectedShortTimeoutOutput[] =
+  "nameserver 8.8.8.8\n"
+  "nameserver 8.8.9.9\n"
+  "search chromium.org google.com\n"
+  "options single-request timeout-ms:300 attempts:15\n";
 }  // namespace {}
 
 class ResolverTest : public Test {
@@ -75,13 +80,36 @@
   properties.domain_search.push_back(kSearchDomain1);
   ipconfig->UpdateProperties(properties, true);
 
-  EXPECT_TRUE(resolver_->SetDNSFromIPConfig(ipconfig));
+  EXPECT_TRUE(resolver_->SetDNSFromIPConfig(
+      ipconfig, Resolver::kDefaultTimeout));
   EXPECT_TRUE(file_util::PathExists(path_));
   EXPECT_EQ(kExpectedOutput, ReadFile());
 
   EXPECT_TRUE(resolver_->ClearDNS());
 }
 
+TEST_F(ResolverTest, ShortTimeout) {
+  EXPECT_FALSE(file_util::PathExists(path_));
+  EXPECT_TRUE(resolver_->ClearDNS());
+
+  // Add DNS info from an IPConfig entry
+  MockControl control;
+  IPConfigRefPtr ipconfig(new IPConfig(&control, kTestDeviceName0));
+  IPConfig::Properties properties;
+  properties.dns_servers.push_back(kNameServer0);
+  properties.dns_servers.push_back(kNameServer1);
+  properties.domain_search.push_back(kSearchDomain0);
+  properties.domain_search.push_back(kSearchDomain1);
+  ipconfig->UpdateProperties(properties, true);
+
+  EXPECT_TRUE(resolver_->SetDNSFromIPConfig(
+      ipconfig, Resolver::kShortTimeout));
+  EXPECT_TRUE(file_util::PathExists(path_));
+  EXPECT_EQ(kExpectedShortTimeoutOutput, ReadFile());
+
+  EXPECT_TRUE(resolver_->ClearDNS());
+}
+
 TEST_F(ResolverTest, Empty) {
   EXPECT_FALSE(file_util::PathExists(path_));
 
@@ -91,7 +119,8 @@
   IPConfig::Properties properties;
   ipconfig->UpdateProperties(properties, true);
 
-  EXPECT_TRUE(resolver_->SetDNSFromIPConfig(ipconfig));
+  EXPECT_TRUE(resolver_->SetDNSFromIPConfig(
+      ipconfig, Resolver::kDefaultTimeout));
   EXPECT_FALSE(file_util::PathExists(path_));
 }