diff --git a/app/app.iml b/app/app.iml
index 9449018a..4c1ac093 100644
--- a/app/app.iml
+++ b/app/app.iml
@@ -100,7 +100,6 @@
-
diff --git a/app/src/main/jni/netguard/icmp.c b/app/src/main/jni/netguard/icmp.c
index 78941cc7..e3313b55 100644
--- a/app/src/main/jni/netguard/icmp.c
+++ b/app/src/main/jni/netguard/icmp.c
@@ -22,6 +22,58 @@
extern struct icmp_session *icmp_session;
extern FILE *pcap_file;
+int check_icmp_sessions(const struct arguments *args) {
+ time_t now = time(NULL);
+
+ int count = 0;
+ struct icmp_session *ic = icmp_session;
+ while (ic != NULL) {
+ if (!ic->stop)
+ count++;
+ ic = ic->next;
+ }
+
+ struct icmp_session *il = NULL;
+ struct icmp_session *i = icmp_session;
+ while (i != NULL) {
+ int timeout = ICMP_TIMEOUT;
+ if (i->stop || i->time + timeout < now) {
+ char source[INET6_ADDRSTRLEN + 1];
+ char dest[INET6_ADDRSTRLEN + 1];
+ if (i->version == 4) {
+ inet_ntop(AF_INET, &i->saddr.ip4, source, sizeof(source));
+ inet_ntop(AF_INET, &i->daddr.ip4, dest, sizeof(dest));
+ }
+ else {
+ inet_ntop(AF_INET6, &i->saddr.ip6, source, sizeof(source));
+ inet_ntop(AF_INET6, &i->daddr.ip6, dest, sizeof(dest));
+ }
+ log_android(ANDROID_LOG_WARN, "ICMP idle %d/%d sec stop %d from %s to %s",
+ now - i->time, timeout, i->stop, dest, source);
+
+ if (close(i->socket))
+ log_android(ANDROID_LOG_ERROR, "ICMP close %d error %d: %s",
+ i->socket, errno, strerror(errno));
+ i->socket = -1;
+
+ if (il == NULL)
+ icmp_session = i->next;
+ else
+ il->next = i->next;
+
+ struct icmp_session *c = i;
+ i = i->next;
+ free(c);
+ }
+ else {
+ il = i;
+ i = i->next;
+ }
+ }
+
+ return count;
+}
+
void check_icmp_sockets(const struct arguments *args, fd_set *rfds, fd_set *wfds, fd_set *efds) {
struct icmp_session *cur = icmp_session;
while (cur != NULL) {
diff --git a/app/src/main/jni/netguard/netguard.h b/app/src/main/jni/netguard/netguard.h
index 80a8439f..1e3f9584 100644
--- a/app/src/main/jni/netguard/netguard.h
+++ b/app/src/main/jni/netguard/netguard.h
@@ -48,7 +48,7 @@
#define TCP_SEND_WINDOW 16384 // bytes (maximum)
#define TCP_INIT_TIMEOUT 30 // seconds ~net.inet.tcp.keepinit
#define TCP_IDLE_TIMEOUT 300 // seconds ~net.inet.tcp.keepidle
-#define TCP_CLOSE_TIMEOUT 3 // seconds
+#define TCP_CLOSE_TIMEOUT 30 // seconds
#define TCP_KEEP_TIMEOUT 300 // seconds
#define TCP_TIMEOUT_SCALE 50
// https://en.wikipedia.org/wiki/Maximum_segment_lifetime
@@ -291,7 +291,11 @@ void report_exit(const struct arguments *args, const char *fmt, ...);
void check_allowed(const struct arguments *args);
-void check_sessions(const struct arguments *args, int isessions, int usessions, int tsessions);
+int check_icmp_sessions(const struct arguments *args);
+
+int check_udp_sessions(const struct arguments *args);
+
+int check_tcp_sessions(const struct arguments *args);
int get_select_timeout(int isessions, int usessions, int tsessions);
diff --git a/app/src/main/jni/netguard/session.c b/app/src/main/jni/netguard/session.c
index 9a5729e5..07907319 100644
--- a/app/src/main/jni/netguard/session.c
+++ b/app/src/main/jni/netguard/session.c
@@ -126,31 +126,11 @@ void *handle_events(void *a) {
while (!stopping) {
log_android(ANDROID_LOG_DEBUG, "Loop thread %x", thread_id);
- // Count sessions
- int isessions = 0;
- struct icmp_session *i = icmp_session;
- while (i != NULL) {
- if (!i->stop)
- isessions++;
- i = i->next;
- }
- int usessions = 0;
- struct udp_session *u = udp_session;
- while (u != NULL) {
- if (u->state == UDP_ACTIVE)
- usessions++;
- u = u->next;
- }
- int tsessions = 0;
- struct tcp_session *t = tcp_session;
- while (t != NULL) {
- if (t->state != TCP_CLOSING && t->state != TCP_CLOSE)
- tsessions++;
- t = t->next;
- }
-
// Check sessions
- check_sessions(args, isessions, usessions, tsessions);
+ int isessions = check_icmp_sessions(args);
+ int usessions = check_udp_sessions(args);
+ int tsessions = check_tcp_sessions(args);
+
// https://bugzilla.mozilla.org/show_bug.cgi?id=1093893
int idle = (tsessions + usessions + tsessions == 0 && sdk >= 16);
log_android(ANDROID_LOG_DEBUG, "sessions ICMP %d UDP %d TCP %d idle %d sdk %d",
@@ -469,172 +449,3 @@ void check_allowed(const struct arguments *args) {
}
}
-void check_sessions(const struct arguments *args, int isessions, int usessions, int tsessions) {
- time_t now = time(NULL);
-
- // Check ICMP sessions
- struct icmp_session *il = NULL;
- struct icmp_session *i = icmp_session;
- while (i != NULL) {
- int timeout = ICMP_TIMEOUT;
- if (i->stop || i->time + timeout < now) {
- char source[INET6_ADDRSTRLEN + 1];
- char dest[INET6_ADDRSTRLEN + 1];
- if (i->version == 4) {
- inet_ntop(AF_INET, &i->saddr.ip4, source, sizeof(source));
- inet_ntop(AF_INET, &i->daddr.ip4, dest, sizeof(dest));
- }
- else {
- inet_ntop(AF_INET6, &i->saddr.ip6, source, sizeof(source));
- inet_ntop(AF_INET6, &i->daddr.ip6, dest, sizeof(dest));
- }
- log_android(ANDROID_LOG_WARN, "ICMP idle %d/%d sec stop %d from %s to %s",
- now - i->time, timeout, i->stop, dest, source);
-
- if (close(i->socket))
- log_android(ANDROID_LOG_ERROR, "ICMP close %d error %d: %s",
- i->socket, errno, strerror(errno));
- i->socket = -1;
-
- if (il == NULL)
- icmp_session = i->next;
- else
- il->next = i->next;
-
- struct icmp_session *c = i;
- i = i->next;
- free(c);
- }
- else {
- il = i;
- i = i->next;
- }
- }
-
- // Check UDP sessions
- struct udp_session *ul = NULL;
- struct udp_session *u = udp_session;
- while (u != NULL) {
- char source[INET6_ADDRSTRLEN + 1];
- char dest[INET6_ADDRSTRLEN + 1];
- if (u->version == 4) {
- inet_ntop(AF_INET, &u->saddr.ip4, source, sizeof(source));
- inet_ntop(AF_INET, &u->daddr.ip4, dest, sizeof(dest));
- }
- else {
- inet_ntop(AF_INET6, &u->saddr.ip6, source, sizeof(source));
- inet_ntop(AF_INET6, &u->daddr.ip6, dest, sizeof(dest));
- }
-
- // Check session timeout
- int timeout = get_udp_timeout(u, usessions);
- if (u->state == UDP_ACTIVE && u->time + timeout < now) {
- log_android(ANDROID_LOG_WARN, "UDP idle %d/%d sec state %d from %s/%u to %s/%u",
- now - u->time, timeout, u->state,
- source, ntohs(u->source), dest, ntohs(u->dest));
- u->state = UDP_FINISHING;
- }
-
- // Check finished sessions
- if (u->state == UDP_FINISHING) {
- log_android(ANDROID_LOG_INFO, "UDP close from %s/%u to %s/%u socket %d",
- source, ntohs(u->source), dest, ntohs(u->dest), u->socket);
-
- if (close(u->socket))
- log_android(ANDROID_LOG_ERROR, "UDP close %d error %d: %s",
- u->socket, errno, strerror(errno));
- u->socket = -1;
-
- u->time = time(NULL);
- u->state = UDP_CLOSED;
- }
-
- // Cleanup lingering sessions
- if ((u->state == UDP_CLOSED || u->state == UDP_BLOCKED) &&
- u->time + UDP_KEEP_TIMEOUT < now) {
- if (ul == NULL)
- udp_session = u->next;
- else
- ul->next = u->next;
-
- struct udp_session *c = u;
- u = u->next;
- free(c);
- }
- else {
- ul = u;
- u = u->next;
- }
- }
-
- // Check TCP sessions
- struct tcp_session *tl = NULL;
- struct tcp_session *t = tcp_session;
- while (t != NULL) {
- char source[INET6_ADDRSTRLEN + 1];
- char dest[INET6_ADDRSTRLEN + 1];
- if (t->version == 4) {
- inet_ntop(AF_INET, &t->saddr.ip4, source, sizeof(source));
- inet_ntop(AF_INET, &t->daddr.ip4, dest, sizeof(dest));
- } else {
- inet_ntop(AF_INET6, &t->saddr.ip6, source, sizeof(source));
- inet_ntop(AF_INET6, &t->daddr.ip6, dest, sizeof(dest));
- }
-
- char session[250];
- sprintf(session, "TCP socket from %s/%u to %s/%u %s socket %d",
- source, ntohs(t->source), dest, ntohs(t->dest), strstate(t->state), t->socket);
-
- // Check session timeout
- int timeout = get_tcp_timeout(t, tsessions);
- if (t->state != TCP_CLOSING && t->state != TCP_CLOSE && t->time + timeout < now) {
- // TODO send keep alives?
- log_android(ANDROID_LOG_WARN, "%s idle %d/%d sec ",
- session, now - t->time, timeout);
- if (t->state == TCP_CLOSE_WAIT && t->forward == NULL) {
- t->remote_seq++; // remote FIN
- if (write_fin_ack(args, t) >= 0) {
- log_android(ANDROID_LOG_WARN, "%s finished idle", session);
- t->local_seq++; // local FIN
- t->state = TCP_LAST_ACK;
- }
- }
- else {
- log_android(ANDROID_LOG_WARN, "%s reset idle", session);
- write_rst(args, t);
- }
- }
-
- // Check closing sessions
- if (t->state == TCP_CLOSING) {
- if (t->socket >= 0) {
- if (close(t->socket))
- log_android(ANDROID_LOG_ERROR, "%s close error %d: %s",
- session, errno, strerror(errno));
- else
- log_android(ANDROID_LOG_WARN, "%s close", session);
- t->socket = -1;
- }
-
- t->time = time(NULL);
- t->state = TCP_CLOSE;
- }
-
- // Cleanup lingering sessions
- if (t->state == TCP_CLOSE && t->time + TCP_KEEP_TIMEOUT < now) {
- if (tl == NULL)
- tcp_session = t->next;
- else
- tl->next = t->next;
-
- struct tcp_session *c = t;
- t = t->next;
- clear_tcp_data(c);
- free(c);
- }
- else {
- tl = t;
- t = t->next;
- }
- }
-}
diff --git a/app/src/main/jni/netguard/tcp.c b/app/src/main/jni/netguard/tcp.c
index 298dd3e3..585bd7be 100644
--- a/app/src/main/jni/netguard/tcp.c
+++ b/app/src/main/jni/netguard/tcp.c
@@ -39,6 +39,90 @@ int get_tcp_timeout(const struct tcp_session *t, int sessions) {
return timeout;
}
+int check_tcp_sessions(const struct arguments *args) {
+ time_t now = time(NULL);
+
+ int count = 0;
+ struct tcp_session *tc = tcp_session;
+ while (tc != NULL) {
+ if (tc->state != TCP_CLOSING && tc->state != TCP_CLOSE)
+ count++;
+ tc = tc->next;
+ }
+
+ struct tcp_session *tl = NULL;
+ struct tcp_session *t = tcp_session;
+ while (t != NULL) {
+ char source[INET6_ADDRSTRLEN + 1];
+ char dest[INET6_ADDRSTRLEN + 1];
+ if (t->version == 4) {
+ inet_ntop(AF_INET, &t->saddr.ip4, source, sizeof(source));
+ inet_ntop(AF_INET, &t->daddr.ip4, dest, sizeof(dest));
+ } else {
+ inet_ntop(AF_INET6, &t->saddr.ip6, source, sizeof(source));
+ inet_ntop(AF_INET6, &t->daddr.ip6, dest, sizeof(dest));
+ }
+
+ char session[250];
+ sprintf(session, "TCP socket from %s/%u to %s/%u %s socket %d",
+ source, ntohs(t->source), dest, ntohs(t->dest), strstate(t->state), t->socket);
+
+ // Check session timeout
+ int timeout = get_tcp_timeout(t, count);
+ if (t->state != TCP_CLOSING && t->state != TCP_CLOSE && t->time + timeout < now) {
+ // TODO send keep alives?
+ log_android(ANDROID_LOG_WARN, "%s idle %d/%d sec ",
+ session, now - t->time, timeout);
+ if (t->state == TCP_CLOSE_WAIT && t->forward == NULL) {
+ t->remote_seq++; // remote FIN
+ if (write_fin_ack(args, t) >= 0) {
+ log_android(ANDROID_LOG_WARN, "%s finished idle", session);
+ t->local_seq++; // local FIN
+ t->state = TCP_LAST_ACK;
+ }
+ }
+ else {
+ log_android(ANDROID_LOG_WARN, "%s reset idle", session);
+ write_rst(args, t);
+ }
+ }
+
+ // Check closing sessions
+ if (t->state == TCP_CLOSING) {
+ if (t->socket >= 0) {
+ if (close(t->socket))
+ log_android(ANDROID_LOG_ERROR, "%s close error %d: %s",
+ session, errno, strerror(errno));
+ else
+ log_android(ANDROID_LOG_WARN, "%s close", session);
+ t->socket = -1;
+ }
+
+ t->time = time(NULL);
+ t->state = TCP_CLOSE;
+ }
+
+ // Cleanup lingering sessions
+ if (t->state == TCP_CLOSE && t->time + TCP_KEEP_TIMEOUT < now) {
+ if (tl == NULL)
+ tcp_session = t->next;
+ else
+ tl->next = t->next;
+
+ struct tcp_session *c = t;
+ t = t->next;
+ clear_tcp_data(c);
+ free(c);
+ }
+ else {
+ tl = t;
+ t = t->next;
+ }
+ }
+
+ return count;
+}
+
void check_tcp_sockets(const struct arguments *args, fd_set *rfds, fd_set *wfds, fd_set *efds) {
struct tcp_session *cur = tcp_session;
while (cur != NULL) {
diff --git a/app/src/main/jni/netguard/udp.c b/app/src/main/jni/netguard/udp.c
index b6835ed6..eef7893d 100644
--- a/app/src/main/jni/netguard/udp.c
+++ b/app/src/main/jni/netguard/udp.c
@@ -33,6 +33,75 @@ int get_udp_timeout(const struct udp_session *u, int sessions) {
return timeout;
}
+int check_udp_sessions(const struct arguments *args) {
+ time_t now = time(NULL);
+
+ int count = 0;
+ struct udp_session *uc = udp_session;
+ while (uc != NULL) {
+ if (uc->state == UDP_ACTIVE)
+ count++;
+ uc = uc->next;
+ }
+
+ struct udp_session *ul = NULL;
+ struct udp_session *u = udp_session;
+ while (u != NULL) {
+ char source[INET6_ADDRSTRLEN + 1];
+ char dest[INET6_ADDRSTRLEN + 1];
+ if (u->version == 4) {
+ inet_ntop(AF_INET, &u->saddr.ip4, source, sizeof(source));
+ inet_ntop(AF_INET, &u->daddr.ip4, dest, sizeof(dest));
+ }
+ else {
+ inet_ntop(AF_INET6, &u->saddr.ip6, source, sizeof(source));
+ inet_ntop(AF_INET6, &u->daddr.ip6, dest, sizeof(dest));
+ }
+
+ // Check session timeout
+ int timeout = get_udp_timeout(u, count);
+ if (u->state == UDP_ACTIVE && u->time + timeout < now) {
+ log_android(ANDROID_LOG_WARN, "UDP idle %d/%d sec state %d from %s/%u to %s/%u",
+ now - u->time, timeout, u->state,
+ source, ntohs(u->source), dest, ntohs(u->dest));
+ u->state = UDP_FINISHING;
+ }
+
+ // Check finished sessions
+ if (u->state == UDP_FINISHING) {
+ log_android(ANDROID_LOG_INFO, "UDP close from %s/%u to %s/%u socket %d",
+ source, ntohs(u->source), dest, ntohs(u->dest), u->socket);
+
+ if (close(u->socket))
+ log_android(ANDROID_LOG_ERROR, "UDP close %d error %d: %s",
+ u->socket, errno, strerror(errno));
+ u->socket = -1;
+
+ u->time = time(NULL);
+ u->state = UDP_CLOSED;
+ }
+
+ // Cleanup lingering sessions
+ if ((u->state == UDP_CLOSED || u->state == UDP_BLOCKED) &&
+ u->time + UDP_KEEP_TIMEOUT < now) {
+ if (ul == NULL)
+ udp_session = u->next;
+ else
+ ul->next = u->next;
+
+ struct udp_session *c = u;
+ u = u->next;
+ free(c);
+ }
+ else {
+ ul = u;
+ u = u->next;
+ }
+ }
+
+ return count;
+}
+
void check_udp_sockets(const struct arguments *args, fd_set *rfds, fd_set *wfds, fd_set *efds) {
struct udp_session *cur = udp_session;
while (cur != NULL) {