summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2015-09-26 02:19:14 +0900
committerSteve Kondik <steve@cyngn.com>2016-06-08 21:12:27 -0700
commit4f99df509e1e6626967aa8bb394045932e75576b (patch)
tree462c2e76dc1ace1695f78094f43eb6b08bdf6917
parent8ac9b35e42dcd874cd313c4bcf9d3244f80ba725 (diff)
downloadandroid_external_android-clat-4f99df509e1e6626967aa8bb394045932e75576b.tar.gz
android_external_android-clat-4f99df509e1e6626967aa8bb394045932e75576b.tar.bz2
android_external_android-clat-4f99df509e1e6626967aa8bb394045932e75576b.zip
Run the receive path in its own thread.
Bug: 24113287 Change-Id: I3e77f5d5e9fcc47819f2a9fe60cff4aa7f97a8bd
-rw-r--r--clatd.c46
1 files changed, 38 insertions, 8 deletions
diff --git a/clatd.c b/clatd.c
index a454770..64f2ebe 100644
--- a/clatd.c
+++ b/clatd.c
@@ -25,6 +25,7 @@
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
+#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
@@ -367,14 +368,37 @@ void read_packet(int read_fd, int write_fd, int to_ipv6) {
translate_packet(write_fd, to_ipv6, packet, readlen, TP_CSUM_NONE);
}
+/* function: recv_loop
+ * reads packets from the packet socket and translates them
+ * tunnel - tun device data
+ */
+void *recv_loop(void *arg) {
+ struct tun_data *tunnel = (struct tun_data *) arg;
+ struct pollfd wait_fd[] = {
+ { tunnel->read_fd6, POLLIN, 0 },
+ };
+
+ while(running) {
+ if(poll(wait_fd, 1, NO_TRAFFIC_INTERFACE_POLL_FREQUENCY*1000) == -1) {
+ if(errno != EINTR) {
+ logmsg(ANDROID_LOG_WARN, "recv_loop/poll returned an error: %s",strerror(errno));
+ }
+ } else {
+ if (wait_fd[0].revents) {
+ ring_read(&tunnel->ring, tunnel->fd4, 0 /* to_ipv6 */);
+ }
+ }
+ }
+ return NULL;
+}
+
/* function: event_loop
- * reads packets from the tun network interface and passes them down the stack
+ * reads packets from the tun interface and translates them. also monitors our upstream IP address
* tunnel - tun device data
*/
void event_loop(struct tun_data *tunnel) {
time_t last_interface_poll;
struct pollfd wait_fd[] = {
- { tunnel->read_fd6, POLLIN, 0 },
{ tunnel->fd4, POLLIN, 0 },
};
@@ -382,9 +406,9 @@ void event_loop(struct tun_data *tunnel) {
last_interface_poll = time(NULL);
while(running) {
- if(poll(wait_fd, 2, NO_TRAFFIC_INTERFACE_POLL_FREQUENCY*1000) == -1) {
+ if(poll(wait_fd, 1, NO_TRAFFIC_INTERFACE_POLL_FREQUENCY*1000) == -1) {
if(errno != EINTR) {
- logmsg(ANDROID_LOG_WARN,"event_loop/poll returned an error: %s",strerror(errno));
+ logmsg(ANDROID_LOG_WARN, "event_loop/poll returned an error: %s",strerror(errno));
}
} else {
// Call read_packet if the socket has data to be read, but also if an
@@ -393,9 +417,6 @@ void event_loop(struct tun_data *tunnel) {
// causing this code to spin in a loop. Calling read() will clear the
// socket error flag instead.
if (wait_fd[0].revents) {
- ring_read(&tunnel->ring, tunnel->fd4, 0 /* to_ipv6 */);
- }
- if (wait_fd[1].revents) {
read_packet(tunnel->fd4, tunnel->write_fd6, 1 /* to_ipv6 */);
}
}
@@ -511,12 +532,21 @@ int main(int argc, char **argv) {
update_clat_ipv6_address(&tunnel, uplink_interface);
- // Loop until someone sends us a signal or brings down the tun interface.
+ // Stop when 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);
}
+ // Start the receive thread.
+ int ret;
+ pthread_t recv_thread;
+ if ((ret = pthread_create(&recv_thread, NULL, recv_loop, (void *) &tunnel)) != 0) {
+ logmsg(ANDROID_LOG_FATAL, "creating receive thread failed: %s", strerror(ret));
+ exit(1);
+ }
+
+ // Run the event loop.
event_loop(&tunnel);
logmsg(ANDROID_LOG_INFO,"Shutting down clat on %s", uplink_interface);