delayed acking

This commit is contained in:
Erik Ekman 2006-06-06 12:36:12 +00:00
parent 824f5fda90
commit 049cb2eff8
3 changed files with 47 additions and 4 deletions

34
dnsd.c
View File

@ -42,6 +42,11 @@ char activepacket[4096];
int outid; int outid;
int outbuflen; int outbuflen;
char outbuf[64*1024]; char outbuf[64*1024];
char delayed_q_name[256];
short delayed_q_type;
short delayed_q_id;
struct sockaddr_in delayed_q_from;
int delayed_q_fromlen;
static int static int
readname(char *packet, char *dst, char *src) readname(char *packet, char *dst, char *src)
@ -126,6 +131,9 @@ open_dnsd(const char *domain)
topdomain[sizeof(topdomain) - 1] = 0; topdomain[sizeof(topdomain) - 1] = 0;
packetlen = 0; packetlen = 0;
delayed_q_type = 0;
delayed_q_id = 0;
delayed_q_fromlen = 0;
return fd; return fd;
} }
@ -169,6 +177,12 @@ dnsd_haspacket()
return (outbuflen > 0); return (outbuflen > 0);
} }
int
dnsd_hasack()
{
return (delayed_q_id != 0);
}
void void
dnsd_queuepacket(const char *buf, const int buflen) dnsd_queuepacket(const char *buf, const int buflen)
{ {
@ -179,7 +193,7 @@ dnsd_queuepacket(const char *buf, const int buflen)
} }
static void static void
dnsd_respond(int fd, char *name, short type, short id, struct sockaddr_in from) dnsd_send(int fd, char *name, short type, short id, struct sockaddr_in from)
{ {
int len; int len;
char *p; char *p;
@ -229,6 +243,13 @@ dnsd_respond(int fd, char *name, short type, short id, struct sockaddr_in from)
outbuflen = 0; outbuflen = 0;
} }
void
dnsd_forceack(int fd)
{
dnsd_send(fd, delayed_q_name, delayed_q_type, delayed_q_id, delayed_q_from);
delayed_q_id = 0;
}
int int
dnsd_read(int fd, char *buf, int buflen) dnsd_read(int fd, char *buf, int buflen)
{ {
@ -274,7 +295,16 @@ dnsd_read(int fd, char *buf, int buflen)
READSHORT(type, data); READSHORT(type, data);
READSHORT(class, data); READSHORT(class, data);
dnsd_respond(fd, name, type, id, from); if (dnsd_haspacket()) {
dnsd_send(fd, name, type, id, from);
} else {
// Store needed info about delayed response
strncpy(delayed_q_name, name, 256);
delayed_q_type = type;
delayed_q_id = id;
delayed_q_fromlen = addrlen;
memcpy((struct sockaddr*)&delayed_q_from, (struct sockaddr*)&from, addrlen);
}
lastblock = name[0] - '0'; lastblock = name[0] - '0';
np = name; np = name;

2
dnsd.h
View File

@ -25,6 +25,8 @@ void close_dnsd(int);
int dnsd_read(int, char *, int); int dnsd_read(int, char *, int);
int dnsd_haspacket(); int dnsd_haspacket();
int dnsd_hasack();
void dnsd_forceack(int);
void dnsd_queuepacket(const char *, const int); void dnsd_queuepacket(const char *, const int);

View File

@ -53,8 +53,13 @@ tunnel(int tun_fd, int dns_fd)
frame = malloc(64*1024); frame = malloc(64*1024);
while (running) { while (running) {
if (dnsd_hasack()) {
tv.tv_sec = 0;
tv.tv_usec = 150000;
} else {
tv.tv_sec = 1; tv.tv_sec = 1;
tv.tv_usec = 0; tv.tv_usec = 0;
}
FD_ZERO(&fds); FD_ZERO(&fds);
if(!dnsd_haspacket()) if(!dnsd_haspacket())
@ -88,6 +93,12 @@ tunnel(int tun_fd, int dns_fd)
write_tun(tun_fd, frame, read + 4); write_tun(tun_fd, frame, read + 4);
} }
} }
} else {
// Timeout on select()
if (dnsd_hasack()) {
printf("Got no data, sending delayed ACK\n");
dnsd_forceack(dns_fd);
}
} }
} }