1
0
Fork 0
mirror of https://github.com/M66B/NetGuard.git synced 2025-02-26 16:13:01 +00:00

Native added TCP close state

This commit is contained in:
M66B 2016-01-21 12:04:41 +01:00
parent f64298769e
commit 568a8b72bc
2 changed files with 248 additions and 211 deletions

View file

@ -237,6 +237,9 @@ void handle_events(void *a) {
while (1) {
log_android(ANDROID_LOG_DEBUG, "Loop thread %lu", thread_id);
// Check sessions
check_sessions(args);
// Select
ts.tv_sec = SELECT_TIMEOUT;
ts.tv_nsec = 0;
@ -248,7 +251,7 @@ void handle_events(void *a) {
if (ready < 0) {
if (errno == EINTR) {
if (signaled) { ;
log_android(ANDROID_LOG_DEBUG, "pselect signaled");
log_android(ANDROID_LOG_WARN, "pselect signaled");
break;
} else {
log_android(ANDROID_LOG_WARN, "pselect interrupted");
@ -329,20 +332,10 @@ void handle_events(void *a) {
// TODO report exit to Java
}
int get_selects(const struct arguments *args, fd_set *rfds, fd_set *wfds, fd_set *efds) {
void check_sessions(const struct arguments *args) {
time_t now = time(NULL);
// Initialize
FD_ZERO(rfds);
FD_ZERO(wfds);
FD_ZERO(efds);
// Always select tun
FD_SET(args->tun, rfds);
FD_SET(args->tun, efds);
int max = args->tun;
// Select UDP sockets
// Check UDP sessions
struct udp_session *ul = NULL;
struct udp_session *u = udp_session;
while (u != NULL) {
@ -361,22 +354,23 @@ int get_selects(const struct arguments *args, fd_set *rfds, fd_set *wfds, fd_set
struct udp_session *c = u;
u = u->next;
free(c);
continue;
} else {
FD_SET(u->socket, efds);
FD_SET(u->socket, rfds);
if (u->socket > max)
max = u->socket;
}
else {
ul = u;
u = u->next;
}
}
// Select TCP sockets
// Check TCP sessions
struct tcp_session *tl = NULL;
struct tcp_session *t = tcp_session;
while (t != NULL) {
char source[20];
char dest[20];
inet_ntop(AF_INET, &(t->saddr), source, sizeof(source));
inet_ntop(AF_INET, &(t->daddr), dest, sizeof(dest));
// Check connection timeout
int timeout = 0;
if (t->state == TCP_LISTEN || t->state == TCP_SYN_RECV)
timeout = TCP_INIT_TIMEOUT;
@ -384,31 +378,29 @@ int get_selects(const struct arguments *args, fd_set *rfds, fd_set *wfds, fd_set
timeout = TCP_IDLE_TIMEOUT;
else
timeout = TCP_CLOSE_TIMEOUT;
char source[20];
char dest[20];
inet_ntop(AF_INET, &(t->saddr), source, sizeof(source));
inet_ntop(AF_INET, &(t->daddr), dest, sizeof(dest));
if (t->state != TCP_TIME_WAIT && t->time + timeout < now) {
if (t->state != TCP_TIME_WAIT && t->state != TCP_CLOSE && t->time + timeout < now) {
// TODO send keep alives?
log_android(ANDROID_LOG_WARN, "Idle from %s/%u to %s/%u",
dest, ntohs(t->dest), source, ntohs(t->source));
log_android(ANDROID_LOG_WARN, "Idle from %s/%u to %s/%u state %s",
dest, ntohs(t->dest), source, ntohs(t->source), strstate(t->state));
write_rst(args, t, args->tun);
}
// Check finished connection
if (t->state == TCP_TIME_WAIT) {
// Log
log_android(ANDROID_LOG_INFO, "Close %s/%u",
source, ntohs(t->source), dest, ntohs(t->dest));
// TODO keep for some time?
log_android(ANDROID_LOG_INFO, "Close from %s/%u to %s/%u socket %d",
source, ntohs(t->source), dest, ntohs(t->dest), t->socket);
// TODO non blocking?
if (close(t->socket))
log_android(ANDROID_LOG_ERROR, "close error %d: %s", errno, strerror(errno));
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
@ -417,9 +409,40 @@ int get_selects(const struct arguments *args, fd_set *rfds, fd_set *wfds, fd_set
struct tcp_session *c = t;
t = t->next;
free(c);
continue;
}
else {
tl = t;
t = t->next;
}
}
}
} else if (t->state == TCP_LISTEN) {
int get_selects(const struct arguments *args, fd_set *rfds, fd_set *wfds, fd_set *efds) {
// Initialize
FD_ZERO(rfds);
FD_ZERO(wfds);
FD_ZERO(efds);
// Always select tun
FD_SET(args->tun, rfds);
FD_SET(args->tun, efds);
int max = args->tun;
// Select UDP sockets
struct udp_session *u = udp_session;
while (u != NULL) {
FD_SET(u->socket, efds);
FD_SET(u->socket, rfds);
if (u->socket > max)
max = u->socket;
u = u->next;
}
// Select TCP sockets
struct tcp_session *t = tcp_session;
while (t != NULL) {
// Select sockets
if (t->state == TCP_LISTEN) {
// Check for connected / errors
FD_SET(t->socket, efds);
FD_SET(t->socket, wfds);
@ -436,7 +459,6 @@ int get_selects(const struct arguments *args, fd_set *rfds, fd_set *wfds, fd_set
max = t->socket;
}
tl = t;
t = t->next;
}
@ -592,7 +614,7 @@ void check_tcp_sockets(const struct arguments *args, fd_set *rfds, fd_set *wfds,
else if (bytes == 0) {
// Socket eof
// TCP: application close
log_android(ANDROID_LOG_DEBUG, "recv empty state %s", strstate(cur->state));
log_android(ANDROID_LOG_INFO, "recv empty state %s", strstate(cur->state));
if (write_fin_ack(args, cur, 0, args->tun) >= 0) {
cur->local_seq++; // local FIN
@ -605,7 +627,7 @@ void check_tcp_sockets(const struct arguments *args, fd_set *rfds, fd_set *wfds,
log_android(ANDROID_LOG_ERROR, "Unknown state %s",
strstate(cur->state));
log_android(ANDROID_LOG_DEBUG, "Half close state %s",
log_android(ANDROID_LOG_INFO, "Half close state %s",
strstate(cur->state));
}
} else {
@ -738,7 +760,7 @@ void handle_ip(const struct arguments *args, const uint8_t *buffer, const uint16
// Get uid
jint uid = -1;
if ((protocol == IPPROTO_TCP && (!args->filter || syn)) || protocol == IPPROTO_UDP) {
log_android(ANDROID_LOG_DEBUG, "get uid %s/%u syn %d", dest, dport, syn);
log_android(ANDROID_LOG_INFO, "get uid %s/%u syn %d", dest, dport, syn);
int tries = 0;
usleep(1000 * UID_DELAY);
while (uid < 0 && tries++ < UID_MAXTRY) {
@ -974,8 +996,9 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
}
else {
uint16_t lport = get_local_port(syn->socket);
log_android(ANDROID_LOG_DEBUG, "lport %u from %s/%u to %s/%u",
lport, source, ntohs(tcphdr->source), dest, ntohs(tcphdr->dest));
log_android(ANDROID_LOG_INFO, "Open from %s/%u to %s/%u socket %d lport %u ",
source, ntohs(tcphdr->source), dest, ntohs(tcphdr->dest),
syn->socket, lport);
if (last == NULL)
tcp_session = syn;
@ -1012,6 +1035,15 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
}
else {
// Session found
if (cur->state == TCP_CLOSE) {
log_android(ANDROID_LOG_WARN,
"Closed session from %s/%u to %s/%u state %s local %u remote %u",
source, ntohs(tcphdr->source),
dest, ntohs(cur->dest), strstate(cur->state),
cur->local_seq - cur->local_start,
cur->remote_seq - cur->remote_start);
}
else {
int oldstate = cur->state;
uint32_t oldlocal = cur->local_seq;
uint32_t oldremote = cur->remote_seq;
@ -1151,7 +1183,7 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
// TODO proper wrap around
if (ntohl(tcphdr->seq) == cur->remote_seq &&
ntohl(tcphdr->ack_seq) < cur->local_seq) {
log_android(ANDROID_LOG_INFO,
log_android(tcphdr->fin ? ANDROID_LOG_WARN : ANDROID_LOG_INFO,
"Previous %s from %s/%u to %s/%u state %s seq %u/%u ack %u/%u data %d",
flags,
source, ntohs(tcphdr->source),
@ -1165,7 +1197,7 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
} else if (ntohl(tcphdr->seq) < cur->remote_seq &&
ntohl(tcphdr->ack_seq) == cur->local_seq)
log_android(ANDROID_LOG_INFO,
log_android(tcphdr->fin ? ANDROID_LOG_WARN : ANDROID_LOG_INFO,
"Repeated %s from %s/%u to %s/%u state %s seq %u/%u ack %u/%u data %d",
flags,
source, ntohs(tcphdr->source),
@ -1193,7 +1225,8 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
}
}
if (cur->state != oldstate || cur->local_seq != oldlocal || cur->remote_seq != oldremote)
if (cur->state != oldstate || cur->local_seq != oldlocal ||
cur->remote_seq != oldremote)
log_android(ANDROID_LOG_INFO,
"Session from %s/%u to %s/%u new state %s local %u remote %u",
source, ntohs(tcphdr->source),
@ -1201,6 +1234,7 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
strstate(cur->state),
cur->local_seq - cur->local_start,
cur->remote_seq - cur->remote_start);
}
#ifdef PROFILE
gettimeofday(&end, NULL);

View file

@ -8,7 +8,8 @@
#define UDP_TTL 64
#define TCP_INIT_TIMEOUT 30 // seconds ~net.inet.tcp.keepinit
#define TCP_IDLE_TIMEOUT 300 // seconds ~net.inet.tcp.keepidle
#define TCP_CLOSE_TIMEOUT 30
#define TCP_CLOSE_TIMEOUT 30 // seconds
#define TCP_KEEP_TIMEOUT 300 // seconds
#define TCP_TTL 64
#define TCP_WINDOW 32768
#define UID_DELAY 1 // milliseconds
@ -89,6 +90,8 @@ void handle_signal(int sig, siginfo_t *info, void *context);
void handle_events(void *a);
void check_sessions(const struct arguments *args);
int get_selects(const struct arguments *args, fd_set *rfds, fd_set *wfds, fd_set *efds);
int check_tun(const struct arguments *args, fd_set *rfds, fd_set *wfds, fd_set *efds);