mirror of https://github.com/M66B/NetGuard.git
Native active close states
This commit is contained in:
parent
e5d403e2a7
commit
9a83f2b17d
|
@ -131,6 +131,7 @@ Java_eu_faircode_netguard_SinkholeService_jni_1stop(JNIEnv *env, jobject instanc
|
||||||
__android_log_print(ANDROID_LOG_WARN, TAG, "pthread_join error %d: %s",
|
__android_log_print(ANDROID_LOG_WARN, TAG, "pthread_join error %d: %s",
|
||||||
err, strerror(err));
|
err, strerror(err));
|
||||||
}
|
}
|
||||||
|
// TODO: clear connection (not reload)
|
||||||
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Stopped");
|
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Stopped");
|
||||||
} else
|
} else
|
||||||
__android_log_print(ANDROID_LOG_WARN, TAG, "Not running");
|
__android_log_print(ANDROID_LOG_WARN, TAG, "Not running");
|
||||||
|
@ -194,6 +195,7 @@ void *handle_events(void *a) {
|
||||||
FD_ZERO(&wfds);
|
FD_ZERO(&wfds);
|
||||||
FD_ZERO(&efds);
|
FD_ZERO(&efds);
|
||||||
|
|
||||||
|
// Always read tun
|
||||||
FD_SET(args->tun, &rfds);
|
FD_SET(args->tun, &rfds);
|
||||||
FD_SET(args->tun, &efds);
|
FD_SET(args->tun, &efds);
|
||||||
|
|
||||||
|
@ -202,16 +204,17 @@ void *handle_events(void *a) {
|
||||||
struct connection *last = NULL;
|
struct connection *last = NULL;
|
||||||
struct connection *cur = connection;
|
struct connection *cur = connection;
|
||||||
while (cur != NULL) {
|
while (cur != NULL) {
|
||||||
if (cur->state == TCP_CLOSE || cur->time + TCPTIMEOUT < now) {
|
if (cur->state == TCP_TIME_WAIT || cur->time + TCPTIMEOUT < now) {
|
||||||
// Log
|
// Log
|
||||||
inet_ntop(AF_INET, &(cur->daddr), dest, sizeof(dest));
|
inet_ntop(AF_INET, &(cur->daddr), dest, sizeof(dest));
|
||||||
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Idle %s/%u lport %u close %d",
|
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Idle %s/%u lport %u close %d",
|
||||||
dest, ntohs(cur->dest), cur->lport,
|
dest, ntohs(cur->dest), cur->lport,
|
||||||
(cur->state == TCP_CLOSE));
|
(cur->state == TCP_TIME_WAIT));
|
||||||
|
|
||||||
if (close(cur->socket))
|
if (close(cur->socket))
|
||||||
__android_log_print(ANDROID_LOG_ERROR, TAG, "close error %d: %s",
|
__android_log_print(ANDROID_LOG_ERROR, TAG, "close error %d: %s",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
|
// TCP_CLOSE state
|
||||||
|
|
||||||
struct data *prev;
|
struct data *prev;
|
||||||
struct data *sent = cur->sent;
|
struct data *sent = cur->sent;
|
||||||
|
@ -233,13 +236,14 @@ void *handle_events(void *a) {
|
||||||
free(c);
|
free(c);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
} else if (cur->state != TCP_CLOSE) {
|
} else if (cur->state != TCP_TIME_WAIT) {
|
||||||
if (cur->state == TCP_SYN_RECV) {
|
if (cur->state == TCP_SYN_RECV) {
|
||||||
FD_SET(cur->socket, &wfds);
|
FD_SET(cur->socket, &wfds);
|
||||||
if (cur->socket > max)
|
if (cur->socket > max)
|
||||||
max = cur->socket;
|
max = cur->socket;
|
||||||
}
|
}
|
||||||
else if (cur->state == TCP_ESTABLISHED || cur->state == TCP_CLOSE_WAIT) {
|
else if (cur->state == TCP_ESTABLISHED ||
|
||||||
|
cur->state == TCP_CLOSE_WAIT) {
|
||||||
FD_SET(cur->socket, &rfds);
|
FD_SET(cur->socket, &rfds);
|
||||||
if (cur->socket > max)
|
if (cur->socket > max)
|
||||||
max = cur->socket;
|
max = cur->socket;
|
||||||
|
@ -307,7 +311,7 @@ void *handle_events(void *a) {
|
||||||
__android_log_print(ANDROID_LOG_ERROR, TAG, "getsockopt error %d: %s",
|
__android_log_print(ANDROID_LOG_ERROR, TAG, "getsockopt error %d: %s",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
// TODO initiate finish
|
// TODO initiate finish
|
||||||
cur->state = TCP_CLOSE;
|
cur->state = TCP_TIME_WAIT;
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -315,7 +319,7 @@ void *handle_events(void *a) {
|
||||||
__android_log_print(ANDROID_LOG_ERROR, TAG, "SO_ERROR %d: %s",
|
__android_log_print(ANDROID_LOG_ERROR, TAG, "SO_ERROR %d: %s",
|
||||||
serr, strerror(serr));
|
serr, strerror(serr));
|
||||||
// TODO initiate FIN
|
// TODO initiate FIN
|
||||||
cur->state = TCP_CLOSE;
|
cur->state = TCP_TIME_WAIT;
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -334,7 +338,7 @@ void *handle_events(void *a) {
|
||||||
if (writeTCP(cur, NULL, 1, 1, 0, 0, args->tun) < 0) { // SYN
|
if (writeTCP(cur, NULL, 1, 1, 0, 0, args->tun) < 0) { // SYN
|
||||||
__android_log_print(ANDROID_LOG_ERROR, TAG, "write SYN error %d: %s",
|
__android_log_print(ANDROID_LOG_ERROR, TAG, "write SYN error %d: %s",
|
||||||
errno, strerror((errno)));
|
errno, strerror((errno)));
|
||||||
cur->state = TCP_CLOSE;
|
cur->state = TCP_TIME_WAIT;
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
continue;
|
continue;
|
||||||
} else
|
} else
|
||||||
|
@ -342,7 +346,8 @@ void *handle_events(void *a) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (cur->state == TCP_ESTABLISHED || cur->state == TCP_CLOSE_WAIT) {
|
else if (cur->state == TCP_ESTABLISHED ||
|
||||||
|
cur->state == TCP_CLOSE_WAIT) {
|
||||||
// Check socket read
|
// Check socket read
|
||||||
if (FD_ISSET(cur->socket, &rfds)) {
|
if (FD_ISSET(cur->socket, &rfds)) {
|
||||||
uint8_t buffer[MAXPKT];
|
uint8_t buffer[MAXPKT];
|
||||||
|
@ -352,18 +357,26 @@ void *handle_events(void *a) {
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
if (errno != EINTR) {
|
if (errno != EINTR) {
|
||||||
// TODO initiate FIN
|
// TODO initiate FIN
|
||||||
cur->state = TCP_CLOSE;
|
cur->state = TCP_TIME_WAIT;
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (bytes == 0) {
|
else if (bytes == 0) {
|
||||||
|
// Socket remotely closed
|
||||||
if (cur->state == TCP_ESTABLISHED) {
|
if (cur->state == TCP_ESTABLISHED) {
|
||||||
// TODO initiate FIN
|
// TODO initiate FIN
|
||||||
__android_log_print(ANDROID_LOG_WARN, TAG, "recv socket empty");
|
__android_log_print(ANDROID_LOG_WARN, TAG, "recv socket empty");
|
||||||
cur->state = TCP_CLOSE;
|
|
||||||
cur = cur->next;
|
if (writeTCP(cur, NULL, 1, 0, 1, 0, args->tun) < 0) // FIN
|
||||||
continue;
|
__android_log_print(ANDROID_LOG_ERROR, TAG,
|
||||||
|
"write FIN error %d: %s",
|
||||||
|
errno, strerror((errno)));
|
||||||
|
else {
|
||||||
|
__android_log_print(ANDROID_LOG_DEBUG, TAG,
|
||||||
|
"Half close initiated");
|
||||||
|
cur->state = TCP_FIN_WAIT1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (cur->state == TCP_CLOSE_WAIT) {
|
else if (cur->state == TCP_CLOSE_WAIT) {
|
||||||
// TODO can write
|
// TODO can write
|
||||||
|
@ -402,7 +415,7 @@ void *handle_events(void *a) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (cur->state == TCP_CLOSE) {
|
else if (cur->state == TCP_TIME_WAIT) {
|
||||||
// Happens after full close
|
// Happens after full close
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -645,7 +658,7 @@ void handle_tcp(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
// Open socket
|
// Open socket
|
||||||
syn->socket = openSocket(env, instance, &daddr);
|
syn->socket = openSocket(env, instance, &daddr);
|
||||||
if (syn->socket < 0) {
|
if (syn->socket < 0) {
|
||||||
syn->state = TCP_CLOSE;
|
syn->state = TCP_TIME_WAIT;
|
||||||
// Remote will retry
|
// Remote will retry
|
||||||
free(syn);
|
free(syn);
|
||||||
}
|
}
|
||||||
|
@ -670,7 +683,7 @@ void handle_tcp(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
rst->source = tcphdr->source;
|
rst->source = tcphdr->source;
|
||||||
rst->daddr = iphdr->daddr;
|
rst->daddr = iphdr->daddr;
|
||||||
rst->dest = tcphdr->dest;
|
rst->dest = tcphdr->dest;
|
||||||
rst->state = TCP_CLOSE;
|
rst->state = TCP_TIME_WAIT;
|
||||||
rst->sent = NULL;
|
rst->sent = NULL;
|
||||||
rst->next = NULL;
|
rst->next = NULL;
|
||||||
|
|
||||||
|
@ -688,7 +701,7 @@ void handle_tcp(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
if (tcphdr->syn)
|
if (tcphdr->syn)
|
||||||
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Ignoring repeated SYN");
|
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Ignoring repeated SYN");
|
||||||
|
|
||||||
if (tcphdr->ack) {
|
if (tcphdr->ack && !tcphdr->fin) {
|
||||||
cur->time = time(NULL);
|
cur->time = time(NULL);
|
||||||
|
|
||||||
if (cur->state == TCP_SYN_SENT) {
|
if (cur->state == TCP_SYN_SENT) {
|
||||||
|
@ -743,12 +756,24 @@ void handle_tcp(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
|
|
||||||
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Full close");
|
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Full close");
|
||||||
// socket has been shutdown already
|
// socket has been shutdown already
|
||||||
cur->state = TCP_CLOSE;
|
cur->state = TCP_TIME_WAIT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
__android_log_print(ANDROID_LOG_WARN, TAG, "Invalid seq/ack");
|
__android_log_print(ANDROID_LOG_WARN, TAG, "Invalid seq/ack");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (cur->state == TCP_FIN_WAIT1) {
|
||||||
|
// TODO process ACK
|
||||||
|
__android_log_print(ANDROID_LOG_DEBUG, TAG, "FIN wait 1");
|
||||||
|
cur->state = TCP_FIN_WAIT2;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (cur->state == TCP_CLOSING) {
|
||||||
|
// TODO process ACK
|
||||||
|
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Closing");
|
||||||
|
cur->state = TCP_TIME_WAIT;
|
||||||
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
__android_log_print(ANDROID_LOG_WARN, TAG, "Invalid ACK state %d", cur->state);
|
__android_log_print(ANDROID_LOG_WARN, TAG, "Invalid ACK state %d", cur->state);
|
||||||
}
|
}
|
||||||
|
@ -762,12 +787,27 @@ void handle_tcp(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Shutdown socket");
|
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Shutdown socket");
|
||||||
cur->state = TCP_CLOSE_WAIT;
|
cur->state = TCP_CLOSE_WAIT;
|
||||||
}
|
}
|
||||||
|
else if (cur->state == TCP_FIN_WAIT1) {
|
||||||
|
__android_log_print(ANDROID_LOG_DEBUG, TAG, "FIN wait 1");
|
||||||
|
if (tcphdr->ack) {
|
||||||
|
// TODO send ACK
|
||||||
|
cur->state = TCP_TIME_WAIT;
|
||||||
|
} else {
|
||||||
|
// TODO send ACK
|
||||||
|
cur->state = TCP_CLOSING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (cur->state == TCP_FIN_WAIT2) {
|
||||||
|
__android_log_print(ANDROID_LOG_DEBUG, TAG, "FIN wait 2");
|
||||||
|
// TODO send ACK
|
||||||
|
cur->state = TCP_TIME_WAIT;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
__android_log_print(ANDROID_LOG_WARN, TAG, "Invalid FIN state %d", cur->state);
|
__android_log_print(ANDROID_LOG_WARN, TAG, "Invalid FIN state %d", cur->state);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tcphdr->rst) {
|
if (tcphdr->rst) {
|
||||||
cur->state = TCP_CLOSE;
|
cur->state = TCP_TIME_WAIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue