Native TCP fixes

This commit is contained in:
M66B 2016-01-20 19:27:13 +01:00
parent f699e497ec
commit 3b1e5446d5
1 changed files with 63 additions and 21 deletions

View File

@ -1077,17 +1077,44 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
// Special case or hack if you like
// TODO proper wrap around
if (cur->state == TCP_FIN_WAIT1 &&
if ((cur->state == TCP_FIN_WAIT1 || cur->state == TCP_CLOSE_WAIT) &&
ntohl(tcphdr->seq) == cur->remote_seq &&
ntohl(tcphdr->ack_seq) < cur->local_seq) {
int confirm = cur->local_seq - ntohl(tcphdr->ack_seq);
log_android(ANDROID_LOG_INFO,
"Simultaneous close %s/%u lport %u confirm %d",
dest, ntohs(cur->dest), cur->lport, confirm);
write_ack(args, cur, confirm, args->tun);
}
else
log_android(ANDROID_LOG_WARN,
"Simultaneous close %s/%u lport %u state %s confirm %d data %d",
dest, ntohs(cur->dest), cur->lport, strstate(cur->state),
confirm, datalen);
// Forward data to socket
if (datalen) {
log_android(ANDROID_LOG_DEBUG, "send socket data %u", datalen);
if (send_socket(cur->socket, buffer + dataoff, datalen) < 0)
write_rst(args, cur, args->tun);
else {
if (write_ack(args, cur, 1 + datalen, args->tun) >= 0)
cur->remote_seq += 1 + datalen;
}
}
else {
if (write_ack(args, cur, confirm, args->tun) >= 0)
cur->remote_seq += 1;
}
}
else {
// TODO proper wrap around
if (ntohl(tcphdr->seq) < cur->remote_seq &&
ntohl(tcphdr->ack_seq) == cur->local_seq)
log_android(ANDROID_LOG_WARN,
"Repeated FIN session %s/%u lport %u state %s seq %u/%u ack %u/%u",
dest, ntohs(cur->dest), cur->lport, strstate(cur->state),
ntohl(tcphdr->seq) - cur->remote_start,
cur->remote_seq - cur->remote_start,
ntohl(tcphdr->ack_seq) - cur->local_start,
cur->local_seq - cur->local_start);
else
log_android(ANDROID_LOG_ERROR,
"Invalid FIN session %s/%u lport %u state %s seq %u/%u ack %u/%u",
dest, ntohs(cur->dest), cur->lport, strstate(cur->state),
ntohl(tcphdr->seq) - cur->remote_start,
@ -1096,6 +1123,7 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
cur->local_seq - cur->local_start);
}
}
}
else if (tcphdr->ack) {
if (((uint32_t) ntohl(tcphdr->seq) + 1) == cur->remote_seq) {
@ -1161,8 +1189,23 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
cur->remote_seq += datalen;
}
}
else {
// TODO write ack?
}
} else {
// TODO proper wrap around
if (ntohl(tcphdr->seq) < cur->remote_seq &&
ntohl(tcphdr->ack_seq) == cur->local_seq)
log_android(ANDROID_LOG_WARN,
"Repeated ACK session %s/%u lport %u state %s seq %u/%u ack %u/%u data %d",
dest, ntohs(cur->dest), cur->lport, strstate(cur->state),
ntohl(tcphdr->seq) - cur->remote_start,
cur->remote_seq - cur->remote_start,
ntohl(tcphdr->ack_seq) - cur->local_start,
cur->local_seq - cur->local_start,
datalen);
else
log_android(ANDROID_LOG_ERROR,
"Invalid ACK session %s/%u lport %u state %s seq %u/%u ack %u/%u data %d",
dest, ntohs(cur->dest), cur->lport, strstate(cur->state),
@ -1171,7 +1214,6 @@ jboolean handle_tcp(const struct arguments *args, const uint8_t *buffer, uint16_
ntohl(tcphdr->ack_seq) - cur->local_start,
cur->local_seq - cur->local_start,
datalen);
//write_ack(cur, 0, args->tun);
}
}
}