From 27da0ad045ce9e386997bcd3d063ced897521c76 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Mon, 1 Jun 2020 12:15:20 +0900 Subject: 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 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 --- Android.bp | 10 ++++---- clatd.c | 17 ++++++++----- clatd.conf | 7 ------ clatd.h | 2 +- config.c | 57 +------------------------------------------- config.h | 4 +--- dns64.c | 80 -------------------------------------------------------------- dns64.h | 23 ------------------ main.c | 32 +++++++------------------ 9 files changed, 27 insertions(+), 205 deletions(-) delete mode 100644 dns64.c delete mode 100644 dns64.h diff --git a/Android.bp b/Android.bp index 8585780..bff97d3 100644 --- a/Android.bp +++ b/Android.bp @@ -10,11 +10,10 @@ cc_defaults { "-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 @@ filegroup { 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 #include -#include +#include // For MARK_UNSET. +#include // 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 @@ int detect_mtu(const struct in6_addr *plat_subnet, uint32_t plat_suffix, uint32_ * 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 @@ ipv6_host_id :: # 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 @@ int configure_clat_ipv6_address(const struct tun_data *tunnel, const char *inter 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 @@ struct in6_addr *config_item_ip6(cnode *root, const char *item_name, const char */ 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 @@ void config_generate_local_ipv6_subnet(struct in6_addr *interface_ip) { * 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 @@ int read_config(const char *file, const char *uplink_interface, const char *plat &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 @@ struct clat_config { 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 -#include -#include -#include -#include -#include -#include -#include - -#include // 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 #include #include #include @@ -24,7 +25,7 @@ #include #include -#include "resolv_netid.h" +#include // For MARK_UNSET. #include "clatd.h" #include "common.h" @@ -44,7 +45,6 @@ void print_help() { 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 @@ void print_help() { 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 @@ int main(int argc, char **argv) { case '6': v6_addr = optarg; break; - case 'n': - net_id_str = optarg; - break; case 'm': mark_str = optarg; break; @@ -98,11 +94,6 @@ int main(int argc, char **argv) { 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 @@ int main(int argc, char **argv) { 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 @@ int main(int argc, char **argv) { // 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); -- cgit v1.2.3