Native ignore SYN data, keepalive, check packet length

This commit is contained in:
M66B 2016-01-14 10:11:38 +01:00
parent 3e4cc108bc
commit 175a6aed9b
1 changed files with 40 additions and 20 deletions

View File

@ -203,11 +203,9 @@ void *handle_events(void *a) {
dest, ntohs(cur->dest), cur->lport); dest, ntohs(cur->dest), cur->lport);
// TODO check if open // TODO check if open
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Shutdown");
shutdown(cur->socket, SHUT_RDWR); shutdown(cur->socket, SHUT_RDWR);
// TODO check for errors // TODO check for errors
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Unlink");
if (last == NULL) if (last == NULL)
connection = cur->next; connection = cur->next;
else else
@ -215,7 +213,6 @@ void *handle_events(void *a) {
struct data *prev; struct data *prev;
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Free received");
struct data *received = cur->received; struct data *received = cur->received;
while (received != NULL) { while (received != NULL) {
prev = received; prev = received;
@ -225,7 +222,6 @@ void *handle_events(void *a) {
free(prev); free(prev);
} }
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Free send");
struct data *sent = cur->sent; struct data *sent = cur->sent;
while (sent != NULL) { while (sent != NULL) {
prev = sent; prev = sent;
@ -235,7 +231,6 @@ void *handle_events(void *a) {
free(prev); free(prev);
} }
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Free");
free(cur); free(cur);
} else { } else {
@ -344,6 +339,7 @@ void *handle_events(void *a) {
uint8_t buffer[MAXPKT]; uint8_t buffer[MAXPKT];
ssize_t bytes = recv(cur->socket, buffer, MAXPKT, MSG_DONTWAIT); ssize_t bytes = recv(cur->socket, buffer, MAXPKT, MSG_DONTWAIT);
if (bytes < 0) { if (bytes < 0) {
// TODO handle EINTR
__android_log_print(ANDROID_LOG_ERROR, TAG, "recv error %d: %s", __android_log_print(ANDROID_LOG_ERROR, TAG, "recv error %d: %s",
errno, strerror(errno)); errno, strerror(errno));
cur->state = TCP_CLOSE; cur->state = TCP_CLOSE;
@ -409,10 +405,9 @@ void handle_tcp(JNIEnv *env, jobject instance, const uint8_t *buffer, uint16_t l
// Log // Log
char dest[20]; char dest[20];
inet_ntop(AF_INET, &(iphdr->daddr), dest, sizeof(dest)); inet_ntop(AF_INET, &(iphdr->daddr), dest, sizeof(dest));
__android_log_print(ANDROID_LOG_DEBUG, TAG, "%s/%u seq %u ack %u data %d %s", __android_log_print(ANDROID_LOG_DEBUG, TAG, "%s/%u seq %u ack %u data %d",
dest, ntohs(tcphdr->dest), dest, ntohs(tcphdr->dest),
ntohl(tcphdr->seq), ntohl(tcphdr->ack_seq), ntohl(tcphdr->seq), ntohl(tcphdr->ack_seq), datalen);
datalen, hex(data->data, data->len));
if (cur == NULL) { if (cur == NULL) {
if (tcphdr->syn) { if (tcphdr->syn) {
@ -428,10 +423,14 @@ void handle_tcp(JNIEnv *env, jobject instance, const uint8_t *buffer, uint16_t l
syn->daddr = iphdr->daddr; syn->daddr = iphdr->daddr;
syn->dest = tcphdr->dest; syn->dest = tcphdr->dest;
syn->state = TCP_SYN_RECV; syn->state = TCP_SYN_RECV;
syn->received = data; syn->received = NULL;
syn->sent = NULL; syn->sent = NULL;
syn->next = NULL; syn->next = NULL;
syn->received = data;
// Ignore data
if (data->data != NULL)
free(data->data);
free(data);
// Build target address // Build target address
struct sockaddr_in daddr; struct sockaddr_in daddr;
@ -456,6 +455,8 @@ void handle_tcp(JNIEnv *env, jobject instance, const uint8_t *buffer, uint16_t l
else else
last->next = syn; last->next = syn;
} }
else
__android_log_print(ANDROID_LOG_WARN, TAG, "Unknown connection");
} }
else { else {
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Existing connection lport %u", cur->lport); __android_log_print(ANDROID_LOG_DEBUG, TAG, "Existing connection lport %u", cur->lport);
@ -467,19 +468,28 @@ void handle_tcp(JNIEnv *env, jobject instance, const uint8_t *buffer, uint16_t l
cur->time = time(NULL); cur->time = time(NULL);
if (cur->state == TCP_SYN_SENT) { if (cur->state == TCP_SYN_SENT) {
// TODO proper warp around
if (ntohl(tcphdr->ack_seq) == cur->local_seq + 1 && if (ntohl(tcphdr->ack_seq) == cur->local_seq + 1 &&
ntohl(tcphdr->seq) == cur->remote_seq + cur->received->len + 1) { ntohl(tcphdr->seq) == cur->remote_seq + 1) {
cur->local_seq += 1; cur->local_seq += 1;
cur->remote_seq += cur->received->len + 1; cur->remote_seq += 1;
if (cur->received->data != NULL)
free(cur->received->data);
free(cur->received);
cur->received = NULL;
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Established"); __android_log_print(ANDROID_LOG_DEBUG, TAG, "Established");
cur->state = TCP_ESTABLISHED; cur->state = TCP_ESTABLISHED;
} }
else
__android_log_print(ANDROID_LOG_WARN, TAG, "Invalid seq/ack");
}
else if (cur->state == TCP_ESTABLISHED) {
if (ntohl(tcphdr->seq) + 1 == cur->remote_seq)
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Keep alive");
else
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Data");
}
else {
__android_log_print(ANDROID_LOG_WARN, TAG, "Ignored");
} }
} }
} }
@ -489,6 +499,7 @@ int openSocket(JNIEnv *env, jobject instance, const struct sockaddr_in *daddr) {
int sock = -1; int sock = -1;
// Get TCP socket // Get TCP socket
// TODO socket options (SO_REUSEADDR, etc)
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
__android_log_print(ANDROID_LOG_ERROR, TAG, "socket error %d: %s", __android_log_print(ANDROID_LOG_ERROR, TAG, "socket error %d: %s",
errno, strerror(errno)); errno, strerror(errno));
@ -585,7 +596,7 @@ int writeSYN(const struct connection *cur, int tun) {
tcp->source = cur->dest; tcp->source = cur->dest;
tcp->dest = cur->source; tcp->dest = cur->source;
tcp->seq = htonl(cur->local_seq); tcp->seq = htonl(cur->local_seq);
tcp->ack_seq = htonl(cur->remote_seq + cur->received->len + 1); // TODO proper wrap around tcp->ack_seq = htonl(cur->remote_seq + 1); // TODO proper wrap around
tcp->doff = sizeof(struct tcphdr) >> 2; tcp->doff = sizeof(struct tcphdr) >> 2;
tcp->syn = 1; tcp->syn = 1;
tcp->ack = 1; tcp->ack = 1;
@ -616,9 +627,11 @@ int writeSYN(const struct connection *cur, int tun) {
to, ntohs(tcp->dest), to, ntohs(tcp->dest),
ntohl(tcp->seq), ntohl(tcp->ack_seq)); ntohl(tcp->seq), ntohl(tcp->ack_seq));
int res = write(tun, buffer, len); int res = write(tun, buffer, len);
if (res < 0) if (res < 0) {
// TODO handle EINTR
__android_log_print(ANDROID_LOG_ERROR, TAG, "write error %d: %s", __android_log_print(ANDROID_LOG_ERROR, TAG, "write error %d: %s",
errno, strerror(errno)); errno, strerror(errno));
}
free(buffer); free(buffer);
@ -650,10 +663,16 @@ void decode(JNIEnv *env, jobject instance, const uint8_t *buffer, const uint16_t
uint8_t optlen = (ip4hdr->ihl - 5) * 4; uint8_t optlen = (ip4hdr->ihl - 5) * 4;
payload = buffer + 20 + optlen; payload = buffer + 20 + optlen;
if (ntohs(ip4hdr->tot_len) != length) {
__android_log_print(ANDROID_LOG_ERROR, TAG, "Invalid length %u header length %u",
length, ntohs(ip4hdr->tot_len));
return;
}
uint16_t csum = checksum(ip4hdr, sizeof(struct iphdr)); uint16_t csum = checksum(ip4hdr, sizeof(struct iphdr));
if (csum != 0) { if (csum != 0) {
// TODO checksum
__android_log_print(ANDROID_LOG_ERROR, TAG, "Invalid IP checksum"); __android_log_print(ANDROID_LOG_ERROR, TAG, "Invalid IP checksum");
return;
} }
} }
else if (version == 6) { else if (version == 6) {
@ -665,6 +684,7 @@ void decode(JNIEnv *env, jobject instance, const uint8_t *buffer, const uint16_t
payload = buffer + 40; payload = buffer + 40;
// TODO check length
// TODO checksum // TODO checksum
} }
else { else {