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.20 by pcg, Sun Mar 6 21:32:15 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;
668
669 printf ("send syn\n");//D
626 670
627 pkt->flags = htons (DEFAULT_CLIENT_FLAGS); 671 pkt->flags = htons (DEFAULT_CLIENT_FLAGS);
628 pkt->qdcount = htons (1); 672 pkt->qdcount = htons (1);
629 673
630 int offs = 6*2; 674 int offs = 6 * 2;
631 675
632 int elen = cdc26.encode ((char *)pkt->at (offs + 1), (u8 *)&cfg, sizeof (dns_cfg)); 676 int elen = cdc26.encode ((char *)pkt->at (offs + 1), (u8 *)&dns->cfg, sizeof (dns_cfg));
633 677
634 assert (elen <= MAX_LBL_SIZE); 678 assert (elen <= MAX_LBL_SIZE);
635 679
636 (*pkt)[offs] = elen; 680 (*pkt)[offs] = elen;
637 offs += elen + 1; 681 offs += elen + 1;
638 append_domain (*pkt, offs, THISNODE->domain); 682 append_domain (*pkt, offs, dns->c->conf->domain);
639 683
640 (*pkt)[offs++] = 0; 684 (*pkt)[offs++] = 0;
641 (*pkt)[offs++] = RR_TYPE_A >> 8; (*pkt)[offs++] = RR_TYPE_A; 685 (*pkt)[offs++] = RR_TYPE_A >> 8; (*pkt)[offs++] = RR_TYPE_A;
642 (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN; 686 (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN;
643 687
666 delete pkt; 710 delete pkt;
667} 711}
668 712
669///////////////////////////////////////////////////////////////////////////// 713/////////////////////////////////////////////////////////////////////////////
670 714
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) 715dns_connection::dns_connection (connection *c)
698: c (c) 716: c (c)
699, rcvdq (MAX_BACKLOG * 2) 717, rcvdq (MAX_BACKLOG * 2)
700, snddq (MAX_BACKLOG * 2) 718, snddq (MAX_BACKLOG * 2)
701, tw (this, &dns_connection::time_cb) 719, tw (this, &dns_connection::time_cb)
765 } 783 }
766 784
767 while (vpn_packet *pkt = rcvdq.get ()) 785 while (vpn_packet *pkt = rcvdq.get ())
768 { 786 {
769 sockinfo si; 787 sockinfo si;
770 si.host = 0; si.port = 0; si.prot = PROT_DNSv4; 788 si.host = 0x01010101; si.port = htons (c->conf->id); si.prot = PROT_DNSv4;
771 789
772 vpn->recv_vpn_packet (pkt, si); 790 vpn->recv_vpn_packet (pkt, si);
773 791
774 delete pkt; 792 delete pkt;
775 } 793 }
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