diff options
author | Lorenzo Colitti <lorenzo@google.com> | 2019-01-04 14:59:11 +0900 |
---|---|---|
committer | Lorenzo Colitti <lorenzo@google.com> | 2019-01-04 19:08:45 +0900 |
commit | eb92f48b1dc1c18d3e194d0634c617cada9cf6ff (patch) | |
tree | 2f104504eea1faeeb0477015c911e70009b92eec | |
parent | b5e8f977bb53cbec0ef311a0ad85b7d64d228bac (diff) | |
download | platform_external_android-clat-eb92f48b1dc1c18d3e194d0634c617cada9cf6ff.tar.gz platform_external_android-clat-eb92f48b1dc1c18d3e194d0634c617cada9cf6ff.tar.bz2 platform_external_android-clat-eb92f48b1dc1c18d3e194d0634c617cada9cf6ff.zip |
Move main() out of clatd.c.
This allows us to unit test methods that are in clatd.c.
Also simplify the build file, adding a defaults stanza and
grouping files in a filegroup so that both the code and the unit
test have the same source files.
Test: atest clatd_test
Test: builds, boots, 464xlat works
Change-Id: I544c3ee846abd3e38b80a2d9a4db5497fd9beb0c
-rw-r--r-- | Android.bp | 92 | ||||
-rw-r--r-- | clatd.c | 110 | ||||
-rw-r--r-- | clatd.h | 30 | ||||
-rw-r--r-- | common.h | 40 | ||||
-rw-r--r-- | main.c | 144 | ||||
-rw-r--r-- | translate.c | 1 | ||||
-rw-r--r-- | translate.h | 1 | ||||
-rw-r--r-- | tun.c | 2 | ||||
-rw-r--r-- | tun.h | 2 |
9 files changed, 247 insertions, 175 deletions
@@ -1,45 +1,60 @@ -// The clat daemon. -cc_binary { - name: "clatd", +cc_defaults { + name: "clatd_defaults", + + cflags: [ + "-Wall", + "-Werror", + "-Wunused-parameter", + // Bug: http://b/33566695 + "-Wno-address-of-packed-member", + ], + + // For NETID_UNSET and MARK_UNSET. + include_dirs: ["bionic/libc/dns/include"], + + // For NETID_USE_LOCAL_NAMESERVERS. + header_libs: ["libnetd_client_headers"], +} + +// Code used both by the daemon and by unit tests. +filegroup { + name: "clatd_common", srcs: [ + "checksum.c", + "config.c", "clatd.c", + "dns64.c", "dump.c", - "checksum.c", - "translate.c", + "getaddr.c", "icmp.c", "ipv4.c", "ipv6.c", - "config.c", - "dns64.c", "logging.c", - "getaddr.c", + "mtu.c", "netlink_callbacks.c", "netlink_msg.c", + "ring.c", "setif.c", - "mtu.c", "tun.c", - "ring.c", + "translate.c", ], +} - cflags: [ - "-Wall", - "-Werror", - "-Wunused-parameter", - - // Bug: http://b/33566695 - "-Wno-address-of-packed-member", +// The clat daemon. +cc_binary { + name: "clatd", + defaults: ["clatd_defaults"], + srcs: [ + ":clatd_common", + "main.c" ], - - include_dirs: ["bionic/libc/dns/include"], - header_libs: ["libnetd_client_headers"], static_libs: ["libnl"], shared_libs: [ "libcutils", "liblog", "libnetutils", ], - } // The configuration file. @@ -51,28 +66,18 @@ prebuilt_etc { // Unit tests. cc_test { name: "clatd_test", - cflags: [ - "-Wall", - "-Werror", - "-Wunused-parameter", - - // Bug: http://b/33566695 - "-Wno-address-of-packed-member", - ], - + defaults: ["clatd_defaults"], srcs: [ - "clatd_test.cpp", - "checksum.c", - "translate.c", - "icmp.c", - "ipv4.c", - "ipv6.c", - "logging.c", - "config.c", - "tun.c", + ":clatd_common", + "clatd_test.cpp" + ], + static_libs: [ + "libbase", + "libnetd_test_tun_interface", + "libnl", ], - shared_libs: [ + "libcutils", "liblog", "libnetutils", ], @@ -81,12 +86,7 @@ cc_test { // Microbenchmark. cc_test { name: "clatd_microbenchmark", - - cflags: [ - "-Wall", - "-Werror", - "-Wunused-parameter", - ], + defaults: ["clatd_defaults"], srcs: [ "clatd_microbenchmark.c", "checksum.c", @@ -53,8 +53,6 @@ #include "translate.h" #include "tun.h" -#define DEVICEPREFIX "v4-" - /* 40 bytes IPv6 header - 20 bytes IPv4 header + 8 bytes fragment header */ #define MTU_DELTA 28 @@ -426,17 +424,6 @@ void event_loop(struct tun_data *tunnel) { } } -/* function: print_help - * in case the user is running this on the command line - */ -void print_help() { - printf("android-clat arguments:\n"); - printf("-i [uplink interface]\n"); - printf("-p [plat prefix]\n"); - printf("-n [NetId]\n"); - printf("-m [socket mark]\n"); -} - /* function: parse_unsigned * parses a string as a decimal/hex/octal unsigned integer * str - the string to parse @@ -447,100 +434,3 @@ int parse_unsigned(const char *str, unsigned *out) { *out = strtoul(str, &end_ptr, 0); return *str && !*end_ptr; } - -/* function: main - * allocate and setup the tun device, then run the event loop - */ -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; - unsigned net_id = NETID_UNSET; - uint32_t mark = MARK_UNSET; - unsigned len; - - while ((opt = getopt(argc, argv, "i:p:n:m:h")) != -1) { - switch (opt) { - case 'i': - uplink_interface = optarg; - break; - case 'p': - plat_prefix = optarg; - break; - case 'n': - net_id_str = optarg; - break; - case 'm': - mark_str = optarg; - break; - case 'h': - print_help(); - exit(0); - default: - logmsg(ANDROID_LOG_FATAL, "Unknown option -%c. Exiting.", (char)optopt); - exit(1); - } - } - - if (uplink_interface == NULL) { - logmsg(ANDROID_LOG_FATAL, "clatd called without an interface"); - 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); - } - - len = snprintf(tunnel.device4, sizeof(tunnel.device4), "%s%s", DEVICEPREFIX, uplink_interface); - if (len >= sizeof(tunnel.device4)) { - logmsg(ANDROID_LOG_FATAL, "interface name too long '%s'", tunnel.device4); - exit(1); - } - - logmsg(ANDROID_LOG_INFO, "Starting clat version %s on %s netid=%s mark=%s", CLATD_VERSION, - uplink_interface, net_id_str ? net_id_str : "(none)", mark_str ? mark_str : "(none)"); - - // run under a regular user but keep needed capabilities - drop_root_but_keep_caps(); - - // open our raw sockets before dropping privs - open_sockets(&tunnel, mark); - - // keeps only admin capability - set_capability(1 << CAP_NET_ADMIN); - - // we can create tun devices as non-root because we're in the VPN group. - tunnel.fd4 = tun_open(); - if (tunnel.fd4 < 0) { - logmsg(ANDROID_LOG_FATAL, "tun_open4 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. Removing the - // following line causes XLAT failure in permissive mode. - unsetenv("ANDROID_DNS_MODE"); - - configure_interface(uplink_interface, plat_prefix, &tunnel, net_id); - - update_clat_ipv6_address(&tunnel, uplink_interface); - - // 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); - - logmsg(ANDROID_LOG_INFO, "Shutting down clat on %s", uplink_interface); - del_anycast_address(tunnel.write_fd6, &Global_Clatd_Config.ipv6_local_subnet); - - return 0; -} @@ -13,13 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * clatd.h - main system definitions + * clatd.h - main routines used by clatd */ #ifndef __CLATD_H__ #define __CLATD_H__ #include <sys/uio.h> +struct tun_data; + #define MAXMTU 1500 #define PACKETLEN (MAXMTU + sizeof(struct tun_pi)) #define CLATD_VERSION "1.4" @@ -32,21 +34,15 @@ // how frequently (in seconds) to poll for an address change while there is no traffic #define NO_TRAFFIC_INTERFACE_POLL_FREQUENCY 90 -// A clat_packet is an array of iovec structures representing a packet that we are translating. -// The CLAT_POS_XXX constants represent the array indices within the clat_packet that contain -// specific parts of the packet. The packet_* functions operate on all the packet segments past a -// given position. -typedef enum { - CLAT_POS_TUNHDR, - CLAT_POS_IPHDR, - CLAT_POS_FRAGHDR, - CLAT_POS_TRANSPORTHDR, - CLAT_POS_ICMPERR_IPHDR, - CLAT_POS_ICMPERR_FRAGHDR, - CLAT_POS_ICMPERR_TRANSPORTHDR, - CLAT_POS_PAYLOAD, - CLAT_POS_MAX -} clat_packet_index; -typedef struct iovec clat_packet[CLAT_POS_MAX]; +void stop_loop(); +void set_capability(uint64_t target_cap); +void drop_root_but_keep_caps(); +void open_sockets(struct tun_data *tunnel, uint32_t mark); +int ipv6_address_changed(const char *interface); +int update_clat_ipv6_address(const struct tun_data *tunnel, const char *interface); +void configure_interface(const char *uplink_interface, const char *plat_prefix, + struct tun_data *tunnel, unsigned net_id); +void event_loop(struct tun_data *tunnel); +int parse_unsigned(const char *str, unsigned *out); #endif /* __CLATD_H__ */ diff --git a/common.h b/common.h new file mode 100644 index 0000000..e9551ee --- /dev/null +++ b/common.h @@ -0,0 +1,40 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * 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. + * + * common.h - common definitions + */ +#ifndef __CLATD_COMMON_H__ +#define __CLATD_COMMON_H__ + +#include <sys/uio.h> + +// A clat_packet is an array of iovec structures representing a packet that we are translating. +// The CLAT_POS_XXX constants represent the array indices within the clat_packet that contain +// specific parts of the packet. The packet_* functions operate on all the packet segments past a +// given position. +typedef enum { + CLAT_POS_TUNHDR, + CLAT_POS_IPHDR, + CLAT_POS_FRAGHDR, + CLAT_POS_TRANSPORTHDR, + CLAT_POS_ICMPERR_IPHDR, + CLAT_POS_ICMPERR_FRAGHDR, + CLAT_POS_ICMPERR_TRANSPORTHDR, + CLAT_POS_PAYLOAD, + CLAT_POS_MAX +} clat_packet_index; +typedef struct iovec clat_packet[CLAT_POS_MAX]; + +#endif /* __CLATD_COMMON_H__ */ @@ -0,0 +1,144 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * 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. + * + * main.c - main function + */ + +#include <errno.h> +#include <netinet/in.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <sys/capability.h> +#include <unistd.h> + +#include "resolv_netid.h" + +#include "clatd.h" +#include "common.h" +#include "config.h" +#include "logging.h" +#include "setif.h" +#include "tun.h" + +#define DEVICEPREFIX "v4-" + +/* function: print_help + * in case the user is running this on the command line + */ +void print_help() { + printf("android-clat arguments:\n"); + printf("-i [uplink interface]\n"); + printf("-p [plat prefix]\n"); + printf("-n [NetId]\n"); + printf("-m [socket mark]\n"); +} + +/* function: main + * allocate and setup the tun device, then run the event loop + */ +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; + unsigned net_id = NETID_UNSET; + uint32_t mark = MARK_UNSET; + unsigned len; + + while ((opt = getopt(argc, argv, "i:p:n:m:h")) != -1) { + switch (opt) { + case 'i': + uplink_interface = optarg; + break; + case 'p': + plat_prefix = optarg; + break; + case 'n': + net_id_str = optarg; + break; + case 'm': + mark_str = optarg; + break; + case 'h': + print_help(); + exit(0); + default: + logmsg(ANDROID_LOG_FATAL, "Unknown option -%c. Exiting.", (char)optopt); + exit(1); + } + } + + if (uplink_interface == NULL) { + logmsg(ANDROID_LOG_FATAL, "clatd called without an interface"); + 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); + } + + len = snprintf(tunnel.device4, sizeof(tunnel.device4), "%s%s", DEVICEPREFIX, uplink_interface); + if (len >= sizeof(tunnel.device4)) { + logmsg(ANDROID_LOG_FATAL, "interface name too long '%s'", tunnel.device4); + exit(1); + } + + logmsg(ANDROID_LOG_INFO, "Starting clat version %s on %s netid=%s mark=%s", CLATD_VERSION, + uplink_interface, net_id_str ? net_id_str : "(none)", mark_str ? mark_str : "(none)"); + + // run under a regular user but keep needed capabilities + drop_root_but_keep_caps(); + + // open our raw sockets before dropping privs + open_sockets(&tunnel, mark); + + // keeps only admin capability + set_capability(1 << CAP_NET_ADMIN); + + // we can create tun devices as non-root because we're in the VPN group. + tunnel.fd4 = tun_open(); + if (tunnel.fd4 < 0) { + logmsg(ANDROID_LOG_FATAL, "tun_open4 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. Removing the + // following line causes XLAT failure in permissive mode. + unsetenv("ANDROID_DNS_MODE"); + + configure_interface(uplink_interface, plat_prefix, &tunnel, net_id); + + update_clat_ipv6_address(&tunnel, uplink_interface); + + // 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); + + logmsg(ANDROID_LOG_INFO, "Shutting down clat on %s", uplink_interface); + del_anycast_address(tunnel.write_fd6, &Global_Clatd_Config.ipv6_local_subnet); + + return 0; +} diff --git a/translate.c b/translate.c index 58a7e9d..df3d020 100644 --- a/translate.c +++ b/translate.c @@ -19,6 +19,7 @@ #include "checksum.h" #include "clatd.h" +#include "common.h" #include "config.h" #include "debug.h" #include "icmp.h" diff --git a/translate.h b/translate.h index 692affc..0e520f7 100644 --- a/translate.h +++ b/translate.h @@ -29,6 +29,7 @@ #include <netinet/udp.h> #include "clatd.h" +#include "common.h" #define MAX_TCP_HDR (15 * 4) // Data offset field is 4 bits and counts in 32-bit words. @@ -24,7 +24,7 @@ #include <sys/uio.h> #include <unistd.h> -#include "clatd.h" +#include "common.h" /* function: tun_open * tries to open the tunnel device @@ -20,7 +20,7 @@ #include <linux/if.h> -#include "clatd.h" +#include "common.h" #include "ring.h" struct tun_data { |