ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/vpn_dns.C
(Generate patch)

Comparing gvpe/src/vpn_dns.C (file contents):
Revision 1.51 by root, Sun Mar 6 19:40:28 2011 UTC vs.
Revision 1.54 by root, Tue Oct 18 11:07:28 2011 UTC

59 59
60#include "netcompat.h" 60#include "netcompat.h"
61 61
62#include "vpn.h" 62#include "vpn.h"
63 63
64#define MIN_POLL_INTERVAL 0.1 // poll at most this often when no data received 64#define MIN_POLL_INTERVAL 0.025 // poll at most this often when no data received
65#define MAX_POLL_INTERVAL 1. // how often to poll minimally when the server has no data 65#define MAX_POLL_INTERVAL 1. // how often to poll minimally when the server has no data
66 66
67#define INITIAL_TIMEOUT 0.1 // retry timeouts 67#define INITIAL_TIMEOUT 0.1 // retry timeouts
68#define INITIAL_SYN_TIMEOUT 2. // retry timeout for initial syn 68#define INITIAL_SYN_TIMEOUT 2. // retry timeout for initial syn
69 69
70#define MAX_SEND_INTERVAL 2. // optimistic? 70#define MAX_SEND_INTERVAL 5. // optimistic?
71 71
72#define MAX_WINDOW 1000 // max. for MAX_OUTSTANDING, and backlog 72#define MAX_WINDOW 1000 // max. for MAX_OUTSTANDING, and backlog
73#define MAX_BACKLOG (64*1024) // size of gvpe protocol backlog (bytes), must be > MAXSIZE 73#define MAX_BACKLOG (64*1024) // size of gvpe protocol backlog (bytes), must be > MAXSIZE
74 74
75#define MAX_DOMAIN_SIZE 240 // 255 is legal limit, but bind doesn't compress well 75#define MAX_DOMAIN_SIZE 235 // 255 is legal limit, but bind doesn't compress well
76// 240 leaves about 4 bytes of server reply data 76// 240 leaves about 4 bytes of server reply data
77// every request byte less give room for two reply bytes 77// every request byte less give room for two reply bytes
78 78
79#define SEQNO_MASK 0x3fff 79#define SEQNO_MASK 0x3fff
80#define SEQNO_EQ(a,b) ( 0 == ( ((a) ^ (b)) & SEQNO_MASK) ) 80#define SEQNO_EQ(a,b) ( 0 == ( ((a) ^ (b)) & SEQNO_MASK) )
397 return true; 397 return true;
398} 398}
399 399
400vpn_packet *byte_stream::get () 400vpn_packet *byte_stream::get ()
401{ 401{
402 if (fill < 2)
403 return 0;
404
402 unsigned int len; 405 unsigned int len;
403 406
404 for (;;) 407 for (;;)
405 { 408 {
406 len = (data [0] << 8) | data [1]; 409 len = (data [0] << 8) | data [1];
407 410
408 if (len <= MAXSIZE || fill < 2) 411 if (len <= MAXSIZE)
409 break; 412 break;
410 413
411 // TODO: handle this better than skipping, e.g. by reset 414 // TODO: handle this better than skipping, e.g. by reset
412 slog (L_DEBUG, _("DNS: corrupted packet stream skipping a byte...")); 415 slog (L_DEBUG, _("DNS: corrupted packet (%02x %02x) stream skipping a byte..."), data [0], data [1]);
413 remove (1); 416 remove (1);
414 } 417 }
415 418
416 if (fill < len + 2) 419 if (fill < len + 2)
417 return 0; 420 return 0;
590static 593static
591u16 next_id () 594u16 next_id ()
592{ 595{
593 static u16 dns_id = 0; // TODO: should be per-vpn 596 static u16 dns_id = 0; // TODO: should be per-vpn
594 597
598#if 1
595 if (!dns_id) 599 if (!dns_id)
596 dns_id = time (0); 600 dns_id = time (0);
597 601
598 // the simplest lsfr with periodicity 65535 i could find 602 // the simplest lsfr with periodicity 65535 i could find
599 dns_id = (dns_id << 1) 603 dns_id = (dns_id << 1)
601 ^ (dns_id >> 2) 605 ^ (dns_id >> 2)
602 ^ (dns_id >> 4) 606 ^ (dns_id >> 4)
603 ^ (dns_id >> 15)) & 1); 607 ^ (dns_id >> 15)) & 1);
604 608
605 return dns_id; 609 return dns_id;
610#else
611 dns_id++;//D
612
613 return htons (dns_id);
614#endif
606} 615}
607 616
608struct dns_rcv; 617struct dns_rcv;
609struct dns_snd; 618struct dns_snd;
610 619
830 839
831 established = false; 840 established = false;
832 841
833 rcvseq = repseq = sndseq = 0; 842 rcvseq = repseq = sndseq = 0;
834 843
835 last_sent = last_received = 0; 844 last_sent = 0;
836 poll_interval = 0.5; // starting here 845 poll_interval = 0.5; // starting here
837 send_interval = 0.5; // starting rate 846 send_interval = 0.5; // starting rate
838 min_latency = INITIAL_TIMEOUT; 847 min_latency = INITIAL_TIMEOUT;
839} 848}
840 849
846 855
847void 856void
848dns_connection::receive_rep (dns_rcv *r) 857dns_connection::receive_rep (dns_rcv *r)
849{ 858{
850 if (r->datalen) 859 if (r->datalen)
851 { 860 poll_interval = max (poll_interval * (1. / 1.2), MIN_POLL_INTERVAL);
852 last_received = ev_now ();
853 tw ();
854
855 poll_interval = send_interval;
856 }
857 else 861 else
858 { 862 poll_interval = min (poll_interval * 1.1, MAX_POLL_INTERVAL);
859 poll_interval *= 1.5;
860
861 if (poll_interval > MAX_POLL_INTERVAL)
862 poll_interval = MAX_POLL_INTERVAL;
863 }
864 863
865 rcvpq.push_back (r); 864 rcvpq.push_back (r);
866 865
867 redo: 866 redo:
868 867
1123 dns_connection *dns = (*i)->dns; 1122 dns_connection *dns = (*i)->dns;
1124 connection *c = dns->c; 1123 connection *c = dns->c;
1125 int seqno = (*i)->seqno; 1124 int seqno = (*i)->seqno;
1126 u8 data[MAXSIZE], *datap = data; 1125 u8 data[MAXSIZE], *datap = data;
1127 //printf ("rcv pkt %x\n", seqno);//D 1126 //printf ("rcv pkt %x\n", seqno);//D
1128 bool back_off = (*i)->retry;
1129 1127
1130 if (back_off) 1128 if ((*i)->retry)
1131 { 1129 {
1132 dns->send_interval *= 1.01; 1130 dns->send_interval *= 1.01;
1133 if (dns->send_interval > MAX_SEND_INTERVAL) 1131 if (dns->send_interval > MAX_SEND_INTERVAL)
1134 dns->send_interval = MAX_SEND_INTERVAL; 1132 dns->send_interval = MAX_SEND_INTERVAL;
1135 } 1133 }
1273 } 1271 }
1274 1272
1275 // todo: pkt now used 1273 // todo: pkt now used
1276 if (datap) 1274 if (datap)
1277 dns->receive_rep (new dns_rcv (seqno, data, datap - data)); 1275 dns->receive_rep (new dns_rcv (seqno, data, datap - data));
1278 else if (dns_sndpq.empty ()) // no data received, and nothing to send - idle
1279 {
1280 dns->send_interval *= 1.1;
1281
1282 if (dns->send_interval < MIN_POLL_INTERVAL)
1283 dns->send_interval = MIN_POLL_INTERVAL;
1284
1285 if (dns->send_interval > MAX_POLL_INTERVAL && !back_off)
1286 dns->send_interval = MAX_POLL_INTERVAL;
1287 }
1288 1276
1289 break; 1277 break;
1290 } 1278 }
1291} 1279}
1292 1280
1327 1315
1328 if (!c->dns) 1316 if (!c->dns)
1329 c->dns = new dns_connection (c); 1317 c->dns = new dns_connection (c);
1330 1318
1331 if (c->dns->snddq.put (pkt)) 1319 if (c->dns->snddq.put (pkt))
1320 {
1321 min_it (c->dns->poll_interval, 0.25);
1332 c->dns->tw (); 1322 c->dns->tw ();
1323 }
1333 1324
1334 // always return true even if the buffer overflows 1325 // always return true even if the buffer overflows
1335 return true; 1326 return true;
1336} 1327}
1337
1338#define NEXT(w) do { if (next > (w)) next = w; } while (0)
1339 1328
1340void 1329void
1341dns_connection::time_cb (ev::timer &w, int revents) 1330dns_connection::time_cb (ev::timer &w, int revents)
1342{ 1331{
1343 // servers have to be polled 1332 // servers have to be polled
1344 if (THISNODE->dns_port) 1333 if (THISNODE->dns_port)
1345 return; 1334 return;
1346 1335
1347 // check for timeouts and (re)transmit 1336 // check for timeouts and (re)transmit
1348 tstamp next = ev::now () + poll_interval; 1337 tstamp next = 86400 * 365;
1349 dns_snd *send = 0; 1338 dns_snd *send = 0;
1350 1339
1351 for (vector<dns_snd *>::iterator i = vpn->dns_sndpq.begin (); 1340 for (vector<dns_snd *>::iterator i = vpn->dns_sndpq.begin ();
1352 i != vpn->dns_sndpq.end (); 1341 i != vpn->dns_sndpq.end ();
1353 ++i) 1342 ++i)
1359 if (!send) 1348 if (!send)
1360 { 1349 {
1361 send = r; 1350 send = r;
1362 1351
1363 r->retry++; 1352 r->retry++;
1364 r->timeout = ev_now () + (r->retry * min_latency * conf.dns_timeout_factor); 1353 r->timeout = ev_now () + r->retry * min_latency * conf.dns_timeout_factor;
1365 //printf ("RETRY %x (%d, %f)\n", r->seqno, r->retry, r->timeout - ev_now ());//D 1354 //printf ("RETRY %x (%d, %f)\n", r->seqno, r->retry, r->timeout - ev_now ());//D
1366 1355
1367 // the following code changes the query section a bit, forcing 1356 // the following code changes the query section a bit, forcing
1368 // the forwarder to generate a new request 1357 // the forwarder to generate a new request
1369 if (r->stdhdr) 1358 if (r->stdhdr)
1370 encode_header ((char *)r->pkt->at (6 * 2 + 1), THISNODE->id, r->seqno, r->retry); 1359 encode_header ((char *)r->pkt->at (6 * 2 + 1), THISNODE->id, r->seqno, r->retry);
1371 } 1360 }
1372 } 1361 }
1373 else 1362 else
1374 NEXT (r->timeout); 1363 min_it (next, r->timeout - ev_now ());
1375 } 1364 }
1376 1365
1377 if (!send) 1366 if (!send)
1378 { 1367 {
1379 // generate a new packet, if wise 1368 // generate a new packet, if wise
1393 && !SEQNO_EQ (rcvseq, sndseq - (MAX_WINDOW - 1))) 1382 && !SEQNO_EQ (rcvseq, sndseq - (MAX_WINDOW - 1)))
1394 { 1383 {
1395 if (last_sent + send_interval <= ev_now ()) 1384 if (last_sent + send_interval <= ev_now ())
1396 { 1385 {
1397 //printf ("sending data request etc.\n"); //D 1386 //printf ("sending data request etc.\n"); //D
1398 if (!snddq.empty () || last_received + 1. > ev_now ()) 1387 if (!snddq.empty ())
1399 {
1400 poll_interval = send_interval; 1388 min_it (next, send_interval);
1401 NEXT (ev_now () + send_interval);
1402 }
1403 1389
1404 send = new dns_snd (this); 1390 send = new dns_snd (this);
1405 send->gen_stream_req (sndseq, snddq); 1391 send->gen_stream_req (sndseq, snddq);
1406 send->timeout = ev_now () + min_latency * conf.dns_timeout_factor; 1392 send->timeout = ev_now () + min_latency * conf.dns_timeout_factor;
1407 //printf ("SEND %x (%f)\n", send->seqno, send->timeout - ev_now (), min_latency, conf.dns_timeout_factor);//D 1393 //printf ("SEND %x (%f)\n", send->seqno, send->timeout - ev_now (), min_latency, conf.dns_timeout_factor);//D
1408 1394
1409 sndseq = (sndseq + 1) & SEQNO_MASK; 1395 sndseq = (sndseq + 1) & SEQNO_MASK;
1410 } 1396 }
1411 else 1397 else
1412 NEXT (last_sent + send_interval); 1398 min_it (next, last_sent + send_interval - ev_now ());
1413 } 1399 }
1414 1400
1415 if (send) 1401 if (send)
1416 vpn->dns_sndpq.push_back (send); 1402 vpn->dns_sndpq.push_back (send);
1417 } 1403 }
1422 sendto (vpn->dnsv4_fd, 1408 sendto (vpn->dnsv4_fd,
1423 send->pkt->at (0), send->pkt->len, 0, 1409 send->pkt->at (0), send->pkt->len, 0,
1424 vpn->dns_forwarder.sav4 (), vpn->dns_forwarder.salenv4 ()); 1410 vpn->dns_forwarder.sav4 (), vpn->dns_forwarder.salenv4 ());
1425 } 1411 }
1426 1412
1413 min_it (next, last_sent + max (poll_interval, send_interval) - ev_now ());
1414
1427 slog (L_NOISE, "DNS: pi %f si %f N %f (%d:%d %d)", 1415 slog (L_NOISE, "DNS: pi %f si %f N %f (%d:%d %d)",
1428 poll_interval, send_interval, next - ev_now (), 1416 poll_interval, send_interval, next - ev_now (),
1429 vpn->dns_sndpq.size (), snddq.size (), 1417 vpn->dns_sndpq.size (), snddq.size (),
1430 rcvpq.size ()); 1418 rcvpq.size ());
1431 1419
1432 // TODO: no idea when this happens, but when next < ev_now (), we have a problem 1420 w.start (next);
1433 // doesn't seem to happen anymore
1434 if (next < ev_now () + 0.001)
1435 next = ev_now () + 0.1;
1436
1437 w.start (next - ev_now ());
1438} 1421}
1439 1422
1440#endif 1423#endif
1441 1424

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines