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.17 by pcg, Sat Mar 5 03:47:05 2005 UTC vs.
Revision 1.47 by pcg, Thu Aug 7 17:54:27 2008 UTC

1/* 1/*
2 vpn_dns.C -- handle the dns tunnel part of the protocol. 2 vpn_dns.C -- handle the dns tunnel part of the protocol.
3 Copyright (C) 2003-2005 Marc Lehmann <gvpe@schmorp.de> 3 Copyright (C) 2003-2008 Marc Lehmann <gvpe@schmorp.de>
4 4
5 This file is part of GVPE. 5 This file is part of GVPE.
6 6
7 GVPE is free software; you can redistribute it and/or modify 7 GVPE is free software; you can redistribute it and/or modify it
8 it under the terms of the GNU General Public License as published by 8 under the terms of the GNU General Public License as published by the
9 the Free Software Foundation; either version 2 of the License, or 9 Free Software Foundation; either version 3 of the License, or (at your
10 (at your option) any later version. 10 option) any later version.
11 11
12 This program is distributed in the hope that it will be useful, 12 This program is distributed in the hope that it will be useful, but
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15 GNU General Public License for more details. 15 Public License for more details.
16 16
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License along
18 along with gvpe; if not, write to the Free Software 18 with this program; if not, see <http://www.gnu.org/licenses/>.
19 Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19
20 Additional permission under GNU GPL version 3 section 7
21
22 If you modify this Program, or any covered work, by linking or
23 combining it with the OpenSSL project's OpenSSL library (or a modified
24 version of that library), containing parts covered by the terms of the
25 OpenSSL or SSLeay licenses, the licensors of this Program grant you
26 additional permission to convey the resulting work. Corresponding
27 Source for a non-source form of such a combination shall include the
28 source code for the parts of OpenSSL used as well as that of the
29 covered work.
20*/ 30*/
31
32// TODO: EDNS0 option to increase dns mtu?
33// TODO: re-write dns packet parsing/creation using a safe mem-buffer
34// to ensure no buffer overflows or similar problems.
21 35
22#include "config.h" 36#include "config.h"
23 37
24#if ENABLE_DNS 38#if ENABLE_DNS
25 39
26// dns processing is EXTREMELY ugly. For obvious(?) reasons. 40// dns processing is EXTREMELY ugly. For obvious(?) reasons.
27// it's a hack, use only in emergency situations please. 41// it's a hack, use only in emergency situations please.
28 42
29#include <cstring> 43#include <cstring>
44#include <cassert>
30 45
31#include <sys/types.h> 46#include <sys/types.h>
32#include <sys/socket.h> 47#include <sys/socket.h>
33#include <sys/wait.h> 48#include <sys/wait.h>
34#include <sys/uio.h> 49#include <sys/uio.h>
37#include <unistd.h> 52#include <unistd.h>
38#include <fcntl.h> 53#include <fcntl.h>
39 54
40#include <map> 55#include <map>
41 56
57#include <cstdio> /* bug in libgmp: gmp.h relies on cstdio being included */
42#include <gmp.h> 58#include <gmp.h>
43 59
44#include "netcompat.h" 60#include "netcompat.h"
45 61
46#include "vpn.h" 62#include "vpn.h"
47 63
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 64#define MAX_POLL_INTERVAL 5. // how often to poll minimally when the server has no data
50#define ACTIVITY_INTERVAL 5. 65#define ACTIVITY_INTERVAL 5.
51 66
52#define INITIAL_TIMEOUT 0.1 // retry timeouts 67#define INITIAL_TIMEOUT 0.1 // retry timeouts
53#define INITIAL_SYN_TIMEOUT 10. // retry timeout for initial syn 68#define INITIAL_SYN_TIMEOUT 2. // retry timeout for initial syn
54 69
55#define MIN_SEND_INTERVAL 0.01 // wait at least this time between sending requests
56#define MAX_SEND_INTERVAL 0.5 // optimistic? 70#define MAX_SEND_INTERVAL 2. // optimistic?
57 71
58#define MAX_OUTSTANDING 10 // max. outstanding requests
59#define MAX_WINDOW 1000 // max. for MAX_OUTSTANDING, and backlog 72#define MAX_WINDOW 1000 // max. for MAX_OUTSTANDING, and backlog
60#define MAX_BACKLOG (100*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
61 74
62#define MAX_DOMAIN_SIZE 220 // 255 is legal limit, but bind doesn't compress well 75#define MAX_DOMAIN_SIZE 240 // 255 is legal limit, but bind doesn't compress well
63// 240 leaves about 4 bytes of server reply data 76// 240 leaves about 4 bytes of server reply data
64// every two request bytes less give room for one reply byte 77// every request byte less give room for two reply bytes
65 78
66#define SEQNO_MASK 0x3fff 79#define SEQNO_MASK 0x3fff
67#define SEQNO_EQ(a,b) ( 0 == ( ((a) ^ (b)) & SEQNO_MASK) ) 80#define SEQNO_EQ(a,b) ( 0 == ( ((a) ^ (b)) & SEQNO_MASK) )
68 81
69#define MAX_LBL_SIZE 63 82#define MAX_LBL_SIZE 63
264static basecoder cdc26 ("dPhZrQmJkBtSvLxAeFwGyO"); 277static basecoder cdc26 ("dPhZrQmJkBtSvLxAeFwGyO");
265 278
266///////////////////////////////////////////////////////////////////////////// 279/////////////////////////////////////////////////////////////////////////////
267 280
268#define HDRSIZE 6 281#define HDRSIZE 6
269 282
270inline void encode_header (char *data, int clientid, int seqno, int retry = 0) 283inline void encode_header (char *data, int clientid, int seqno, int retry = 0)
271{ 284{
272 seqno &= SEQNO_MASK; 285 seqno &= SEQNO_MASK;
273 286
274 u8 hdr[3] = { 287 u8 hdr[3] = {
356 return true; 369 return true;
357} 370}
358 371
359vpn_packet *byte_stream::get () 372vpn_packet *byte_stream::get ()
360{ 373{
374 unsigned int len;
375
376 for (;;)
377 {
361 unsigned int len = (data [0] << 8) | data [1]; 378 len = (data [0] << 8) | data [1];
362 379
363 if (len > MAXSIZE && fill >= 2) 380 if (len <= MAXSIZE || fill < 2)
364 assert (len <= MAXSIZE || fill < 2); // TODO handle this gracefully, connection reset 381 break;
365 382
383 // TODO: handle this better than skipping, e.g. by reset
384 slog (L_DEBUG, _("DNS: corrupted packet stream skipping a byte..."));
385 remove (1);
386 }
387
366 if (fill < len + 2) 388 if (fill < len + 2)
367 return 0; 389 return 0;
368 390
369 vpn_packet *pkt = new vpn_packet; 391 vpn_packet *pkt = new vpn_packet;
370 392
399struct dns_cfg 421struct dns_cfg
400{ 422{
401 static int next_uid; 423 static int next_uid;
402 424
403 u8 id1, id2, id3, id4; 425 u8 id1, id2, id3, id4;
426
404 u8 version; 427 u8 version;
428 u8 flags;
405 u8 rrtype; 429 u8 rrtype;
406 u8 flags;
407 u8 def_ttl; 430 u8 def_ttl;
408 u8 rcv_cdc; 431
409 u8 snd_cdc;
410 u16 max_size;
411 u16 client; 432 u16 client;
412 u16 uid; // to make request unique 433 u16 uid; // to make request unique
413 434
414 u8 reserved[8]; 435 u16 max_size;
436 u8 seq_cdc;
437 u8 req_cdc;
438
439 u8 rep_cdc;
440 u8 delay; // time in 0.01s units that the server may delay replying packets
441 u8 r3, r4;
442
443 u8 r5, r6, r7, r8;
415 444
416 void reset (int clientid); 445 void reset (int clientid);
417 bool valid (); 446 bool valid ();
418}; 447};
419 448
428 457
429 version = 1; 458 version = 1;
430 459
431 rrtype = RR_TYPE_TXT; 460 rrtype = RR_TYPE_TXT;
432 flags = 0; 461 flags = 0;
433 def_ttl = 1; 462 def_ttl = 0;
463 seq_cdc = 26;
464 req_cdc = 62;
434 rcv_cdc = 0; 465 rep_cdc = 0;
435 snd_cdc = 62;
436 max_size = ntohs (MAX_PKT_SIZE); 466 max_size = htons (MAX_PKT_SIZE);
437 client = ntohs (clientid); 467 client = htons (clientid);
438 uid = next_uid++; 468 uid = next_uid++;
469 delay = 0;
439 470
440 memset (reserved, 0, 8); 471 r3 = r4 = 0;
472 r4 = r5 = r6 = r7 = 0;
441} 473}
442 474
443bool dns_cfg::valid () 475bool dns_cfg::valid ()
444{ 476{
477 // although the protocol itself allows for some configurability,
478 // only the following encoding/decoding settings are implemented.
445 return id1 == 'G' 479 return id1 == 'G'
446 && id2 == 'V' 480 && id2 == 'V'
447 && id3 == 'P' 481 && id3 == 'P'
448 && id4 == 'E' 482 && id4 == 'E'
483 && seq_cdc == 26
484 && req_cdc == 62
485 && rep_cdc == 0
449 && version == 1 486 && version == 1;
450 && flags == 0
451 && rcv_cdc == 0
452 && snd_cdc == 62
453 && max_size == ntohs (MAX_PKT_SIZE);
454} 487}
455 488
456struct dns_packet : net_packet 489struct dns_packet : net_packet
457{ 490{
458 u16 id; 491 u16 id;
459 u16 flags; // QR:1 Opcode:4 AA:1 TC:1 RD:1 RA:1 Z:3 RCODE:4 492 u16 flags; // QR:1 Opcode:4 AA:1 TC:1 RD:1 RA:1 Z:3 RCODE:4
460 u16 qdcount, ancount, nscount, arcount; 493 u16 qdcount, ancount, nscount, arcount;
461 494
462 u8 data[MAXSIZE - 6 * 2]; 495 u8 data [MAXSIZE - 6 * 2];
463 496
464 int decode_label (char *data, int size, int &offs); 497 int decode_label (char *data, int size, int &offs);
465}; 498};
466 499
467int dns_packet::decode_label (char *data, int size, int &offs) 500int dns_packet::decode_label (char *data, int size, int &offs)
498 return data - orig; 531 return data - orig;
499} 532}
500 533
501///////////////////////////////////////////////////////////////////////////// 534/////////////////////////////////////////////////////////////////////////////
502 535
536static u16 dns_id = 0; // TODO: should be per-vpn
537
538static u16 next_id ()
539{
540 if (!dns_id)
541 dns_id = time (0);
542
543 // the simplest lsfr with periodicity 65535 i could find
544 dns_id = (dns_id << 1)
545 | (((dns_id >> 1)
546 ^ (dns_id >> 2)
547 ^ (dns_id >> 4)
548 ^ (dns_id >> 15)) & 1);
549
550 return dns_id;
551}
552
553struct dns_rcv;
554struct dns_snd;
555
556struct dns_connection
557{
558 connection *c;
559 struct vpn *vpn;
560
561 dns_cfg cfg;
562
563 bool established;
564
565 tstamp last_received;
566 tstamp last_sent;
567 double min_latency;
568 double poll_interval, send_interval;
569
570 vector<dns_rcv *> rcvpq;
571
572 byte_stream rcvdq; int rcvseq; int repseq;
573 byte_stream snddq; int sndseq;
574
575 inline void time_cb (ev::timer &w, int revents); ev::timer tw;
576 void receive_rep (dns_rcv *r);
577
578 dns_connection (connection *c);
579 ~dns_connection ();
580};
581
503struct dns_snd 582struct dns_snd
504{ 583{
505 dns_packet *pkt; 584 dns_packet *pkt;
506 tstamp timeout, sent; 585 tstamp timeout, sent;
507 int retry; 586 int retry;
508 struct dns_connection *dns; 587 struct dns_connection *dns;
509 int seqno; 588 int seqno;
510 bool stdhdr; 589 bool stdhdr;
511 590
512 void gen_stream_req (int seqno, byte_stream &stream); 591 void gen_stream_req (int seqno, byte_stream &stream);
513 void gen_syn_req (const dns_cfg &cfg); 592 void gen_syn_req ();
514 593
515 dns_snd (dns_connection *dns); 594 dns_snd (dns_connection *dns);
516 ~dns_snd (); 595 ~dns_snd ();
517}; 596};
518 597
519static u16 dns_id = 12098; // TODO: should be per-vpn
520
521static u16 next_id ()
522{
523 // the simplest lsfr with periodicity 65535 i could find
524 dns_id = (dns_id << 1)
525 | (((dns_id >> 1)
526 ^ (dns_id >> 2)
527 ^ (dns_id >> 4)
528 ^ (dns_id >> 15)) & 1);
529
530 return dns_id;
531}
532
533dns_snd::dns_snd (dns_connection *dns) 598dns_snd::dns_snd (dns_connection *dns)
534: dns (dns) 599: dns (dns)
535{ 600{
536 timeout = 0; 601 timeout = 0;
537 retry = 0; 602 retry = 0;
538 seqno = 0; 603 seqno = 0;
539 sent = NOW; 604 sent = ev_now ();
540 stdhdr = false; 605 stdhdr = false;
541 606
542 pkt = new dns_packet; 607 pkt = new dns_packet;
543 608
544 pkt->id = next_id (); 609 pkt->id = next_id ();
575void dns_snd::gen_stream_req (int seqno, byte_stream &stream) 640void dns_snd::gen_stream_req (int seqno, byte_stream &stream)
576{ 641{
577 stdhdr = true; 642 stdhdr = true;
578 this->seqno = seqno; 643 this->seqno = seqno;
579 644
580 timeout = NOW + INITIAL_TIMEOUT; 645 timeout = ev_now () + INITIAL_TIMEOUT;
581 646
582 pkt->flags = htons (DEFAULT_CLIENT_FLAGS); 647 pkt->flags = htons (DEFAULT_CLIENT_FLAGS);
583 pkt->qdcount = htons (1); 648 pkt->qdcount = htons (1);
584 649
585 int offs = 6*2; 650 int offs = 6*2;
586 int dlen = MAX_DOMAIN_SIZE - (strlen (THISNODE->domain) + 2); 651 int dlen = MAX_DOMAIN_SIZE - (strlen (dns->c->conf->domain) + 2);
587 // MAX_DOMAIN_SIZE is technically 255, but bind doesn't compress responses well, 652 // MAX_DOMAIN_SIZE is technically 255, but bind doesn't compress responses well,
588 // so we need to have space for 2*MAX_DOMAIN_SIZE + header + extra 653 // so we need to have space for 2*MAX_DOMAIN_SIZE + header + extra
589 654
590 char enc[256], *encp = enc; 655 char enc[256], *encp = enc;
591 encode_header (enc, THISNODE->id, seqno); 656 encode_header (enc, THISNODE->id, seqno);
609 encp += lbllen; 674 encp += lbllen;
610 675
611 enclen -= lbllen; 676 enclen -= lbllen;
612 } 677 }
613 678
614 append_domain (*pkt, offs, THISNODE->domain); 679 append_domain (*pkt, offs, dns->c->conf->domain);
615 680
616 (*pkt)[offs++] = 0; 681 (*pkt)[offs++] = 0;
617 (*pkt)[offs++] = RR_TYPE_ANY >> 8; (*pkt)[offs++] = RR_TYPE_ANY; 682 (*pkt)[offs++] = RR_TYPE_ANY >> 8; (*pkt)[offs++] = RR_TYPE_ANY;
618 (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN; 683 (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN;
619 684
620 pkt->len = offs; 685 pkt->len = offs;
621} 686}
622 687
623void dns_snd::gen_syn_req (const dns_cfg &cfg) 688void dns_snd::gen_syn_req ()
624{ 689{
625 timeout = NOW + INITIAL_SYN_TIMEOUT; 690 timeout = ev_now () + INITIAL_SYN_TIMEOUT;
626 691
627 pkt->flags = htons (DEFAULT_CLIENT_FLAGS); 692 pkt->flags = htons (DEFAULT_CLIENT_FLAGS);
628 pkt->qdcount = htons (1); 693 pkt->qdcount = htons (1);
629 694
630 int offs = 6*2; 695 int offs = 6 * 2;
631 696
632 int elen = cdc26.encode ((char *)pkt->at (offs + 1), (u8 *)&cfg, sizeof (dns_cfg)); 697 int elen = cdc26.encode ((char *)pkt->at (offs + 1), (u8 *)&dns->cfg, sizeof (dns_cfg));
633 698
634 assert (elen <= MAX_LBL_SIZE); 699 assert (elen <= MAX_LBL_SIZE);
635 700
636 (*pkt)[offs] = elen; 701 (*pkt)[offs] = elen;
637 offs += elen + 1; 702 offs += elen + 1;
638 append_domain (*pkt, offs, THISNODE->domain); 703 append_domain (*pkt, offs, dns->c->conf->domain);
639 704
640 (*pkt)[offs++] = 0; 705 (*pkt)[offs++] = 0;
641 (*pkt)[offs++] = RR_TYPE_A >> 8; (*pkt)[offs++] = RR_TYPE_A; 706 (*pkt)[offs++] = RR_TYPE_A >> 8; (*pkt)[offs++] = RR_TYPE_A;
642 (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN; 707 (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN;
643 708
666 delete pkt; 731 delete pkt;
667} 732}
668 733
669///////////////////////////////////////////////////////////////////////////// 734/////////////////////////////////////////////////////////////////////////////
670 735
671struct dns_connection
672{
673 connection *c;
674 struct vpn *vpn;
675
676 dns_cfg cfg;
677
678 bool established;
679
680 tstamp last_received;
681 tstamp last_sent;
682 double last_latency;
683 double poll_interval, send_interval;
684
685 vector<dns_rcv *> rcvpq;
686
687 byte_stream rcvdq; int rcvseq;
688 byte_stream snddq; int sndseq;
689
690 void time_cb (time_watcher &w); time_watcher tw;
691 void receive_rep (dns_rcv *r);
692
693 dns_connection (connection *c);
694 ~dns_connection ();
695};
696
697dns_connection::dns_connection (connection *c) 736dns_connection::dns_connection (connection *c)
698: c (c) 737: c (c)
699, rcvdq (MAX_BACKLOG * 2) 738, rcvdq (MAX_BACKLOG * 2)
700, snddq (MAX_BACKLOG * 2) 739, snddq (MAX_BACKLOG)
701, tw (this, &dns_connection::time_cb)
702{ 740{
741 tw.set<dns_connection, &dns_connection::time_cb> (this);
742
703 vpn = c->vpn; 743 vpn = c->vpn;
704 744
705 established = false; 745 established = false;
706 746
707 rcvseq = sndseq = 0; 747 rcvseq = repseq = sndseq = 0;
708 748
709 last_sent = last_received = 0; 749 last_sent = last_received = 0;
710 poll_interval = MIN_POLL_INTERVAL; 750 poll_interval = 0.5; // starting here
711 send_interval = 0.5; // starting rate 751 send_interval = 0.5; // starting rate
712 last_latency = INITIAL_TIMEOUT; 752 min_latency = INITIAL_TIMEOUT;
713} 753}
714 754
715dns_connection::~dns_connection () 755dns_connection::~dns_connection ()
716{ 756{
717 for (vector<dns_rcv *>::iterator i = rcvpq.begin (); 757 for (vector<dns_rcv *>::iterator i = rcvpq.begin ();
722 762
723void dns_connection::receive_rep (dns_rcv *r) 763void dns_connection::receive_rep (dns_rcv *r)
724{ 764{
725 if (r->datalen) 765 if (r->datalen)
726 { 766 {
727 last_received = NOW; 767 last_received = ev_now ();
728 tw.trigger (); 768 tw ();
729 769
730 poll_interval = send_interval; 770 poll_interval = send_interval;
731 } 771 }
732 else 772 else
733 { 773 {
734 poll_interval *= 1.5; 774 poll_interval *= 1.5;
775
735 if (poll_interval > MAX_POLL_INTERVAL) 776 if (poll_interval > MAX_POLL_INTERVAL)
736 poll_interval = MAX_POLL_INTERVAL; 777 poll_interval = MAX_POLL_INTERVAL;
737 } 778 }
738 779
739 rcvpq.push_back (r); 780 rcvpq.push_back (r);
742 783
743 // find next packet 784 // find next packet
744 for (vector<dns_rcv *>::iterator i = rcvpq.end (); i-- != rcvpq.begin (); ) 785 for (vector<dns_rcv *>::iterator i = rcvpq.end (); i-- != rcvpq.begin (); )
745 if (SEQNO_EQ (rcvseq, (*i)->seqno)) 786 if (SEQNO_EQ (rcvseq, (*i)->seqno))
746 { 787 {
788 //printf ("seqno eq %x %x\n", rcvseq, (*i)->seqno);//D
747 // enter the packet into our input stream 789 // enter the packet into our input stream
748 r = *i; 790 r = *i;
749 791
750 // remove the oldest packet, look forward, as it's oldest first 792 // remove the oldest packet, look forward, as it's oldest first
751 for (vector<dns_rcv *>::iterator j = rcvpq.begin (); j != rcvpq.end (); ++j) 793 for (vector<dns_rcv *>::iterator j = rcvpq.begin (); j != rcvpq.end (); ++j)
752 if (SEQNO_EQ ((*j)->seqno, rcvseq - MAX_WINDOW)) 794 if (SEQNO_EQ ((*j)->seqno, rcvseq - MAX_WINDOW))
753 { 795 {
796 //printf ("seqno RR %x %x\n", (*j)->seqno, rcvseq - MAX_WINDOW);//D
754 delete *j; 797 delete *j;
755 rcvpq.erase (j); 798 rcvpq.erase (j);
756 break; 799 break;
757 } 800 }
758 801
765 } 808 }
766 809
767 while (vpn_packet *pkt = rcvdq.get ()) 810 while (vpn_packet *pkt = rcvdq.get ())
768 { 811 {
769 sockinfo si; 812 sockinfo si;
770 si.host = 0; si.port = 0; si.prot = PROT_DNSv4; 813 si.host = htonl (c->conf->id); si.port = 0; si.prot = PROT_DNSv4;
771 814
772 vpn->recv_vpn_packet (pkt, si); 815 vpn->recv_vpn_packet (pkt, si);
773 816
774 delete pkt; 817 delete pkt;
775 } 818 }
789 pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR); 832 pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR);
790 833
791 if (0 == (flags & (FLAG_RESPONSE | FLAG_OP_MASK)) 834 if (0 == (flags & (FLAG_RESPONSE | FLAG_OP_MASK))
792 && pkt.qdcount == htons (1)) 835 && pkt.qdcount == htons (1))
793 { 836 {
794 char qname[MAXSIZE]; 837 char qname [MAXSIZE];
795 int qlen = pkt.decode_label ((char *)qname, MAXSIZE - offs, offs); 838 int qlen = pkt.decode_label ((char *)qname, MAXSIZE - offs, offs);
796 839
797 u16 qtype = pkt [offs++] << 8; qtype |= pkt [offs++]; 840 u16 qtype = pkt [offs++] << 8; qtype |= pkt [offs++];
798 u16 qclass = pkt [offs++] << 8; qclass |= pkt [offs++]; 841 u16 qclass = pkt [offs++] << 8; qclass |= pkt [offs++];
799 842
806 849
807 int dlen = strlen (THISNODE->domain); 850 int dlen = strlen (THISNODE->domain);
808 851
809 if (qclass == RR_CLASS_IN 852 if (qclass == RR_CLASS_IN
810 && qlen > dlen + 1 853 && qlen > dlen + 1
811 && !memcmp (qname + qlen - dlen - 1, THISNODE->domain, dlen)) 854 && !memcmp (qname + qlen - (dlen + 1), THISNODE->domain, dlen))
812 { 855 {
813 // now generate reply 856 // now generate reply
814 pkt.ancount = htons (1); // one answer RR 857 pkt.ancount = htons (1); // one answer RR
815 pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_OK); 858 pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_OK);
816 859
829 if (0 < client && client <= conns.size ()) 872 if (0 < client && client <= conns.size ())
830 { 873 {
831 connection *c = conns [client - 1]; 874 connection *c = conns [client - 1];
832 dns_connection *dns = c->dns; 875 dns_connection *dns = c->dns;
833 dns_rcv *rcv; 876 dns_rcv *rcv;
834 bool in_seq;
835 877
836 if (dns) 878 if (dns)
837 { 879 {
838 for (vector<dns_rcv *>::iterator i = dns->rcvpq.end (); i-- != dns->rcvpq.begin (); ) 880 for (vector<dns_rcv *>::iterator i = dns->rcvpq.end (); i-- != dns->rcvpq.begin (); )
839 if (SEQNO_EQ ((*i)->seqno, seqno)) 881 if (SEQNO_EQ ((*i)->seqno, seqno))
850 memcpy (pkt.at (0), r->pkt->at (0), offs = r->pkt->len); 892 memcpy (pkt.at (0), r->pkt->at (0), offs = r->pkt->len);
851 893
852 goto duplicate_request; 894 goto duplicate_request;
853 } 895 }
854 896
855 in_seq = dns->rcvseq == seqno;
856
857 // new packet, queue 897 // new packet, queue
858 rcv = new dns_rcv (seqno, data, datalen); 898 rcv = new dns_rcv (seqno, data, datalen);
859 dns->receive_rep (rcv); 899 dns->receive_rep (rcv);
860 } 900 }
861 901
902 {
862 pkt [offs++] = 0xc0; pkt [offs++] = 6 * 2; // refer to name in query section 903 pkt [offs++] = 0xc0; pkt [offs++] = 6 * 2; // refer to name in query section
863 904
864 int rtype = dns ? dns->cfg.rrtype : RR_TYPE_A; 905 int rtype = dns ? dns->cfg.rrtype : RR_TYPE_A;
865 pkt [offs++] = rtype >> 8; pkt [offs++] = rtype; // type 906 pkt [offs++] = rtype >> 8; pkt [offs++] = rtype; // type
866 pkt [offs++] = RR_CLASS_IN >> 8; pkt [offs++] = RR_CLASS_IN; // class 907 pkt [offs++] = RR_CLASS_IN >> 8; pkt [offs++] = RR_CLASS_IN; // class
867 pkt [offs++] = 0; pkt [offs++] = 0; 908 pkt [offs++] = 0; pkt [offs++] = 0;
868 pkt [offs++] = 0; pkt [offs++] = dns ? dns->cfg.def_ttl : 0; // TTL 909 pkt [offs++] = 0; pkt [offs++] = dns ? dns->cfg.def_ttl : 0; // TTL
869 910
870 int rdlen_offs = offs += 2; 911 int rdlen_offs = offs += 2;
871 912
913 if (dns)
914 {
872 int dlen = (dns ? ntohs (dns->cfg.max_size) : MAX_PKT_SIZE) - offs; 915 int dlen = ntohs (dns->cfg.max_size) - offs;
916
873 // bind doesn't compress well, so reduce further by one label length 917 // bind doesn't compress well, so reduce further by one label length
874 dlen -= qlen; 918 dlen -= qlen;
875 919
876 if (dns)
877 {
878 // only put data into in-order sequence packets, if 920 // only put data into in-order sequence packets, if
879 // we receive out-of-order packets we generate empty 921 // we receive out-of-order packets we generate empty
880 // replies 922 // replies
881 while (dlen > 1 && !dns->snddq.empty () && in_seq) 923 //printf ("%d - %d & %x (=%d) < %d\n", seqno, dns->repseq, SEQNO_MASK, (seqno - dns->repseq) & SEQNO_MASK, MAX_WINDOW);//D
924 if (((seqno - dns->repseq) & SEQNO_MASK) <= MAX_WINDOW)
882 { 925 {
926 dns->repseq = seqno;
927
928 while (dlen > 1 && !dns->snddq.empty ())
929 {
883 int txtlen = dlen <= 255 ? dlen - 1 : 255; 930 int txtlen = dlen <= 255 ? dlen - 1 : 255;
884 931
885 if (txtlen > dns->snddq.size ()) 932 if (txtlen > dns->snddq.size ())
886 txtlen = dns->snddq.size (); 933 txtlen = dns->snddq.size ();
887 934
888 pkt[offs++] = txtlen; 935 pkt[offs++] = txtlen;
889 memcpy (pkt.at (offs), dns->snddq.begin (), txtlen); 936 memcpy (pkt.at (offs), dns->snddq.begin (), txtlen);
890 offs += txtlen; 937 offs += txtlen;
891 dns->snddq.remove (txtlen); 938 dns->snddq.remove (txtlen);
892 939
893 dlen -= txtlen + 1; 940 dlen -= txtlen + 1;
941 }
894 } 942 }
895 943
896 // avoid empty TXT rdata 944 // avoid completely empty TXT rdata
897 if (offs == rdlen_offs) 945 if (offs == rdlen_offs)
898 pkt[offs++] = 0; 946 pkt[offs++] = 0;
899 947
900 slog (L_NOISE, "DNS: snddq %d", dns->snddq.size ()); 948 slog (L_NOISE, "DNS: snddq %d", dns->snddq.size ());
901 } 949 }
902 else 950 else
903 { 951 {
904 // send RST 952 // send RST
905 pkt [offs++] = CMD_IP_1; pkt [offs++] = CMD_IP_2; pkt [offs++] = CMD_IP_3; 953 pkt [offs++] = CMD_IP_1; pkt [offs++] = CMD_IP_2; pkt [offs++] = CMD_IP_3;
906 pkt [offs++] = CMD_IP_RST; 954 pkt [offs++] = CMD_IP_RST;
907 } 955 }
908 956
909 int rdlen = offs - rdlen_offs; 957 int rdlen = offs - rdlen_offs;
910 958
911 pkt [rdlen_offs - 2] = rdlen >> 8; 959 pkt [rdlen_offs - 2] = rdlen >> 8;
912 pkt [rdlen_offs - 1] = rdlen; 960 pkt [rdlen_offs - 1] = rdlen;
913 961
914 if (dns) 962 if (dns)
915 { 963 {
916 // now update dns_rcv copy 964 // now update dns_rcv copy
917 rcv->pkt->len = offs; 965 rcv->pkt->len = offs;
918 memcpy (rcv->pkt->at (0), pkt.at (0), offs); 966 memcpy (rcv->pkt->at (0), pkt.at (0), offs);
919 } 967 }
968 }
920 969
921 duplicate_request: ; 970 duplicate_request: ;
922 } 971 }
923 else 972 else
924 pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR); 973 pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR);
936 pkt [offs++] = RR_CLASS_IN >> 8; pkt [offs++] = RR_CLASS_IN; // class 985 pkt [offs++] = RR_CLASS_IN >> 8; pkt [offs++] = RR_CLASS_IN; // class
937 pkt [offs++] = 0; pkt [offs++] = 0; 986 pkt [offs++] = 0; pkt [offs++] = 0;
938 pkt [offs++] = 0; pkt [offs++] = cfg.def_ttl; // TTL 987 pkt [offs++] = 0; pkt [offs++] = cfg.def_ttl; // TTL
939 pkt [offs++] = 0; pkt [offs++] = 4; // rdlength 988 pkt [offs++] = 0; pkt [offs++] = 4; // rdlength
940 989
941 slog (L_INFO, _("DNS: client %d tries to connect"), client); 990 slog (L_INFO, _("DNS: client %d connects"), client);
942 991
943 pkt [offs++] = CMD_IP_1; pkt [offs++] = CMD_IP_2; pkt [offs++] = CMD_IP_3; 992 pkt [offs++] = CMD_IP_1; pkt [offs++] = CMD_IP_2; pkt [offs++] = CMD_IP_3;
944 pkt [offs++] = CMD_IP_REJ; 993 pkt [offs++] = CMD_IP_REJ;
945 994
946 if (0 < client && client <= conns.size ()) 995 if (0 < client && client <= conns.size ())
980 { 1029 {
981 dns_connection *dns = (*i)->dns; 1030 dns_connection *dns = (*i)->dns;
982 connection *c = dns->c; 1031 connection *c = dns->c;
983 int seqno = (*i)->seqno; 1032 int seqno = (*i)->seqno;
984 u8 data[MAXSIZE], *datap = data; 1033 u8 data[MAXSIZE], *datap = data;
1034 //printf ("rcv pkt %x\n", seqno);//D
985 1035
986 if ((*i)->retry) 1036 if ((*i)->retry)
987 { 1037 {
988 dns->send_interval *= 1.01; 1038 dns->send_interval *= 1.01;
989 if (dns->send_interval > MAX_SEND_INTERVAL) 1039 if (dns->send_interval > MAX_SEND_INTERVAL)
990 dns->send_interval = MAX_SEND_INTERVAL; 1040 dns->send_interval = MAX_SEND_INTERVAL;
991 } 1041 }
992 else 1042 else
993 { 1043 {
994#if 1 1044#if 0
995 dns->send_interval *= 0.999; 1045 dns->send_interval *= 0.999;
996#endif 1046#endif
997 if (dns->send_interval < MIN_SEND_INTERVAL)
998 dns->send_interval = MIN_SEND_INTERVAL;
999
1000 // the latency surely puts an upper bound on 1047 // the latency surely puts an upper bound on
1001 // the minimum send interval 1048 // the minimum send interval
1002 double latency = NOW - (*i)->sent; 1049 double latency = ev_now () - (*i)->sent;
1050
1051 if (latency < dns->min_latency)
1003 dns->last_latency = latency; 1052 dns->min_latency = latency;
1004 1053
1005 if (dns->send_interval > latency) 1054 if (dns->send_interval > dns->min_latency * conf.dns_overlap_factor)
1055 dns->send_interval = dns->min_latency * conf.dns_overlap_factor;
1056
1057 if (dns->send_interval < conf.dns_send_interval)
1006 dns->send_interval = latency; 1058 dns->send_interval = conf.dns_send_interval;
1007 } 1059 }
1008 1060
1009 delete *i; 1061 delete *i;
1010 dns_sndpq.erase (i); 1062 dns_sndpq.erase (i);
1011 1063
1116 break; 1168 break;
1117 } 1169 }
1118} 1170}
1119 1171
1120void 1172void
1121vpn::dnsv4_ev (io_watcher &w, short revents) 1173vpn::dnsv4_ev (ev::io &w, int revents)
1122{ 1174{
1123 if (revents & EVENT_READ) 1175 if (revents & EV_READ)
1124 { 1176 {
1125 dns_packet *pkt = new dns_packet; 1177 dns_packet *pkt = new dns_packet;
1126 struct sockaddr_in sa; 1178 struct sockaddr_in sa;
1127 socklen_t sa_len = sizeof (sa); 1179 socklen_t sa_len = sizeof (sa);
1128 1180
1129 pkt->len = recvfrom (w.fd, pkt->at (0), MAXSIZE, 0, (sockaddr *)&sa, &sa_len); 1181 pkt->len = recvfrom (w.fd, pkt->at (0), MAXSIZE, 0, (sockaddr *)&sa, &sa_len);
1130 1182
1131 if (pkt->len > 0) 1183 if (pkt->len > 0)
1132 { 1184 {
1133 if (THISNODE->dns_port) 1185 if (ntohs (pkt->flags) & FLAG_RESPONSE)
1186 dnsv4_client (*pkt);
1187 else
1134 { 1188 {
1135 dnsv4_server (*pkt); 1189 dnsv4_server (*pkt);
1136 sendto (w.fd, pkt->at (0), pkt->len, 0, (sockaddr *)&sa, sa_len); 1190 sendto (w.fd, pkt->at (0), pkt->len, 0, (sockaddr *)&sa, sa_len);
1137 } 1191 }
1138 else
1139 dnsv4_client (*pkt);
1140 1192
1141 delete pkt; 1193 delete pkt;
1142 } 1194 }
1143 } 1195 }
1144} 1196}
1145 1197
1146bool 1198bool
1147connection::send_dnsv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 1199vpn::send_dnsv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
1148{ 1200{
1201 int client = ntohl (si.host);
1202
1203 assert (0 < client && client <= conns.size ());
1204
1205 connection *c = conns [client - 1];
1206
1149 if (!dns) 1207 if (!c->dns)
1150 dns = new dns_connection (this); 1208 c->dns = new dns_connection (c);
1151 1209
1152 if (!dns->snddq.put (pkt)) 1210 if (c->dns->snddq.put (pkt))
1153 return false; 1211 c->dns->tw ();
1154 1212
1155 dns->tw.trigger (); 1213 // always return true even if the buffer overflows
1156
1157 return true; 1214 return true;
1158} 1215}
1159 1216
1160void 1217void
1161connection::dnsv4_reset_connection () 1218connection::dnsv4_reset_connection ()
1164} 1221}
1165 1222
1166#define NEXT(w) do { if (next > (w)) next = w; } while (0) 1223#define NEXT(w) do { if (next > (w)) next = w; } while (0)
1167 1224
1168void 1225void
1169dns_connection::time_cb (time_watcher &w) 1226dns_connection::time_cb (ev::timer &w, int revents)
1170{ 1227{
1171 // servers have to be polled 1228 // servers have to be polled
1172 if (THISNODE->dns_port) 1229 if (THISNODE->dns_port)
1173 return; 1230 return;
1174 1231
1175 // check for timeouts and (re)transmit 1232 // check for timeouts and (re)transmit
1176 tstamp next = NOW + poll_interval; 1233 tstamp next = ev::now () + poll_interval;
1177 dns_snd *send = 0; 1234 dns_snd *send = 0;
1178 1235
1179 for (vector<dns_snd *>::iterator i = vpn->dns_sndpq.begin (); 1236 for (vector<dns_snd *>::iterator i = vpn->dns_sndpq.begin ();
1180 i != vpn->dns_sndpq.end (); 1237 i != vpn->dns_sndpq.end ();
1181 ++i) 1238 ++i)
1182 { 1239 {
1183 dns_snd *r = *i; 1240 dns_snd *r = *i;
1184 1241
1185 if (r->timeout <= NOW) 1242 if (r->timeout <= ev_now ())
1186 { 1243 {
1187 if (!send) 1244 if (!send)
1188 { 1245 {
1189 send = r; 1246 send = r;
1190 1247
1191 r->retry++; 1248 r->retry++;
1192 r->timeout = NOW + (r->retry * last_latency * 8.); 1249 r->timeout = ev_now () + (r->retry * min_latency * conf.dns_timeout_factor);
1250 //printf ("RETRY %x (%d, %f)\n", r->seqno, r->retry, r->timeout - ev_now ());//D
1193 1251
1194 // the following code changes the query section a bit, forcing 1252 // the following code changes the query section a bit, forcing
1195 // the forwarder to generate a new request 1253 // the forwarder to generate a new request
1196 if (r->stdhdr) 1254 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); 1255 encode_header ((char *)r->pkt->at (6 * 2 + 1), THISNODE->id, r->seqno, r->retry);
1200 }
1201 } 1256 }
1202 } 1257 }
1203 else 1258 else
1204 NEXT (r->timeout); 1259 NEXT (r->timeout);
1205 } 1260 }
1206 1261
1207 if (last_sent + send_interval <= NOW)
1208 {
1209 if (!send) 1262 if (!send)
1263 {
1264 // generate a new packet, if wise
1265
1266 if (!established)
1210 { 1267 {
1211 // generate a new packet, if wise 1268 if (vpn->dns_sndpq.empty ())
1212
1213 if (!established)
1214 { 1269 {
1215 if (vpn->dns_sndpq.empty ())
1216 {
1217 send = new dns_snd (this); 1270 send = new dns_snd (this);
1218 1271
1219 cfg.reset (THISNODE->id); 1272 cfg.reset (THISNODE->id);
1220 send->gen_syn_req (cfg); 1273 send->gen_syn_req ();
1221 }
1222 } 1274 }
1223 else if (vpn->dns_sndpq.size () < MAX_OUTSTANDING 1275 }
1276 else if (vpn->dns_sndpq.size () < conf.dns_max_outstanding
1224 && !SEQNO_EQ (rcvseq, sndseq - (MAX_WINDOW - 1))) 1277 && !SEQNO_EQ (rcvseq, sndseq - (MAX_WINDOW - 1)))
1278 {
1279 if (last_sent + send_interval <= ev_now ())
1225 { 1280 {
1226 if (!snddq.empty ()) 1281 //printf ("sending data request etc.\n"); //D
1282 if (!snddq.empty () || last_received + 1. > ev_now ())
1227 { 1283 {
1228 poll_interval = send_interval; 1284 poll_interval = send_interval;
1229 NEXT (NOW + send_interval); 1285 NEXT (ev_now () + send_interval);
1230 } 1286 }
1231 1287
1232 send = new dns_snd (this); 1288 send = new dns_snd (this);
1233 send->gen_stream_req (sndseq, snddq); 1289 send->gen_stream_req (sndseq, snddq);
1234 send->timeout = NOW + last_latency * 8.; 1290 send->timeout = ev_now () + min_latency * conf.dns_timeout_factor;
1291 //printf ("SEND %x (%f)\n", send->seqno, send->timeout - ev_now (), min_latency, conf.dns_timeout_factor);//D
1235 1292
1236 sndseq = (sndseq + 1) & SEQNO_MASK; 1293 sndseq = (sndseq + 1) & SEQNO_MASK;
1237 } 1294 }
1238 1295 else
1239 if (send) 1296 NEXT (last_sent + send_interval);
1240 vpn->dns_sndpq.push_back (send);
1241 } 1297 }
1242 1298
1243 if (send) 1299 if (send)
1244 { 1300 vpn->dns_sndpq.push_back (send);
1245 last_sent = NOW; 1301 }
1302
1303 if (send)
1304 {
1305 last_sent = ev_now ();
1246 sendto (vpn->dnsv4_fd, 1306 sendto (vpn->dnsv4_fd,
1247 send->pkt->at (0), send->pkt->len, 0, 1307 send->pkt->at (0), send->pkt->len, 0,
1248 vpn->dns_forwarder.sav4 (), vpn->dns_forwarder.salenv4 ()); 1308 vpn->dns_forwarder.sav4 (), vpn->dns_forwarder.salenv4 ());
1249 }
1250 } 1309 }
1251 else
1252 NEXT (last_sent + send_interval);
1253 1310
1254 slog (L_NOISE, "DNS: pi %f si %f N %f (%d:%d)", 1311 slog (L_NOISE, "DNS: pi %f si %f N %f (%d:%d %d)",
1255 poll_interval, send_interval, next - NOW, 1312 poll_interval, send_interval, next - ev_now (),
1256 vpn->dns_sndpq.size (), snddq.size ()); 1313 vpn->dns_sndpq.size (), snddq.size (),
1314 rcvpq.size ());
1257 1315
1258 // TODO: no idea when this happens, but when next < NOW, we have a problem 1316 // TODO: no idea when this happens, but when next < ev_now (), we have a problem
1317 // doesn't seem to happen anymore
1259 if (next < NOW + 0.0001) 1318 if (next < ev_now () + 0.001)
1260 next = NOW + 0.1; 1319 next = ev_now () + 0.1;
1261 1320
1262 w.start (next); 1321 w.start (next - ev_now ());
1263} 1322}
1264 1323
1265#endif 1324#endif
1266 1325

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines