… | |
… | |
43 | |
43 | |
44 | #include "netcompat.h" |
44 | #include "netcompat.h" |
45 | |
45 | |
46 | #include "vpn.h" |
46 | #include "vpn.h" |
47 | |
47 | |
48 | #define MIN_POLL_INTERVAL .2 // how often to poll minimally when the server is having data |
48 | #define MIN_POLL_INTERVAL .02 // how often to poll minimally when the server has data |
49 | #define MAX_POLL_INTERVAL 6. // how often to poll minimally when the server has no data |
49 | #define MAX_POLL_INTERVAL 6. // how often to poll minimally when the server has no data |
50 | #define ACTIVITY_INTERVAL 5. |
50 | #define ACTIVITY_INTERVAL 5. |
51 | |
51 | |
52 | #define INITIAL_TIMEOUT 1. |
52 | #define INITIAL_TIMEOUT 0.1 // retry timeouts |
53 | #define INITIAL_SYN_TIMEOUT 2. |
53 | #define INITIAL_SYN_TIMEOUT 10. // retry timeout for initial syn |
54 | |
54 | |
55 | #define MIN_SEND_INTERVAL (1./1000.) |
55 | #define MIN_SEND_INTERVAL 0.01 // wait at least this time between sending requests |
56 | #define MAX_SEND_INTERVAL 0.5 // optimistic? |
56 | #define MAX_SEND_INTERVAL 0.5 // optimistic? |
57 | |
57 | |
58 | #define MAX_OUTSTANDING 400 // max. outstanding requests |
58 | #define MAX_OUTSTANDING 10 // max. outstanding requests |
59 | #define MAX_WINDOW 1000 // max. for MAX_OUTSTANDING |
59 | #define MAX_WINDOW 1000 // max. for MAX_OUTSTANDING, and backlog |
60 | #define MAX_RATE 100 // requests/s |
|
|
61 | #define MAX_BACKLOG (100*1024) // size of protocol backlog, must be > MAXSIZE |
60 | #define MAX_BACKLOG (100*1024) // size of gvpe protocol backlog (bytes), must be > MAXSIZE |
62 | |
61 | |
63 | #define MAX_DOMAIN_SIZE 220 // 255 is legal limit, but bind doesn't compress well |
62 | #define MAX_DOMAIN_SIZE 220 // 255 is legal limit, but bind doesn't compress well |
64 | // 240 leaves about 4 bytes of server reply data |
63 | // 240 leaves about 4 bytes of server reply data |
65 | // every two request byte sless give room for one reply byte |
64 | // every two request bytes less give room for one reply byte |
66 | |
65 | |
67 | #define SEQNO_MASK 0xffff |
66 | #define SEQNO_MASK 0x3fff |
68 | #define SEQNO_EQ(a,b) ( 0 == ( ((a) ^ (b)) & SEQNO_MASK) ) |
67 | #define SEQNO_EQ(a,b) ( 0 == ( ((a) ^ (b)) & SEQNO_MASK) ) |
69 | |
68 | |
70 | #define MAX_LBL_SIZE 63 |
69 | #define MAX_LBL_SIZE 63 |
71 | #define MAX_PKT_SIZE 512 |
70 | #define MAX_PKT_SIZE 512 |
72 | |
71 | |
… | |
… | |
266 | |
265 | |
267 | ///////////////////////////////////////////////////////////////////////////// |
266 | ///////////////////////////////////////////////////////////////////////////// |
268 | |
267 | |
269 | #define HDRSIZE 6 |
268 | #define HDRSIZE 6 |
270 | |
269 | |
271 | inline void encode_header (char *data, int clientid, int seqno) |
270 | inline void encode_header (char *data, int clientid, int seqno, int retry = 0) |
272 | { |
271 | { |
273 | u8 hdr[3] = { clientid, seqno >> 8, seqno }; |
272 | seqno &= SEQNO_MASK; |
|
|
273 | |
|
|
274 | u8 hdr[3] = { |
|
|
275 | clientid, |
|
|
276 | (seqno >> 8) | (retry << 6), |
|
|
277 | seqno, |
|
|
278 | }; |
274 | |
279 | |
275 | assert (clientid < 256); |
280 | assert (clientid < 256); |
276 | |
281 | |
277 | cdc26.encode (data, hdr, 3); |
282 | cdc26.encode (data, hdr, 3); |
278 | } |
283 | } |
… | |
… | |
282 | u8 hdr[3]; |
287 | u8 hdr[3]; |
283 | |
288 | |
284 | cdc26.decode (hdr, data, HDRSIZE); |
289 | cdc26.decode (hdr, data, HDRSIZE); |
285 | |
290 | |
286 | clientid = hdr[0]; |
291 | clientid = hdr[0]; |
287 | seqno = (hdr[1] << 8) | hdr[2]; |
292 | seqno = ((hdr[1] << 8) | hdr[2]) & SEQNO_MASK; |
288 | } |
293 | } |
289 | |
294 | |
290 | ///////////////////////////////////////////////////////////////////////////// |
295 | ///////////////////////////////////////////////////////////////////////////// |
291 | |
296 | |
292 | struct byte_stream |
297 | struct byte_stream |
… | |
… | |
321 | } |
326 | } |
322 | |
327 | |
323 | void byte_stream::remove (int count) |
328 | void byte_stream::remove (int count) |
324 | { |
329 | { |
325 | if (count > fill) |
330 | if (count > fill) |
326 | abort (); |
331 | assert (count <= fill); |
327 | |
332 | |
328 | memmove (data, data + count, fill -= count); |
333 | memmove (data, data + count, fill -= count); |
329 | } |
334 | } |
330 | |
335 | |
331 | bool byte_stream::put (u8 *data, unsigned int datalen) |
336 | bool byte_stream::put (u8 *data, unsigned int datalen) |
… | |
… | |
351 | return true; |
356 | return true; |
352 | } |
357 | } |
353 | |
358 | |
354 | vpn_packet *byte_stream::get () |
359 | vpn_packet *byte_stream::get () |
355 | { |
360 | { |
356 | int len = (data [0] << 8) | data [1]; |
361 | unsigned int len = (data [0] << 8) | data [1]; |
357 | |
362 | |
358 | if (len > MAXSIZE && fill >= 2) |
363 | if (len > MAXSIZE && fill >= 2) |
359 | abort (); // TODO handle this gracefully, connection reset |
364 | assert (len <= MAXSIZE || fill < 2); // TODO handle this gracefully, connection reset |
360 | |
365 | |
361 | if (fill < len + 2) |
366 | if (fill < len + 2) |
362 | return 0; |
367 | return 0; |
363 | |
368 | |
364 | vpn_packet *pkt = new vpn_packet; |
369 | vpn_packet *pkt = new vpn_packet; |
… | |
… | |
423 | |
428 | |
424 | version = 1; |
429 | version = 1; |
425 | |
430 | |
426 | rrtype = RR_TYPE_TXT; |
431 | rrtype = RR_TYPE_TXT; |
427 | flags = 0; |
432 | flags = 0; |
428 | def_ttl = 0; |
433 | def_ttl = 1; |
429 | rcv_cdc = 0; |
434 | rcv_cdc = 0; |
430 | snd_cdc = 62; |
435 | snd_cdc = 62; |
431 | max_size = ntohs (MAX_PKT_SIZE); |
436 | max_size = ntohs (MAX_PKT_SIZE); |
432 | client = ntohs (clientid); |
437 | client = ntohs (clientid); |
433 | uid = next_uid++; |
438 | uid = next_uid++; |
… | |
… | |
500 | dns_packet *pkt; |
505 | dns_packet *pkt; |
501 | tstamp timeout, sent; |
506 | tstamp timeout, sent; |
502 | int retry; |
507 | int retry; |
503 | struct dns_connection *dns; |
508 | struct dns_connection *dns; |
504 | int seqno; |
509 | int seqno; |
|
|
510 | bool stdhdr; |
505 | |
511 | |
506 | dns_snd (dns_connection *dns); |
|
|
507 | void gen_stream_req (int seqno, byte_stream &stream); |
512 | void gen_stream_req (int seqno, byte_stream &stream); |
508 | void gen_syn_req (const dns_cfg &cfg); |
513 | void gen_syn_req (const dns_cfg &cfg); |
|
|
514 | |
|
|
515 | dns_snd (dns_connection *dns); |
|
|
516 | ~dns_snd (); |
509 | }; |
517 | }; |
510 | |
518 | |
511 | static u16 dns_id = 12098; // TODO: should be per-vpn |
519 | static u16 dns_id = 12098; // TODO: should be per-vpn |
512 | |
520 | |
513 | static u16 next_id () |
521 | static u16 next_id () |
… | |
… | |
526 | : dns (dns) |
534 | : dns (dns) |
527 | { |
535 | { |
528 | timeout = 0; |
536 | timeout = 0; |
529 | retry = 0; |
537 | retry = 0; |
530 | seqno = 0; |
538 | seqno = 0; |
|
|
539 | sent = NOW; |
|
|
540 | stdhdr = false; |
531 | |
541 | |
532 | pkt = new dns_packet; |
542 | pkt = new dns_packet; |
533 | |
543 | |
534 | pkt->id = next_id (); |
544 | pkt->id = next_id (); |
|
|
545 | } |
|
|
546 | |
|
|
547 | dns_snd::~dns_snd () |
|
|
548 | { |
|
|
549 | delete pkt; |
535 | } |
550 | } |
536 | |
551 | |
537 | static void append_domain (dns_packet &pkt, int &offs, const char *domain) |
552 | static void append_domain (dns_packet &pkt, int &offs, const char *domain) |
538 | { |
553 | { |
539 | // add tunnel domain |
554 | // add tunnel domain |
… | |
… | |
557 | } |
572 | } |
558 | } |
573 | } |
559 | |
574 | |
560 | void dns_snd::gen_stream_req (int seqno, byte_stream &stream) |
575 | void dns_snd::gen_stream_req (int seqno, byte_stream &stream) |
561 | { |
576 | { |
|
|
577 | stdhdr = true; |
562 | this->seqno = seqno; |
578 | this->seqno = seqno; |
563 | |
579 | |
564 | timeout = NOW + INITIAL_TIMEOUT; |
580 | timeout = NOW + INITIAL_TIMEOUT; |
565 | |
581 | |
566 | pkt->flags = htons (DEFAULT_CLIENT_FLAGS); |
582 | pkt->flags = htons (DEFAULT_CLIENT_FLAGS); |
… | |
… | |
661 | |
677 | |
662 | bool established; |
678 | bool established; |
663 | |
679 | |
664 | tstamp last_received; |
680 | tstamp last_received; |
665 | tstamp last_sent; |
681 | tstamp last_sent; |
|
|
682 | double last_latency; |
666 | double poll_interval, send_interval; |
683 | double poll_interval, send_interval; |
667 | |
684 | |
668 | vector<dns_rcv *> rcvpq; |
685 | vector<dns_rcv *> rcvpq; |
669 | |
686 | |
670 | byte_stream rcvdq; int rcvseq; |
687 | byte_stream rcvdq; int rcvseq; |
… | |
… | |
689 | |
706 | |
690 | rcvseq = sndseq = 0; |
707 | rcvseq = sndseq = 0; |
691 | |
708 | |
692 | last_sent = last_received = 0; |
709 | last_sent = last_received = 0; |
693 | poll_interval = MIN_POLL_INTERVAL; |
710 | poll_interval = MIN_POLL_INTERVAL; |
694 | send_interval = 0.2; // starting rate |
711 | send_interval = 0.5; // starting rate |
|
|
712 | last_latency = INITIAL_TIMEOUT; |
695 | } |
713 | } |
696 | |
714 | |
697 | dns_connection::~dns_connection () |
715 | dns_connection::~dns_connection () |
698 | { |
716 | { |
699 | for (vector<dns_rcv *>::iterator i = rcvpq.begin (); |
717 | for (vector<dns_rcv *>::iterator i = rcvpq.begin (); |
… | |
… | |
707 | if (r->datalen) |
725 | if (r->datalen) |
708 | { |
726 | { |
709 | last_received = NOW; |
727 | last_received = NOW; |
710 | tw.trigger (); |
728 | tw.trigger (); |
711 | |
729 | |
712 | poll_interval *= 0.99; |
730 | poll_interval = send_interval; |
713 | if (poll_interval > MIN_POLL_INTERVAL) |
|
|
714 | poll_interval = MIN_POLL_INTERVAL; |
|
|
715 | } |
731 | } |
716 | else |
732 | else |
717 | { |
733 | { |
718 | poll_interval *= 1.1; |
734 | poll_interval *= 1.5; |
719 | if (poll_interval > MAX_POLL_INTERVAL) |
735 | if (poll_interval > MAX_POLL_INTERVAL) |
720 | poll_interval = MAX_POLL_INTERVAL; |
736 | poll_interval = MAX_POLL_INTERVAL; |
721 | } |
737 | } |
722 | |
738 | |
723 | rcvpq.push_back (r); |
739 | rcvpq.push_back (r); |
… | |
… | |
741 | } |
757 | } |
742 | |
758 | |
743 | rcvseq = (rcvseq + 1) & SEQNO_MASK; |
759 | rcvseq = (rcvseq + 1) & SEQNO_MASK; |
744 | |
760 | |
745 | if (!rcvdq.put (r->data, r->datalen)) |
761 | if (!rcvdq.put (r->data, r->datalen)) |
|
|
762 | { |
|
|
763 | slog (L_ERR, "DNS: !rcvdq.put (r->data, r->datalen)"); |
746 | abort (); // MUST never overflow, can be caused by data corruption, TODO |
764 | abort (); // MUST never overflow, can be caused by data corruption, TODO |
|
|
765 | } |
747 | |
766 | |
748 | while (vpn_packet *pkt = rcvdq.get ()) |
767 | while (vpn_packet *pkt = rcvdq.get ()) |
749 | { |
768 | { |
750 | sockinfo si; |
769 | sockinfo si; |
751 | si.host = 0; si.port = 0; si.prot = PROT_DNSv4; |
770 | si.host = 0; si.port = 0; si.prot = PROT_DNSv4; |
752 | |
771 | |
753 | vpn->recv_vpn_packet (pkt, si); |
772 | vpn->recv_vpn_packet (pkt, si); |
|
|
773 | |
|
|
774 | delete pkt; |
754 | } |
775 | } |
755 | |
776 | |
756 | // check for further packets |
777 | // check for further packets |
757 | goto redo; |
778 | goto redo; |
758 | } |
779 | } |
… | |
… | |
779 | pkt.qdcount = htons (1); |
800 | pkt.qdcount = htons (1); |
780 | pkt.ancount = 0; |
801 | pkt.ancount = 0; |
781 | pkt.nscount = 0; // should be self, as other nameservers reply like this |
802 | pkt.nscount = 0; // should be self, as other nameservers reply like this |
782 | pkt.arcount = 0; // a record for self, as other nameservers reply like this |
803 | pkt.arcount = 0; // a record for self, as other nameservers reply like this |
783 | |
804 | |
784 | pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_NXDOMAIN); |
805 | pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_SERVFAIL); |
785 | |
806 | |
786 | int dlen = strlen (THISNODE->domain); |
807 | int dlen = strlen (THISNODE->domain); |
787 | |
808 | |
788 | if (qclass == RR_CLASS_IN |
809 | if (qclass == RR_CLASS_IN |
789 | && qlen > dlen + 1 |
810 | && qlen > dlen + 1 |
… | |
… | |
808 | if (0 < client && client <= conns.size ()) |
829 | if (0 < client && client <= conns.size ()) |
809 | { |
830 | { |
810 | connection *c = conns [client - 1]; |
831 | connection *c = conns [client - 1]; |
811 | dns_connection *dns = c->dns; |
832 | dns_connection *dns = c->dns; |
812 | dns_rcv *rcv; |
833 | dns_rcv *rcv; |
|
|
834 | bool in_seq; |
813 | |
835 | |
814 | if (dns) |
836 | if (dns) |
815 | { |
837 | { |
816 | for (vector<dns_rcv *>::iterator i = dns->rcvpq.end (); i-- != dns->rcvpq.begin (); ) |
838 | for (vector<dns_rcv *>::iterator i = dns->rcvpq.end (); i-- != dns->rcvpq.begin (); ) |
817 | if (SEQNO_EQ ((*i)->seqno, seqno)) |
839 | if (SEQNO_EQ ((*i)->seqno, seqno)) |
818 | { |
840 | { |
819 | // already seen that request: simply reply with the cached reply |
841 | // already seen that request: simply reply with the cached reply |
820 | dns_rcv *r = *i; |
842 | dns_rcv *r = *i; |
821 | |
843 | |
822 | printf ("DUPLICATE %d\n", htons (r->pkt->id));//D |
844 | slog (L_DEBUG, "DNS: duplicate packet received ID %d, SEQ %d", htons (r->pkt->id), seqno); |
|
|
845 | |
|
|
846 | // refresh header & id, as the retry count could have changed |
|
|
847 | memcpy (r->pkt->at (6 * 2 + 1), pkt.at (6 * 2 + 1), HDRSIZE); |
|
|
848 | r->pkt->id = pkt.id; |
823 | |
849 | |
824 | memcpy (pkt.at (0), r->pkt->at (0), offs = r->pkt->len); |
850 | memcpy (pkt.at (0), r->pkt->at (0), offs = r->pkt->len); |
825 | pkt.id = r->pkt->id; |
851 | |
826 | goto duplicate_request; |
852 | goto duplicate_request; |
827 | } |
853 | } |
|
|
854 | |
|
|
855 | in_seq = dns->rcvseq == seqno; |
828 | |
856 | |
829 | // new packet, queue |
857 | // new packet, queue |
830 | rcv = new dns_rcv (seqno, data, datalen); |
858 | rcv = new dns_rcv (seqno, data, datalen); |
831 | dns->receive_rep (rcv); |
859 | dns->receive_rep (rcv); |
832 | } |
860 | } |
833 | |
861 | |
834 | pkt [offs++] = 0xc0; pkt [offs++] = 6 * 2; // refer to name in query section |
862 | pkt [offs++] = 0xc0; pkt [offs++] = 6 * 2; // refer to name in query section |
835 | |
863 | |
836 | // type |
|
|
837 | int rtype = dns ? dns->cfg.rrtype : RR_TYPE_A; |
864 | int rtype = dns ? dns->cfg.rrtype : RR_TYPE_A; |
838 | pkt [offs++] = rtype >> 8; pkt [offs++] = rtype; |
865 | pkt [offs++] = rtype >> 8; pkt [offs++] = rtype; // type |
839 | |
|
|
840 | // class |
|
|
841 | pkt [offs++] = RR_CLASS_IN >> 8; pkt [offs++] = RR_CLASS_IN; |
866 | pkt [offs++] = RR_CLASS_IN >> 8; pkt [offs++] = RR_CLASS_IN; // class |
842 | |
|
|
843 | // TTL |
|
|
844 | pkt [offs++] = 0; pkt [offs++] = 0; |
867 | pkt [offs++] = 0; pkt [offs++] = 0; |
845 | pkt [offs++] = 0; pkt [offs++] = dns ? dns->cfg.def_ttl : 0; |
868 | pkt [offs++] = 0; pkt [offs++] = dns ? dns->cfg.def_ttl : 0; // TTL |
846 | |
869 | |
847 | int rdlen_offs = offs += 2; |
870 | int rdlen_offs = offs += 2; |
848 | |
871 | |
849 | int dlen = (dns ? ntohs (dns->cfg.max_size) : MAX_PKT_SIZE) - offs; |
872 | int dlen = (dns ? ntohs (dns->cfg.max_size) : MAX_PKT_SIZE) - offs; |
850 | // bind doesn't compress well, so reduce further by one label length |
873 | // bind doesn't compress well, so reduce further by one label length |
851 | dlen -= qlen; |
874 | dlen -= qlen; |
852 | |
875 | |
853 | if (dns) |
876 | if (dns) |
854 | { |
877 | { |
|
|
878 | // only put data into in-order sequence packets, if |
|
|
879 | // we receive out-of-order packets we generate empty |
|
|
880 | // replies |
855 | while (dlen > 1 && !dns->snddq.empty ()) |
881 | while (dlen > 1 && !dns->snddq.empty () && in_seq) |
856 | { |
882 | { |
857 | int txtlen = dlen <= 255 ? dlen - 1 : 255; |
883 | int txtlen = dlen <= 255 ? dlen - 1 : 255; |
858 | |
884 | |
859 | if (txtlen > dns->snddq.size ()) |
885 | if (txtlen > dns->snddq.size ()) |
860 | txtlen = dns->snddq.size (); |
886 | txtlen = dns->snddq.size (); |
… | |
… | |
868 | } |
894 | } |
869 | |
895 | |
870 | // avoid empty TXT rdata |
896 | // avoid empty TXT rdata |
871 | if (offs == rdlen_offs) |
897 | if (offs == rdlen_offs) |
872 | pkt[offs++] = 0; |
898 | pkt[offs++] = 0; |
|
|
899 | |
|
|
900 | slog (L_NOISE, "DNS: snddq %d", dns->snddq.size ()); |
873 | } |
901 | } |
874 | else |
902 | else |
875 | { |
903 | { |
876 | // send RST |
904 | // send RST |
877 | pkt [offs++] = CMD_IP_1; pkt [offs++] = CMD_IP_2; pkt [offs++] = CMD_IP_3; |
905 | pkt [offs++] = CMD_IP_1; pkt [offs++] = CMD_IP_2; pkt [offs++] = CMD_IP_3; |
… | |
… | |
908 | pkt [offs++] = RR_CLASS_IN >> 8; pkt [offs++] = RR_CLASS_IN; // class |
936 | pkt [offs++] = RR_CLASS_IN >> 8; pkt [offs++] = RR_CLASS_IN; // class |
909 | pkt [offs++] = 0; pkt [offs++] = 0; |
937 | pkt [offs++] = 0; pkt [offs++] = 0; |
910 | pkt [offs++] = 0; pkt [offs++] = cfg.def_ttl; // TTL |
938 | pkt [offs++] = 0; pkt [offs++] = cfg.def_ttl; // TTL |
911 | pkt [offs++] = 0; pkt [offs++] = 4; // rdlength |
939 | pkt [offs++] = 0; pkt [offs++] = 4; // rdlength |
912 | |
940 | |
913 | slog (L_INFO, _("DNS tunnel: client %d tries to connect"), client); |
941 | slog (L_INFO, _("DNS: client %d tries to connect"), client); |
914 | |
942 | |
915 | pkt [offs++] = CMD_IP_1; pkt [offs++] = CMD_IP_2; pkt [offs++] = CMD_IP_3; |
943 | pkt [offs++] = CMD_IP_1; pkt [offs++] = CMD_IP_2; pkt [offs++] = CMD_IP_3; |
916 | pkt [offs++] = CMD_IP_REJ; |
944 | pkt [offs++] = CMD_IP_REJ; |
917 | |
945 | |
918 | if (0 < client && client <= conns.size ()) |
946 | if (0 < client && client <= conns.size ()) |
… | |
… | |
949 | i != dns_sndpq.end (); |
977 | i != dns_sndpq.end (); |
950 | ++i) |
978 | ++i) |
951 | if ((*i)->pkt->id == pkt.id) |
979 | if ((*i)->pkt->id == pkt.id) |
952 | { |
980 | { |
953 | dns_connection *dns = (*i)->dns; |
981 | dns_connection *dns = (*i)->dns; |
|
|
982 | connection *c = dns->c; |
954 | int seqno = (*i)->seqno; |
983 | int seqno = (*i)->seqno; |
955 | u8 data[MAXSIZE], *datap = data; |
984 | u8 data[MAXSIZE], *datap = data; |
956 | |
985 | |
957 | if ((*i)->retry) |
986 | if ((*i)->retry) |
958 | { |
987 | { |
959 | dns->send_interval *= 1.01; |
988 | dns->send_interval *= 1.01; |
960 | if (dns->send_interval < MAX_SEND_INTERVAL) |
989 | if (dns->send_interval > MAX_SEND_INTERVAL) |
961 | dns->send_interval = MAX_SEND_INTERVAL; |
990 | dns->send_interval = MAX_SEND_INTERVAL; |
962 | } |
991 | } |
963 | else |
992 | else |
964 | { |
993 | { |
|
|
994 | #if 1 |
965 | dns->send_interval *= 0.99; |
995 | dns->send_interval *= 0.999; |
|
|
996 | #endif |
966 | if (dns->send_interval < MIN_SEND_INTERVAL) |
997 | if (dns->send_interval < MIN_SEND_INTERVAL) |
967 | dns->send_interval = MIN_SEND_INTERVAL; |
998 | dns->send_interval = MIN_SEND_INTERVAL; |
968 | |
999 | |
969 | // the latency surely puts an upper bound on |
1000 | // the latency surely puts an upper bound on |
970 | // the minimum send interval |
1001 | // the minimum send interval |
|
|
1002 | double latency = NOW - (*i)->sent; |
|
|
1003 | dns->last_latency = latency; |
|
|
1004 | |
971 | if (dns->send_interval > NOW - (*i)->sent) |
1005 | if (dns->send_interval > latency) |
972 | dns->send_interval = NOW - (*i)->sent; |
1006 | dns->send_interval = latency; |
973 | } |
1007 | } |
974 | |
1008 | |
975 | delete *i; |
1009 | delete *i; |
976 | dns_sndpq.erase (i); |
1010 | dns_sndpq.erase (i); |
977 | |
1011 | |
… | |
… | |
1027 | |
1061 | |
1028 | if (ip [0] == CMD_IP_1 |
1062 | if (ip [0] == CMD_IP_1 |
1029 | && ip [1] == CMD_IP_2 |
1063 | && ip [1] == CMD_IP_2 |
1030 | && ip [2] == CMD_IP_3) |
1064 | && ip [2] == CMD_IP_3) |
1031 | { |
1065 | { |
1032 | slog (L_TRACE, _("got tunnel meta command %02x"), ip [3]); |
1066 | slog (L_TRACE, _("DNS: got tunnel meta command %02x"), ip [3]); |
1033 | |
1067 | |
1034 | if (ip [3] == CMD_IP_RST) |
1068 | if (ip [3] == CMD_IP_RST) |
1035 | { |
1069 | { |
1036 | slog (L_DEBUG, _("got tunnel RST request")); |
1070 | slog (L_DEBUG, _("DNS: got tunnel RST request")); |
1037 | |
1071 | |
1038 | connection *c = dns->c; |
|
|
1039 | delete c->dns; c->dns = 0; |
1072 | delete dns; c->dns = 0; |
1040 | |
1073 | |
1041 | return; |
1074 | return; |
1042 | } |
1075 | } |
1043 | else if (ip [3] == CMD_IP_SYN) |
1076 | else if (ip [3] == CMD_IP_SYN) |
|
|
1077 | { |
|
|
1078 | slog (L_DEBUG, _("DNS: got tunnel SYN reply, server likes us.")); |
1044 | dns->established = true; |
1079 | dns->established = true; |
|
|
1080 | } |
|
|
1081 | else if (ip [3] == CMD_IP_REJ) |
|
|
1082 | { |
|
|
1083 | slog (L_DEBUG, _("DNS: got tunnel REJ reply, server does not like us, aborting.")); |
|
|
1084 | abort (); |
|
|
1085 | } |
1045 | else |
1086 | else |
1046 | slog (L_INFO, _("got unknown meta command %02x"), ip [3]); |
1087 | slog (L_INFO, _("DNS: got unknown meta command %02x"), ip [3]); |
1047 | } |
1088 | } |
1048 | else |
1089 | else |
1049 | slog (L_INFO, _("got spurious a record %d.%d.%d.%d"), |
1090 | slog (L_INFO, _("DNS: got spurious a record %d.%d.%d.%d"), |
1050 | ip [0], ip [1], ip [2], ip [3]); |
1091 | ip [0], ip [1], ip [2], ip [3]); |
1051 | |
1092 | |
1052 | return; |
1093 | return; |
1053 | } |
1094 | } |
1054 | |
1095 | |
1055 | int client, rseqno; |
1096 | int client, rseqno; |
1056 | decode_header (qname, client, rseqno); |
1097 | decode_header (qname, client, rseqno); |
1057 | |
1098 | |
1058 | if (client != THISNODE->id) |
1099 | if (client != THISNODE->id) |
1059 | { |
1100 | { |
1060 | slog (L_INFO, _("got dns tunnel response with wrong clientid, ignoring")); |
1101 | slog (L_INFO, _("DNS: got dns tunnel response with wrong clientid, ignoring")); |
1061 | datap = 0; |
1102 | datap = 0; |
1062 | } |
1103 | } |
1063 | else if (rseqno != seqno) |
1104 | else if (rseqno != seqno) |
1064 | { |
1105 | { |
1065 | slog (L_DEBUG, _("got dns tunnel response with wrong seqno, badly caching nameserver?")); |
1106 | slog (L_DEBUG, _("DNS: got dns tunnel response with wrong seqno, badly caching nameserver?")); |
1066 | datap = 0; |
1107 | datap = 0; |
1067 | } |
1108 | } |
1068 | } |
1109 | } |
1069 | } |
1110 | } |
1070 | |
1111 | |
… | |
… | |
1114 | dns->tw.trigger (); |
1155 | dns->tw.trigger (); |
1115 | |
1156 | |
1116 | return true; |
1157 | return true; |
1117 | } |
1158 | } |
1118 | |
1159 | |
|
|
1160 | void |
|
|
1161 | connection::dnsv4_reset_connection () |
|
|
1162 | { |
|
|
1163 | //delete dns; dns = 0; //TODO |
|
|
1164 | } |
|
|
1165 | |
1119 | #define NEXT(w) do { if (next > (w)) next = w; } while (0) |
1166 | #define NEXT(w) do { if (next > (w)) next = w; } while (0) |
1120 | |
1167 | |
1121 | void |
1168 | void |
1122 | dns_connection::time_cb (time_watcher &w) |
1169 | dns_connection::time_cb (time_watcher &w) |
1123 | { |
1170 | { |
… | |
… | |
1140 | if (!send) |
1187 | if (!send) |
1141 | { |
1188 | { |
1142 | send = r; |
1189 | send = r; |
1143 | |
1190 | |
1144 | r->retry++; |
1191 | r->retry++; |
1145 | r->timeout = NOW + r->retry; |
1192 | r->timeout = NOW + (r->retry * last_latency * 8.); |
|
|
1193 | |
|
|
1194 | // the following code changes the query section a bit, forcing |
|
|
1195 | // the forwarder to generate a new request |
|
|
1196 | if (r->stdhdr) |
|
|
1197 | { |
|
|
1198 | //printf ("reencoded header for ID %d retry %d:%d:%d\n", htons (r->pkt->id), THISNODE->id, r->seqno, r->retry);printf ("reencoded header for ID %d retry %d:%d:%d\n", htons (r->pkt->id), THISNODE->id, r->seqno, r->retry); |
|
|
1199 | //encode_header ((char *)r->pkt->at (6 * 2 + 1), THISNODE->id, r->seqno, r->retry); |
|
|
1200 | } |
1146 | } |
1201 | } |
1147 | } |
1202 | } |
1148 | else if (r->timeout < next) |
1203 | else |
1149 | NEXT (r->timeout); |
1204 | NEXT (r->timeout); |
1150 | } |
1205 | } |
1151 | |
1206 | |
1152 | if (last_sent + send_interval <= NOW) |
1207 | if (last_sent + send_interval <= NOW) |
1153 | { |
1208 | { |
… | |
… | |
1163 | |
1218 | |
1164 | cfg.reset (THISNODE->id); |
1219 | cfg.reset (THISNODE->id); |
1165 | send->gen_syn_req (cfg); |
1220 | send->gen_syn_req (cfg); |
1166 | } |
1221 | } |
1167 | } |
1222 | } |
1168 | else if (vpn->dns_sndpq.size () < MAX_OUTSTANDING) |
1223 | else if (vpn->dns_sndpq.size () < MAX_OUTSTANDING |
|
|
1224 | && !SEQNO_EQ (rcvseq, sndseq - (MAX_WINDOW - 1))) |
1169 | { |
1225 | { |
|
|
1226 | if (!snddq.empty ()) |
|
|
1227 | { |
|
|
1228 | poll_interval = send_interval; |
|
|
1229 | NEXT (NOW + send_interval); |
|
|
1230 | } |
|
|
1231 | |
1170 | send = new dns_snd (this); |
1232 | send = new dns_snd (this); |
1171 | send->gen_stream_req (sndseq, snddq); |
1233 | send->gen_stream_req (sndseq, snddq); |
|
|
1234 | send->timeout = NOW + last_latency * 8.; |
1172 | |
1235 | |
1173 | sndseq = (sndseq + 1) & SEQNO_MASK; |
1236 | sndseq = (sndseq + 1) & SEQNO_MASK; |
1174 | } |
1237 | } |
1175 | |
1238 | |
1176 | if (send) |
1239 | if (send) |
1177 | vpn->dns_sndpq.push_back (send); |
1240 | vpn->dns_sndpq.push_back (send); |
1178 | } |
1241 | } |
1179 | |
1242 | |
1180 | if (send) |
1243 | if (send) |
1181 | { |
1244 | { |
1182 | printf ("send pkt\n"); |
|
|
1183 | last_sent = NOW; |
1245 | last_sent = NOW; |
1184 | |
|
|
1185 | if (!send->retry) |
|
|
1186 | send->sent = NOW; |
|
|
1187 | |
|
|
1188 | sendto (vpn->dnsv4_fd, |
1246 | sendto (vpn->dnsv4_fd, |
1189 | send->pkt->at (0), send->pkt->len, 0, |
1247 | send->pkt->at (0), send->pkt->len, 0, |
1190 | vpn->dns_forwarder.sav4 (), vpn->dns_forwarder.salenv4 ()); |
1248 | vpn->dns_forwarder.sav4 (), vpn->dns_forwarder.salenv4 ()); |
1191 | } |
1249 | } |
1192 | } |
1250 | } |
1193 | else |
1251 | else |
1194 | NEXT (last_sent + send_interval); |
1252 | NEXT (last_sent + send_interval); |
1195 | |
1253 | |
1196 | printf ("pi %f si %f N %f (%d:%d)\n", poll_interval, send_interval, next - NOW, vpn->dns_sndpq.size (), snddq.size ()); |
1254 | slog (L_NOISE, "DNS: pi %f si %f N %f (%d:%d)", |
|
|
1255 | poll_interval, send_interval, next - NOW, |
|
|
1256 | vpn->dns_sndpq.size (), snddq.size ()); |
|
|
1257 | |
|
|
1258 | // TODO: no idea when this happens, but when next < NOW, we have a problem |
|
|
1259 | if (next < NOW + 0.0001) |
|
|
1260 | next = NOW + 0.1; |
1197 | |
1261 | |
1198 | w.start (next); |
1262 | w.start (next); |
1199 | } |
1263 | } |
1200 | |
1264 | |
1201 | #endif |
1265 | #endif |