#11 Fix delayed ack timer

This commit is contained in:
Erik Ekman 2007-02-11 01:30:41 +00:00
parent 8d766e2857
commit b56a4d23f5

View file

@ -79,13 +79,30 @@ init_users()
} }
static int static int
find_user_by_ip(uint32_t ip) users_waiting_on_reply()
{ {
int ret = -1; int ret;
int i; int i;
ret = 0;
for (i = 0; i < USERS; i++) {
if (users[i].active && users[i].last_pkt + 60 > time(NULL) &&
users[i].q.id != 0) {
ret++;
}
}
return ret;
}
static int
find_user_by_ip(uint32_t ip)
{
int ret;
int i;
ret = -1;
for (i = 0; i < USERS; i++) { for (i = 0; i < USERS; i++) {
/* Not used at all or not used in one minute */
if (users[i].active && users[i].last_pkt + 60 > time(NULL) && if (users[i].active && users[i].last_pkt + 60 > time(NULL) &&
ip == users[i].tun_ip) { ip == users[i].tun_ip) {
ret = i; ret = i;
@ -177,7 +194,7 @@ static int
tunnel_dns(int tun_fd, int dns_fd) tunnel_dns(int tun_fd, int dns_fd)
{ {
struct in_addr tempip; struct in_addr tempip;
struct query q; struct user dummy;
unsigned long outlen; unsigned long outlen;
char logindata[16]; char logindata[16];
char out[64*1024]; char out[64*1024];
@ -189,7 +206,7 @@ tunnel_dns(int tun_fd, int dns_fd)
int code; int code;
userid = -1; userid = -1;
if ((read = read_dns(dns_fd, &q, in, sizeof(in))) <= 0) if ((read = read_dns(dns_fd, &(dummy.q), in, sizeof(in))) <= 0)
return 0; return 0;
if(in[0] == 'V' || in[0] == 'v') { if(in[0] == 'V' || in[0] == 'v') {
@ -206,33 +223,36 @@ tunnel_dns(int tun_fd, int dns_fd)
userid = find_available_user(); userid = find_available_user();
if (userid >= 0) { if (userid >= 0) {
users[userid].seed = rand(); users[userid].seed = rand();
memcpy(&(users[userid].host), &(q.from), q.fromlen); memcpy(&(users[userid].host), &(dummy.q.from), dummy.q.fromlen);
memcpy(&(users[userid].q), &q, sizeof(struct query)); users[userid].addrlen = dummy.q.fromlen;
users[userid].addrlen = q.fromlen; memcpy(&(users[userid].q), &(dummy.q), sizeof(struct query));
users[userid].q.id = 0;
send_version_response(dns_fd, VERSION_ACK, users[userid].seed, &users[userid]); send_version_response(dns_fd, VERSION_ACK, users[userid].seed, &users[userid]);
} else { } else {
/* No space for another user */ /* No space for another user */
send_version_response(dns_fd, VERSION_FULL, USERS, NULL); send_version_response(dns_fd, VERSION_FULL, USERS, &dummy);
} }
} else { } else {
send_version_response(dns_fd, VERSION_NACK, VERSION, NULL); send_version_response(dns_fd, VERSION_NACK, VERSION, &dummy);
} }
} else { } else {
send_version_response(dns_fd, VERSION_NACK, VERSION, NULL); send_version_response(dns_fd, VERSION_NACK, VERSION, &dummy);
} }
} else if(in[0] == 'L' || in[0] == 'l') { } else if(in[0] == 'L' || in[0] == 'l') {
/* Login phase, handle auth */ /* Login phase, handle auth */
userid = in[1]; userid = in[1];
if (userid < 0 || userid >= USERS) { if (userid < 0 || userid >= USERS) {
write_dns(dns_fd, &q, "BADIP", 5); write_dns(dns_fd, &(dummy.q), "BADIP", 5);
return 0; /* illegal id */ return 0; /* illegal id */
} }
users[userid].last_pkt = time(NULL); users[userid].last_pkt = time(NULL);
memcpy(&(users[userid].q), &(dummy.q), sizeof(struct query));
users[userid].q.id = 0;
login_calculate(logindata, 16, password, users[userid].seed); login_calculate(logindata, 16, password, users[userid].seed);
if (q.fromlen != users[userid].addrlen || if (dummy.q.fromlen != users[userid].addrlen ||
memcmp(&(users[userid].host), &(q.from), q.fromlen) != 0) { memcmp(&(users[userid].host), &(dummy.q.from), dummy.q.fromlen) != 0) {
write_dns(dns_fd, &q, "BADIP", 5); write_dns(dns_fd, &(dummy.q), "BADIP", 5);
} else { } else {
if (read >= 18 && (memcmp(logindata, in+2, 16) == 0)) { if (read >= 18 && (memcmp(logindata, in+2, 16) == 0)) {
/* Login ok, send ip/mtu info */ /* Login ok, send ip/mtu info */
@ -245,20 +265,20 @@ tunnel_dns(int tun_fd, int dns_fd)
read = snprintf(out, sizeof(out), "%s-%s-%d", read = snprintf(out, sizeof(out), "%s-%s-%d",
tmp[0], tmp[1], my_mtu); tmp[0], tmp[1], my_mtu);
write_dns(dns_fd, &q, out, read); write_dns(dns_fd, &(dummy.q), out, read);
q.id = 0; dummy.q.id = 0;
free(tmp[1]); free(tmp[1]);
free(tmp[0]); free(tmp[0]);
} else { } else {
write_dns(dns_fd, &q, "LNAK", 4); write_dns(dns_fd, &(dummy.q), "LNAK", 4);
} }
} }
} else if(in[0] == 'P' || in[0] == 'p') { } else if(in[0] == 'P' || in[0] == 'p') {
/* Ping packet, store userid */ /* Ping packet, store userid */
userid = in[1]; userid = in[1];
if (userid < 0 || userid >= USERS) { if (userid < 0 || userid >= USERS) {
write_dns(dns_fd, &q, "BADIP", 5); write_dns(dns_fd, &(dummy.q), "BADIP", 5);
return 0; /* illegal id */ return 0; /* illegal id */
} }
} else if((in[0] >= '0' && in[0] <= '9') } else if((in[0] >= '0' && in[0] <= '9')
@ -273,16 +293,18 @@ tunnel_dns(int tun_fd, int dns_fd)
userid = code >> 1; userid = code >> 1;
if (userid < 0 || userid >= USERS) { if (userid < 0 || userid >= USERS) {
write_dns(dns_fd, &q, "BADIP", 5); write_dns(dns_fd, &(dummy.q), "BADIP", 5);
return 0; /* illegal id */ return 0; /* illegal id */
} }
users[userid].last_pkt = time(NULL);
/* Check sending ip number */ /* Check sending ip number */
if (q.fromlen != users[userid].addrlen || if (dummy.q.fromlen != users[userid].addrlen ||
memcmp(&(users[userid].host), &(q.from), q.fromlen) != 0) { memcmp(&(users[userid].host), &(dummy.q.from), dummy.q.fromlen) != 0) {
write_dns(dns_fd, &q, "BADIP", 5); write_dns(dns_fd, &(dummy.q), "BADIP", 5);
} else { } else {
users[userid].last_pkt = time(NULL);
memcpy(&(users[userid].q), &(dummy.q), sizeof(struct query));
users[userid].addrlen = dummy.q.fromlen;
memcpy(users[userid].inpacket.data + users[userid].inpacket.offset, in + 1, read - 1); memcpy(users[userid].inpacket.data + users[userid].inpacket.offset, in + 1, read - 1);
users[userid].inpacket.len += read - 1; users[userid].inpacket.len += read - 1;
users[userid].inpacket.offset += read - 1; users[userid].inpacket.offset += read - 1;
@ -299,13 +321,13 @@ tunnel_dns(int tun_fd, int dns_fd)
} }
} }
/* userid must be set for a reply to be sent */ /* userid must be set for a reply to be sent */
if (userid >= 0 && userid < USERS && q.fromlen == users[userid].addrlen && if (userid >= 0 && userid < USERS && dummy.q.fromlen == users[userid].addrlen &&
memcmp(&(users[userid].host), &(q.from), q.fromlen) == 0 && memcmp(&(users[userid].host), &(dummy.q.from), dummy.q.fromlen) == 0 &&
users[userid].outpacket.len > 0) { users[userid].outpacket.len > 0) {
write_dns(dns_fd, &q, users[userid].outpacket.data, users[userid].outpacket.len); write_dns(dns_fd, &(dummy.q), users[userid].outpacket.data, users[userid].outpacket.len);
users[userid].outpacket.len = 0; users[userid].outpacket.len = 0;
q.id = 0; dummy.q.id = 0;
} }
return 0; return 0;
@ -320,13 +342,13 @@ tunnel(int tun_fd, int dns_fd)
int j; int j;
while (running) { while (running) {
//if (q.id != 0) { if (users_waiting_on_reply()) {
tv.tv_sec = 0; tv.tv_sec = 0;
tv.tv_usec = 5000; tv.tv_usec = 5000;
/*} else { } else {
tv.tv_sec = 1; tv.tv_sec = 1;
tv.tv_usec = 0; tv.tv_usec = 0;
}*/ }
FD_ZERO(&fds); FD_ZERO(&fds);
//if(outpacket.len == 0) TODO fix this //if(outpacket.len == 0) TODO fix this