1
0
Fork 0
mirror of https://github.com/M66B/NetGuard.git synced 2025-01-01 12:54:07 +00:00

Native ACK remote FIN without delay

This commit is contained in:
M66B 2016-02-10 10:46:00 +01:00
parent 0608189bdf
commit 92f8dd662d
2 changed files with 36 additions and 22 deletions

View file

@ -372,7 +372,7 @@ int32_t get_local_port(const int sock);
int write_syn_ack(const struct arguments *args, struct tcp_session *cur);
int write_ack(const struct arguments *args, struct tcp_session *cur, size_t bytes);
int write_ack(const struct arguments *args, struct tcp_session *cur);
int write_data(const struct arguments *args, struct tcp_session *cur,
const uint8_t *buffer, size_t length);
@ -388,7 +388,7 @@ ssize_t write_udp(const struct arguments *args, const struct udp_session *cur,
uint8_t *data, size_t datalen);
ssize_t write_tcp(const struct arguments *args, const struct tcp_session *cur,
const uint8_t *data, size_t datalen, size_t confirm,
const uint8_t *data, size_t datalen,
int syn, int ack, int fin, int rst);
uint8_t char2nible(const char c);

View file

@ -77,6 +77,7 @@ int check_tcp_sessions(const struct arguments *args) {
// Check closing sessions
if (t->state == TCP_CLOSING) {
// eof closes socket
if (t->socket >= 0) {
if (close(t->socket))
log_android(ANDROID_LOG_ERROR, "%s close error %d: %s",
@ -158,10 +159,10 @@ void check_tcp_sockets(const struct arguments *args, fd_set *rfds, fd_set *wfds,
if (FD_ISSET(cur->socket, wfds)) {
log_android(ANDROID_LOG_INFO, "%s connected", session);
cur->remote_seq++; // remote SYN
if (write_syn_ack(args, cur) >= 0) {
cur->time = time(NULL);
cur->local_seq++; // local SYN
cur->remote_seq++; // remote SYN
cur->state = TCP_SYN_RECV;
}
}
@ -235,7 +236,11 @@ void check_tcp_sockets(const struct arguments *args, fd_set *rfds, fd_set *wfds,
// Acknowledge forwarded data
// TODO send less ACKs?
if (fwd || (prev == 0 && window > 0)) {
if (!write_ack(args, cur, 0))
if (fwd && cur->forward == NULL && cur->state == TCP_CLOSE_WAIT) {
log_android(ANDROID_LOG_WARN, "%s confirm FIN", session);
cur->remote_seq++; // remote FIN
}
if (write_ack(args, cur) >= 0)
cur->time = time(NULL);
}
@ -262,8 +267,6 @@ void check_tcp_sockets(const struct arguments *args, fd_set *rfds, fd_set *wfds,
log_android(ANDROID_LOG_WARN, "%s recv eof", session);
if (cur->forward == NULL) {
if (cur->state == TCP_CLOSE_WAIT)
cur->remote_seq++; // remote FIN
if (write_fin_ack(args, cur) >= 0) {
log_android(ANDROID_LOG_WARN, "%s FIN sent", session);
cur->local_seq++; // local FIN
@ -278,8 +281,7 @@ void check_tcp_sockets(const struct arguments *args, fd_set *rfds, fd_set *wfds,
}
else {
// There was still data to send
log_android(ANDROID_LOG_ERROR, "%s close with data queued",
session);
log_android(ANDROID_LOG_ERROR, "%s close with queue", session);
write_rst(args, cur);
}
@ -480,6 +482,11 @@ jboolean handle_tcp(const struct arguments *args,
// Queue data to forward
if (datalen) {
if (cur->socket < 0) {
log_android(ANDROID_LOG_ERROR, "%s data while local closed", session);
write_rst(args, cur);
return 0;
}
if (cur->state == TCP_CLOSE_WAIT) {
log_android(ANDROID_LOG_ERROR, "%s data while remote closed", session);
write_rst(args, cur);
return 0;
@ -504,7 +511,13 @@ jboolean handle_tcp(const struct arguments *args,
} else if (tcphdr->fin /* +ACK */) {
if (cur->state == TCP_ESTABLISHED) {
log_android(ANDROID_LOG_WARN, "%s FIN received", session);
cur->state = TCP_CLOSE_WAIT;
if (cur->forward == NULL) {
cur->remote_seq++; // remote FIN
if (write_ack(args, cur) >= 0)
cur->state = TCP_CLOSE_WAIT;
}
else
cur->state = TCP_CLOSE_WAIT;
}
else if (cur->state == TCP_CLOSE_WAIT) {
@ -514,7 +527,8 @@ jboolean handle_tcp(const struct arguments *args,
else if (cur->state == TCP_FIN_WAIT1) {
log_android(ANDROID_LOG_WARN, "%s last ACK", session);
if (write_ack(args, cur, 1) >= 0)
cur->remote_seq++; // remote FIN
if (write_ack(args, cur) >= 0)
cur->state = TCP_CLOSE;
}
@ -692,15 +706,15 @@ int open_tcp_socket(const struct arguments *args,
}
int write_syn_ack(const struct arguments *args, struct tcp_session *cur) {
if (write_tcp(args, cur, NULL, 0, 1, 1, 1, 0, 0) < 0) {
if (write_tcp(args, cur, NULL, 0, 1, 1, 0, 0) < 0) {
cur->state = TCP_CLOSING;
return -1;
}
return 0;
}
int write_ack(const struct arguments *args, struct tcp_session *cur, size_t bytes) {
if (write_tcp(args, cur, NULL, 0, bytes, 0, 1, 0, 0) < 0) {
int write_ack(const struct arguments *args, struct tcp_session *cur) {
if (write_tcp(args, cur, NULL, 0, 0, 1, 0, 0) < 0) {
cur->state = TCP_CLOSING;
return -1;
}
@ -709,7 +723,7 @@ int write_ack(const struct arguments *args, struct tcp_session *cur, size_t byte
int write_data(const struct arguments *args, struct tcp_session *cur,
const uint8_t *buffer, size_t length) {
if (write_tcp(args, cur, buffer, length, 0, 0, 1, 0, 0) < 0) {
if (write_tcp(args, cur, buffer, length, 0, 1, 0, 0) < 0) {
cur->state = TCP_CLOSING;
return -1;
}
@ -717,7 +731,7 @@ int write_data(const struct arguments *args, struct tcp_session *cur,
}
int write_fin_ack(const struct arguments *args, struct tcp_session *cur) {
if (write_tcp(args, cur, NULL, 0, 0, 0, 1, 1, 0) < 0) {
if (write_tcp(args, cur, NULL, 0, 0, 1, 1, 0) < 0) {
cur->state = TCP_CLOSING;
return -1;
}
@ -725,13 +739,13 @@ int write_fin_ack(const struct arguments *args, struct tcp_session *cur) {
}
void write_rst(const struct arguments *args, struct tcp_session *cur) {
write_tcp(args, cur, NULL, 0, 0, 0, 0, 0, 1);
write_tcp(args, cur, NULL, 0, 0, 0, 0, 1);
if (cur->state != TCP_CLOSE)
cur->state = TCP_CLOSING;
}
ssize_t write_tcp(const struct arguments *args, const struct tcp_session *cur,
const uint8_t *data, size_t datalen, size_t confirm,
const uint8_t *data, size_t datalen,
int syn, int ack, int fin, int rst) {
size_t len;
u_int8_t *buffer;
@ -810,7 +824,7 @@ ssize_t write_tcp(const struct arguments *args, const struct tcp_session *cur,
tcp->source = cur->dest;
tcp->dest = cur->source;
tcp->seq = htonl(cur->local_seq);
tcp->ack_seq = htonl((uint32_t) (cur->remote_seq + confirm));
tcp->ack_seq = htonl((uint32_t) (cur->remote_seq));
tcp->doff = (__u16) ((sizeof(struct tcphdr) + optlen) >> 2);
tcp->syn = (__u16) syn;
tcp->ack = (__u16) ack;
@ -843,7 +857,7 @@ ssize_t write_tcp(const struct arguments *args, const struct tcp_session *cur,
// Send packet
log_android(ANDROID_LOG_DEBUG,
"TCP sending%s%s%s%s to tun %s/%u seq %u ack %u data %u confirm %u",
"TCP sending%s%s%s%s to tun %s/%u seq %u ack %u data %u",
(tcp->syn ? " SYN" : ""),
(tcp->ack ? " ACK" : ""),
(tcp->fin ? " FIN" : ""),
@ -851,7 +865,7 @@ ssize_t write_tcp(const struct arguments *args, const struct tcp_session *cur,
dest, ntohs(tcp->dest),
ntohl(tcp->seq) - cur->local_start,
ntohl(tcp->ack_seq) - cur->remote_start,
datalen, confirm);
datalen);
ssize_t res = write(args->tun, buffer, len);
@ -860,12 +874,12 @@ ssize_t write_tcp(const struct arguments *args, const struct tcp_session *cur,
if (pcap_file != NULL)
write_pcap_rec(buffer, (size_t) res);
} else
log_android(ANDROID_LOG_ERROR, "TCP write%s%s%s%s data %d confirm %d error %d: %s",
log_android(ANDROID_LOG_ERROR, "TCP write%s%s%s%s data %d error %d: %s",
(tcp->syn ? " SYN" : ""),
(tcp->ack ? " ACK" : ""),
(tcp->fin ? " FIN" : ""),
(tcp->rst ? " RST" : ""),
datalen, confirm,
datalen,
errno, strerror((errno)));
free(buffer);