mirror of https://github.com/M66B/NetGuard.git
Native refactoring
This commit is contained in:
parent
f624815db8
commit
b61cc13d6d
|
@ -86,22 +86,22 @@ typedef struct pcaprec_hdr_s {
|
||||||
|
|
||||||
#define LINKTYPE_RAW 101
|
#define LINKTYPE_RAW 101
|
||||||
|
|
||||||
void pcap_write(const void *, size_t);
|
|
||||||
|
|
||||||
void *handle_events(void *);
|
void *handle_events(void *);
|
||||||
|
|
||||||
|
void check_sockets(const struct arguments *, fd_set *, fd_set *, fd_set *);
|
||||||
|
|
||||||
void handle_ip(JNIEnv *, jobject, const struct arguments *, const uint8_t *, const uint16_t);
|
void handle_ip(JNIEnv *, jobject, const struct arguments *, const uint8_t *, const uint16_t);
|
||||||
|
|
||||||
void handle_tcp(JNIEnv *, jobject, const struct arguments *args,
|
void handle_tcp(JNIEnv *, jobject, const struct arguments *args,
|
||||||
const uint8_t *, const uint16_t, int uid);
|
const uint8_t *, const uint16_t, int uid);
|
||||||
|
|
||||||
int openSocket(JNIEnv *, jobject, const struct sockaddr_in *);
|
int open_socket(JNIEnv *, jobject, const struct sockaddr_in *);
|
||||||
|
|
||||||
int getLocalPort(const int);
|
int get_local_port(const int);
|
||||||
|
|
||||||
int writeTCP(const struct session *, uint8_t *, uint16_t, uint16_t, int, int, int, int);
|
int write_tcp(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 get_uid(const int, const int, const void *, const uint16_t);
|
||||||
|
|
||||||
uint16_t checksum(uint8_t *, uint16_t);
|
uint16_t checksum(uint8_t *, uint16_t);
|
||||||
|
|
||||||
|
@ -111,6 +111,8 @@ 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);
|
||||||
|
|
||||||
|
void pcap_write(const void *, size_t);
|
||||||
|
|
||||||
// Global variables
|
// Global variables
|
||||||
|
|
||||||
static JavaVM *jvm;
|
static JavaVM *jvm;
|
||||||
|
@ -151,21 +153,6 @@ Java_eu_faircode_netguard_SinkholeService_jni_1init(JNIEnv *env, jobject instanc
|
||||||
(*env)->ReleaseStringUTFChars(env, pcap_, pcap);
|
(*env)->ReleaseStringUTFChars(env, pcap_, pcap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcap_write(const void *ptr, size_t len) {
|
|
||||||
FILE *fd = fopen(pcap_fn, "ab");
|
|
||||||
if (fd == NULL)
|
|
||||||
ng_log(ANDROID_LOG_ERROR, "fopen %s error %d: %s", pcap_fn, errno, strerror(errno));
|
|
||||||
else {
|
|
||||||
if (fwrite(ptr, len, 1, fd) < 1)
|
|
||||||
ng_log(ANDROID_LOG_ERROR, "fwrite %s error %d: %s", pcap_fn, errno, strerror(errno));
|
|
||||||
else
|
|
||||||
ng_log(ANDROID_LOG_DEBUG, "PCAP write %d", len);
|
|
||||||
|
|
||||||
if (fclose(fd))
|
|
||||||
ng_log(ANDROID_LOG_ERROR, "fclose %s error %d: %s", pcap_fn, errno, strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
Java_eu_faircode_netguard_SinkholeService_jni_1start(JNIEnv *env, jobject instance,
|
Java_eu_faircode_netguard_SinkholeService_jni_1start(JNIEnv *env, jobject instance,
|
||||||
jint tun) {
|
jint tun) {
|
||||||
|
@ -292,7 +279,7 @@ void *handle_events(void *a) {
|
||||||
if (cur->state == TCP_SYN_RECV ||
|
if (cur->state == TCP_SYN_RECV ||
|
||||||
cur->state == TCP_ESTABLISHED ||
|
cur->state == TCP_ESTABLISHED ||
|
||||||
cur->state == TCP_CLOSE_WAIT) {
|
cur->state == TCP_CLOSE_WAIT) {
|
||||||
if (writeTCP(cur, NULL, 0, 0, 0, 1, 0, args->tun) < 0) { // FIN
|
if (write_tcp(cur, NULL, 0, 0, 0, 1, 0, args->tun) < 0) { // FIN
|
||||||
ng_log(ANDROID_LOG_ERROR,
|
ng_log(ANDROID_LOG_ERROR,
|
||||||
"write FIN lport %u error %d: %s",
|
"write FIN lport %u error %d: %s",
|
||||||
cur->lport, errno, strerror((errno)));
|
cur->lport, errno, strerror((errno)));
|
||||||
|
@ -437,9 +424,25 @@ void *handle_events(void *a) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check sockets
|
// Check sockets
|
||||||
|
check_sockets(args, &rfds, &wfds, &efds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(*env)->DeleteGlobalRef(env, args->instance);
|
||||||
|
rs = (*jvm)->DetachCurrentThread(jvm);
|
||||||
|
if (rs != JNI_OK)
|
||||||
|
ng_log(ANDROID_LOG_ERROR, "DetachCurrentThread failed");
|
||||||
|
free(args);
|
||||||
|
|
||||||
|
ng_log(ANDROID_LOG_INFO, "Stopped events tun=%d thread %u",
|
||||||
|
args->tun, thread_id);
|
||||||
|
// TODO conditionally report to Java
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_sockets(const struct arguments *args, fd_set *rfds, fd_set *wfds, fd_set *efds) {
|
||||||
struct session *cur = session;
|
struct session *cur = session;
|
||||||
while (cur != NULL) {
|
while (cur != NULL) {
|
||||||
if (FD_ISSET(cur->socket, &efds)) {
|
if (FD_ISSET(cur->socket, efds)) {
|
||||||
// Socket exception
|
// Socket exception
|
||||||
int serr;
|
int serr;
|
||||||
socklen_t optlen = sizeof(int);
|
socklen_t optlen = sizeof(int);
|
||||||
|
@ -451,7 +454,7 @@ void *handle_events(void *a) {
|
||||||
ng_log(ANDROID_LOG_ERROR, "lport %u SO_ERROR %d: %s",
|
ng_log(ANDROID_LOG_ERROR, "lport %u SO_ERROR %d: %s",
|
||||||
cur->lport, serr, strerror(serr));
|
cur->lport, serr, strerror(serr));
|
||||||
if (err < 0 || (serr && serr != EINTR)) {
|
if (err < 0 || (serr && serr != EINTR)) {
|
||||||
if (writeTCP(cur, NULL, 0, 0, 0, 0, 1, args->tun) < 0) // RST
|
if (write_tcp(cur, NULL, 0, 0, 0, 0, 1, args->tun) < 0) // RST
|
||||||
ng_log(ANDROID_LOG_ERROR, "write RST error %d: %s",
|
ng_log(ANDROID_LOG_ERROR, "write RST error %d: %s",
|
||||||
errno, strerror((errno)));
|
errno, strerror((errno)));
|
||||||
}
|
}
|
||||||
|
@ -461,14 +464,14 @@ void *handle_events(void *a) {
|
||||||
// Assume socket okay
|
// Assume socket okay
|
||||||
if (cur->state == TCP_LISTEN) {
|
if (cur->state == TCP_LISTEN) {
|
||||||
// Check socket connect
|
// Check socket connect
|
||||||
if (FD_ISSET(cur->socket, &wfds)) {
|
if (FD_ISSET(cur->socket, wfds)) {
|
||||||
// Log
|
// Log
|
||||||
char dest[20];
|
char dest[20];
|
||||||
inet_ntop(AF_INET, &(cur->daddr), dest, sizeof(dest));
|
inet_ntop(AF_INET, &(cur->daddr), dest, sizeof(dest));
|
||||||
ng_log(ANDROID_LOG_INFO, "Connected %s/%u lport %u",
|
ng_log(ANDROID_LOG_INFO, "Connected %s/%u lport %u",
|
||||||
dest, ntohs(cur->dest), cur->lport);
|
dest, ntohs(cur->dest), cur->lport);
|
||||||
|
|
||||||
if (writeTCP(cur, NULL, 0, 1, 1, 0, 0, args->tun) < 0) { // SYN+ACK
|
if (write_tcp(cur, NULL, 0, 1, 1, 0, 0, args->tun) < 0) { // SYN+ACK
|
||||||
ng_log(ANDROID_LOG_ERROR, "write SYN+ACK error %d: %s",
|
ng_log(ANDROID_LOG_ERROR, "write SYN+ACK error %d: %s",
|
||||||
errno, strerror((errno)));
|
errno, strerror((errno)));
|
||||||
// Remote will retry
|
// Remote will retry
|
||||||
|
@ -487,7 +490,7 @@ void *handle_events(void *a) {
|
||||||
cur->state == TCP_ESTABLISHED ||
|
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
|
// 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);
|
||||||
|
@ -496,7 +499,7 @@ void *handle_events(void *a) {
|
||||||
ng_log(ANDROID_LOG_ERROR, "recv lport %u error %d: %s",
|
ng_log(ANDROID_LOG_ERROR, "recv lport %u error %d: %s",
|
||||||
cur->lport, errno, strerror(errno));
|
cur->lport, errno, strerror(errno));
|
||||||
if (errno != EINTR) {
|
if (errno != EINTR) {
|
||||||
if (writeTCP(cur, NULL, 0, 0, 0, 0, 1, args->tun) < 0) // RST
|
if (write_tcp(cur, NULL, 0, 0, 0, 0, 1, args->tun) < 0) // RST
|
||||||
ng_log(ANDROID_LOG_ERROR, "write RST error %d: %s",
|
ng_log(ANDROID_LOG_ERROR, "write RST error %d: %s",
|
||||||
errno, strerror((errno)));
|
errno, strerror((errno)));
|
||||||
}
|
}
|
||||||
|
@ -506,7 +509,7 @@ void *handle_events(void *a) {
|
||||||
ng_log(ANDROID_LOG_DEBUG, "recv empty lport %u state %s",
|
ng_log(ANDROID_LOG_DEBUG, "recv empty lport %u state %s",
|
||||||
cur->lport, strstate(cur->state));
|
cur->lport, strstate(cur->state));
|
||||||
|
|
||||||
if (writeTCP(cur, NULL, 0, 0, 0, 1, 0, args->tun) < 0) // FIN
|
if (write_tcp(cur, NULL, 0, 0, 0, 1, 0, args->tun) < 0) // FIN
|
||||||
ng_log(ANDROID_LOG_ERROR, "write FIN lport %u error %d: %s",
|
ng_log(ANDROID_LOG_ERROR, "write FIN lport %u error %d: %s",
|
||||||
cur->lport, errno, strerror((errno)));
|
cur->lport, errno, strerror((errno)));
|
||||||
else {
|
else {
|
||||||
|
@ -523,7 +526,7 @@ void *handle_events(void *a) {
|
||||||
ng_log(ANDROID_LOG_DEBUG,
|
ng_log(ANDROID_LOG_DEBUG,
|
||||||
"recv lport %u bytes %d state %s",
|
"recv lport %u bytes %d state %s",
|
||||||
cur->lport, bytes, strstate(cur->state));
|
cur->lport, bytes, strstate(cur->state));
|
||||||
if (writeTCP(cur, buffer, bytes, 0, 0, 0, 0, args->tun) < 0) // ACK
|
if (write_tcp(cur, buffer, bytes, 0, 0, 0, 0, args->tun) < 0) // ACK
|
||||||
ng_log(ANDROID_LOG_ERROR, "write ACK lport %u error %d: %s",
|
ng_log(ANDROID_LOG_ERROR, "write ACK lport %u error %d: %s",
|
||||||
cur->lport, errno, strerror((errno)));
|
cur->lport, errno, strerror((errno)));
|
||||||
else
|
else
|
||||||
|
@ -535,18 +538,6 @@ void *handle_events(void *a) {
|
||||||
|
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(*env)->DeleteGlobalRef(env, args->instance);
|
|
||||||
rs = (*jvm)->DetachCurrentThread(jvm);
|
|
||||||
if (rs != JNI_OK)
|
|
||||||
ng_log(ANDROID_LOG_ERROR, "DetachCurrentThread failed");
|
|
||||||
free(args);
|
|
||||||
|
|
||||||
ng_log(ANDROID_LOG_INFO, "Stopped events tun=%d thread %u",
|
|
||||||
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,
|
||||||
|
@ -647,14 +638,14 @@ void handle_ip(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
int tries = 0;
|
int tries = 0;
|
||||||
while (tries++ < UIDTRIES && uid < 0) {
|
while (tries++ < UIDTRIES && uid < 0) {
|
||||||
// Lookup uid
|
// Lookup uid
|
||||||
uid = getUid(protocol, version, saddr, sport);
|
uid = get_uid(protocol, version, saddr, sport);
|
||||||
if (uid < 0 && version == 4) {
|
if (uid < 0 && version == 4) {
|
||||||
int8_t saddr128[16];
|
int8_t saddr128[16];
|
||||||
memset(saddr128, 0, 10);
|
memset(saddr128, 0, 10);
|
||||||
saddr128[10] = 0xFF;
|
saddr128[10] = 0xFF;
|
||||||
saddr128[11] = 0xFF;
|
saddr128[11] = 0xFF;
|
||||||
memcpy(saddr128 + 12, saddr, 4);
|
memcpy(saddr128 + 12, saddr, 4);
|
||||||
uid = getUid(protocol, 6, saddr128, sport);
|
uid = get_uid(protocol, 6, saddr128, sport);
|
||||||
}
|
}
|
||||||
if (uid < 0 && tries < UIDTRIES) {
|
if (uid < 0 && tries < UIDTRIES) {
|
||||||
ng_log("get uid try %d", tries);
|
ng_log("get uid try %d", tries);
|
||||||
|
@ -769,14 +760,14 @@ void handle_tcp(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
daddr.sin_addr.s_addr = iphdr->daddr;
|
daddr.sin_addr.s_addr = iphdr->daddr;
|
||||||
|
|
||||||
// Open socket
|
// Open socket
|
||||||
syn->socket = openSocket(env, instance, &daddr);
|
syn->socket = open_socket(env, instance, &daddr);
|
||||||
if (syn->socket < 0) {
|
if (syn->socket < 0) {
|
||||||
syn->state = TCP_TIME_WAIT;
|
syn->state = TCP_TIME_WAIT;
|
||||||
// Remote will retry
|
// Remote will retry
|
||||||
free(syn);
|
free(syn);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
syn->lport = getLocalPort(syn->socket);
|
syn->lport = get_local_port(syn->socket);
|
||||||
|
|
||||||
ng_log(ANDROID_LOG_DEBUG, "Connecting to %s/%u lport %u",
|
ng_log(ANDROID_LOG_DEBUG, "Connecting to %s/%u lport %u",
|
||||||
dest, ntohs(tcphdr->dest), syn->lport);
|
dest, ntohs(tcphdr->dest), syn->lport);
|
||||||
|
@ -796,7 +787,7 @@ void handle_tcp(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
rst.daddr = iphdr->daddr;
|
rst.daddr = iphdr->daddr;
|
||||||
rst.dest = tcphdr->dest;
|
rst.dest = tcphdr->dest;
|
||||||
|
|
||||||
if (writeTCP(&rst, NULL, 0, 0, 0, 0, 1, args->tun) < 0)
|
if (write_tcp(&rst, NULL, 0, 0, 0, 0, 1, args->tun) < 0)
|
||||||
ng_log(ANDROID_LOG_ERROR,
|
ng_log(ANDROID_LOG_ERROR,
|
||||||
"write RST error %d: %s",
|
"write RST error %d: %s",
|
||||||
errno, strerror((errno)));
|
errno, strerror((errno)));
|
||||||
|
@ -858,7 +849,7 @@ void handle_tcp(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ok) {
|
if (ok) {
|
||||||
if (writeTCP(cur, NULL, 0, 1 + datalen, 0, 0, 0, args->tun) < 0) // ACK
|
if (write_tcp(cur, NULL, 0, 1 + datalen, 0, 0, 0, args->tun) < 0) // ACK
|
||||||
ng_log(ANDROID_LOG_ERROR, "write ACK error %d: %s",
|
ng_log(ANDROID_LOG_ERROR, "write ACK error %d: %s",
|
||||||
errno, strerror((errno)));
|
errno, strerror((errno)));
|
||||||
else {
|
else {
|
||||||
|
@ -885,7 +876,7 @@ void handle_tcp(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
int confirm = cur->local_seq - ntohl(tcphdr->ack_seq);
|
int confirm = cur->local_seq - ntohl(tcphdr->ack_seq);
|
||||||
ng_log(ANDROID_LOG_INFO, "Simultaneous close %d", confirm);
|
ng_log(ANDROID_LOG_INFO, "Simultaneous close %d", confirm);
|
||||||
|
|
||||||
if (writeTCP(cur, NULL, 0, confirm, 0, 0, 0, args->tun) < 0) // ACK
|
if (write_tcp(cur, NULL, 0, confirm, 0, 0, 0, args->tun) < 0) // ACK
|
||||||
ng_log(ANDROID_LOG_ERROR, "write ACK error %d: %s",
|
ng_log(ANDROID_LOG_ERROR, "write ACK error %d: %s",
|
||||||
errno, strerror((errno)));
|
errno, strerror((errno)));
|
||||||
}
|
}
|
||||||
|
@ -922,7 +913,7 @@ void handle_tcp(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
// Remote will retry
|
// Remote will retry
|
||||||
} else {
|
} else {
|
||||||
if (writeTCP(cur, NULL, 0, datalen, 0, 0, 0, args->tun) < 0) // ACK
|
if (write_tcp(cur, NULL, 0, datalen, 0, 0, 0, args->tun) < 0) // ACK
|
||||||
ng_log(ANDROID_LOG_ERROR, "write data error %d: %s",
|
ng_log(ANDROID_LOG_ERROR, "write data error %d: %s",
|
||||||
errno, strerror((errno)));
|
errno, strerror((errno)));
|
||||||
else
|
else
|
||||||
|
@ -972,7 +963,7 @@ void handle_tcp(JNIEnv *env, jobject instance, const struct arguments *args,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int openSocket(JNIEnv *env, jobject instance, const struct sockaddr_in *daddr) {
|
int open_socket(JNIEnv *env, jobject instance, const struct sockaddr_in *daddr) {
|
||||||
int sock = -1;
|
int sock = -1;
|
||||||
|
|
||||||
// Get TCP socket
|
// Get TCP socket
|
||||||
|
@ -1025,7 +1016,7 @@ int openSocket(JNIEnv *env, jobject instance, const struct sockaddr_in *daddr) {
|
||||||
return sock;
|
return sock;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getLocalPort(const int sock) {
|
int get_local_port(const int sock) {
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
int len = sizeof(sin);
|
int len = sizeof(sin);
|
||||||
if (getsockname(sock, &sin, &len) < 0) {
|
if (getsockname(sock, &sin, &len) < 0) {
|
||||||
|
@ -1035,7 +1026,7 @@ int getLocalPort(const int sock) {
|
||||||
return ntohs(sin.sin_port);
|
return ntohs(sin.sin_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
int writeTCP(const struct session *cur,
|
int write_tcp(const struct session *cur,
|
||||||
uint8_t *data, uint16_t datalen, 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
|
||||||
|
@ -1133,7 +1124,7 @@ int writeTCP(const struct session *cur,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
jint getUid(const int protocol, const int version, const void *saddr, const uint16_t sport) {
|
jint get_uid(const int protocol, const int version, const void *saddr, const uint16_t sport) {
|
||||||
char line[250];
|
char line[250];
|
||||||
int fields;
|
int fields;
|
||||||
int32_t addr32;
|
int32_t addr32;
|
||||||
|
@ -1272,3 +1263,18 @@ char *hex(const u_int8_t *data, const u_int16_t len) {
|
||||||
}
|
}
|
||||||
return hexout;
|
return hexout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pcap_write(const void *ptr, size_t len) {
|
||||||
|
FILE *fd = fopen(pcap_fn, "ab");
|
||||||
|
if (fd == NULL)
|
||||||
|
ng_log(ANDROID_LOG_ERROR, "fopen %s error %d: %s", pcap_fn, errno, strerror(errno));
|
||||||
|
else {
|
||||||
|
if (fwrite(ptr, len, 1, fd) < 1)
|
||||||
|
ng_log(ANDROID_LOG_ERROR, "fwrite %s error %d: %s", pcap_fn, errno, strerror(errno));
|
||||||
|
else
|
||||||
|
ng_log(ANDROID_LOG_DEBUG, "PCAP write %d", len);
|
||||||
|
|
||||||
|
if (fclose(fd))
|
||||||
|
ng_log(ANDROID_LOG_ERROR, "fclose %s error %d: %s", pcap_fn, errno, strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue