summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2019-01-04 14:59:11 +0900
committerLorenzo Colitti <lorenzo@google.com>2019-01-04 19:08:45 +0900
commiteb92f48b1dc1c18d3e194d0634c617cada9cf6ff (patch)
tree2f104504eea1faeeb0477015c911e70009b92eec
parentb5e8f977bb53cbec0ef311a0ad85b7d64d228bac (diff)
downloadplatform_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.bp92
-rw-r--r--clatd.c110
-rw-r--r--clatd.h30
-rw-r--r--common.h40
-rw-r--r--main.c144
-rw-r--r--translate.c1
-rw-r--r--translate.h1
-rw-r--r--tun.c2
-rw-r--r--tun.h2
9 files changed, 247 insertions, 175 deletions
diff --git a/Android.bp b/Android.bp
index 2603472..7f28a3c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -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",
diff --git a/clatd.c b/clatd.c
index 18d7562..2ef10a5 100644
--- a/clatd.c
+++ b/clatd.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;
-}
diff --git a/clatd.h b/clatd.h
index 327a948..32f8cd5 100644
--- a/clatd.h
+++ b/clatd.h
@@ -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__ */
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..e717498
--- /dev/null
+++ b/main.c
@@ -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.
diff --git a/tun.c b/tun.c
index 1120bae..406fc2f 100644
--- a/tun.c
+++ b/tun.c
@@ -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
diff --git a/tun.h b/tun.h
index bcdd10e..f0449b9 100644
--- a/tun.h
+++ b/tun.h
@@ -20,7 +20,7 @@
#include <linux/if.h>
-#include "clatd.h"
+#include "common.h"
#include "ring.h"
struct tun_data {