From 9bb84fe05d093294d660a200fc88d86d68469128 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Mon, 5 Jun 2006 20:05:11 +0000 Subject: [PATCH] first try on send functionality --- dns.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- dns.h | 4 +-- dnsd.c | 9 ++++-- dnstun.c | 16 ++++++++-- 4 files changed, 104 insertions(+), 14 deletions(-) diff --git a/dns.c b/dns.c index 4a5cd8f..f531177 100644 --- a/dns.c +++ b/dns.c @@ -35,6 +35,13 @@ static int host2dns(const char *, char *, int); struct sockaddr_in peer; char topdomain[256]; +// Current IP packet +char activepacket[4096]; +int lastlen; +int packetpos; +int packetlen; +uint16_t chunkid; + static int readname(char *packet, char *dst, char *src) { @@ -128,6 +135,9 @@ open_dns(const char *host, const char *domain) strncpy(topdomain, domain, sizeof(topdomain) - 2); topdomain[sizeof(topdomain) - 1] = 0; + // Init chunk id + chunkid = 0; + return fd; } @@ -137,12 +147,77 @@ close_dns(int fd) close(fd); } +int +dns_sending() +{ + return (packetlen != 0); +} + +static void +dns_send_chunk(int fd) +{ + int avail; + char *p; + + p = activepacket; + p += packetpos; + avail = packetlen - packetpos; + lastlen = dns_write(fd, ++chunkid, p, avail); + printf("Sent %d bytes of %d remaining\n", lastlen, avail); +} + +void +dns_handle_tun(int fd, char *data, int len) +{ + memcpy(activepacket, data, MIN(len, sizeof(activepacket))); + lastlen = 0; + packetpos = 0; + packetlen = len; + + dns_send_chunk(fd); +} + +static int +dns_handle_reply(int fd, char *data, int len) +{ + uint16_t id; + char *p; + + p = data; + READSHORT(id, p); + + // Handle ACKing + if (dns_sending() && id == chunkid) { + // Got ACK on sent packet + packetpos += lastlen; + if (packetpos == packetlen) { + // Packet completed + printf("IP packet size %d sent successfully!\n", packetlen); + packetpos = 0; + packetlen = 0; + lastlen = 0; + } else { + // More to send + dns_send_chunk(fd); + } + } + + // Detect if any data is attached + // TODO + + return 0; +} + void dns_ping(int dns_fd) { - dns_write(dns_fd, dns_fd, - "AAAAAAAAAAAKRYOAAAAAAAAAAAKRYOAAAAAAAAAAAAAKRYOAAAAAAAAAAAAAKRYOAAAAAAAAAAAAAAAKRYOAAAAAAAAAAAAAKRYOAAAAAAAAAAAAAAAAAAB", - 119); + if (dns_sending()) { + // Resend latest chunk + printf("No reply on chunk, resending\n"); + dns_send_chunk(dns_fd); + } else { + dns_write(dns_fd, dns_fd, "\0", 1); + } } void @@ -178,7 +253,7 @@ dns_query(int fd, int id, char *host, int type) peerlen = sizeof(peer); len = p - buf; - sendto(fd, buf, len+1, 0, (struct sockaddr*)&peer, peerlen); + sendto(fd, buf, len, 0, (struct sockaddr*)&peer, peerlen); } int @@ -248,7 +323,7 @@ dns_read(int fd, char *buf, int buflen) printf("Read %d bytes DNS reply\n", r); if(r == -1) { - perror("recvfrom"); + perror("recv"); } else { header = (HEADER*)packet; @@ -277,8 +352,10 @@ dns_read(int fd, char *buf, int buflen) READSHORT(port, r); READNAME(packet, host, r); } - printf("%s\n", name); + // printf("%s\n", name); } + // Is any data attached? + return dns_handle_reply(fd, packet, r); } } diff --git a/dns.h b/dns.h index cb84fc3..3678076 100644 --- a/dns.h +++ b/dns.h @@ -17,11 +17,11 @@ #ifndef _DNS_H_ #define _DNS_H_ -extern struct sockaddr_in peer; - int open_dns(const char *, const char *); void close_dns(int); +int dns_sending(); +void dns_handle_tun(int, char *, int); void dns_ping(int); void dns_query(int, int, char *, int); int dns_write(int, int, char *, int); diff --git a/dnsd.c b/dnsd.c index deabf82..7282332 100644 --- a/dnsd.c +++ b/dnsd.c @@ -150,7 +150,7 @@ host2dns(const char *host, char *buffer, int size) } static void -dnsd_respond(int fd, struct sockaddr_in from) +dnsd_respond(int fd, short id, struct sockaddr_in from) { int len; int size; @@ -163,7 +163,7 @@ dnsd_respond(int fd, struct sockaddr_in from) len = 0; header = (HEADER*)buf; - header->id = 0; + header->id = id; header->qr = 1; header->opcode = 0; header->aa = 1; @@ -194,6 +194,7 @@ dnsd_read(int fd, char *buf, int buflen) { int i; int r; + short id; short type; short class; short qdcount; @@ -214,6 +215,8 @@ dnsd_read(int fd, char *buf, int buflen) } else { header = (HEADER*)packet; + id = ntohs(header->id); + data = packet + sizeof(HEADER); if(!header->qr) { @@ -227,7 +230,7 @@ dnsd_read(int fd, char *buf, int buflen) printf("%s %d %d\n", name, type, class); - dnsd_respond(fd, from); + dnsd_respond(fd, id, from); } } } diff --git a/dnstun.c b/dnstun.c index 149ade0..ff75dcb 100644 --- a/dnstun.c +++ b/dnstun.c @@ -41,7 +41,7 @@ tunnel(int tun_fd, int dns_fd) int i; int read; fd_set fds; - char buf[1024]; + char buf[4096]; struct timeval tv; while (running) { @@ -49,7 +49,9 @@ tunnel(int tun_fd, int dns_fd) tv.tv_usec = 0; FD_ZERO(&fds); - FD_SET(tun_fd, &fds); + if (!dns_sending()) { + FD_SET(tun_fd, &fds); + } FD_SET(dns_fd, &fds); i = select(MAX(tun_fd, dns_fd) + 1, &fds, NULL, NULL, &tv); @@ -65,10 +67,18 @@ tunnel(int tun_fd, int dns_fd) dns_ping(dns_fd); } else { if(FD_ISSET(tun_fd, &fds)) { - + read = read_tun(tun_fd, buf, sizeof(buf)); + if (read > 0) { + printf("Got data on tun! %d bytes\n", read); + dns_handle_tun(dns_fd, buf, read); + } } if(FD_ISSET(dns_fd, &fds)) { read = dns_read(dns_fd, buf, sizeof(buf)); + if (read > 0) { + printf("Got data on dns! %d bytes\n", read); + write_tun(tun_fd, buf, read); + } } } }