mirror of https://github.com/M66B/NetGuard.git
Native close
This commit is contained in:
parent
36bb564edb
commit
a317fa3f3e
|
@ -78,6 +78,8 @@ jint getUid(const int, const int, const void *, const uint16_t);
|
||||||
|
|
||||||
uint16_t checksum(uint8_t *, uint16_t);
|
uint16_t checksum(uint8_t *, uint16_t);
|
||||||
|
|
||||||
|
const char *strstate(const int state);
|
||||||
|
|
||||||
char *hex(const u_int8_t *, const u_int16_t);
|
char *hex(const u_int8_t *, const u_int16_t);
|
||||||
|
|
||||||
// Global variables
|
// Global variables
|
||||||
|
@ -228,12 +230,13 @@ void *handle_events(void *a) {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
} else if (cur->state != TCP_TIME_WAIT) {
|
} else if (cur->state != TCP_TIME_WAIT) {
|
||||||
if (cur->state == TCP_SYN_RECV) {
|
if (cur->state == TCP_LISTEN) {
|
||||||
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 ||
|
else if (cur->state == TCP_ESTABLISHED ||
|
||||||
|
cur->state == TCP_SYN_RECV ||
|
||||||
cur->state == TCP_CLOSE_WAIT) {
|
cur->state == TCP_CLOSE_WAIT) {
|
||||||
FD_SET(cur->socket, &rfds);
|
FD_SET(cur->socket, &rfds);
|
||||||
if (cur->socket > max)
|
if (cur->socket > max)
|
||||||
|
@ -281,6 +284,9 @@ void *handle_events(void *a) {
|
||||||
if (length < 0) {
|
if (length < 0) {
|
||||||
__android_log_print(ANDROID_LOG_ERROR, TAG, "tun read error %d: %s",
|
__android_log_print(ANDROID_LOG_ERROR, TAG, "tun read error %d: %s",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
|
if (errno == EINTR)
|
||||||
|
continue;
|
||||||
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (length > 0)
|
if (length > 0)
|
||||||
|
@ -302,7 +308,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_TIME_WAIT;
|
cur->state = TCP_TIME_WAIT; // will close socket
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -310,13 +316,14 @@ 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_TIME_WAIT;
|
if (serr != EINTR)
|
||||||
|
cur->state = TCP_TIME_WAIT; // will close socket
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur->state == TCP_SYN_RECV) {
|
if (cur->state == TCP_LISTEN) {
|
||||||
// Check socket connect
|
// Check socket connect
|
||||||
if (FD_ISSET(cur->socket, &wfds) && canWrite(args->tun)) {
|
if (FD_ISSET(cur->socket, &wfds) && canWrite(args->tun)) {
|
||||||
// Log
|
// Log
|
||||||
|
@ -326,63 +333,58 @@ void *handle_events(void *a) {
|
||||||
dest, ntohs(cur->dest), cur->lport);
|
dest, ntohs(cur->dest), cur->lport);
|
||||||
|
|
||||||
// TODO can write
|
// TODO can write
|
||||||
if (writeTCP(cur, NULL, 1, 1, 0, 0, args->tun) < 0) { // SYN
|
if (writeTCP(cur, NULL, 1, 1, 0, 0, args->tun) < 0) { // SYN+ACK
|
||||||
__android_log_print(ANDROID_LOG_ERROR, TAG, "write SYN error %d: %s",
|
__android_log_print(ANDROID_LOG_ERROR, TAG,
|
||||||
|
"write SYN+ACK error %d: %s",
|
||||||
errno, strerror((errno)));
|
errno, strerror((errno)));
|
||||||
cur->state = TCP_TIME_WAIT;
|
// Remote will retry
|
||||||
|
cur->state = TCP_TIME_WAIT; // will close socket
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
continue;
|
continue;
|
||||||
} else
|
} else {
|
||||||
cur->state = TCP_SYN_SENT;
|
cur->local_seq++;
|
||||||
|
cur->remote_seq++;
|
||||||
|
cur->state = TCP_SYN_RECV;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (cur->state == TCP_ESTABLISHED ||
|
else if (cur->state == TCP_SYN_RECV ||
|
||||||
|
cur->state == TCP_ESTABLISHED ||
|
||||||
cur->state == TCP_CLOSE_WAIT) {
|
cur->state == TCP_CLOSE_WAIT) {
|
||||||
// Check socket read
|
// Check socket read
|
||||||
if (FD_ISSET(cur->socket, &rfds)) {
|
if (FD_ISSET(cur->socket, &rfds)) {
|
||||||
|
// TODO window size
|
||||||
uint8_t buffer[MAXPKT];
|
uint8_t buffer[MAXPKT];
|
||||||
ssize_t bytes = recv(cur->socket, buffer, MAXPKT, 0);
|
ssize_t bytes = recv(cur->socket, buffer, MAXPKT, 0);
|
||||||
|
if (bytes <= 0) {
|
||||||
|
// Socket remotely closed / error
|
||||||
if (bytes < 0) {
|
if (bytes < 0) {
|
||||||
__android_log_print(ANDROID_LOG_ERROR, TAG, "recv socket error %d: %s",
|
__android_log_print(ANDROID_LOG_ERROR, TAG,
|
||||||
|
"recv socket error %d: %s",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
if (errno != EINTR) {
|
if (errno == EINTR) {
|
||||||
// TODO initiate FIN
|
|
||||||
cur->state = TCP_TIME_WAIT;
|
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (bytes == 0) {
|
else
|
||||||
// Socket remotely closed
|
__android_log_print(ANDROID_LOG_DEBUG, TAG, "recv socket empty");
|
||||||
if (cur->state == TCP_ESTABLISHED) {
|
|
||||||
// TODO initiate FIN
|
|
||||||
__android_log_print(ANDROID_LOG_WARN, TAG, "recv socket empty");
|
|
||||||
|
|
||||||
if (writeTCP(cur, NULL, 1, 0, 1, 0, args->tun) < 0) // FIN
|
// TODO can write
|
||||||
|
if (writeTCP(cur, NULL, 0, 0, 1, 0, args->tun) < 0) // FIN
|
||||||
__android_log_print(ANDROID_LOG_ERROR, TAG,
|
__android_log_print(ANDROID_LOG_ERROR, TAG,
|
||||||
"write FIN error %d: %s",
|
"write FIN error %d: %s",
|
||||||
errno, strerror((errno)));
|
errno, strerror((errno)));
|
||||||
else {
|
else {
|
||||||
__android_log_print(ANDROID_LOG_DEBUG, TAG,
|
__android_log_print(ANDROID_LOG_DEBUG, TAG,
|
||||||
"Half close initiated");
|
"Half close initiated");
|
||||||
|
cur->local_seq++;
|
||||||
|
if (cur->state == TCP_SYN_RECV || cur->state == TCP_ESTABLISHED)
|
||||||
cur->state = TCP_FIN_WAIT1;
|
cur->state = TCP_FIN_WAIT1;
|
||||||
}
|
else // close wait
|
||||||
}
|
|
||||||
else if (cur->state == TCP_CLOSE_WAIT) {
|
|
||||||
// TODO can write
|
|
||||||
if (writeTCP(cur, NULL, 1, 0, 1, 0, args->tun) < 0) // FIN
|
|
||||||
__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");
|
|
||||||
cur->state = TCP_LAST_ACK;
|
cur->state = TCP_LAST_ACK;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
__android_log_print(ANDROID_LOG_ERROR, TAG, "Invalid state %d",
|
|
||||||
cur->state);
|
|
||||||
} else {
|
} else {
|
||||||
__android_log_print(ANDROID_LOG_DEBUG, TAG,
|
__android_log_print(ANDROID_LOG_DEBUG, TAG,
|
||||||
"recv socket lport %u bytes %d",
|
"recv socket lport %u bytes %d",
|
||||||
|
@ -405,12 +407,8 @@ void *handle_events(void *a) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (cur->state == TCP_TIME_WAIT) {
|
__android_log_print(ANDROID_LOG_DEBUG, TAG, "New state %s",
|
||||||
// Happens after full close
|
strstate(cur->state));
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Unknown state %d", cur->state);
|
|
||||||
|
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
|
@ -425,6 +423,7 @@ void *handle_events(void *a) {
|
||||||
|
|
||||||
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Stopped events tun=%d thread %u",
|
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Stopped events tun=%d thread %u",
|
||||||
args->tun, thread_id);
|
args->tun, thread_id);
|
||||||
|
// TODO conditionally report to Java
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_ip(JNIEnv *env, jobject instance, const struct arguments *args,
|
void handle_ip(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
|
@ -608,6 +607,7 @@ void handle_tcp(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
struct session *last = NULL;
|
struct session *last = NULL;
|
||||||
struct session *cur = session;
|
struct session *cur = session;
|
||||||
while (cur != NULL && !(cur->saddr == iphdr->saddr && cur->source == tcphdr->source)) {
|
while (cur != NULL && !(cur->saddr == iphdr->saddr && cur->source == tcphdr->source)) {
|
||||||
|
// TODO check source
|
||||||
last = cur;
|
last = cur;
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
|
@ -615,9 +615,10 @@ void handle_tcp(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
// Log
|
// Log
|
||||||
char dest[20];
|
char dest[20];
|
||||||
inet_ntop(AF_INET, &(iphdr->daddr), dest, sizeof(dest));
|
inet_ntop(AF_INET, &(iphdr->daddr), dest, sizeof(dest));
|
||||||
__android_log_print(ANDROID_LOG_DEBUG, TAG, "%s/%u seq %u ack %u data %d",
|
__android_log_print(ANDROID_LOG_DEBUG, TAG, "%s/%u seq %u ack %u window %u data %d",
|
||||||
dest, ntohs(tcphdr->dest),
|
dest, ntohs(tcphdr->dest),
|
||||||
ntohl(tcphdr->seq), ntohl(tcphdr->ack_seq), datalen);
|
ntohl(tcphdr->seq), ntohl(tcphdr->ack_seq),
|
||||||
|
ntohs(tcphdr->window), datalen);
|
||||||
|
|
||||||
if (cur == NULL) {
|
if (cur == NULL) {
|
||||||
if (tcphdr->syn) {
|
if (tcphdr->syn) {
|
||||||
|
@ -633,7 +634,7 @@ void handle_tcp(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
syn->source = tcphdr->source;
|
syn->source = tcphdr->source;
|
||||||
syn->daddr = iphdr->daddr;
|
syn->daddr = iphdr->daddr;
|
||||||
syn->dest = tcphdr->dest;
|
syn->dest = tcphdr->dest;
|
||||||
syn->state = TCP_SYN_RECV;
|
syn->state = TCP_LISTEN;
|
||||||
syn->next = NULL;
|
syn->next = NULL;
|
||||||
|
|
||||||
// TODO handle SYN data?
|
// TODO handle SYN data?
|
||||||
|
@ -685,23 +686,25 @@ void handle_tcp(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Existing session lport %u", cur->lport);
|
int oldstate = cur->state;
|
||||||
|
uint32_t oldlocal = cur->local_seq;
|
||||||
|
uint32_t oldremote = cur->remote_seq;
|
||||||
|
|
||||||
|
__android_log_print(ANDROID_LOG_DEBUG, TAG,
|
||||||
|
"Session lport %u current state %s local %u remote %u",
|
||||||
|
cur->lport, strstate(cur->state), cur->local_seq, cur->remote_seq);
|
||||||
|
|
||||||
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 && !tcphdr->fin) {
|
else if (tcphdr->ack && !tcphdr->fin) {
|
||||||
cur->time = time(NULL);
|
cur->time = time(NULL);
|
||||||
|
|
||||||
if (cur->state == TCP_SYN_SENT) {
|
if (cur->state == TCP_SYN_RECV) {
|
||||||
// TODO proper wrap around
|
// TODO proper wrap around
|
||||||
if (ntohl(tcphdr->ack_seq) == cur->local_seq + 1 &&
|
if (ntohl(tcphdr->ack_seq) == cur->local_seq &&
|
||||||
ntohl(tcphdr->seq) >= cur->remote_seq + 1) {
|
ntohl(tcphdr->seq) >= cur->remote_seq) {
|
||||||
cur->local_seq += 1; // local SYN
|
|
||||||
cur->remote_seq += 1; // remote SYN
|
|
||||||
// TODO process data?
|
// TODO process data?
|
||||||
|
|
||||||
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Established");
|
|
||||||
cur->state = TCP_ESTABLISHED;
|
cur->state = TCP_ESTABLISHED;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -715,16 +718,17 @@ void handle_tcp(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Keep alive");
|
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Keep alive");
|
||||||
else if (ntohl(tcphdr->seq) < cur->remote_seq)
|
else if (ntohl(tcphdr->seq) < cur->remote_seq)
|
||||||
__android_log_print(ANDROID_LOG_WARN, TAG, "Processed ack");
|
__android_log_print(ANDROID_LOG_WARN, TAG, "Processed ack");
|
||||||
else {
|
else if (ntohl(tcphdr->seq) == cur->remote_seq) {
|
||||||
__android_log_print(ANDROID_LOG_DEBUG, TAG, "New ack");
|
__android_log_print(ANDROID_LOG_DEBUG, TAG, "New ack");
|
||||||
if (data != NULL) {
|
if (data != NULL) {
|
||||||
// TODO non blocking
|
// TODO non blocking
|
||||||
__android_log_print(ANDROID_LOG_DEBUG, TAG, "send socket data %u",
|
__android_log_print(ANDROID_LOG_DEBUG, TAG, "send socket data %u",
|
||||||
data->len);
|
data->len);
|
||||||
if (send(cur->socket, data->data, data->len, 0) < 0)
|
if (send(cur->socket, data->data, data->len, 0) < 0) {
|
||||||
__android_log_print(ANDROID_LOG_ERROR, TAG, "send error %d: %s",
|
__android_log_print(ANDROID_LOG_ERROR, TAG, "send error %d: %s",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
else {
|
// Remote will retry
|
||||||
|
} else {
|
||||||
// TODO can write
|
// TODO can write
|
||||||
if (writeTCP(cur, NULL, data->len, 0, 0, 0, args->tun) < 0) // ACK
|
if (writeTCP(cur, NULL, data->len, 0, 0, 0, args->tun) < 0) // ACK
|
||||||
__android_log_print(ANDROID_LOG_ERROR, TAG,
|
__android_log_print(ANDROID_LOG_ERROR, TAG,
|
||||||
|
@ -735,70 +739,96 @@ void handle_tcp(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
__android_log_print(ANDROID_LOG_WARN, TAG, "Invalid remote seq");
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (cur->state == TCP_LAST_ACK) {
|
else if (cur->state == TCP_LAST_ACK) {
|
||||||
if (ntohl(tcphdr->ack_seq) == cur->local_seq + 1 &&
|
if (ntohl(tcphdr->ack_seq) == cur->local_seq &&
|
||||||
ntohl(tcphdr->seq) >= cur->remote_seq + 1) {
|
ntohl(tcphdr->seq) == cur->remote_seq) {
|
||||||
cur->local_seq += 1; // local ACK
|
|
||||||
cur->remote_seq += 1; // remote FIN
|
|
||||||
|
|
||||||
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Full close");
|
|
||||||
// socket has been shutdown already
|
// socket has been shutdown already
|
||||||
cur->state = TCP_TIME_WAIT;
|
cur->state = TCP_TIME_WAIT; // Will close socket
|
||||||
}
|
}
|
||||||
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) {
|
else if (cur->state == TCP_FIN_WAIT1) {
|
||||||
// TODO process ACK
|
// TODO check seq/ack
|
||||||
__android_log_print(ANDROID_LOG_DEBUG, TAG, "FIN wait 1");
|
|
||||||
cur->state = TCP_FIN_WAIT2;
|
cur->state = TCP_FIN_WAIT2;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (cur->state == TCP_CLOSING) {
|
else if (cur->state == TCP_CLOSING) {
|
||||||
// TODO process ACK
|
// TODO check seq/ack
|
||||||
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Closing");
|
|
||||||
cur->state = TCP_TIME_WAIT;
|
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");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tcphdr->fin) {
|
else if (tcphdr->fin /* ack */) {
|
||||||
if (cur->state == TCP_ESTABLISHED) {
|
if (ntohl(tcphdr->ack_seq) == cur->local_seq &&
|
||||||
if (shutdown(cur->socket, SHUT_RD))
|
ntohl(tcphdr->seq) == cur->remote_seq) {
|
||||||
|
|
||||||
|
if (shutdown(cur->socket, SHUT_RD)) {
|
||||||
__android_log_print(ANDROID_LOG_ERROR, TAG, "shutdown error %d: %s",
|
__android_log_print(ANDROID_LOG_ERROR, TAG, "shutdown error %d: %s",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
else
|
// Remote will retry
|
||||||
|
}
|
||||||
|
else {
|
||||||
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Shutdown socket");
|
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Shutdown socket");
|
||||||
cur->state = TCP_CLOSE_WAIT;
|
|
||||||
|
int ok = 1;
|
||||||
|
if (tcphdr->ack && datalen) {
|
||||||
|
// TODO non blocking
|
||||||
|
__android_log_print(ANDROID_LOG_DEBUG, TAG, "send socket data %u",
|
||||||
|
data->len);
|
||||||
|
if (send(cur->socket, data->data, data->len, 0) < 0) {
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, TAG, "send error %d: %s",
|
||||||
|
errno, strerror(errno));
|
||||||
|
ok = 0;
|
||||||
}
|
}
|
||||||
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
|
|
||||||
__android_log_print(ANDROID_LOG_WARN, TAG, "Invalid FIN state %d", cur->state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tcphdr->rst) {
|
if (ok) {
|
||||||
|
// TODO can write
|
||||||
|
if (writeTCP(cur, NULL, 1 + datalen, 0, 0, 0, args->tun) < 0) // ACK
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, TAG,
|
||||||
|
"write ACK error %d: %s",
|
||||||
|
errno, strerror((errno)));
|
||||||
|
else {
|
||||||
|
cur->remote_seq += 1 + datalen; // FIN + data
|
||||||
|
if (cur->state == TCP_ESTABLISHED)
|
||||||
|
cur->state = TCP_CLOSE_WAIT;
|
||||||
|
else if (cur->state == TCP_FIN_WAIT1) if (tcphdr->ack)
|
||||||
cur->state = TCP_TIME_WAIT;
|
cur->state = TCP_TIME_WAIT;
|
||||||
|
else
|
||||||
|
cur->state = TCP_CLOSING;
|
||||||
|
else if (cur->state == TCP_FIN_WAIT2)
|
||||||
|
cur->state = TCP_TIME_WAIT;
|
||||||
|
else
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, TAG, "Invalid FIN");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
__android_log_print(ANDROID_LOG_WARN, TAG, "Invalid seq/ack");
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (tcphdr->rst)
|
||||||
|
cur->state = TCP_TIME_WAIT; // will close socket
|
||||||
|
|
||||||
|
else
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, TAG, "Unknown packet");
|
||||||
|
|
||||||
|
if (cur->state != oldstate || cur->local_seq != oldlocal || cur->remote_seq != oldremote)
|
||||||
|
__android_log_print(ANDROID_LOG_DEBUG, TAG,
|
||||||
|
"Session lport %u new state %s local %u remote %u",
|
||||||
|
cur->lport, strstate(cur->state), cur->local_seq, cur->remote_seq);
|
||||||
|
}
|
||||||
|
|
||||||
if (data != NULL) {
|
if (data != NULL) {
|
||||||
free(data->data);
|
free(data->data);
|
||||||
|
@ -1043,6 +1073,38 @@ uint16_t checksum(uint8_t *buffer, uint16_t length) {
|
||||||
return (uint16_t) (~sum);
|
return (uint16_t) (~sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *strstate(const int state) {
|
||||||
|
char buf[20];
|
||||||
|
switch (state) {
|
||||||
|
case TCP_ESTABLISHED:
|
||||||
|
return "Established";
|
||||||
|
case TCP_SYN_SENT:
|
||||||
|
return "SYN sent";
|
||||||
|
case TCP_SYN_RECV:
|
||||||
|
return "SYN recv";
|
||||||
|
case TCP_FIN_WAIT1:
|
||||||
|
return "FIN wait 1";
|
||||||
|
case TCP_FIN_WAIT2:
|
||||||
|
return "FIN wait 2";
|
||||||
|
case TCP_TIME_WAIT:
|
||||||
|
return "Time wait";
|
||||||
|
case TCP_CLOSE:
|
||||||
|
return "Close";
|
||||||
|
case TCP_CLOSE_WAIT:
|
||||||
|
return "Close wait";
|
||||||
|
case TCP_LAST_ACK:
|
||||||
|
return "Last ACK";
|
||||||
|
case TCP_LISTEN:
|
||||||
|
return "Listen";
|
||||||
|
case TCP_CLOSING:
|
||||||
|
return "Closing";
|
||||||
|
default:
|
||||||
|
sprintf(buf, "%d", state);
|
||||||
|
return buf;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
char *hex(const u_int8_t *data, const u_int16_t len) {
|
char *hex(const u_int8_t *data, const u_int16_t len) {
|
||||||
char hex_str[] = "0123456789ABCDEF";
|
char hex_str[] = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue