Merge "Support enable/disable dns forwarding of dnsmasq"
am: 9fedafaf24

Change-Id: Ic3b2ad037be80ff4ad3d3a7d08283c8d2177120c
diff --git a/server/Android.bp b/server/Android.bp
index 0911841..92c5b5c 100644
--- a/server/Android.bp
+++ b/server/Android.bp
@@ -101,7 +101,7 @@
         "libpcap",
         "libqtaguid",
         "libssl",
-        "netd_aidl_interface-V2-cpp",
+        "netd_aidl_interface-cpp",
         "netd_event_listener_interface-V1-cpp",
     ],
     header_libs: [
@@ -143,7 +143,7 @@
         "libselinux",
         "libsysutils",
         "libutils",
-        "netd_aidl_interface-V2-cpp",
+        "netd_aidl_interface-cpp",
         "netd_event_listener_interface-V1-cpp",
         "oemnetd_aidl_interface-cpp",
     ],
diff --git a/server/NetdNativeService.cpp b/server/NetdNativeService.cpp
index 31c62b9..9aec5e2 100644
--- a/server/NetdNativeService.cpp
+++ b/server/NetdNativeService.cpp
@@ -905,11 +905,16 @@
 }
 
 binder::Status NetdNativeService::tetherStart(const std::vector<std::string>& dhcpRanges) {
+    return tetherStartWithConfiguration(true, dhcpRanges);
+}
+
+binder::Status NetdNativeService::tetherStartWithConfiguration(
+        bool usingLegacyDnsProxy, const std::vector<std::string>& dhcpRanges) {
     NETD_LOCKING_RPC(gCtls->tetherCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
     if (dhcpRanges.size() % 2 == 1) {
         return statusFromErrcode(-EINVAL);
     }
-    int res = gCtls->tetherCtrl.startTethering(dhcpRanges);
+    int res = gCtls->tetherCtrl.startTethering(usingLegacyDnsProxy, dhcpRanges);
     return statusFromErrcode(res);
 }
 
diff --git a/server/NetdNativeService.h b/server/NetdNativeService.h
index 68c9886..8f9c40f 100644
--- a/server/NetdNativeService.h
+++ b/server/NetdNativeService.h
@@ -121,6 +121,8 @@
     binder::Status tetherGetStats(
             std::vector<android::net::TetherStatsParcel>* tetherStatsVec) override;
     binder::Status tetherStart(const std::vector<std::string>& dhcpRanges) override;
+    binder::Status tetherStartWithConfiguration(
+            bool usingLegacyDnsProxy, const std::vector<std::string>& dhcpRanges) override;
     binder::Status tetherStop() override;
     binder::Status tetherIsEnabled(bool* enabled) override;
     binder::Status tetherInterfaceAdd(const std::string& ifName) override;
diff --git a/server/TetherController.cpp b/server/TetherController.cpp
index 9d56b3e..c987d63 100644
--- a/server/TetherController.cpp
+++ b/server/TetherController.cpp
@@ -190,8 +190,15 @@
     return mForwardingRequests;
 }
 
-int TetherController::startTethering(int num_addrs, char **dhcp_ranges) {
-    if (mDaemonPid != 0) {
+int TetherController::startTethering(bool usingLegacyDnsProxy, int num_addrs, char** dhcp_ranges) {
+    if (!usingLegacyDnsProxy && num_addrs == 0) {
+        // Both DHCP and DnsProxy are disabled, we don't need to start dnsmasq
+        configureForTethering(true);
+        mIsTetheringStarted = true;
+        return 0;
+    }
+
+    if (mIsTetheringStarted) {
         ALOGE("Tethering already started");
         errno = EBUSY;
         return -errno;
@@ -230,8 +237,11 @@
             kDnsmasqUsername,
     };
 
-    // DHCP server will be disabled if num_addrs == 0 and no --dhcp-range is
-    // passed.
+    if (!usingLegacyDnsProxy) {
+        argVector.push_back("--port=0");
+    }
+
+    // DHCP server will be disabled if num_addrs == 0 and no --dhcp-range is passed.
     for (int addrIndex = 0; addrIndex < num_addrs; addrIndex += 2) {
         argVector.push_back(StringPrintf("--dhcp-range=%s,%s,1h", dhcp_ranges[addrIndex],
                                          dhcp_ranges[addrIndex + 1]));
@@ -286,6 +296,7 @@
     mDaemonPid = pid;
     mDaemonFd = pipeWrite.release();
     configureForTethering(true);
+    mIsTetheringStarted = true;
     applyDnsInterfaces();
     ALOGD("Tethering services running");
 
@@ -301,7 +312,8 @@
     return addrsCstrVec;
 }
 
-int TetherController::startTethering(const std::vector<std::string>& dhcpRanges) {
+int TetherController::startTethering(bool usingLegacyDnsProxy,
+                                     const std::vector<std::string>& dhcpRanges) {
     struct in_addr v4_addr;
     for (const auto& dhcpRange : dhcpRanges) {
         if (!inet_aton(dhcpRange.c_str(), &v4_addr)) {
@@ -309,17 +321,23 @@
         }
     }
     auto dhcp_ranges = toCstrVec(dhcpRanges);
-    return startTethering(dhcp_ranges.size(), dhcp_ranges.data());
+    return startTethering(usingLegacyDnsProxy, dhcp_ranges.size(), dhcp_ranges.data());
 }
 
 int TetherController::stopTethering() {
     configureForTethering(false);
 
-    if (mDaemonPid == 0) {
+    if (!mIsTetheringStarted) {
         ALOGE("Tethering already stopped");
         return 0;
     }
 
+    mIsTetheringStarted = false;
+    // dnsmasq is not started
+    if (mDaemonPid == 0) {
+        return 0;
+    }
+
     ALOGD("Stopping tethering services");
 
     kill(mDaemonPid, SIGTERM);
@@ -333,7 +351,7 @@
 }
 
 bool TetherController::isTetheringStarted() {
-    return (mDaemonPid == 0 ? false : true);
+    return mIsTetheringStarted;
 }
 
 // dnsmasq can't parse commands larger than this due to the fixed-size buffer
diff --git a/server/TetherController.h b/server/TetherController.h
index 0a04874..7f8ba06 100644
--- a/server/TetherController.h
+++ b/server/TetherController.h
@@ -43,6 +43,8 @@
     // some point since the controller was initialized.
     std::multimap<std::string, ForwardingDownstream> mFwdIfaces;
 
+    bool mIsTetheringStarted = false;
+
     // NetId to use for forwarded DNS queries. This may not be the default
     // network, e.g., in the case where we are tethering to a DUN APN.
     unsigned               mDnsNetId = 0;
@@ -73,8 +75,9 @@
     bool disableForwarding(const char* requester);
     const std::set<std::string>& getIpfwdRequesterList() const;
 
-    int startTethering(int num_addrs, char **dhcp_ranges);
-    int startTethering(const std::vector<std::string>& dhcpRanges);
+    //TODO: Clean up the overload function
+    int startTethering(bool isLegacyDnsProxy, int num_addrs, char** dhcp_ranges);
+    int startTethering(bool isLegacyDnsProxy, const std::vector<std::string>& dhcpRanges);
     int stopTethering();
     bool isTetheringStarted();
 
diff --git a/server/binder/android/net/INetd.aidl b/server/binder/android/net/INetd.aidl
index ec9bbc3..fdea52e 100644
--- a/server/binder/android/net/INetd.aidl
+++ b/server/binder/android/net/INetd.aidl
@@ -1194,4 +1194,18 @@
     * @return a IBinder object, it could be casted to oem specific interface.
     */
     IBinder getOemNetd();
+
+   /**
+    * Start tethering with given configuration
+    *
+    * @param usingLegacyDnsProxy, whether to enable or disable legacy DNS proxy server.
+    * @param dhcpRanges dhcp ranges to set.
+    *                   dhcpRanges might contain many addresss {addr1, addr2, aadr3, addr4...}
+    *                   Netd splits them into ranges: addr1-addr2, addr3-addr4, etc.
+    *                   An odd number of addrs will fail.
+    * @throws ServiceSpecificException in case of failure, with an error code indicating the
+    *         cause of the failure.
+    */
+    void tetherStartWithConfiguration(
+            boolean usingLegacyDnsProxy, in @utf8InCpp String[] dhcpRanges);
 }
diff --git a/tests/binder_test.cpp b/tests/binder_test.cpp
index ad954c7..02e9eaf 100644
--- a/tests/binder_test.cpp
+++ b/tests/binder_test.cpp
@@ -1992,22 +1992,30 @@
     std::vector<std::string> noDhcpRange = {};
     static const char dnsdName[] = "dnsmasq";
 
-    binder::Status status = mNetd->tetherStart(noDhcpRange);
-    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
-    expectProcessExists(dnsdName);
+    for (bool usingLegacyDnsProxy : {true, false}) {
+        binder::Status status =
+                mNetd->tetherStartWithConfiguration(usingLegacyDnsProxy, noDhcpRange);
+        EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
+        SCOPED_TRACE(StringPrintf("usingLegacyDnsProxy: %d", usingLegacyDnsProxy));
+        if (usingLegacyDnsProxy == true) {
+            expectProcessExists(dnsdName);
+        } else {
+            expectProcessDoesNotExist(dnsdName);
+        }
 
-    bool tetherEnabled;
-    status = mNetd->tetherIsEnabled(&tetherEnabled);
-    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
-    EXPECT_TRUE(tetherEnabled);
+        bool tetherEnabled;
+        status = mNetd->tetherIsEnabled(&tetherEnabled);
+        EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
+        EXPECT_TRUE(tetherEnabled);
 
-    status = mNetd->tetherStop();
-    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
-    expectProcessDoesNotExist(dnsdName);
+        status = mNetd->tetherStop();
+        EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
+        expectProcessDoesNotExist(dnsdName);
 
-    status = mNetd->tetherIsEnabled(&tetherEnabled);
-    EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
-    EXPECT_FALSE(tetherEnabled);
+        status = mNetd->tetherIsEnabled(&tetherEnabled);
+        EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
+        EXPECT_FALSE(tetherEnabled);
+    }
 }
 
 TEST_F(BinderTest, TetherInterfaceAddRemoveList) {