Native receive buffer

This commit is contained in:
M66B 2016-01-12 19:44:56 +01:00
parent 1542e29ccd
commit 1ba8a56118
1 changed files with 60 additions and 15 deletions

View File

@ -20,6 +20,12 @@
#define TIMEOUTPKT 30 #define TIMEOUTPKT 30
#define TTL 64 #define TTL 64
struct data {
__be32 seq;
jbyte *data;
struct data *next;
};
struct connection { struct connection {
time_t time; time_t time;
__be32 remote_seq; // host notation __be32 remote_seq; // host notation
@ -31,6 +37,8 @@ struct connection {
int state; int state;
int socket; int socket;
int lport; // host notation int lport; // host notation
struct data *received;
struct data *sent;
struct connection *next; struct connection *next;
}; };
@ -108,6 +116,25 @@ void poll() {
else else
last->next = cur->next; last->next = cur->next;
struct data *prev;
struct data *received = cur->received;
while (received != NULL) {
prev = received;
received = received->next;
if (prev->data != NULL)
free(prev->data);
free(prev);
}
struct data *sent = cur->sent;
while (sent != NULL) {
prev = sent;
sent = sent->next;
if (prev->data != NULL)
free(prev->data);
free(prev);
}
free(cur); free(cur);
} else { } else {
@ -205,8 +232,9 @@ void poll() {
// Send packet // Send packet
__android_log_print(ANDROID_LOG_DEBUG, TAG, __android_log_print(ANDROID_LOG_DEBUG, TAG,
"Sending SYN+ACK to tun %s/%u ack %u", "Sending SYN+ACK to tun %s/%u seq %u ack %u",
to, ntohs(tcp->dest), ntohl(tcp->ack_seq)); to, ntohs(tcp->dest),
ntohl(tcp->seq), ntohl(tcp->ack_seq));
if (write(tun, buffer, len) < 0) { if (write(tun, buffer, len) < 0) {
// TODO // TODO
__android_log_print(ANDROID_LOG_ERROR, TAG, "write error %d: %s", __android_log_print(ANDROID_LOG_ERROR, TAG, "write error %d: %s",
@ -231,25 +259,34 @@ void poll() {
errno, strerror(errno)); errno, strerror(errno));
} }
void handle_tcp(JNIEnv *env, jobject instance, jbyte *buffer, int len) { void handle_tcp(JNIEnv *env, jobject instance, jbyte *buffer, int length) {
// Check version // Check version
jbyte version = (*buffer) >> 4; jbyte version = (*buffer) >> 4;
if (version != 4) if (version != 4)
return; return;
// Copy buffer
jbyte *copy = malloc(len); // TODO check/free
memcpy(copy, buffer, len);
// Get headers // Get headers
struct iphdr *iphdr = copy; struct iphdr *iphdr = buffer;
jbyte optlen = (iphdr->ihl > 5 ? copy[20] : 0); jbyte optlen = (iphdr->ihl > 5 ? buffer[sizeof(struct iphdr)] : 0);
struct tcphdr *tcphdr = buffer + (20 + optlen) * sizeof(jbyte); struct tcphdr *tcphdr = buffer + sizeof(struct iphdr) + optlen;
if (ntohs(iphdr->tot_len) != length)
__android_log_print(ANDROID_LOG_WARN, TAG, "Invalid length %u/%d", iphdr->tot_len, length);
// Get data
int dataoff = sizeof(struct iphdr) + optlen + sizeof(struct tcphdr);
int datalen = length - dataoff;
struct data *data = malloc(sizeof(struct data));
data->seq = ntohl(tcphdr->seq);
data->data = malloc(datalen); // TODO free
data->next = NULL;
if (datalen)
memcpy(data->data, buffer + dataoff, datalen);
// Search connection // Search connection
struct connection *last = NULL; struct connection *last = NULL;
struct connection *cur = connection; struct connection *cur = connection;
while (cur != NULL && !(cur->saddr == iphdr->saddr && cur->source != tcphdr->source)) { while (cur != NULL && !(cur->saddr == iphdr->saddr && cur->source == tcphdr->source)) {
last = cur; last = cur;
cur = cur->next; cur = cur->next;
} }
@ -257,11 +294,14 @@ void handle_tcp(JNIEnv *env, jobject instance, jbyte *buffer, int len) {
// 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",
dest, ntohs(tcphdr->dest),
ntohl(tcphdr->seq), ntohl(tcphdr->ack_seq),
datalen);
if (cur == NULL) { if (cur == NULL) {
if (tcphdr->syn) { if (tcphdr->syn) {
__android_log_print(ANDROID_LOG_DEBUG, TAG, "SYN %s/%u seq %u", dest, __android_log_print(ANDROID_LOG_DEBUG, TAG, "New SYN");
ntohs(tcphdr->dest), ntohl(tcphdr->seq));
// Register connection // Register connection
struct connection *syn = malloc(sizeof(struct connection)); // TODO check/free struct connection *syn = malloc(sizeof(struct connection)); // TODO check/free
@ -273,6 +313,8 @@ void handle_tcp(JNIEnv *env, jobject instance, jbyte *buffer, int len) {
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->sent = NULL;
syn->next = NULL; syn->next = NULL;
if (last == NULL) if (last == NULL)
@ -352,17 +394,20 @@ void handle_tcp(JNIEnv *env, jobject instance, jbyte *buffer, int len) {
} }
else { else {
cur->time = time(NULL); cur->time = time(NULL);
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Existing connection lport %u", cur->lport);
if (tcphdr->syn) { if (tcphdr->syn) {
// TODO // TODO
__android_log_print(ANDROID_LOG_DEBUG, TAG, "SYNx2 %s/%u", dest, ntohs(tcphdr->dest)); __android_log_print(ANDROID_LOG_DEBUG, TAG, "Repeated SYN");
} }
else if (tcphdr->ack) { else if (tcphdr->ack) {
// TODO // TODO
// check seq // check seq
// check ack // check ack
if (cur->state == TCP_SYN_SENT) if (cur->state == TCP_SYN_SENT) {
__android_log_print(ANDROID_LOG_DEBUG, TAG, "Established");
cur->state = TCP_ESTABLISHED; cur->state = TCP_ESTABLISHED;
}
} }
shutdown(cur->socket, SHUT_RDWR); shutdown(cur->socket, SHUT_RDWR);