summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErik Kline <ek@google.com>2014-09-22 13:32:27 +0900
committerErik Kline <ek@google.com>2014-09-24 16:02:31 +0900
commit0ec5dfa1da6a97532dc8cca825bae4edfb7d3dce (patch)
tree34185fdc8520137e7aaa4e711f4f6bf4511da514
parentdce3ddf54083ccd0e3752c4c08013688f79baa7a (diff)
downloadandroid_external_android-clat-staging/cm-12.0-caf.tar.gz
android_external_android-clat-staging/cm-12.0-caf.tar.bz2
android_external_android-clat-staging/cm-12.0-caf.zip
Simplify and always retry DNS64 prefix discovery.staging/cm-12.0-cafstaging/cm-12.0
- Only request AAAAs for the IPv4-only hostname, since that's all the information being used. Perhaps at some point in the future when _validation_ of the IPv4 address(es)'s presence within the IPv6 address(es) is being done this should be revisited. - Only use the first AAAA returned to find the DNS64 prefix. It's not clear how to properly resolve any potential DNS64 prefix conflicts anyway. - Re-try DNS64 prefix discovery on any type of error. If clatd was started (presumably an IPv6-only network), retry DNS64 prefix discovery with exponential backoff. Some "permanent" errors can be indistinguishable from transient errors (e.g. receiving an erroneous SERVFAIL from a DNS resolver, ...). - Fix-up back-off logic to not sleep 128 then 120, 120, ... :-) Bug: 17569702 Change-Id: I226ea7772cd7c88d2b60153ef76e5435400e11aa
-rw-r--r--config.c9
-rw-r--r--dns64.c69
2 files changed, 24 insertions, 54 deletions
diff --git a/config.c b/config.c
index d8bec80..13889a0 100644
--- a/config.c
+++ b/config.c
@@ -165,16 +165,11 @@ void dns64_detection(unsigned net_id) {
memcpy(&Global_Clatd_Config.plat_subnet, &tmp_ptr, sizeof(struct in6_addr));
return;
}
- if(status < 0) {
- logmsg(ANDROID_LOG_FATAL, "dns64_detection/no dns64, giving up\n");
- exit(1);
- }
- logmsg(ANDROID_LOG_WARN, "dns64_detection failed, sleeping for %d seconds", backoff_sleep);
+ logmsg(ANDROID_LOG_WARN, "dns64_detection -- error, sleeping for %d seconds", backoff_sleep);
sleep(backoff_sleep);
+ backoff_sleep *= 2;
if(backoff_sleep >= 120) {
backoff_sleep = 120;
- } else {
- backoff_sleep *= 2;
}
}
}
diff --git a/dns64.c b/dns64.c
index ce8539d..4e9252d 100644
--- a/dns64.c
+++ b/dns64.c
@@ -30,69 +30,44 @@
#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
+ * 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) {
- struct addrinfo hints, *result, *p;
- int status, plat_addr_set, ipv4_records, ipv6_records;
- struct in6_addr plat_addr, this_plat_addr;
- struct sockaddr_in6 *this_addr;
+ 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...");
- result = NULL;
- plat_addr_set = 0;
- ipv4_records = ipv6_records = 0;
-
- bzero(&hints, sizeof(hints));
- hints.ai_family = AF_UNSPEC;
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));
+ if (status != 0 || result == NULL) {
+ logmsg(ANDROID_LOG_ERROR, "plat_prefix/dns(%s) status = %d/%s",
+ ipv4_name, status, gai_strerror(status));
return 0;
}
- for(p = result; p; p = p->ai_next) {
- if(p->ai_family == AF_INET) {
- ipv4_records++;
- continue;
- }
- if(p->ai_family != AF_INET6) {
- logmsg(ANDROID_LOG_WARN,"plat_prefix/unexpected address family: %d\n", p->ai_family);
- continue;
- }
- ipv6_records++;
- this_addr = (struct sockaddr_in6 *)p->ai_addr;
- this_plat_addr = this_addr->sin6_addr;
- this_plat_addr.s6_addr32[3] = 0;
-
- if(!plat_addr_set) {
- plat_addr = this_plat_addr;
- plat_addr_set = 1;
- continue;
- }
+ // 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).
- inet_ntop(AF_INET6, &plat_addr, plat_addr_str, sizeof(plat_addr_str));
- if(!IN6_ARE_ADDR_EQUAL(&plat_addr, &this_plat_addr)) {
- char this_plat_addr_str[INET6_ADDRSTRLEN];
- inet_ntop(AF_INET6, &this_plat_addr, this_plat_addr_str, sizeof(this_plat_addr_str));
- logmsg(ANDROID_LOG_ERROR,"plat_prefix/two different plat addrs = %s,%s",
- plat_addr_str,this_plat_addr_str);
- }
- }
- if(result != NULL) {
- freeaddrinfo(result);
- }
- if(ipv4_records > 0 && ipv6_records == 0) {
- logmsg(ANDROID_LOG_WARN,"plat_prefix/no dns64 detected\n");
- return -1;
+ 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", plat_addr_str);
+ 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;
}