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.22 by pcg, Sun Mar 6 21:47:35 2005 UTC

25 25
26// dns processing is EXTREMELY ugly. For obvious(?) reasons. 26// dns processing is EXTREMELY ugly. For obvious(?) reasons.
27// it's a hack, use only in emergency situations please. 27// it's a hack, use only in emergency situations please.
28 28
29#include <cstring> 29#include <cstring>
30#include <cassert>
30 31
31#include <sys/types.h> 32#include <sys/types.h>
32#include <sys/socket.h> 33#include <sys/socket.h>
33#include <sys/wait.h> 34#include <sys/wait.h>
34#include <sys/uio.h> 35#include <sys/uio.h>
356 return true; 357 return true;
357} 358}
358 359
359vpn_packet *byte_stream::get () 360vpn_packet *byte_stream::get ()
360{ 361{
362 unsigned int len;
363
364 for (;;)
365 {
361 unsigned int len = (data [0] << 8) | data [1]; 366 len = (data [0] << 8) | data [1];
362 367
363 if (len > MAXSIZE && fill >= 2) 368 if (len <= MAXSIZE || fill < 2)
364 assert (len <= MAXSIZE || fill < 2); // TODO handle this gracefully, connection reset 369 break;
365 370
371 // TODO: handle this better than skipping, e.g. by reset
372 slog (L_DEBUG, _("DNS: corrupted packet stream skipping a byte..."));
373 remove (1);
374 }
375
366 if (fill < len + 2) 376 if (fill < len + 2)
367 return 0; 377 return 0;
368 378
369 vpn_packet *pkt = new vpn_packet; 379 vpn_packet *pkt = new vpn_packet;
370 380
498 return data - orig; 508 return data - orig;
499} 509}
500 510
501///////////////////////////////////////////////////////////////////////////// 511/////////////////////////////////////////////////////////////////////////////
502 512
513static u16 dns_id = 0; // TODO: should be per-vpn
514
515static u16 next_id ()
516{
517 if (!dns_id)
518 dns_id = time (0);
519
520 // the simplest lsfr with periodicity 65535 i could find
521 dns_id = (dns_id << 1)
522 | (((dns_id >> 1)
523 ^ (dns_id >> 2)
524 ^ (dns_id >> 4)
525 ^ (dns_id >> 15)) & 1);
526
527 return dns_id;
528}
529
530struct dns_rcv;
531struct dns_snd;
532
533struct dns_connection
534{
535 connection *c;
536 struct vpn *vpn;
537
538 dns_cfg cfg;
539
540 bool established;
541
542 tstamp last_received;
543 tstamp last_sent;
544 double last_latency;
545 double poll_interval, send_interval;
546
547 vector<dns_rcv *> rcvpq;
548
549 byte_stream rcvdq; int rcvseq;
550 byte_stream snddq; int sndseq;
551
552 void time_cb (time_watcher &w); time_watcher tw;
553 void receive_rep (dns_rcv *r);
554
555 dns_connection (connection *c);
556 ~dns_connection ();
557};
558
503struct dns_snd 559struct dns_snd
504{ 560{
505 dns_packet *pkt; 561 dns_packet *pkt;
506 tstamp timeout, sent; 562 tstamp timeout, sent;
507 int retry; 563 int retry;
508 struct dns_connection *dns; 564 struct dns_connection *dns;
509 int seqno; 565 int seqno;
510 bool stdhdr; 566 bool stdhdr;
511 567
512 void gen_stream_req (int seqno, byte_stream &stream); 568 void gen_stream_req (int seqno, byte_stream &stream);
513 void gen_syn_req (const dns_cfg &cfg); 569 void gen_syn_req ();
514 570
515 dns_snd (dns_connection *dns); 571 dns_snd (dns_connection *dns);
516 ~dns_snd (); 572 ~dns_snd ();
517}; 573};
518
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 574
533dns_snd::dns_snd (dns_connection *dns) 575dns_snd::dns_snd (dns_connection *dns)
534: dns (dns) 576: dns (dns)
535{ 577{
536 timeout = 0; 578 timeout = 0;
581 623
582 pkt->flags = htons (DEFAULT_CLIENT_FLAGS); 624 pkt->flags = htons (DEFAULT_CLIENT_FLAGS);
583 pkt->qdcount = htons (1); 625 pkt->qdcount = htons (1);
584 626
585 int offs = 6*2; 627 int offs = 6*2;
586 int dlen = MAX_DOMAIN_SIZE - (strlen (THISNODE->domain) + 2); 628 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, 629 // 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 630 // so we need to have space for 2*MAX_DOMAIN_SIZE + header + extra
589 631
590 char enc[256], *encp = enc; 632 char enc[256], *encp = enc;
591 encode_header (enc, THISNODE->id, seqno); 633 encode_header (enc, THISNODE->id, seqno);
609 encp += lbllen; 651 encp += lbllen;
610 652
611 enclen -= lbllen; 653 enclen -= lbllen;
612 } 654 }
613 655
614 append_domain (*pkt, offs, THISNODE->domain); 656 append_domain (*pkt, offs, dns->c->conf->domain);
615 657
616 (*pkt)[offs++] = 0; 658 (*pkt)[offs++] = 0;
617 (*pkt)[offs++] = RR_TYPE_ANY >> 8; (*pkt)[offs++] = RR_TYPE_ANY; 659 (*pkt)[offs++] = RR_TYPE_ANY >> 8; (*pkt)[offs++] = RR_TYPE_ANY;
618 (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN; 660 (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN;
619 661
620 pkt->len = offs; 662 pkt->len = offs;
621} 663}
622 664
623void dns_snd::gen_syn_req (const dns_cfg &cfg) 665void dns_snd::gen_syn_req ()
624{ 666{
625 timeout = NOW + INITIAL_SYN_TIMEOUT; 667 timeout = NOW + INITIAL_SYN_TIMEOUT;
626 668
627 pkt->flags = htons (DEFAULT_CLIENT_FLAGS); 669 pkt->flags = htons (DEFAULT_CLIENT_FLAGS);
628 pkt->qdcount = htons (1); 670 pkt->qdcount = htons (1);
629 671
630 int offs = 6*2; 672 int offs = 6 * 2;
631 673
632 int elen = cdc26.encode ((char *)pkt->at (offs + 1), (u8 *)&cfg, sizeof (dns_cfg)); 674 int elen = cdc26.encode ((char *)pkt->at (offs + 1), (u8 *)&dns->cfg, sizeof (dns_cfg));
633 675
634 assert (elen <= MAX_LBL_SIZE); 676 assert (elen <= MAX_LBL_SIZE);
635 677
636 (*pkt)[offs] = elen; 678 (*pkt)[offs] = elen;
637 offs += elen + 1; 679 offs += elen + 1;
638 append_domain (*pkt, offs, THISNODE->domain); 680 append_domain (*pkt, offs, dns->c->conf->domain);
639 681
640 (*pkt)[offs++] = 0; 682 (*pkt)[offs++] = 0;
641 (*pkt)[offs++] = RR_TYPE_A >> 8; (*pkt)[offs++] = RR_TYPE_A; 683 (*pkt)[offs++] = RR_TYPE_A >> 8; (*pkt)[offs++] = RR_TYPE_A;
642 (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN; 684 (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN;
643 685
666 delete pkt; 708 delete pkt;
667} 709}
668 710
669///////////////////////////////////////////////////////////////////////////// 711/////////////////////////////////////////////////////////////////////////////
670 712
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) 713dns_connection::dns_connection (connection *c)
698: c (c) 714: c (c)
699, rcvdq (MAX_BACKLOG * 2) 715, rcvdq (MAX_BACKLOG * 2)
700, snddq (MAX_BACKLOG * 2) 716, snddq (MAX_BACKLOG * 2)
701, tw (this, &dns_connection::time_cb) 717, tw (this, &dns_connection::time_cb)
765 } 781 }
766 782
767 while (vpn_packet *pkt = rcvdq.get ()) 783 while (vpn_packet *pkt = rcvdq.get ())
768 { 784 {
769 sockinfo si; 785 sockinfo si;
770 si.host = 0; si.port = 0; si.prot = PROT_DNSv4; 786 si.host = 0x01010101; si.port = htons (c->conf->id); si.prot = PROT_DNSv4;
771 787
772 vpn->recv_vpn_packet (pkt, si); 788 vpn->recv_vpn_packet (pkt, si);
773 789
774 delete pkt; 790 delete pkt;
775 } 791 }
857 // new packet, queue 873 // new packet, queue
858 rcv = new dns_rcv (seqno, data, datalen); 874 rcv = new dns_rcv (seqno, data, datalen);
859 dns->receive_rep (rcv); 875 dns->receive_rep (rcv);
860 } 876 }
861 877
878 {
862 pkt [offs++] = 0xc0; pkt [offs++] = 6 * 2; // refer to name in query section 879 pkt [offs++] = 0xc0; pkt [offs++] = 6 * 2; // refer to name in query section
863 880
864 int rtype = dns ? dns->cfg.rrtype : RR_TYPE_A; 881 int rtype = dns ? dns->cfg.rrtype : RR_TYPE_A;
865 pkt [offs++] = rtype >> 8; pkt [offs++] = rtype; // type 882 pkt [offs++] = rtype >> 8; pkt [offs++] = rtype; // type
866 pkt [offs++] = RR_CLASS_IN >> 8; pkt [offs++] = RR_CLASS_IN; // class 883 pkt [offs++] = RR_CLASS_IN >> 8; pkt [offs++] = RR_CLASS_IN; // class
867 pkt [offs++] = 0; pkt [offs++] = 0; 884 pkt [offs++] = 0; pkt [offs++] = 0;
868 pkt [offs++] = 0; pkt [offs++] = dns ? dns->cfg.def_ttl : 0; // TTL 885 pkt [offs++] = 0; pkt [offs++] = dns ? dns->cfg.def_ttl : 0; // TTL
869 886
870 int rdlen_offs = offs += 2; 887 int rdlen_offs = offs += 2;
871 888
872 int dlen = (dns ? ntohs (dns->cfg.max_size) : MAX_PKT_SIZE) - offs; 889 int dlen = (dns ? ntohs (dns->cfg.max_size) : MAX_PKT_SIZE) - offs;
873 // bind doesn't compress well, so reduce further by one label length 890 // bind doesn't compress well, so reduce further by one label length
874 dlen -= qlen; 891 dlen -= qlen;
875 892
876 if (dns) 893 if (dns)
877 { 894 {
878 // only put data into in-order sequence packets, if 895 // only put data into in-order sequence packets, if
879 // we receive out-of-order packets we generate empty 896 // we receive out-of-order packets we generate empty
880 // replies 897 // replies
881 while (dlen > 1 && !dns->snddq.empty () && in_seq) 898 while (dlen > 1 && !dns->snddq.empty () && in_seq)
882 { 899 {
883 int txtlen = dlen <= 255 ? dlen - 1 : 255; 900 int txtlen = dlen <= 255 ? dlen - 1 : 255;
884 901
885 if (txtlen > dns->snddq.size ()) 902 if (txtlen > dns->snddq.size ())
886 txtlen = dns->snddq.size (); 903 txtlen = dns->snddq.size ();
887 904
888 pkt[offs++] = txtlen; 905 pkt[offs++] = txtlen;
889 memcpy (pkt.at (offs), dns->snddq.begin (), txtlen); 906 memcpy (pkt.at (offs), dns->snddq.begin (), txtlen);
890 offs += txtlen; 907 offs += txtlen;
891 dns->snddq.remove (txtlen); 908 dns->snddq.remove (txtlen);
892 909
893 dlen -= txtlen + 1; 910 dlen -= txtlen + 1;
894 } 911 }
895 912
896 // avoid empty TXT rdata 913 // avoid empty TXT rdata
897 if (offs == rdlen_offs) 914 if (offs == rdlen_offs)
898 pkt[offs++] = 0; 915 pkt[offs++] = 0;
899 916
900 slog (L_NOISE, "DNS: snddq %d", dns->snddq.size ()); 917 slog (L_NOISE, "DNS: snddq %d", dns->snddq.size ());
901 } 918 }
902 else 919 else
903 { 920 {
904 // send RST 921 // send RST
905 pkt [offs++] = CMD_IP_1; pkt [offs++] = CMD_IP_2; pkt [offs++] = CMD_IP_3; 922 pkt [offs++] = CMD_IP_1; pkt [offs++] = CMD_IP_2; pkt [offs++] = CMD_IP_3;
906 pkt [offs++] = CMD_IP_RST; 923 pkt [offs++] = CMD_IP_RST;
907 } 924 }
908 925
909 int rdlen = offs - rdlen_offs; 926 int rdlen = offs - rdlen_offs;
910 927
911 pkt [rdlen_offs - 2] = rdlen >> 8; 928 pkt [rdlen_offs - 2] = rdlen >> 8;
912 pkt [rdlen_offs - 1] = rdlen; 929 pkt [rdlen_offs - 1] = rdlen;
913 930
914 if (dns) 931 if (dns)
915 { 932 {
916 // now update dns_rcv copy 933 // now update dns_rcv copy
917 rcv->pkt->len = offs; 934 rcv->pkt->len = offs;
918 memcpy (rcv->pkt->at (0), pkt.at (0), offs); 935 memcpy (rcv->pkt->at (0), pkt.at (0), offs);
919 } 936 }
937 }
920 938
921 duplicate_request: ; 939 duplicate_request: ;
922 } 940 }
923 else 941 else
924 pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR); 942 pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR);
1142 } 1160 }
1143 } 1161 }
1144} 1162}
1145 1163
1146bool 1164bool
1147connection::send_dnsv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 1165vpn::send_dnsv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
1148{ 1166{
1167 int client = ntohs (si.port);
1168
1169 assert (0 < client && client <= conns.size ());
1170
1171 connection *c = conns [client - 1];
1172
1149 if (!dns) 1173 if (!c->dns)
1150 dns = new dns_connection (this); 1174 c->dns = new dns_connection (c);
1151 1175
1152 if (!dns->snddq.put (pkt)) 1176 if (!c->dns->snddq.put (pkt))
1153 return false; 1177 return false;
1154 1178
1155 dns->tw.trigger (); 1179 c->dns->tw.trigger ();
1156 1180
1157 return true; 1181 return true;
1158} 1182}
1159 1183
1160void 1184void
1214 { 1238 {
1215 if (vpn->dns_sndpq.empty ()) 1239 if (vpn->dns_sndpq.empty ())
1216 { 1240 {
1217 send = new dns_snd (this); 1241 send = new dns_snd (this);
1218 1242
1243 printf ("new conn %p %d\n", this, c->conf->id);//D
1219 cfg.reset (THISNODE->id); 1244 cfg.reset (THISNODE->id);
1220 send->gen_syn_req (cfg); 1245 send->gen_syn_req ();
1221 } 1246 }
1222 } 1247 }
1223 else if (vpn->dns_sndpq.size () < MAX_OUTSTANDING 1248 else if (vpn->dns_sndpq.size () < MAX_OUTSTANDING
1224 && !SEQNO_EQ (rcvseq, sndseq - (MAX_WINDOW - 1))) 1249 && !SEQNO_EQ (rcvseq, sndseq - (MAX_WINDOW - 1)))
1225 { 1250 {
1251 //printf ("sending data request etc.\n"); //D
1226 if (!snddq.empty ()) 1252 if (!snddq.empty ())
1227 { 1253 {
1228 poll_interval = send_interval; 1254 poll_interval = send_interval;
1229 NEXT (NOW + send_interval); 1255 NEXT (NOW + send_interval);
1230 } 1256 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines