… | |
… | |
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 | |
400 | vpn_packet *byte_stream::get () |
400 | vpn_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; |
… | |
… | |
590 | static |
593 | static |
591 | u16 next_id () |
594 | u16 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 | |
608 | struct dns_rcv; |
617 | struct dns_rcv; |
609 | struct dns_snd; |
618 | struct 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 | |
847 | void |
856 | void |
848 | dns_connection::receive_rep (dns_rcv *r) |
857 | dns_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 | |
1340 | void |
1329 | void |
1341 | dns_connection::time_cb (ev::timer &w, int revents) |
1330 | dns_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 | |