mirror of
https://github.com/M66B/NetGuard.git
synced 2025-02-26 16:13:01 +00:00
Native log errors, better UDP handling
This commit is contained in:
parent
70cf8a6077
commit
064f4922fe
1 changed files with 42 additions and 19 deletions
|
@ -453,10 +453,12 @@ int get_selects(const struct arguments *args, fd_set *rfds, fd_set *wfds, fd_set
|
||||||
// Select UDP sockets
|
// Select UDP sockets
|
||||||
struct udp_session *u = udp_session;
|
struct udp_session *u = udp_session;
|
||||||
while (u != NULL) {
|
while (u != NULL) {
|
||||||
FD_SET(u->socket, efds);
|
if (!u->error) {
|
||||||
FD_SET(u->socket, rfds);
|
FD_SET(u->socket, efds);
|
||||||
if (u->socket > max)
|
FD_SET(u->socket, rfds);
|
||||||
max = u->socket;
|
if (u->socket > max)
|
||||||
|
max = u->socket;
|
||||||
|
}
|
||||||
u = u->next;
|
u = u->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -834,18 +836,22 @@ void handle_ip(const struct arguments *args, const uint8_t *buffer, const uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle allowed traffic
|
// Handle allowed traffic
|
||||||
|
int log = 0;
|
||||||
if (allowed) {
|
if (allowed) {
|
||||||
if (protocol == IPPROTO_UDP)
|
if (protocol == IPPROTO_UDP)
|
||||||
allowed = handle_udp(args, buffer, length, uid);
|
allowed = handle_udp(args, buffer, length, uid);
|
||||||
else if (protocol == IPPROTO_TCP)
|
else if (protocol == IPPROTO_TCP) {
|
||||||
allowed = handle_tcp(args, buffer, length, uid);
|
allowed = handle_tcp(args, buffer, length, uid);
|
||||||
|
if (!allowed)
|
||||||
|
log = 1;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
allowed = 0;
|
allowed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log traffic
|
// Log traffic
|
||||||
if (args->log) {
|
if (args->log) {
|
||||||
if (!args->filter || syn || protocol != IPPROTO_TCP)
|
if (!args->filter || syn || log || protocol != IPPROTO_TCP)
|
||||||
log_packet(args, time(NULL), version, dest, protocol, dport, flags, uid, allowed);
|
log_packet(args, time(NULL), version, dest, protocol, dport, flags, uid, allowed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -875,13 +881,11 @@ jboolean handle_udp(const struct arguments *args, const uint8_t *buffer, uint16_
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create new session if needed
|
// Create new session if needed
|
||||||
int usock = -1;
|
|
||||||
if (cur == NULL) {
|
if (cur == NULL) {
|
||||||
log_android(ANDROID_LOG_INFO, "UDP new session");
|
log_android(ANDROID_LOG_INFO, "UDP new session");
|
||||||
|
|
||||||
// Register session
|
// Register session
|
||||||
struct udp_session *u = malloc(sizeof(struct udp_session));
|
struct udp_session *u = malloc(sizeof(struct udp_session));
|
||||||
u->time = time(NULL);
|
|
||||||
u->uid = uid;
|
u->uid = uid;
|
||||||
u->version = 4;
|
u->version = 4;
|
||||||
u->saddr = iphdr->saddr;
|
u->saddr = iphdr->saddr;
|
||||||
|
@ -895,6 +899,7 @@ jboolean handle_udp(const struct arguments *args, const uint8_t *buffer, uint16_
|
||||||
u->socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
u->socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
if (u->socket < 0) {
|
if (u->socket < 0) {
|
||||||
log_android(ANDROID_LOG_ERROR, "UDP socket error %d: %s", errno, strerror(errno));
|
log_android(ANDROID_LOG_ERROR, "UDP socket error %d: %s", errno, strerror(errno));
|
||||||
|
u->error = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -905,12 +910,9 @@ jboolean handle_udp(const struct arguments *args, const uint8_t *buffer, uint16_
|
||||||
else
|
else
|
||||||
last->next = u;
|
last->next = u;
|
||||||
|
|
||||||
usock = u->socket;
|
cur = u;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
cur->time = time(NULL);
|
|
||||||
usock = cur->socket;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char source[40];
|
char source[40];
|
||||||
|
@ -921,13 +923,16 @@ jboolean handle_udp(const struct arguments *args, const uint8_t *buffer, uint16_
|
||||||
log_android(ANDROID_LOG_INFO, "UDP forward from tun %s/%u to %s/%u data %d",
|
log_android(ANDROID_LOG_INFO, "UDP forward from tun %s/%u to %s/%u data %d",
|
||||||
source, ntohs(udphdr->source), dest, ntohs(udphdr->dest), datalen);
|
source, ntohs(udphdr->source), dest, ntohs(udphdr->dest), datalen);
|
||||||
|
|
||||||
|
cur->time = time(NULL);
|
||||||
|
|
||||||
struct sockaddr_in server;
|
struct sockaddr_in server;
|
||||||
server.sin_family = (version == 4 ? AF_INET : AF_INET6);
|
server.sin_family = (version == 4 ? AF_INET : AF_INET6);
|
||||||
server.sin_addr.s_addr = iphdr->daddr;
|
server.sin_addr.s_addr = iphdr->daddr;
|
||||||
server.sin_port = udphdr->dest;
|
server.sin_port = udphdr->dest;
|
||||||
|
|
||||||
if (sendto(usock, buffer + dataoff, datalen, 0, &server, sizeof(server)) != datalen) {
|
if (sendto(cur->socket, buffer + dataoff, datalen, 0, &server, sizeof(server)) != datalen) {
|
||||||
log_android(ANDROID_LOG_ERROR, "UDP sendto error %s:%s", errno, strerror(errno));
|
log_android(ANDROID_LOG_ERROR, "UDP sendto error %s:%s", errno, strerror(errno));
|
||||||
|
cur->error = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1014,6 +1019,7 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
|
||||||
syn->state = TCP_TIME_WAIT;
|
syn->state = TCP_TIME_WAIT;
|
||||||
// Remote might retry
|
// Remote might retry
|
||||||
free(syn);
|
free(syn);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
uint16_t lport = get_local_port(syn->socket);
|
uint16_t lport = get_local_port(syn->socket);
|
||||||
|
@ -1064,6 +1070,7 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
|
||||||
cur->local_seq - cur->local_start,
|
cur->local_seq - cur->local_start,
|
||||||
cur->remote_seq - cur->remote_start);
|
cur->remote_seq - cur->remote_start);
|
||||||
write_rst(args, cur, args->tun);
|
write_rst(args, cur, args->tun);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int oldstate = cur->state;
|
int oldstate = cur->state;
|
||||||
|
@ -1090,6 +1097,7 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
|
||||||
log_android(ANDROID_LOG_ERROR, "send error %d: %s", errno, strerror(errno));
|
log_android(ANDROID_LOG_ERROR, "send error %d: %s", errno, strerror(errno));
|
||||||
ok = 0;
|
ok = 0;
|
||||||
write_rst(args, cur, args->tun);
|
write_rst(args, cur, args->tun);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (tcphdr->fin ||
|
if (tcphdr->fin ||
|
||||||
|
@ -1113,6 +1121,7 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
|
||||||
source, ntohs(tcphdr->source), dest, ntohs(cur->dest),
|
source, ntohs(tcphdr->source), dest, ntohs(cur->dest),
|
||||||
strstate(cur->state));
|
strstate(cur->state));
|
||||||
cur->state = TCP_TIME_WAIT;
|
cur->state = TCP_TIME_WAIT;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (ntohl(tcphdr->ack_seq) == cur->local_seq &&
|
if (ntohl(tcphdr->ack_seq) == cur->local_seq &&
|
||||||
|
@ -1131,8 +1140,9 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
|
||||||
if (shutdown(cur->socket, SHUT_WR)) {
|
if (shutdown(cur->socket, SHUT_WR)) {
|
||||||
log_android(ANDROID_LOG_ERROR, "shutdown WR error %d: %s",
|
log_android(ANDROID_LOG_ERROR, "shutdown WR error %d: %s",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
write_rst(args, cur, args->tun);
|
|
||||||
// Data might be lost
|
// Data might be lost
|
||||||
|
write_rst(args, cur, args->tun);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (write_ack(args, cur, 1, args->tun) >= 0) {
|
if (write_ack(args, cur, 1, args->tun) >= 0) {
|
||||||
|
@ -1145,15 +1155,19 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
|
||||||
cur->state = TCP_CLOSING;
|
cur->state = TCP_CLOSING;
|
||||||
else if (cur->state == TCP_FIN_WAIT2 /* && !tcphdr->ack */)
|
else if (cur->state == TCP_FIN_WAIT2 /* && !tcphdr->ack */)
|
||||||
cur->state = TCP_TIME_WAIT;
|
cur->state = TCP_TIME_WAIT;
|
||||||
else
|
else {
|
||||||
log_android(ANDROID_LOG_ERROR,
|
log_android(ANDROID_LOG_ERROR,
|
||||||
"Invalid FIN from %s/%u to %s/%u state %s ACK %d",
|
"Invalid FIN from %s/%u to %s/%u state %s ACK %d",
|
||||||
source, ntohs(tcphdr->source),
|
source, ntohs(tcphdr->source),
|
||||||
dest, ntohs(cur->dest),
|
dest, ntohs(cur->dest),
|
||||||
strstate(cur->state), tcphdr->ack);
|
strstate(cur->state), tcphdr->ack);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
write_rst(args, cur, args->tun);
|
write_rst(args, cur, args->tun);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1174,18 +1188,22 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
|
||||||
cur->state = TCP_FIN_WAIT2;
|
cur->state = TCP_FIN_WAIT2;
|
||||||
else if (cur->state == TCP_CLOSING)
|
else if (cur->state == TCP_CLOSING)
|
||||||
cur->state = TCP_TIME_WAIT;
|
cur->state = TCP_TIME_WAIT;
|
||||||
else
|
else {
|
||||||
log_android(ANDROID_LOG_ERROR,
|
log_android(ANDROID_LOG_ERROR,
|
||||||
"Invalid ACK from %s/%u to %s/%u state %s",
|
"Invalid ACK from %s/%u to %s/%u state %s",
|
||||||
source, ntohs(tcphdr->source), dest, ntohs(cur->dest),
|
source, ntohs(tcphdr->source), dest, ntohs(cur->dest),
|
||||||
strstate(cur->state));
|
strstate(cur->state));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else {
|
||||||
log_android(ANDROID_LOG_ERROR,
|
log_android(ANDROID_LOG_ERROR,
|
||||||
"Unknown packet from %s/%u to %s/%u state %s",
|
"Unknown packet from %s/%u to %s/%u state %s",
|
||||||
source, ntohs(tcphdr->source), dest, ntohs(cur->dest),
|
source, ntohs(tcphdr->source), dest, ntohs(cur->dest),
|
||||||
strstate(cur->state));
|
strstate(cur->state));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
char *msg;
|
char *msg;
|
||||||
|
@ -1195,6 +1213,7 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
|
||||||
static const char keepalive[] = "Keep alive";
|
static const char keepalive[] = "Keep alive";
|
||||||
|
|
||||||
// TODO proper wrap around
|
// TODO proper wrap around
|
||||||
|
int allowed = 1;
|
||||||
if (tcphdr->ack && ((uint32_t) ntohl(tcphdr->seq) + 1) == cur->remote_seq)
|
if (tcphdr->ack && ((uint32_t) ntohl(tcphdr->seq) + 1) == cur->remote_seq)
|
||||||
msg = keepalive;
|
msg = keepalive;
|
||||||
else if (ntohl(tcphdr->seq) == cur->remote_seq &&
|
else if (ntohl(tcphdr->seq) == cur->remote_seq &&
|
||||||
|
@ -1203,8 +1222,10 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
|
||||||
else if (ntohl(tcphdr->seq) < cur->remote_seq &&
|
else if (ntohl(tcphdr->seq) < cur->remote_seq &&
|
||||||
ntohl(tcphdr->ack_seq) == cur->local_seq)
|
ntohl(tcphdr->ack_seq) == cur->local_seq)
|
||||||
msg = repeated;
|
msg = repeated;
|
||||||
else
|
else {
|
||||||
msg = invalid;
|
msg = invalid;
|
||||||
|
allowed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
char flags[10];
|
char flags[10];
|
||||||
int flen = 0;
|
int flen = 0;
|
||||||
|
@ -1227,6 +1248,8 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
|
||||||
ntohl(tcphdr->ack_seq) - cur->local_start,
|
ntohl(tcphdr->ack_seq) - cur->local_start,
|
||||||
cur->local_seq - cur->local_start,
|
cur->local_seq - cur->local_start,
|
||||||
datalen);
|
datalen);
|
||||||
|
|
||||||
|
return allowed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue