From 247dd7199b4e89c6a974794056b468bfac5f0e51 Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Fri, 30 May 2014 13:19:10 -0400 Subject: Make DNS request for plat prefix detection network specific. When plat prefix detection is done on a non-default network it must use the network specific version of getaddrinfo() so the plat prefix corresponds to the particular network. The network is specified to clatd via a NetID command line argument. (cherry picked from commit a1c871c8efad6c0b69e27d3b85e82a27e282b8be) Change-Id: I270c5afc4b445cf20e95fd3e58eada6bc24b16ef --- Android.mk | 2 +- clatd.c | 25 ++++++++++++++++++++----- config.c | 11 +++++++---- config.h | 3 ++- dns64.c | 10 ++++++---- dns64.h | 2 +- 6 files changed, 37 insertions(+), 16 deletions(-) diff --git a/Android.mk b/Android.mk index 72fc0f9..f94acdf 100644 --- a/Android.mk +++ b/Android.mk @@ -4,7 +4,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:=clatd.c dump.c checksum.c translate.c icmp.c ipv4.c ipv6.c config.c dns64.c logging.c getaddr.c getroute.c netlink_callbacks.c netlink_msg.c setif.c setroute.c mtu.c LOCAL_CFLAGS := -Wall -Werror -Wunused-parameter -LOCAL_C_INCLUDES := external/libnl/include +LOCAL_C_INCLUDES := external/libnl/include bionic/libc/dns/include LOCAL_STATIC_LIBRARIES := libnl LOCAL_SHARED_LIBRARIES := libcutils liblog diff --git a/clatd.c b/clatd.c index 63c4d6d..7b8e43f 100644 --- a/clatd.c +++ b/clatd.c @@ -42,6 +42,7 @@ #include "clatd.h" #include "config.h" #include "logging.h" +#include "resolv_netid.h" #include "setif.h" #include "setroute.h" #include "mtu.h" @@ -252,11 +253,12 @@ void drop_root() { * uplink_interface - network interface to use to reach the ipv6 internet * plat_prefix - PLAT prefix to use * tunnel - tun device data + * net_id - NetID to use, NETID_UNSET indicates use of default network */ -void configure_interface(const char *uplink_interface, const char *plat_prefix, struct tun_data *tunnel) { +void configure_interface(const char *uplink_interface, const char *plat_prefix, struct tun_data *tunnel, unsigned net_id) { int error; - if(!read_config("/system/etc/clatd.conf", uplink_interface, plat_prefix)) { + if(!read_config("/system/etc/clatd.conf", uplink_interface, plat_prefix, net_id)) { logmsg(ANDROID_LOG_FATAL,"read_config failed"); exit(1); } @@ -374,6 +376,7 @@ void print_help() { printf("android-clat arguments:\n"); printf("-i [uplink interface]\n"); printf("-p [plat prefix]\n"); + printf("-n [NetId]\n"); } /* function: main @@ -382,12 +385,13 @@ void print_help() { int main(int argc, char **argv) { struct tun_data tunnel; int opt; - char *uplink_interface = NULL, *plat_prefix = NULL; + char *uplink_interface = NULL, *plat_prefix = NULL, *net_id_str = NULL; + unsigned net_id = NETID_UNSET; strcpy(tunnel.device6, DEVICENAME6); strcpy(tunnel.device4, DEVICENAME4); - while((opt = getopt(argc, argv, "i:p:h")) != -1) { + while((opt = getopt(argc, argv, "i:p:n:h")) != -1) { switch(opt) { case 'i': uplink_interface = optarg; @@ -395,6 +399,9 @@ int main(int argc, char **argv) { case 'p': plat_prefix = optarg; break; + case 'n': + net_id_str = optarg; + break; case 'h': default: print_help(); @@ -408,6 +415,14 @@ int main(int argc, char **argv) { printf("I need an interface\n"); exit(1); } + if (net_id_str != NULL) { + char *end_ptr; + net_id = strtoul(net_id_str, &end_ptr, 0); + if (net_id == ULONG_MAX || *net_id_str == 0 || *end_ptr != 0) { + logmsg(ANDROID_LOG_FATAL, "clatd called with invalid NetID %s", net_id_str); + exit(1); + } + } logmsg(ANDROID_LOG_INFO, "Starting clat version %s on %s", CLATD_VERSION, uplink_interface); // open the tunnel device before dropping privs @@ -438,7 +453,7 @@ int main(int argc, char **argv) { // "local", but that only works for the netd process itself. unsetenv("ANDROID_DNS_MODE"); - configure_interface(uplink_interface, plat_prefix, &tunnel); + configure_interface(uplink_interface, plat_prefix, &tunnel, net_id); set_forwarding(forwarding_fd,"1\n"); diff --git a/config.c b/config.c index b82ac6c..3d39ff0 100644 --- a/config.c +++ b/config.c @@ -152,15 +152,16 @@ void free_config() { /* 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() { +void dns64_detection(unsigned net_id) { int backoff_sleep, status; struct in6_addr tmp_ptr; backoff_sleep = 1; while(1) { - status = plat_prefix(Global_Clatd_Config.plat_from_dns64_hostname,&tmp_ptr); + status = plat_prefix(Global_Clatd_Config.plat_from_dns64_hostname,net_id,&tmp_ptr); if(status > 0) { memcpy(&Global_Clatd_Config.plat_subnet, &tmp_ptr, sizeof(struct in6_addr)); return; @@ -223,8 +224,10 @@ int subnet_from_interface(cnode *root, const char *interface) { * 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) { +int read_config(const char *file, const char *uplink_interface, const char *plat_prefix, + unsigned net_id) { cnode *root = config_node("", ""); void *tmp_ptr = NULL; @@ -277,7 +280,7 @@ int read_config(const char *file, const char *uplink_interface, const char *plat if(!(Global_Clatd_Config.plat_from_dns64_hostname = config_item_str(root, "plat_from_dns64_hostname", DEFAULT_DNS64_DETECTION_HOSTNAME))) goto failed; - dns64_detection(); + dns64_detection(net_id); } } diff --git a/config.h b/config.h index 18760c3..fa47152 100644 --- a/config.h +++ b/config.h @@ -39,7 +39,8 @@ struct clat_config { extern struct clat_config Global_Clatd_Config; -int read_config(const char *file, const char *uplink_interface, const char *plat_prefix); +int read_config(const char *file, const char *uplink_interface, const char *plat_prefix, + unsigned net_id); void config_generate_local_ipv6_subnet(struct in6_addr *interface_ip); #endif /* __CONFIG_H__ */ diff --git a/dns64.c b/dns64.c index b139fe4..ce8539d 100644 --- a/dns64.c +++ b/dns64.c @@ -27,13 +27,15 @@ #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 temporary failure, -1 on permanent failure - * ipv4_name - name to lookup - * prefix - the plat /96 prefix + * 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, struct in6_addr *prefix) { +int plat_prefix(const char *ipv4_name, unsigned net_id, struct in6_addr *prefix) { struct addrinfo hints, *result, *p; int status, plat_addr_set, ipv4_records, ipv6_records; struct in6_addr plat_addr, this_plat_addr; @@ -48,7 +50,7 @@ int plat_prefix(const char *ipv4_name, struct in6_addr *prefix) { bzero(&hints, sizeof(hints)); hints.ai_family = AF_UNSPEC; - status = getaddrinfo(ipv4_name, NULL, &hints, &result); + status = android_getaddrinfofornet(ipv4_name, NULL, &hints, net_id, MARK_UNSET, &result); if(status != 0) { logmsg(ANDROID_LOG_ERROR,"plat_prefix/dns(%s) status = %d/%s\n", ipv4_name, status, gai_strerror(status)); return 0; diff --git a/dns64.h b/dns64.h index f295e50..f5eaea8 100644 --- a/dns64.h +++ b/dns64.h @@ -18,6 +18,6 @@ #ifndef __DNS64_H__ #define __DNS64_H__ -int plat_prefix(const char *ipv4_name, struct in6_addr *prefix); +int plat_prefix(const char *ipv4_name, unsigned net_id, struct in6_addr *prefix); #endif -- cgit v1.2.3