1
0
Fork 0
mirror of https://github.com/M66B/NetGuard.git synced 2025-01-01 12:54:07 +00:00

Native refactoring

This commit is contained in:
M66B 2016-02-09 19:55:28 +01:00
parent e638533e06
commit 47a27f61c4
6 changed files with 215 additions and 196 deletions

View file

@ -100,7 +100,6 @@
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/objectFiles" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard-rules" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/restart-dex" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />

View file

@ -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) {

View file

@ -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);

View file

@ -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;
}
}
}

View file

@ -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) {

View file

@ -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) {