From baf62997b598ac38a99fd30419ccf7c109ffb3bc Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Fri, 1 Mar 2013 20:29:39 +0900 Subject: Make clatd a bit more robust when started by netd. 1. When started from netd, DNS lookups (used to detect the NAT64 prefix) fail because ANDROID_DNS_MODE=local. Unset it. 2. Only add the SIGTERM handler just before starting the event loop. Otherwise, if clatd hangs before the event loop is started (e.g., when #1 happens), it can't be stopped. While I'm at it, add a couple of logging statements. Change-Id: Ie24b37e34b729ce6cd3769b5d64348f2c1b9627d --- clatd.c | 22 ++++++++++++++-------- dns64.c | 13 +++++++++---- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/clatd.c b/clatd.c index 17a3548..74aabcb 100644 --- a/clatd.c +++ b/clatd.c @@ -109,10 +109,10 @@ void set_accept_ra() { } } -/* function: got_sigterm - * signal handler: mark it time to clean up +/* function: stop_loop + * signal handler: stop the event loop */ -void got_sigterm(int signal) { +void stop_loop(int signal) { running = 0; } @@ -474,6 +474,7 @@ int main(int argc, char **argv) { printf("I need an interface\n"); exit(1); } + logmsg(ANDROID_LOG_INFO,"Starting clat on %s", uplink_interface); // open the tunnel device before dropping privs tunnel.fd6 = tun_open(); @@ -502,10 +503,9 @@ int main(int argc, char **argv) { // run under a regular user drop_root(); - if(signal(SIGTERM, got_sigterm) == SIG_ERR) { - logmsg(ANDROID_LOG_FATAL, "sigterm handler failed: %s", strerror(errno)); - exit(1); - } + // When run from netd, the environment variable ANDROID_DNS_MODE is set to + // "local", but that only works for the netd process itself. + unsetenv("ANDROID_DNS_MODE"); configure_interface(uplink_interface, plat_prefix, &tunnel); @@ -514,9 +514,15 @@ int main(int argc, char **argv) { set_default_ipv6_route(uplink_interface); set_forwarding(forwarding_fd,"1\n"); - event_loop(&tunnel); // event_loop returns if someone sets the tun interface down manually + // Loop until someone sends us a signal or brings down the tun interface. + if(signal(SIGTERM, stop_loop) == SIG_ERR) { + logmsg(ANDROID_LOG_FATAL, "sigterm handler failed: %s", strerror(errno)); + exit(1); + } + event_loop(&tunnel); set_forwarding(forwarding_fd,"0\n"); + logmsg(ANDROID_LOG_INFO,"Shutting down clat on %s", uplink_interface); return 0; } diff --git a/dns64.c b/dns64.c index ab662c7..b139fe4 100644 --- a/dns64.c +++ b/dns64.c @@ -38,6 +38,9 @@ int plat_prefix(const char *ipv4_name, struct in6_addr *prefix) { int status, plat_addr_set, ipv4_records, ipv6_records; struct in6_addr plat_addr, this_plat_addr; struct sockaddr_in6 *this_addr; + char plat_addr_str[INET6_ADDRSTRLEN]; + + logmsg(ANDROID_LOG_INFO, "Detecting NAT64 prefix from DNS..."); result = NULL; plat_addr_set = 0; @@ -71,12 +74,12 @@ int plat_prefix(const char *ipv4_name, struct in6_addr *prefix) { continue; } + inet_ntop(AF_INET6, &plat_addr, plat_addr_str, sizeof(plat_addr_str)); if(!IN6_ARE_ADDR_EQUAL(&plat_addr, &this_plat_addr)) { - char plat_addr_str[INET6_ADDRSTRLEN], this_plat_addr_str[INET6_ADDRSTRLEN]; + 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", - inet_ntop(AF_INET6, &plat_addr, plat_addr_str, sizeof(plat_addr_str)), - inet_ntop(AF_INET6, &this_plat_addr, this_plat_addr_str, sizeof(this_plat_addr_str)) - ); + plat_addr_str,this_plat_addr_str); } } if(result != NULL) { @@ -86,6 +89,8 @@ int plat_prefix(const char *ipv4_name, struct in6_addr *prefix) { logmsg(ANDROID_LOG_WARN,"plat_prefix/no dns64 detected\n"); return -1; } + + logmsg(ANDROID_LOG_INFO, "Detected NAT64 prefix %s/96", plat_addr_str); *prefix = plat_addr; return 1; } -- cgit v1.2.3