--- gvpe/src/vpn_dns.C 2005/03/04 08:15:04 1.10 +++ gvpe/src/vpn_dns.C 2005/03/04 09:51:23 1.14 @@ -45,19 +45,18 @@ #include "vpn.h" -#define MIN_POLL_INTERVAL .2 // how often to poll minimally when the server is having data +#define MIN_POLL_INTERVAL .02 // how often to poll minimally when the server is having data #define MAX_POLL_INTERVAL 6. // how often to poll minimally when the server has no data #define ACTIVITY_INTERVAL 5. #define INITIAL_TIMEOUT 1. #define INITIAL_SYN_TIMEOUT 2. -#define MIN_SEND_INTERVAL (1./1000.) +#define MIN_SEND_INTERVAL 0.01 #define MAX_SEND_INTERVAL 0.5 // optimistic? -#define MAX_OUTSTANDING 400 // max. outstanding requests -#define MAX_WINDOW 1000 // max. for MAX_OUTSTANDING -#define MAX_RATE 100 // requests/s +#define MAX_OUTSTANDING 40 // max. outstanding requests +#define MAX_WINDOW 100 // max. for MAX_OUTSTANDING #define MAX_BACKLOG (100*1024) // size of protocol backlog, must be > MAXSIZE #define MAX_DOMAIN_SIZE 220 // 255 is legal limit, but bind doesn't compress well @@ -353,7 +352,7 @@ vpn_packet *byte_stream::get () { - int len = (data [0] << 8) | data [1]; + unsigned int len = (data [0] << 8) | data [1]; if (len > MAXSIZE && fill >= 2) abort (); // TODO handle this gracefully, connection reset @@ -503,9 +502,11 @@ struct dns_connection *dns; int seqno; - dns_snd (dns_connection *dns); void gen_stream_req (int seqno, byte_stream &stream); void gen_syn_req (const dns_cfg &cfg); + + dns_snd (dns_connection *dns); + ~dns_snd (); }; static u16 dns_id = 12098; // TODO: should be per-vpn @@ -528,12 +529,18 @@ timeout = 0; retry = 0; seqno = 0; + sent = NOW; pkt = new dns_packet; pkt->id = next_id (); } +dns_snd::~dns_snd () +{ + delete pkt; +} + static void append_domain (dns_packet &pkt, int &offs, const char *domain) { // add tunnel domain @@ -709,9 +716,7 @@ last_received = NOW; tw.trigger (); - poll_interval *= 0.99; - if (poll_interval > MIN_POLL_INTERVAL) - poll_interval = MIN_POLL_INTERVAL; + poll_interval = send_interval; } else { @@ -751,6 +756,8 @@ si.host = 0; si.port = 0; si.prot = PROT_DNSv4; vpn->recv_vpn_packet (pkt, si); + + delete pkt; } // check for further packets @@ -819,7 +826,7 @@ // already seen that request: simply reply with the cached reply dns_rcv *r = *i; - printf ("DUPLICATE %d\n", htons (r->pkt->id));//D + slog (L_DEBUG, "DUPLICATE %d\n", htons (r->pkt->id)); memcpy (pkt.at (0), r->pkt->at (0), offs = r->pkt->len); pkt.id = r->pkt->id; @@ -833,16 +840,11 @@ pkt [offs++] = 0xc0; pkt [offs++] = 6 * 2; // refer to name in query section - // type int rtype = dns ? dns->cfg.rrtype : RR_TYPE_A; - pkt [offs++] = rtype >> 8; pkt [offs++] = rtype; - - // class - pkt [offs++] = RR_CLASS_IN >> 8; pkt [offs++] = RR_CLASS_IN; - - // TTL + pkt [offs++] = rtype >> 8; pkt [offs++] = rtype; // type + pkt [offs++] = RR_CLASS_IN >> 8; pkt [offs++] = RR_CLASS_IN; // class pkt [offs++] = 0; pkt [offs++] = 0; - pkt [offs++] = 0; pkt [offs++] = dns ? dns->cfg.def_ttl : 0; + pkt [offs++] = 0; pkt [offs++] = dns ? dns->cfg.def_ttl : 0; // TTL int rdlen_offs = offs += 2; @@ -951,25 +953,30 @@ if ((*i)->pkt->id == pkt.id) { dns_connection *dns = (*i)->dns; + connection *c = dns->c; int seqno = (*i)->seqno; u8 data[MAXSIZE], *datap = data; if ((*i)->retry) { - dns->send_interval *= 1.01; - if (dns->send_interval < MAX_SEND_INTERVAL) + dns->send_interval *= 1.001; + if (dns->send_interval > MAX_SEND_INTERVAL) dns->send_interval = MAX_SEND_INTERVAL; } else { - dns->send_interval *= 0.99; +#if 1 + dns->send_interval *= 0.9999; +#endif if (dns->send_interval < MIN_SEND_INTERVAL) dns->send_interval = MIN_SEND_INTERVAL; // the latency surely puts an upper bound on // the minimum send interval - if (dns->send_interval > NOW - (*i)->sent) - dns->send_interval = NOW - (*i)->sent; + double latency = NOW - (*i)->sent; + + if (dns->send_interval > latency) + dns->send_interval = latency; } delete *i; @@ -1035,13 +1042,20 @@ { slog (L_DEBUG, _("got tunnel RST request")); - connection *c = dns->c; - delete c->dns; c->dns = 0; + delete dns; c->dns = 0; return; } else if (ip [3] == CMD_IP_SYN) - dns->established = true; + { + slog (L_DEBUG, _("got tunnel SYN reply, server likes us.")); + dns->established = true; + } + else if (ip [3] == CMD_IP_REJ) + { + slog (L_DEBUG, _("got tunnel REJ reply, server does not like us, aborting.")); + abort (); + } else slog (L_INFO, _("got unknown meta command %02x"), ip [3]); } @@ -1116,6 +1130,12 @@ return true; } +void +connection::dnsv4_reset_connection () +{ + //delete dns; dns = 0; //TODO +} + #define NEXT(w) do { if (next > (w)) next = w; } while (0) void @@ -1145,7 +1165,7 @@ r->timeout = NOW + r->retry; } } - else if (r->timeout < next) + else NEXT (r->timeout); } @@ -1179,12 +1199,7 @@ if (send) { - printf ("send pkt\n"); last_sent = NOW; - - if (!send->retry) - send->sent = NOW; - sendto (vpn->dnsv4_fd, send->pkt->at (0), send->pkt->len, 0, vpn->dns_forwarder.sav4 (), vpn->dns_forwarder.salenv4 ()); @@ -1193,7 +1208,13 @@ else NEXT (last_sent + send_interval); - printf ("pi %f si %f N %f (%d:%d)\n", poll_interval, send_interval, next - NOW, vpn->dns_sndpq.size (), snddq.size ()); + slog (L_NOISE, "pi %f si %f N %f (%d:%d)", + poll_interval, send_interval, next - NOW, + vpn->dns_sndpq.size (), snddq.size ()); + + // TODO: no idea when this happens, but when next < NOW, we have a problem + if (next < NOW + 0.0001) + next = NOW + 0.1; w.start (next); }