mirror of https://github.com/M66B/NetGuard.git
Native optimize memory usage
This commit is contained in:
parent
e30b1a15d2
commit
83db13a773
|
@ -38,12 +38,6 @@ struct arguments {
|
||||||
int tun;
|
int tun;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct data {
|
|
||||||
uint32_t len;
|
|
||||||
uint8_t *data;
|
|
||||||
struct data *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct session {
|
struct session {
|
||||||
time_t time;
|
time_t time;
|
||||||
int uid;
|
int uid;
|
||||||
|
@ -72,7 +66,7 @@ int getLocalPort(const int);
|
||||||
|
|
||||||
int canWrite(const int);
|
int canWrite(const int);
|
||||||
|
|
||||||
int writeTCP(const struct session *, struct data *, uint16_t, int, int, int, int);
|
int writeTCP(const struct session *, uint8_t *, uint16_t, uint16_t, int, int, int, int);
|
||||||
|
|
||||||
jint getUid(const int, const int, const void *, const uint16_t);
|
jint getUid(const int, const int, const void *, const uint16_t);
|
||||||
|
|
||||||
|
@ -215,7 +209,7 @@ void *handle_events(void *a) {
|
||||||
cur->state == TCP_ESTABLISHED ||
|
cur->state == TCP_ESTABLISHED ||
|
||||||
cur->state == TCP_CLOSE_WAIT) {
|
cur->state == TCP_CLOSE_WAIT) {
|
||||||
// TODO can write
|
// TODO can write
|
||||||
if (writeTCP(cur, NULL, 0, 0, 1, 0, args->tun) < 0) { // FIN
|
if (writeTCP(cur, NULL, 0, 0, 0, 1, 0, args->tun) < 0) { // FIN
|
||||||
__android_log_print(ANDROID_LOG_ERROR, TAG,
|
__android_log_print(ANDROID_LOG_ERROR, TAG,
|
||||||
"write FIN lport %u error %d: %s",
|
"write FIN lport %u error %d: %s",
|
||||||
cur->lport, errno, strerror((errno)));
|
cur->lport, errno, strerror((errno)));
|
||||||
|
@ -362,7 +356,7 @@ void *handle_events(void *a) {
|
||||||
cur->lport, dest, ntohs(cur->dest));
|
cur->lport, dest, ntohs(cur->dest));
|
||||||
|
|
||||||
// TODO can write
|
// TODO can write
|
||||||
if (writeTCP(cur, NULL, 1, 1, 0, 0, args->tun) < 0) { // SYN+ACK
|
if (writeTCP(cur, NULL, 0, 1, 1, 0, 0, args->tun) < 0) { // SYN+ACK
|
||||||
__android_log_print(ANDROID_LOG_ERROR, TAG,
|
__android_log_print(ANDROID_LOG_ERROR, TAG,
|
||||||
"write SYN+ACK error %d: %s",
|
"write SYN+ACK error %d: %s",
|
||||||
errno, strerror((errno)));
|
errno, strerror((errno)));
|
||||||
|
@ -402,7 +396,7 @@ void *handle_events(void *a) {
|
||||||
cur->lport);
|
cur->lport);
|
||||||
|
|
||||||
// TODO can write
|
// TODO can write
|
||||||
if (writeTCP(cur, NULL, 0, 0, 1, 0, args->tun) < 0) // FIN
|
if (writeTCP(cur, NULL, 0, 0, 0, 1, 0, args->tun) < 0) // FIN
|
||||||
__android_log_print(ANDROID_LOG_ERROR, TAG,
|
__android_log_print(ANDROID_LOG_ERROR, TAG,
|
||||||
"write FIN lport %u error %d: %s",
|
"write FIN lport %u error %d: %s",
|
||||||
cur->lport, errno, strerror((errno)));
|
cur->lport, errno, strerror((errno)));
|
||||||
|
@ -419,20 +413,13 @@ void *handle_events(void *a) {
|
||||||
__android_log_print(ANDROID_LOG_DEBUG, TAG,
|
__android_log_print(ANDROID_LOG_DEBUG, TAG,
|
||||||
"recv lport %u bytes %d",
|
"recv lport %u bytes %d",
|
||||||
cur->lport, bytes);
|
cur->lport, bytes);
|
||||||
struct data *data = malloc(sizeof(struct data));
|
|
||||||
data->len = bytes;
|
|
||||||
data->data = malloc(bytes);
|
|
||||||
memcpy(data->data, buffer, bytes);
|
|
||||||
|
|
||||||
// TODO can write
|
// TODO can write
|
||||||
if (writeTCP(cur, data, 0, 0, 0, 0, args->tun) < 0) // ACK
|
if (writeTCP(cur, buffer, bytes, 0, 0, 0, 0, args->tun) < 0) // ACK
|
||||||
__android_log_print(ANDROID_LOG_ERROR, TAG,
|
__android_log_print(ANDROID_LOG_ERROR, TAG,
|
||||||
"write ACK lport %u error %d: %s",
|
"write ACK lport %u error %d: %s",
|
||||||
cur->lport, errno, strerror((errno)));
|
cur->lport, errno, strerror((errno)));
|
||||||
else
|
else
|
||||||
cur->local_seq += bytes;
|
cur->local_seq += bytes;
|
||||||
free(data->data);
|
|
||||||
free(data);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -621,14 +608,6 @@ void handle_tcp(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
// Get data
|
// Get data
|
||||||
uint16_t dataoff = sizeof(struct iphdr) + optlen + sizeof(struct tcphdr);
|
uint16_t dataoff = sizeof(struct iphdr) + optlen + sizeof(struct tcphdr);
|
||||||
uint16_t datalen = length - dataoff;
|
uint16_t datalen = length - dataoff;
|
||||||
struct data *data = NULL;
|
|
||||||
if (datalen > 0) {
|
|
||||||
data = malloc(sizeof(struct data));
|
|
||||||
data->len = datalen;
|
|
||||||
data->data = malloc(datalen);
|
|
||||||
memcpy(data->data, buffer + dataoff, datalen);
|
|
||||||
data->next = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search session
|
// Search session
|
||||||
struct session *last = NULL;
|
struct session *last = NULL;
|
||||||
|
@ -705,7 +684,7 @@ void handle_tcp(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
rst->next = NULL;
|
rst->next = NULL;
|
||||||
|
|
||||||
// TODO can write
|
// TODO can write
|
||||||
if (writeTCP(rst, NULL, 0, 0, 0, 1, args->tun) < 0)
|
if (writeTCP(rst, NULL, 0, 0, 0, 0, 1, args->tun) < 0)
|
||||||
__android_log_print(ANDROID_LOG_ERROR, TAG,
|
__android_log_print(ANDROID_LOG_ERROR, TAG,
|
||||||
"write RST error %d: %s",
|
"write RST error %d: %s",
|
||||||
errno, strerror((errno)));
|
errno, strerror((errno)));
|
||||||
|
@ -743,22 +722,22 @@ void handle_tcp(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
}
|
}
|
||||||
else if (cur->state == TCP_ESTABLISHED) {
|
else if (cur->state == TCP_ESTABLISHED) {
|
||||||
__android_log_print(ANDROID_LOG_DEBUG, TAG, "New ack");
|
__android_log_print(ANDROID_LOG_DEBUG, TAG, "New ack");
|
||||||
if (data != NULL) {
|
if (datalen) {
|
||||||
__android_log_print(ANDROID_LOG_DEBUG, TAG, "send socket data %u",
|
__android_log_print(ANDROID_LOG_DEBUG, TAG, "send socket data %u",
|
||||||
data->len);
|
datalen);
|
||||||
// TODO non blocking
|
// TODO non blocking
|
||||||
if (send(cur->socket, data->data, data->len, 0) < 0) {
|
if (send(cur->socket, buffer + dataoff, datalen, 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));
|
||||||
// Remote will retry
|
// Remote will retry
|
||||||
} else {
|
} else {
|
||||||
// TODO can write
|
// TODO can write
|
||||||
if (writeTCP(cur, NULL, data->len, 0, 0, 0, args->tun) < 0) // ACK
|
if (writeTCP(cur, NULL, 0, datalen, 0, 0, 0, args->tun) < 0) // ACK
|
||||||
__android_log_print(ANDROID_LOG_ERROR, TAG,
|
__android_log_print(ANDROID_LOG_ERROR, TAG,
|
||||||
"write data error %d: %s",
|
"write data error %d: %s",
|
||||||
errno, strerror((errno)));
|
errno, strerror((errno)));
|
||||||
else
|
else
|
||||||
cur->remote_seq += data->len;
|
cur->remote_seq += datalen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -793,9 +772,9 @@ void handle_tcp(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
int ok = 1;
|
int ok = 1;
|
||||||
if (tcphdr->ack && datalen) {
|
if (tcphdr->ack && datalen) {
|
||||||
__android_log_print(ANDROID_LOG_DEBUG, TAG, "send socket data %u",
|
__android_log_print(ANDROID_LOG_DEBUG, TAG, "send socket data %u",
|
||||||
data->len);
|
datalen);
|
||||||
// TODO non blocking
|
// TODO non blocking
|
||||||
if (send(cur->socket, data->data, data->len, 0) < 0) {
|
if (send(cur->socket, buffer + dataoff, datalen, 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));
|
||||||
ok = 0;
|
ok = 0;
|
||||||
|
@ -804,7 +783,7 @@ void handle_tcp(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
|
|
||||||
if (ok) {
|
if (ok) {
|
||||||
// TODO can write
|
// TODO can write
|
||||||
if (writeTCP(cur, NULL, 1 + datalen, 0, 0, 0, args->tun) < 0) // ACK
|
if (writeTCP(cur, NULL, 0, 1 + datalen, 0, 0, 0, args->tun) < 0) // ACK
|
||||||
__android_log_print(ANDROID_LOG_ERROR, TAG,
|
__android_log_print(ANDROID_LOG_ERROR, TAG,
|
||||||
"write ACK error %d: %s",
|
"write ACK error %d: %s",
|
||||||
errno, strerror((errno)));
|
errno, strerror((errno)));
|
||||||
|
@ -841,11 +820,6 @@ void handle_tcp(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
"Session lport %u new state %s local %u remote %u",
|
"Session lport %u new state %s local %u remote %u",
|
||||||
cur->lport, strstate(cur->state), cur->local_seq, cur->remote_seq);
|
cur->lport, strstate(cur->state), cur->local_seq, cur->remote_seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data != NULL) {
|
|
||||||
free(data->data);
|
|
||||||
free(data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int openSocket(JNIEnv *env, jobject instance, const struct sockaddr_in *daddr) {
|
int openSocket(JNIEnv *env, jobject instance, const struct sockaddr_in *daddr) {
|
||||||
|
@ -927,16 +901,15 @@ int canWrite(const int fd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int writeTCP(const struct session *cur,
|
int writeTCP(const struct session *cur,
|
||||||
struct data *data, uint16_t confirm,
|
uint8_t *data, uint16_t datalen, uint16_t confirm,
|
||||||
int syn, int fin, int rst, int tun) {
|
int syn, int fin, int rst, int tun) {
|
||||||
// Build packet
|
// Build packet
|
||||||
uint16_t datalen = (data == NULL ? 0 : data->len);
|
|
||||||
uint16_t len = sizeof(struct iphdr) + sizeof(struct tcphdr) + datalen;
|
uint16_t len = sizeof(struct iphdr) + sizeof(struct tcphdr) + datalen;
|
||||||
u_int8_t *buffer = calloc(len, 1);
|
u_int8_t *buffer = calloc(len, 1);
|
||||||
struct iphdr *ip = buffer;
|
struct iphdr *ip = buffer;
|
||||||
struct tcphdr *tcp = buffer + sizeof(struct iphdr);
|
struct tcphdr *tcp = buffer + sizeof(struct iphdr);
|
||||||
if (datalen)
|
if (datalen)
|
||||||
memcpy(buffer + sizeof(struct iphdr) + sizeof(struct tcphdr), data->data, data->len);
|
memcpy(buffer + sizeof(struct iphdr) + sizeof(struct tcphdr), data, datalen);
|
||||||
|
|
||||||
// Build IP header
|
// Build IP header
|
||||||
ip->version = 4;
|
ip->version = 4;
|
||||||
|
@ -963,6 +936,7 @@ int writeTCP(const struct session *cur,
|
||||||
tcp->window = htons(TCPWINDOW);
|
tcp->window = htons(TCPWINDOW);
|
||||||
|
|
||||||
// Calculate TCP checksum
|
// Calculate TCP checksum
|
||||||
|
// TODO optimize memory usage
|
||||||
uint16_t clen = sizeof(struct ippseudo) + sizeof(struct tcphdr) + datalen;
|
uint16_t clen = sizeof(struct ippseudo) + sizeof(struct tcphdr) + datalen;
|
||||||
uint8_t csum[clen];
|
uint8_t csum[clen];
|
||||||
|
|
||||||
|
@ -977,7 +951,7 @@ int writeTCP(const struct session *cur,
|
||||||
// Copy TCP header + data
|
// Copy TCP header + data
|
||||||
memcpy(csum + sizeof(struct ippseudo), tcp, sizeof(struct tcphdr));
|
memcpy(csum + sizeof(struct ippseudo), tcp, sizeof(struct tcphdr));
|
||||||
if (datalen)
|
if (datalen)
|
||||||
memcpy(csum + sizeof(struct ippseudo) + sizeof(struct tcphdr), data->data, data->len);
|
memcpy(csum + sizeof(struct ippseudo) + sizeof(struct tcphdr), data, datalen);
|
||||||
|
|
||||||
tcp->check = checksum(csum, clen);
|
tcp->check = checksum(csum, clen);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue