Remove DNS64 detection code from clatd.

This has been unused since Q, when the NAT64 prefix started being
detected and passed in by netd instead. Many things depend on the
prefix being correct, including clat BPF offload and DNS64
synthesis, and doing DNS64 detection in clatd provides no way to
make these work.  Additionally, R now supports getting the NAT64
prefix via the RA, which makes DNS64 detection in clatd even less
useful.

This CL removes all the DNS64 detection code. The new code parses
the prefix in main.c, and if the prefix is not valid, refuses to
start.

This also lets us remove the -n <netid> parameter which was only
used for DNS64 detection.

It also removes a dependency on dnsproxyd_protocol_headers, which
should be depended on by as few parts of the system as possible.

Test: m
Bug: 144730808
Bug: 151895202
Test: IPv6-only wifi continues to work
Change-Id: I892f364d6cbfe76277686387e35c04d3d6eb5ecc
diff --git a/Android.bp b/Android.bp
index 8585780..bff97d3 100644
--- a/Android.bp
+++ b/Android.bp
@@ -10,11 +10,10 @@
         "-Wno-address-of-packed-member",
     ],
 
-    // For NETID_UNSET and MARK_UNSET.
-    include_dirs: ["bionic/libc/dns/include"],
-
-    // For NETID_USE_LOCAL_NAMESERVERS.
-    header_libs: ["dnsproxyd_protocol_headers"],
+    // For MARK_UNSET.
+    header_libs: [
+        "libnetd_client_headers"
+    ],
 }
 
 // Code used both by the daemon and by unit tests.
@@ -23,7 +22,6 @@
     srcs: [
         "config.c",
         "clatd.c",
-        "dns64.c",
         "dump.c",
         "getaddr.c",
         "icmp.c",
diff --git a/clatd.c b/clatd.c
index 54fc2f7..3f9dc71 100644
--- a/clatd.c
+++ b/clatd.c
@@ -39,14 +39,14 @@
 #include <sys/capability.h>
 #include <sys/uio.h>
 
-#include <private/android_filesystem_config.h>
+#include <netid_client.h>                       // For MARK_UNSET.
+#include <private/android_filesystem_config.h>  // For AID_CLAT.
 
 #include "clatd.h"
 #include "config.h"
 #include "dump.h"
 #include "getaddr.h"
 #include "logging.h"
-#include "resolv_netid.h"
 #include "ring.h"
 #include "setif.h"
 #include "translate.h"
@@ -388,18 +388,23 @@
  * reads the configuration and applies it to the interface
  *   uplink_interface - network interface to use to reach the ipv6 internet
  *   plat_prefix      - PLAT prefix to use
+ *   v4_addr          - the v4 address to use on the tunnel interface
+ *   v6_addr          - the v6 address to use on the native interface
  *   tunnel           - tun device data
- *   net_id           - NetID to use, NETID_UNSET indicates use of default network
  *   mark             - the socket mark to use for the sending raw socket
  */
 void configure_interface(const char *uplink_interface, const char *plat_prefix, const char *v4_addr,
-                         const char *v6_addr, struct tun_data *tunnel, unsigned net_id,
-                         uint32_t mark) {
-  if (!read_config("/system/etc/clatd.conf", uplink_interface, plat_prefix, net_id)) {
+                         const char *v6_addr, struct tun_data *tunnel, uint32_t mark) {
+  if (!read_config("/system/etc/clatd.conf", uplink_interface)) {
     logmsg(ANDROID_LOG_FATAL, "read_config failed");
     exit(1);
   }
 
+  if (!plat_prefix || inet_pton(AF_INET6, plat_prefix, &Global_Clatd_Config.plat_subnet) <= 0) {
+    logmsg(ANDROID_LOG_FATAL, "invalid IPv6 address specified for plat prefix: %s", plat_prefix);
+    exit(1);
+  }
+
   int mtu = detect_mtu(&Global_Clatd_Config.plat_subnet, htonl(0x08080808), mark);
   // clamp to minimum ipv6 mtu - this probably cannot ever trigger
   if (mtu < 1280) mtu = 1280;
diff --git a/clatd.conf b/clatd.conf
index aef9c75..1025fb2 100644
--- a/clatd.conf
+++ b/clatd.conf
@@ -11,10 +11,3 @@
 # which allows up to 8 clat daemons (.4, .5, .6, .7, .0, .1, .2, .3).
 ipv4_local_subnet 192.0.0.4
 ipv4_local_prefixlen 29
-
-# get the plat_subnet from dns lookups (requires DNS64)
-plat_from_dns64 yes
-
-# plat subnet to send ipv4 traffic to. This is a /96 subnet.
-# This setting only makes sense with: plat_from_dns64 no
-#plat_subnet 2001:db8:1:2:3:4::
diff --git a/clatd.h b/clatd.h
index e1d28a7..a3f9326 100644
--- a/clatd.h
+++ b/clatd.h
@@ -45,7 +45,7 @@
                                 const char *src_addr);
 int detect_mtu(const struct in6_addr *plat_subnet, uint32_t plat_suffix, uint32_t mark);
 void configure_interface(const char *uplink_interface, const char *plat_prefix, const char *v4_addr,
-                         const char *v6, struct tun_data *tunnel, unsigned net_id, uint32_t mark);
+                         const char *v6, struct tun_data *tunnel, uint32_t mark);
 void event_loop(struct tun_data *tunnel);
 
 /* function: parse_int
diff --git a/config.c b/config.c
index 1c1a1f7..db0abc8 100644
--- a/config.c
+++ b/config.c
@@ -30,7 +30,6 @@
 
 #include "clatd.h"
 #include "config.h"
-#include "dns64.h"
 #include "getaddr.h"
 #include "logging.h"
 
@@ -158,35 +157,6 @@
  */
 int ipv6_prefix_equal(struct in6_addr *a1, struct in6_addr *a2) { return !memcmp(a1, a2, 8); }
 
-/* function: dns64_detection
- * does dns lookups to set the plat subnet or exits on failure, waits forever for a dns response
- * with a query backoff timer
- *   net_id - (optional) netId to use, NETID_UNSET indicates use of default network
- */
-void dns64_detection(unsigned net_id) {
-  int backoff_sleep, status;
-  struct in6_addr tmp_ptr;
-
-  backoff_sleep = 1;
-
-  while (1) {
-    status = plat_prefix(DNS64_DETECTION_HOSTNAME, net_id, &tmp_ptr);
-    if (status > 0) {
-      memcpy(&Global_Clatd_Config.plat_subnet, &tmp_ptr, sizeof(struct in6_addr));
-      return;
-    }
-    logmsg(ANDROID_LOG_WARN, "dns64_detection -- error, sleeping for %d seconds", backoff_sleep);
-    sleep(backoff_sleep);
-    backoff_sleep *= 2;
-    if (backoff_sleep >= 1800) {
-      // Scale down to one DNS query per half hour. Unnecessary DNS queries waste power, and the
-      // benefit is minimal (basically, only limited to the case where a network goes from IPv6-only
-      // to IPv6 with NAT64).
-      backoff_sleep = 1800;
-    }
-  }
-}
-
 /* function: gen_random_iid
  * picks a random interface ID that is checksum neutral with the IPv4 address and the NAT64 prefix
  *   myaddr            - IPv6 address to write to
@@ -293,13 +263,9 @@
  * failure, 1 on success
  *   file             - filename to parse
  *   uplink_interface - interface to use to reach the internet and supplier of address space
- *   plat_prefix      - (optional) plat prefix to use, otherwise follow config file
- *   net_id           - (optional) netId to use, NETID_UNSET indicates use of default network
  */
-int read_config(const char *file, const char *uplink_interface, const char *plat_prefix,
-                unsigned net_id) {
+int read_config(const char *file, const char *uplink_interface) {
   cnode *root   = config_node("", "");
-  void *tmp_ptr = NULL;
   unsigned flags;
 
   if (!root) {
@@ -326,27 +292,6 @@
                            &Global_Clatd_Config.ipv4_local_prefixlen))
     goto failed;
 
-  if (plat_prefix) {  // plat subnet is coming from the command line
-    if (inet_pton(AF_INET6, plat_prefix, &Global_Clatd_Config.plat_subnet) <= 0) {
-      logmsg(ANDROID_LOG_FATAL, "invalid IPv6 address specified for plat prefix: %s", plat_prefix);
-      goto failed;
-    }
-  } else {
-    tmp_ptr = (void *)config_item_str(root, "plat_from_dns64", "yes");
-    if (!tmp_ptr || strcmp(tmp_ptr, "no") == 0) {
-      free(tmp_ptr);
-
-      if (!config_item_ip6(root, "plat_subnet", NULL, &Global_Clatd_Config.plat_subnet)) {
-        logmsg(ANDROID_LOG_FATAL, "plat_from_dns64 disabled, but no plat_subnet specified");
-        goto failed;
-      }
-    } else {
-      free(tmp_ptr);
-
-      dns64_detection(net_id);
-    }
-  }
-
   if (!config_item_ip6(root, "ipv6_host_id", "::", &Global_Clatd_Config.ipv6_host_id)) goto failed;
 
   /* In order to prevent multiple devices attempting to use the same clat address, never use a
diff --git a/config.h b/config.h
index d5c4399..c47fc88 100644
--- a/config.h
+++ b/config.h
@@ -23,7 +23,6 @@
 
 #define DEFAULT_IPV4_LOCAL_SUBNET "192.0.0.4"
 #define DEFAULT_IPV4_LOCAL_PREFIXLEN "29"
-#define DNS64_DETECTION_HOSTNAME "ipv4only.arpa"
 
 struct clat_config {
   struct in6_addr ipv6_local_subnet;
@@ -37,8 +36,7 @@
 
 extern struct clat_config Global_Clatd_Config;
 
-int read_config(const char *file, const char *uplink_interface, const char *plat_prefix,
-                unsigned net_id);
+int read_config(const char *file, const char *uplink_interface);
 void config_generate_local_ipv6_subnet(struct in6_addr *interface_ip);
 in_addr_t config_select_ipv4_address(const struct in_addr *ip, int16_t prefixlen);
 int ipv6_prefix_equal(struct in6_addr *a1, struct in6_addr *a2);
diff --git a/dns64.c b/dns64.c
deleted file mode 100644
index 66cb7dc..0000000
--- a/dns64.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2011 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * dns64.c - find the nat64 prefix with a dns64 lookup
- */
-
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <strings.h>
-#include <sys/socket.h>
-#include <unistd.h>
-
-#include <DnsProxydProtocol.h>  // NETID_USE_LOCAL_NAMESERVERS
-#include "dns64.h"
-#include "logging.h"
-#include "resolv_netid.h"
-
-/* function: plat_prefix
- * looks up an ipv4-only hostname and looks for a nat64 /96 prefix, returns 1 on success, 0 on
- * failure
- *   ipv4_name  - name to lookup
- *   net_id     - (optional) netId to use, NETID_UNSET indicates use of default network
- *   prefix     - the plat /96 prefix
- */
-int plat_prefix(const char *ipv4_name, unsigned net_id, struct in6_addr *prefix) {
-  const struct addrinfo hints = {
-    .ai_family = AF_INET6,
-  };
-  int status;
-  struct addrinfo *result = NULL;
-  struct in6_addr plat_addr;
-  char plat_addr_str[INET6_ADDRSTRLEN];
-
-  logmsg(ANDROID_LOG_INFO, "Detecting NAT64 prefix from DNS...");
-
-  // Be sure to query local DNS64 servers, bypassing Private DNS (if enabled).
-  if (net_id != NETID_UNSET) {
-    net_id |= NETID_USE_LOCAL_NAMESERVERS;
-  }
-
-  status = android_getaddrinfofornet(ipv4_name, NULL, &hints, net_id, MARK_UNSET, &result);
-  if (status != 0 || result == NULL) {
-    logmsg(ANDROID_LOG_ERROR, "plat_prefix/dns(%s) status = %d/%s", ipv4_name, status,
-           gai_strerror(status));
-    return 0;
-  }
-
-  // Use only the first result.  If other records are present, possibly with
-  // differing DNS64 prefixes they are ignored (there is very little sensible
-  // that could be done with them at this time anyway).
-
-  if (result->ai_family != AF_INET6) {
-    logmsg(ANDROID_LOG_WARN, "plat_prefix/unexpected address family: %d", result->ai_family);
-    return 0;
-  }
-  plat_addr = ((struct sockaddr_in6 *)result->ai_addr)->sin6_addr;
-  // Only /96 DNS64 prefixes are supported at this time.
-  plat_addr.s6_addr32[3] = 0;
-  freeaddrinfo(result);
-
-  logmsg(ANDROID_LOG_INFO, "Detected NAT64 prefix %s/96",
-         inet_ntop(AF_INET6, &plat_addr, plat_addr_str, sizeof(plat_addr_str)));
-  *prefix = plat_addr;
-  return 1;
-}
diff --git a/dns64.h b/dns64.h
deleted file mode 100644
index f5eaea8..0000000
--- a/dns64.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright 2011 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * dns64.h - find the nat64 prefix with a dns64 lookup
- */
-#ifndef __DNS64_H__
-#define __DNS64_H__
-
-int plat_prefix(const char *ipv4_name, unsigned net_id, struct in6_addr *prefix);
-
-#endif
diff --git a/main.c b/main.c
index e973bf3..c4834d9 100644
--- a/main.c
+++ b/main.c
@@ -16,6 +16,7 @@
  * main.c - main function
  */
 
+#include <arpa/inet.h>
 #include <errno.h>
 #include <netinet/in.h>
 #include <stdint.h>
@@ -24,7 +25,7 @@
 #include <sys/capability.h>
 #include <unistd.h>
 
-#include "resolv_netid.h"
+#include <netid_client.h>  // For MARK_UNSET.
 
 #include "clatd.h"
 #include "common.h"
@@ -44,7 +45,6 @@
   printf("-p [plat prefix]\n");
   printf("-4 [IPv4 address]\n");
   printf("-6 [IPv6 address]\n");
-  printf("-n [NetId]\n");
   printf("-m [socket mark]\n");
   printf("-t [tun file descriptor number]\n");
 }
@@ -55,13 +55,12 @@
 int main(int argc, char **argv) {
   struct tun_data tunnel;
   int opt;
-  char *uplink_interface = NULL, *plat_prefix = NULL, *net_id_str = NULL, *mark_str = NULL;
+  char *uplink_interface = NULL, *plat_prefix = NULL, *mark_str = NULL;
   char *v4_addr = NULL, *v6_addr = NULL, *tunfd_str = NULL;
-  unsigned net_id = NETID_UNSET;
   uint32_t mark   = MARK_UNSET;
   unsigned len;
 
-  while ((opt = getopt(argc, argv, "i:p:4:6:n:m:t:h")) != -1) {
+  while ((opt = getopt(argc, argv, "i:p:4:6:m:t:h")) != -1) {
     switch (opt) {
       case 'i':
         uplink_interface = optarg;
@@ -75,9 +74,6 @@
       case '6':
         v6_addr = optarg;
         break;
-      case 'n':
-        net_id_str = optarg;
-        break;
       case 'm':
         mark_str = optarg;
         break;
@@ -98,11 +94,6 @@
     exit(1);
   }
 
-  if (net_id_str != NULL && !parse_unsigned(net_id_str, &net_id)) {
-    logmsg(ANDROID_LOG_FATAL, "invalid NetID %s", net_id_str);
-    exit(1);
-  }
-
   if (mark_str != NULL && !parse_unsigned(mark_str, &mark)) {
     logmsg(ANDROID_LOG_FATAL, "invalid mark %s", mark_str);
     exit(1);
@@ -123,10 +114,10 @@
     exit(1);
   }
 
-  logmsg(ANDROID_LOG_INFO, "Starting clat version %s on %s netid=%s mark=%s plat=%s v4=%s v6=%s",
-         CLATD_VERSION, uplink_interface, net_id_str ? net_id_str : "(none)",
-         mark_str ? mark_str : "(none)", plat_prefix ? plat_prefix : "(none)",
-         v4_addr ? v4_addr : "(none)", v6_addr ? v6_addr : "(none)");
+  logmsg(ANDROID_LOG_INFO, "Starting clat version %s on %s mark=%s plat=%s v4=%s v6=%s",
+         CLATD_VERSION, uplink_interface, mark_str ? mark_str : "(none)",
+         plat_prefix ? plat_prefix : "(none)", v4_addr ? v4_addr : "(none)",
+         v6_addr ? v6_addr : "(none)");
 
   // run under a regular user but keep needed capabilities
   drop_root_but_keep_caps();
@@ -137,12 +128,7 @@
   // keeps only admin capability
   set_capability(1 << CAP_NET_ADMIN);
 
-  // When run from netd, the environment variable ANDROID_DNS_MODE is set to
-  // "local", but that only works for the netd process itself. Removing the
-  // following line causes XLAT failure in permissive mode.
-  unsetenv("ANDROID_DNS_MODE");
-
-  configure_interface(uplink_interface, plat_prefix, v4_addr, v6_addr, &tunnel, net_id, mark);
+  configure_interface(uplink_interface, plat_prefix, v4_addr, v6_addr, &tunnel, mark);
 
   // Drop all remaining capabilities.
   set_capability(0);