mirror of https://github.com/M66B/NetGuard.git
Native receive buffer
This commit is contained in:
parent
1542e29ccd
commit
1ba8a56118
|
@ -20,6 +20,12 @@
|
||||||
#define TIMEOUTPKT 30
|
#define TIMEOUTPKT 30
|
||||||
#define TTL 64
|
#define TTL 64
|
||||||
|
|
||||||
|
struct data {
|
||||||
|
__be32 seq;
|
||||||
|
jbyte *data;
|
||||||
|
struct data *next;
|
||||||
|
};
|
||||||
|
|
||||||
struct connection {
|
struct connection {
|
||||||
time_t time;
|
time_t time;
|
||||||
__be32 remote_seq; // host notation
|
__be32 remote_seq; // host notation
|
||||||
|
@ -31,6 +37,8 @@ struct connection {
|
||||||
int state;
|
int state;
|
||||||
int socket;
|
int socket;
|
||||||
int lport; // host notation
|
int lport; // host notation
|
||||||
|
struct data *received;
|
||||||
|
struct data *sent;
|
||||||
struct connection *next;
|
struct connection *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -108,6 +116,25 @@ void poll() {
|
||||||
else
|
else
|
||||||
last->next = cur->next;
|
last->next = cur->next;
|
||||||
|
|
||||||
|
struct data *prev;
|
||||||
|
struct data *received = cur->received;
|
||||||
|
while (received != NULL) {
|
||||||
|
prev = received;
|
||||||
|
received = received->next;
|
||||||
|
if (prev->data != NULL)
|
||||||
|
free(prev->data);
|
||||||
|
free(prev);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct data *sent = cur->sent;
|
||||||
|
while (sent != NULL) {
|
||||||
|
prev = sent;
|
||||||
|
sent = sent->next;
|
||||||
|
if (prev->data != NULL)
|
||||||
|
free(prev->data);
|
||||||
|
free(prev);
|
||||||
|
}
|
||||||
|
|
||||||
free(cur);
|
free(cur);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -205,8 +232,9 @@ void poll() {
|
||||||
|
|
||||||
// Send packet
|
// Send packet
|
||||||
__android_log_print(ANDROID_LOG_DEBUG, TAG,
|
__android_log_print(ANDROID_LOG_DEBUG, TAG,
|
||||||
"Sending SYN+ACK to tun %s/%u ack %u",
|
"Sending SYN+ACK to tun %s/%u seq %u ack %u",
|
||||||
to, ntohs(tcp->dest), ntohl(tcp->ack_seq));
|
to, ntohs(tcp->dest),
|
||||||
|
ntohl(tcp->seq), ntohl(tcp->ack_seq));
|
||||||
if (write(tun, buffer, len) < 0) {
|
if (write(tun, buffer, len) < 0) {
|
||||||
// TODO
|
// TODO
|
||||||
__android_log_print(ANDROID_LOG_ERROR, TAG, "write error %d: %s",
|
__android_log_print(ANDROID_LOG_ERROR, TAG, "write error %d: %s",
|
||||||
|
@ -231,25 +259,34 @@ void poll() {
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_tcp(JNIEnv *env, jobject instance, jbyte *buffer, int len) {
|
void handle_tcp(JNIEnv *env, jobject instance, jbyte *buffer, int length) {
|
||||||
// Check version
|
// Check version
|
||||||
jbyte version = (*buffer) >> 4;
|
jbyte version = (*buffer) >> 4;
|
||||||
if (version != 4)
|
if (version != 4)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Copy buffer
|
|
||||||
jbyte *copy = malloc(len); // TODO check/free
|
|
||||||
memcpy(copy, buffer, len);
|
|
||||||
|
|
||||||
// Get headers
|
// Get headers
|
||||||
struct iphdr *iphdr = copy;
|
struct iphdr *iphdr = buffer;
|
||||||
jbyte optlen = (iphdr->ihl > 5 ? copy[20] : 0);
|
jbyte optlen = (iphdr->ihl > 5 ? buffer[sizeof(struct iphdr)] : 0);
|
||||||
struct tcphdr *tcphdr = buffer + (20 + optlen) * sizeof(jbyte);
|
struct tcphdr *tcphdr = buffer + sizeof(struct iphdr) + optlen;
|
||||||
|
|
||||||
|
if (ntohs(iphdr->tot_len) != length)
|
||||||
|
__android_log_print(ANDROID_LOG_WARN, TAG, "Invalid length %u/%d", iphdr->tot_len, length);
|
||||||
|
|
||||||
|
// Get data
|
||||||
|
int dataoff = sizeof(struct iphdr) + optlen + sizeof(struct tcphdr);
|
||||||
|
int datalen = length - dataoff;
|
||||||
|
struct data *data = malloc(sizeof(struct data));
|
||||||
|
data->seq = ntohl(tcphdr->seq);
|
||||||
|
data->data = malloc(datalen); // TODO free
|
||||||
|
data->next = NULL;
|
||||||
|
if (datalen)
|
||||||
|
memcpy(data->data, buffer + dataoff, datalen);
|
||||||
|
|
||||||
// Search connection
|
// Search connection
|
||||||
struct connection *last = NULL;
|
struct connection *last = NULL;
|
||||||
struct connection *cur = connection;
|
struct connection *cur = connection;
|
||||||
while (cur != NULL && !(cur->saddr == iphdr->saddr && cur->source != tcphdr->source)) {
|
while (cur != NULL && !(cur->saddr == iphdr->saddr && cur->source == tcphdr->source)) {
|
||||||
last = cur;
|
last = cur;
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
|
@ -257,11 +294,14 @@ void handle_tcp(JNIEnv *env, jobject instance, jbyte *buffer, int len) {
|
||||||
// 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",
|
||||||
|
dest, ntohs(tcphdr->dest),
|
||||||
|
ntohl(tcphdr->seq), ntohl(tcphdr->ack_seq),
|
||||||
|
datalen);
|
||||||
|
|
||||||
if (cur == NULL) {
|
if (cur == NULL) {
|
||||||
if (tcphdr->syn) {
|
if (tcphdr->syn) {
|
||||||
__android_log_print(ANDROID_LOG_DEBUG, TAG, "SYN %s/%u seq %u", dest,
|
__android_log_print(ANDROID_LOG_DEBUG, TAG, "New SYN");
|
||||||
ntohs(tcphdr->dest), ntohl(tcphdr->seq));
|
|
||||||
|
|
||||||
// Register connection
|
// Register connection
|
||||||
struct connection *syn = malloc(sizeof(struct connection)); // TODO check/free
|
struct connection *syn = malloc(sizeof(struct connection)); // TODO check/free
|
||||||
|
@ -273,6 +313,8 @@ void handle_tcp(JNIEnv *env, jobject instance, jbyte *buffer, int len) {
|
||||||
syn->daddr = iphdr->daddr;
|
syn->daddr = iphdr->daddr;
|
||||||
syn->dest = tcphdr->dest;
|
syn->dest = tcphdr->dest;
|
||||||
syn->state = TCP_SYN_RECV;
|
syn->state = TCP_SYN_RECV;
|
||||||
|
syn->received = data;
|
||||||
|
syn->sent = NULL;
|
||||||
syn->next = NULL;
|
syn->next = NULL;
|
||||||
|
|
||||||
if (last == NULL)
|
if (last == NULL)
|
||||||
|
@ -352,17 +394,20 @@ void handle_tcp(JNIEnv *env, jobject instance, jbyte *buffer, int len) {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cur->time = time(NULL);
|
cur->time = time(NULL);
|
||||||
|
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Existing connection lport %u", cur->lport);
|
||||||
|
|
||||||
if (tcphdr->syn) {
|
if (tcphdr->syn) {
|
||||||
// TODO
|
// TODO
|
||||||
__android_log_print(ANDROID_LOG_DEBUG, TAG, "SYNx2 %s/%u", dest, ntohs(tcphdr->dest));
|
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Repeated SYN");
|
||||||
}
|
}
|
||||||
else if (tcphdr->ack) {
|
else if (tcphdr->ack) {
|
||||||
// TODO
|
// TODO
|
||||||
// check seq
|
// check seq
|
||||||
// check ack
|
// check ack
|
||||||
if (cur->state == TCP_SYN_SENT)
|
if (cur->state == TCP_SYN_SENT) {
|
||||||
|
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Established");
|
||||||
cur->state = TCP_ESTABLISHED;
|
cur->state = TCP_ESTABLISHED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shutdown(cur->socket, SHUT_RDWR);
|
shutdown(cur->socket, SHUT_RDWR);
|
||||||
|
|
Loading…
Reference in New Issue