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.47 by pcg, Thu Aug 7 17:54:27 2008 UTC vs.
Revision 1.54 by root, Tue Oct 18 11:07:28 2011 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-2008 Marc Lehmann <gvpe@schmorp.de> 3 Copyright (C) 2003-2011 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 it 7 GVPE is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the 8 under the terms of the GNU General Public License as published by the
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.025 // poll at most this often when no data received
64#define MAX_POLL_INTERVAL 5. // 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
65#define ACTIVITY_INTERVAL 5.
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) )
83#define MAX_PKT_SIZE 512 83#define MAX_PKT_SIZE 512
84 84
85#define RR_TYPE_A 1 85#define RR_TYPE_A 1
86#define RR_TYPE_NULL 10 86#define RR_TYPE_NULL 10
87#define RR_TYPE_TXT 16 87#define RR_TYPE_TXT 16
88#define RR_TYPE_AAAA 28
88#define RR_TYPE_ANY 255 89#define RR_TYPE_ANY 255
89 90
90#define RR_CLASS_IN 1 91#define RR_CLASS_IN 1
91 92
92#define CMD_IP_1 207 93#define CMD_IP_1 207
93#define CMD_IP_2 46 94#define CMD_IP_2 46
94#define CMD_IP_3 236 95#define CMD_IP_3 236
95#define CMD_IP_RST 29 96
96#define CMD_IP_SYN 113 97#define CMD_IP_RST 29 // some error, reset and retry
97#define CMD_IP_REJ 32 98#define CMD_IP_REJ 32 // do not want you
99#define CMD_IP_SYN 113 // connection established
100#define CMD_IP_CSE 213 // connection established, but likely case mismatch
101
102static bool
103is_uc (char c)
104{
105 return 'A' <= c && c <= 'Z';
106}
107
108static bool
109is_lc (char c)
110{
111 return 'a' <= c && c <= 'z';
112}
98 113
99// works for cmaps up to 255 (not 256!) 114// works for cmaps up to 255 (not 256!)
100struct charmap 115struct charmap
101{ 116{
102 enum { INVALID = (u8)255 }; 117 enum { INVALID = (u8)255 };
116 memset (enc, (char) 0, 256); 131 memset (enc, (char) 0, 256);
117 memset (dec, (char)INVALID, 256); 132 memset (dec, (char)INVALID, 256);
118 133
119 for (size = 0; cmap [size]; size++) 134 for (size = 0; cmap [size]; size++)
120 { 135 {
136 char c = cmap [size];
137
121 enc [size] = cmap [size]; 138 enc [size] = c;
122 dec [(u8)enc [size]] = size; 139 dec [(u8)c] = size;
140
141 // allow lowercase/uppercase aliases if possible
142 if (is_uc (c) && dec [c + ('a' - 'A')] == INVALID) dec [c + ('a' - 'A')] = size;
143 if (is_lc (c) && dec [c - ('a' - 'A')] == INVALID) dec [c - ('a' - 'A')] = size;
123 } 144 }
124 145
125 assert (size < 256); 146 assert (size < 256);
126} 147}
127 148
134{ 155{
135 charmap cmap; 156 charmap cmap;
136 unsigned int enc_len [MAX_DEC_LEN]; 157 unsigned int enc_len [MAX_DEC_LEN];
137 unsigned int dec_len [MAX_ENC_LEN]; 158 unsigned int dec_len [MAX_ENC_LEN];
138 159
139 unsigned int encode_len (unsigned int len); 160 unsigned int encode_len (unsigned int len) const;
140 unsigned int decode_len (unsigned int len); 161 unsigned int decode_len (unsigned int len) const;
141 162
142 unsigned int encode (char *dst, u8 *src, unsigned int len); 163 unsigned int encode (char *dst, u8 *src, unsigned int len) const;
143 unsigned int decode (u8 *dst, char *src, unsigned int len); 164 unsigned int decode (u8 *dst, char *src, unsigned int len) const;
144 165
145 basecoder (const char *cmap); 166 basecoder (const char *cmap);
146}; 167};
147 168
148basecoder::basecoder (const char *cmap) 169basecoder::basecoder (const char *cmap)
167 enc_len [len] = n; 188 enc_len [len] = n;
168 dec_len [n] = len; 189 dec_len [n] = len;
169 } 190 }
170} 191}
171 192
193unsigned int
172unsigned int basecoder::encode_len (unsigned int len) 194basecoder::encode_len (unsigned int len) const
173{ 195{
174 return enc_len [len]; 196 return enc_len [len];
175} 197}
176 198
199unsigned int
177unsigned int basecoder::decode_len (unsigned int len) 200basecoder::decode_len (unsigned int len) const
178{ 201{
179 while (len && !dec_len [len]) 202 while (len && !dec_len [len])
180 --len; 203 --len;
181 204
182 return dec_len [len]; 205 return dec_len [len];
183} 206}
184 207
208unsigned int
185unsigned int basecoder::encode (char *dst, u8 *src, unsigned int len) 209basecoder::encode (char *dst, u8 *src, unsigned int len) const
186{ 210{
187 if (!len || len > MAX_DEC_LEN) 211 if (!len || len > MAX_DEC_LEN)
188 return 0; 212 return 0;
189 213
190 int elen = encode_len (len); 214 int elen = encode_len (len);
209 *dst++ = cmap.encode [dst_ [i]]; 233 *dst++ = cmap.encode [dst_ [i]];
210 234
211 return elen; 235 return elen;
212} 236}
213 237
238unsigned int
214unsigned int basecoder::decode (u8 *dst, char *src, unsigned int len) 239basecoder::decode (u8 *dst, char *src, unsigned int len) const
215{ 240{
216 if (!len || len > MAX_ENC_LEN) 241 if (!len || len > MAX_ENC_LEN)
217 return 0; 242 return 0;
218 243
219 u8 src_ [MAX_ENC_LEN]; 244 u8 src_ [MAX_ENC_LEN];
268 } 293 }
269 abort (); 294 abort ();
270} 295}
271#endif 296#endif
272 297
273//static basecoder cdc64 ("_dDpPhHzZrR06QqMmjJkKBb34TtSsvVlL81xXaAeEFf92WwGgYyoO57UucCNniI-");
274//static basecoder cdc63 ("_dDpPhHzZrR06QqMmjJkKBb34TtSsvVlL81xXaAeEFf92WwGgYyoO57UucCNniI");
275static basecoder cdc62 ("dDpPhHzZrR06QqMmjJkKBb34TtSsvVlL81xXaAeEFf92WwGgYyoO57UucCNniI"); 298static basecoder cdc62 ("dDpPhHzZrR06QqMmjJkKBb34TtSsvVlL81xXaAeEFf92WwGgYyoO57UucCNniI"); // a-zA-Z0-9
276//static basecoder cdc36 ("dphzr06qmjkb34tsvl81xaef92wgyo57ucni"); // unused as of yet 299static basecoder cdc36 ("dPhZr06QmJkB34tSvL81xAeF92wGyO57uCnI"); // a-z0-9 for case-changers
277static basecoder cdc26 ("dPhZrQmJkBtSvLxAeFwGyO"); 300static basecoder cdc26 ("dPhZrQmJkBtSvLxAeFwGyOuCnI"); // a-z
278 301
279///////////////////////////////////////////////////////////////////////////// 302/////////////////////////////////////////////////////////////////////////////
280 303
281#define HDRSIZE 6 304#define HDRSIZE 5
282 305
306inline void
283inline void encode_header (char *data, int clientid, int seqno, int retry = 0) 307encode_header (char *data, int clientid, int seqno, int retry = 0)
284{ 308{
309 assert (clientid < 256);
310
285 seqno &= SEQNO_MASK; 311 seqno &= SEQNO_MASK;
286 312
287 u8 hdr[3] = { 313 u8 hdr[3] = {
314 seqno,
315 (seqno >> 8) | (retry << 6),
288 clientid, 316 clientid,
289 (seqno >> 8) | (retry << 6),
290 seqno,
291 }; 317 };
292 318
293 assert (clientid < 256);
294
295 cdc26.encode (data, hdr, 3); 319 cdc36.encode (data, hdr, 3);
296} 320}
297 321
322inline void
298inline void decode_header (char *data, int &clientid, int &seqno) 323decode_header (char *data, int &clientid, int &seqno)
299{ 324{
300 u8 hdr[3]; 325 u8 hdr[3];
301 326
302 cdc26.decode (hdr, data, HDRSIZE); 327 cdc36.decode (hdr, data, HDRSIZE);
303 328
304 clientid = hdr[0]; 329 clientid = hdr[2];
305 seqno = ((hdr[1] << 8) | hdr[2]) & SEQNO_MASK; 330 seqno = ((hdr[1] << 8) | hdr[0]) & SEQNO_MASK;
306} 331}
307 332
308///////////////////////////////////////////////////////////////////////////// 333/////////////////////////////////////////////////////////////////////////////
309 334
310struct byte_stream 335struct byte_stream
336byte_stream::~byte_stream () 361byte_stream::~byte_stream ()
337{ 362{
338 delete data; 363 delete data;
339} 364}
340 365
366void
341void byte_stream::remove (int count) 367byte_stream::remove (int count)
342{ 368{
343 if (count > fill) 369 if (count > fill)
344 assert (count <= fill); 370 assert (count <= fill);
345 371
346 memmove (data, data + count, fill -= count); 372 memmove (data, data + count, fill -= count);
347} 373}
348 374
375bool
349bool byte_stream::put (u8 *data, unsigned int datalen) 376byte_stream::put (u8 *data, unsigned int datalen)
350{ 377{
351 if (maxsize - fill < datalen) 378 if (maxsize - fill < datalen)
352 return false; 379 return false;
353 380
354 memcpy (this->data + fill, data, datalen); fill += datalen; 381 memcpy (this->data + fill, data, datalen); fill += datalen;
355 382
356 return true; 383 return true;
357} 384}
358 385
386bool
359bool byte_stream::put (vpn_packet *pkt) 387byte_stream::put (vpn_packet *pkt)
360{ 388{
361 if (maxsize - fill < pkt->len + 2) 389 if (maxsize - fill < pkt->len + 2)
362 return false; 390 return false;
363 391
364 data [fill++] = pkt->len >> 8; 392 data [fill++] = pkt->len >> 8;
369 return true; 397 return true;
370} 398}
371 399
372vpn_packet *byte_stream::get () 400vpn_packet *byte_stream::get ()
373{ 401{
402 if (fill < 2)
403 return 0;
404
374 unsigned int len; 405 unsigned int len;
375 406
376 for (;;) 407 for (;;)
377 { 408 {
378 len = (data [0] << 8) | data [1]; 409 len = (data [0] << 8) | data [1];
379 410
380 if (len <= MAXSIZE || fill < 2) 411 if (len <= MAXSIZE)
381 break; 412 break;
382 413
383 // TODO: handle this better than skipping, e.g. by reset 414 // TODO: handle this better than skipping, e.g. by reset
384 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]);
385 remove (1); 416 remove (1);
386 } 417 }
387 418
388 if (fill < len + 2) 419 if (fill < len + 2)
389 return 0; 420 return 0;
420 451
421struct dns_cfg 452struct dns_cfg
422{ 453{
423 static int next_uid; 454 static int next_uid;
424 455
425 u8 id1, id2, id3, id4; 456 u8 chksum;
457 u8 rrtype;
458 u16 uid; // to make request unique
426 459
427 u8 version; 460 u8 version;
428 u8 flags; 461 u8 flags;
429 u8 rrtype; 462 u16 max_size;
463
464 u8 id1, id2, id3, id4;
465
466 u16 client;
430 u8 def_ttl; 467 u8 def_ttl;
468 u8 r0;
431 469
432 u16 client; 470 u8 syn_cdc; // cdc en/decoder for syn (A?) requests
433 u16 uid; // to make request unique 471 u8 hdr_cdc; // cdc en/decoder for regular request headers
472 u8 req_cdc; // cdc en/decoder for regular (ANY?) request data
473 u8 rep_cdc; // cdc en/decoder for regular (TXT) replies, 0 == 8 bit encoding
434 474
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; 475 u8 r1, r2, r3, r4;
444 476
445 void reset (int clientid); 477 void reset (int clientid);
446 bool valid (); 478 bool valid ();
479 u8 get_chksum ();
447}; 480};
448 481
449int dns_cfg::next_uid; 482int dns_cfg::next_uid;
450 483
484void
451void dns_cfg::reset (int clientid) 485dns_cfg::reset (int clientid)
452{ 486{
487 // this ID must result in some mixed-case characters in cdc26-encoding
453 id1 = 'G'; 488 id1 = 'G';
454 id2 = 'V'; 489 id2 = 'V';
455 id3 = 'P'; 490 id3 = 'P';
456 id4 = 'E'; 491 id4 = 'E';
457 492
458 version = 1; 493 version = 2;
459 494
460 rrtype = RR_TYPE_TXT; 495 rrtype = RR_TYPE_TXT;
461 flags = 0; 496 flags = 0;
462 def_ttl = 0; 497 def_ttl = 0;
463 seq_cdc = 26; 498 syn_cdc = 26;
464 req_cdc = 62; 499 hdr_cdc = 36;
500 req_cdc = conf.dns_case_preserving ? 62 : 36;
465 rep_cdc = 0; 501 rep_cdc = 0;
466 max_size = htons (MAX_PKT_SIZE); 502 max_size = htons (MAX_PKT_SIZE);
467 client = htons (clientid); 503 client = htons (clientid);
468 uid = next_uid++; 504 uid = ++next_uid;
469 delay = 0;
470 505
471 r3 = r4 = 0; 506 r0 = r1 = r2 = r3 = r4 = 0;
472 r4 = r5 = r6 = r7 = 0;
473}
474 507
508 chksum = get_chksum ();
509}
510
511// simple but not trivial chksum
512u8
513dns_cfg::get_chksum ()
514{
515 unsigned int sum = 0xff00; // only 16 bits required
516
517 u8 old_chksum = chksum;
518 chksum = 0;
519
520 for (unsigned int i = 0; i < sizeof (*this); ++i)
521 sum += ((u8 *)this)[i] * (i + 1);
522
523 chksum = old_chksum;
524
525 return sum + (sum >> 8);
526}
527
528bool
475bool dns_cfg::valid () 529dns_cfg::valid ()
476{ 530{
477 // although the protocol itself allows for some configurability, 531 // although the protocol itself allows for some configurability,
478 // only the following encoding/decoding settings are implemented. 532 // only the following encoding/decoding settings are implemented.
479 return id1 == 'G' 533 return id1 == 'G'
480 && id2 == 'V' 534 && id2 == 'V'
481 && id3 == 'P' 535 && id3 == 'P'
482 && id4 == 'E' 536 && id4 == 'E'
537 && version == 2
483 && seq_cdc == 26 538 && syn_cdc == 26
484 && req_cdc == 62 539 && hdr_cdc == 36
540 && (req_cdc == 36 || req_cdc == 62)
485 && rep_cdc == 0 541 && rep_cdc == 0
486 && version == 1; 542 && chksum == get_chksum ();
487} 543}
488 544
489struct dns_packet : net_packet 545struct dns_packet : net_packet
490{ 546{
491 u16 id; 547 u16 id;
495 u8 data [MAXSIZE - 6 * 2]; 551 u8 data [MAXSIZE - 6 * 2];
496 552
497 int decode_label (char *data, int size, int &offs); 553 int decode_label (char *data, int size, int &offs);
498}; 554};
499 555
556int
500int dns_packet::decode_label (char *data, int size, int &offs) 557dns_packet::decode_label (char *data, int size, int &offs)
501{ 558{
502 char *orig = data; 559 char *orig = data;
503 560
504 memset (data, 0, size); 561 memset (data, 0, size);
505 562
531 return data - orig; 588 return data - orig;
532} 589}
533 590
534///////////////////////////////////////////////////////////////////////////// 591/////////////////////////////////////////////////////////////////////////////
535 592
593static
594u16 next_id ()
595{
536static u16 dns_id = 0; // TODO: should be per-vpn 596 static u16 dns_id = 0; // TODO: should be per-vpn
537 597
538static u16 next_id () 598#if 1
539{
540 if (!dns_id) 599 if (!dns_id)
541 dns_id = time (0); 600 dns_id = time (0);
542 601
543 // the simplest lsfr with periodicity 65535 i could find 602 // the simplest lsfr with periodicity 65535 i could find
544 dns_id = (dns_id << 1) 603 dns_id = (dns_id << 1)
546 ^ (dns_id >> 2) 605 ^ (dns_id >> 2)
547 ^ (dns_id >> 4) 606 ^ (dns_id >> 4)
548 ^ (dns_id >> 15)) & 1); 607 ^ (dns_id >> 15)) & 1);
549 608
550 return dns_id; 609 return dns_id;
610#else
611 dns_id++;//D
612
613 return htons (dns_id);
614#endif
551} 615}
552 616
553struct dns_rcv; 617struct dns_rcv;
554struct dns_snd; 618struct dns_snd;
555 619
559 struct vpn *vpn; 623 struct vpn *vpn;
560 624
561 dns_cfg cfg; 625 dns_cfg cfg;
562 626
563 bool established; 627 bool established;
628 const basecoder *cdc;
564 629
565 tstamp last_received; 630 tstamp last_received;
566 tstamp last_sent; 631 tstamp last_sent;
567 double min_latency; 632 double min_latency;
568 double poll_interval, send_interval; 633 double poll_interval, send_interval;
572 byte_stream rcvdq; int rcvseq; int repseq; 637 byte_stream rcvdq; int rcvseq; int repseq;
573 byte_stream snddq; int sndseq; 638 byte_stream snddq; int sndseq;
574 639
575 inline void time_cb (ev::timer &w, int revents); ev::timer tw; 640 inline void time_cb (ev::timer &w, int revents); ev::timer tw;
576 void receive_rep (dns_rcv *r); 641 void receive_rep (dns_rcv *r);
642
643 void reset (); // quite like tcp RST
644 void set_cfg (); // to be called after any cfg changes
577 645
578 dns_connection (connection *c); 646 dns_connection (connection *c);
579 ~dns_connection (); 647 ~dns_connection ();
580}; 648};
581 649
612dns_snd::~dns_snd () 680dns_snd::~dns_snd ()
613{ 681{
614 delete pkt; 682 delete pkt;
615} 683}
616 684
685static void
617static void append_domain (dns_packet &pkt, int &offs, const char *domain) 686append_domain (dns_packet &pkt, int &offs, const char *domain)
618{ 687{
619 // add tunnel domain 688 // add tunnel domain
620 for (;;) 689 for (;;)
621 { 690 {
622 const char *end = strchr (domain, '.'); 691 const char *end = strchr (domain, '.');
635 704
636 domain = end + 1; 705 domain = end + 1;
637 } 706 }
638} 707}
639 708
709void
640void dns_snd::gen_stream_req (int seqno, byte_stream &stream) 710dns_snd::gen_stream_req (int seqno, byte_stream &stream)
641{ 711{
642 stdhdr = true; 712 stdhdr = true;
643 this->seqno = seqno; 713 this->seqno = seqno;
644 714
645 timeout = ev_now () + INITIAL_TIMEOUT; 715 timeout = ev_now () + INITIAL_TIMEOUT;
653 // so we need to have space for 2*MAX_DOMAIN_SIZE + header + extra 723 // so we need to have space for 2*MAX_DOMAIN_SIZE + header + extra
654 724
655 char enc[256], *encp = enc; 725 char enc[256], *encp = enc;
656 encode_header (enc, THISNODE->id, seqno); 726 encode_header (enc, THISNODE->id, seqno);
657 727
658 int datalen = cdc62.decode_len (dlen - (dlen + MAX_LBL_SIZE - 1) / MAX_LBL_SIZE - HDRSIZE); 728 int datalen = dns->cdc->decode_len (dlen - (dlen + MAX_LBL_SIZE - 1) / MAX_LBL_SIZE - HDRSIZE);
659 729
660 if (datalen > stream.size ()) 730 if (datalen > stream.size ())
661 datalen = stream.size (); 731 datalen = stream.size ();
662 732
663 int enclen = cdc62.encode (enc + HDRSIZE, stream.begin (), datalen) + HDRSIZE; 733 int enclen = dns->cdc->encode (enc + HDRSIZE, stream.begin (), datalen) + HDRSIZE;
664 stream.remove (datalen); 734 stream.remove (datalen);
665 735
666 while (enclen) 736 while (enclen)
667 { 737 {
668 int lbllen = enclen < MAX_LBL_SIZE ? enclen : MAX_LBL_SIZE; 738 int lbllen = enclen < MAX_LBL_SIZE ? enclen : MAX_LBL_SIZE;
683 (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN; 753 (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN;
684 754
685 pkt->len = offs; 755 pkt->len = offs;
686} 756}
687 757
758void
688void dns_snd::gen_syn_req () 759dns_snd::gen_syn_req ()
689{ 760{
690 timeout = ev_now () + INITIAL_SYN_TIMEOUT; 761 timeout = ev_now () + INITIAL_SYN_TIMEOUT;
691 762
692 pkt->flags = htons (DEFAULT_CLIENT_FLAGS); 763 pkt->flags = htons (DEFAULT_CLIENT_FLAGS);
693 pkt->qdcount = htons (1); 764 pkt->qdcount = htons (1);
740{ 811{
741 tw.set<dns_connection, &dns_connection::time_cb> (this); 812 tw.set<dns_connection, &dns_connection::time_cb> (this);
742 813
743 vpn = c->vpn; 814 vpn = c->vpn;
744 815
816 reset ();
817}
818
819dns_connection::~dns_connection ()
820{
821 reset ();
822}
823
824void
825dns_connection::reset ()
826{
827 while (!rcvpq.empty ())
828 {
829 delete rcvpq.back ();
830 rcvpq.pop_back ();
831 }
832
833 for (int i = vpn->dns_sndpq.size (); i--; )
834 if (vpn->dns_sndpq [i]->dns == this)
835 {
836 vpn->dns_sndpq [i] = vpn->dns_sndpq.back ();
837 vpn->dns_sndpq.pop_back ();
838 }
839
745 established = false; 840 established = false;
746 841
747 rcvseq = repseq = sndseq = 0; 842 rcvseq = repseq = sndseq = 0;
748 843
749 last_sent = last_received = 0; 844 last_sent = 0;
750 poll_interval = 0.5; // starting here 845 poll_interval = 0.5; // starting here
751 send_interval = 0.5; // starting rate 846 send_interval = 0.5; // starting rate
752 min_latency = INITIAL_TIMEOUT; 847 min_latency = INITIAL_TIMEOUT;
753} 848}
754 849
755dns_connection::~dns_connection () 850void
851dns_connection::set_cfg ()
756{ 852{
757 for (vector<dns_rcv *>::iterator i = rcvpq.begin (); 853 cdc = cfg.req_cdc == 36 ? &cdc36 : &cdc62;
758 i != rcvpq.end ();
759 ++i)
760 delete *i;
761} 854}
762 855
856void
763void dns_connection::receive_rep (dns_rcv *r) 857dns_connection::receive_rep (dns_rcv *r)
764{ 858{
765 if (r->datalen) 859 if (r->datalen)
766 { 860 poll_interval = max (poll_interval * (1. / 1.2), MIN_POLL_INTERVAL);
767 last_received = ev_now ();
768 tw ();
769
770 poll_interval = send_interval;
771 }
772 else 861 else
773 { 862 poll_interval = min (poll_interval * 1.1, MAX_POLL_INTERVAL);
774 poll_interval *= 1.5;
775
776 if (poll_interval > MAX_POLL_INTERVAL)
777 poll_interval = MAX_POLL_INTERVAL;
778 }
779 863
780 rcvpq.push_back (r); 864 rcvpq.push_back (r);
781 865
782 redo: 866 redo:
783 867
801 885
802 rcvseq = (rcvseq + 1) & SEQNO_MASK; 886 rcvseq = (rcvseq + 1) & SEQNO_MASK;
803 887
804 if (!rcvdq.put (r->data, r->datalen)) 888 if (!rcvdq.put (r->data, r->datalen))
805 { 889 {
890 // MUST never overflow, can be caused by data corruption, TODO
806 slog (L_ERR, "DNS: !rcvdq.put (r->data, r->datalen)"); 891 slog (L_CRIT, "DNS: !rcvdq.put (r->data, r->datalen)");
807 abort (); // MUST never overflow, can be caused by data corruption, TODO 892 reset ();
893 return;
808 } 894 }
809 895
810 while (vpn_packet *pkt = rcvdq.get ()) 896 while (vpn_packet *pkt = rcvdq.get ())
811 { 897 {
812 sockinfo si; 898 sockinfo si;
813 si.host = htonl (c->conf->id); si.port = 0; si.prot = PROT_DNSv4; 899 si.host = htonl (c->conf->id); si.port = 0; si.prot = PROT_DNSv4;
814 900
815 vpn->recv_vpn_packet (pkt, si); 901 vpn->recv_vpn_packet (pkt, si);
816
817 delete pkt; 902 delete pkt;
818 } 903 }
819 904
820 // check for further packets 905 // check for further packets
821 goto redo; 906 goto redo;
864 { 949 {
865 // correct class, domain: parse 950 // correct class, domain: parse
866 int client, seqno; 951 int client, seqno;
867 decode_header (qname, client, seqno); 952 decode_header (qname, client, seqno);
868 953
869 u8 data[MAXSIZE];
870 int datalen = cdc62.decode (data, qname + HDRSIZE, qlen - (dlen + 1 + HDRSIZE));
871
872 if (0 < client && client <= conns.size ()) 954 if (0 < client && client <= conns.size ())
873 { 955 {
874 connection *c = conns [client - 1]; 956 connection *c = conns [client - 1];
875 dns_connection *dns = c->dns; 957 dns_connection *dns = c->dns;
876 dns_rcv *rcv; 958 dns_rcv *rcv;
877 959
878 if (dns) 960 if (dns)
879 { 961 {
962 u8 data[MAXSIZE];
963 int datalen = dns->cdc->decode (data, qname + HDRSIZE, qlen - (dlen + 1 + HDRSIZE));
964
880 for (vector<dns_rcv *>::iterator i = dns->rcvpq.end (); i-- != dns->rcvpq.begin (); ) 965 for (vector<dns_rcv *>::iterator i = dns->rcvpq.end (); i-- != dns->rcvpq.begin (); )
881 if (SEQNO_EQ ((*i)->seqno, seqno)) 966 if (SEQNO_EQ ((*i)->seqno, seqno))
882 { 967 {
883 // already seen that request: simply reply with the cached reply 968 // already seen that request: simply reply with the cached reply
884 dns_rcv *r = *i; 969 dns_rcv *r = *i;
985 pkt [offs++] = RR_CLASS_IN >> 8; pkt [offs++] = RR_CLASS_IN; // class 1070 pkt [offs++] = RR_CLASS_IN >> 8; pkt [offs++] = RR_CLASS_IN; // class
986 pkt [offs++] = 0; pkt [offs++] = 0; 1071 pkt [offs++] = 0; pkt [offs++] = 0;
987 pkt [offs++] = 0; pkt [offs++] = cfg.def_ttl; // TTL 1072 pkt [offs++] = 0; pkt [offs++] = cfg.def_ttl; // TTL
988 pkt [offs++] = 0; pkt [offs++] = 4; // rdlength 1073 pkt [offs++] = 0; pkt [offs++] = 4; // rdlength
989 1074
990 slog (L_INFO, _("DNS: client %d connects"), client);
991
992 pkt [offs++] = CMD_IP_1; pkt [offs++] = CMD_IP_2; pkt [offs++] = CMD_IP_3; 1075 pkt [offs++] = CMD_IP_1; pkt [offs++] = CMD_IP_2; pkt [offs++] = CMD_IP_3;
993 pkt [offs++] = CMD_IP_REJ; 1076 pkt [offs++] = CMD_IP_REJ;
994 1077
995 if (0 < client && client <= conns.size ()) 1078 if (0 < client && client <= conns.size ())
996 { 1079 {
997 connection *c = conns [client - 1]; 1080 connection *c = conns [client - 1];
998 1081
999 if (cfg.valid ()) 1082 if (cfg.valid ())
1000 { 1083 {
1001 pkt [offs - 1] = CMD_IP_SYN; 1084 slog (L_INFO, _("DNS: client %d connects (version %d, req_cdc %d)"), client, cfg.version, cfg.req_cdc);
1085
1086 // check for any encoding mismatches - hints at a case problem
1087 char qname2 [MAX_ENC_LEN];
1088 cdc26.encode (qname2, (u8 *)&cfg, sizeof (dns_cfg));
1002 1089
1003 delete c->dns; 1090 delete c->dns;
1091
1092 pkt [offs - 1] = memcmp (qname, qname2, cdc26.encode_len (sizeof (dns_cfg)))
1093 ? CMD_IP_CSE : CMD_IP_SYN;
1094
1004 c->dns = new dns_connection (c); 1095 c->dns = new dns_connection (c);
1005 c->dns->cfg = cfg; 1096 c->dns->cfg = cfg;
1097 c->dns->set_cfg ();
1006 } 1098 }
1007 } 1099 }
1008 } 1100 }
1009 } 1101 }
1010 1102
1081 ttl |= pkt [offs++] << 16; 1173 ttl |= pkt [offs++] << 16;
1082 ttl |= pkt [offs++] << 8; 1174 ttl |= pkt [offs++] << 8;
1083 ttl |= pkt [offs++]; 1175 ttl |= pkt [offs++];
1084 u16 rdlen = pkt [offs++] << 8; rdlen |= pkt [offs++]; 1176 u16 rdlen = pkt [offs++] << 8; rdlen |= pkt [offs++];
1085 1177
1086 if (qtype == RR_TYPE_NULL || qtype == RR_TYPE_TXT) 1178 if (qtype == RR_TYPE_NULL || qtype == RR_TYPE_TXT || qtype == dns->cfg.rrtype)
1087 { 1179 {
1088 if (rdlen <= MAXSIZE - offs) 1180 if (rdlen <= MAXSIZE - offs)
1089 { 1181 {
1090 // decode bytes, finally 1182 // decode bytes, finally
1091 1183
1117 { 1209 {
1118 slog (L_TRACE, _("DNS: got tunnel meta command %02x"), ip [3]); 1210 slog (L_TRACE, _("DNS: got tunnel meta command %02x"), ip [3]);
1119 1211
1120 if (ip [3] == CMD_IP_RST) 1212 if (ip [3] == CMD_IP_RST)
1121 { 1213 {
1122 slog (L_DEBUG, _("DNS: got tunnel RST request")); 1214 slog (L_DEBUG, _("DNS: got tunnel RST request."));
1123 1215
1124 delete dns; c->dns = 0; 1216 dns->reset ();
1125
1126 return; 1217 return;
1127 } 1218 }
1128 else if (ip [3] == CMD_IP_SYN) 1219 else if (ip [3] == CMD_IP_SYN)
1129 { 1220 {
1130 slog (L_DEBUG, _("DNS: got tunnel SYN reply, server likes us.")); 1221 slog (L_DEBUG, _("DNS: got tunnel SYN reply, server likes us."));
1131 dns->established = true; 1222 dns->established = true;
1132 } 1223 }
1224 else if (ip [3] == CMD_IP_CSE)
1225 {
1226 if (conf.dns_case_preserving)
1227 {
1228 slog (L_INFO, _("DNS: got tunnel CSE reply, globally downgrading to case-insensitive protocol."));
1229 conf.dns_case_preserving = false;
1230 dns->reset ();
1231 return;
1232 }
1233 else
1234 {
1235 slog (L_DEBUG, _("DNS: got tunnel CSE reply, server likes us."));
1236 dns->established = true;
1237 }
1238 }
1133 else if (ip [3] == CMD_IP_REJ) 1239 else if (ip [3] == CMD_IP_REJ)
1134 { 1240 {
1135 slog (L_DEBUG, _("DNS: got tunnel REJ reply, server does not like us, aborting.")); 1241 slog (L_ERR, _("DNS: got tunnel REJ reply, server does not like us."));
1136 abort (); 1242 dns->tw.start (60.);
1137 } 1243 }
1138 else 1244 else
1245 {
1139 slog (L_INFO, _("DNS: got unknown meta command %02x"), ip [3]); 1246 slog (L_INFO, _("DNS: got unknown meta command %02x"), ip [3]);
1247 dns->tw.start (60.);
1248 }
1140 } 1249 }
1141 else 1250 else
1142 slog (L_INFO, _("DNS: got spurious a record %d.%d.%d.%d"), 1251 slog (L_INFO, _("DNS: got spurious a record %d.%d.%d.%d"),
1143 ip [0], ip [1], ip [2], ip [3]); 1252 ip [0], ip [1], ip [2], ip [3]);
1144 1253
1206 1315
1207 if (!c->dns) 1316 if (!c->dns)
1208 c->dns = new dns_connection (c); 1317 c->dns = new dns_connection (c);
1209 1318
1210 if (c->dns->snddq.put (pkt)) 1319 if (c->dns->snddq.put (pkt))
1320 {
1321 min_it (c->dns->poll_interval, 0.25);
1211 c->dns->tw (); 1322 c->dns->tw ();
1323 }
1212 1324
1213 // always return true even if the buffer overflows 1325 // always return true even if the buffer overflows
1214 return true; 1326 return true;
1215} 1327}
1216
1217void
1218connection::dnsv4_reset_connection ()
1219{
1220 //delete dns; dns = 0; //TODO
1221}
1222
1223#define NEXT(w) do { if (next > (w)) next = w; } while (0)
1224 1328
1225void 1329void
1226dns_connection::time_cb (ev::timer &w, int revents) 1330dns_connection::time_cb (ev::timer &w, int revents)
1227{ 1331{
1228 // servers have to be polled 1332 // servers have to be polled
1229 if (THISNODE->dns_port) 1333 if (THISNODE->dns_port)
1230 return; 1334 return;
1231 1335
1232 // check for timeouts and (re)transmit 1336 // check for timeouts and (re)transmit
1233 tstamp next = ev::now () + poll_interval; 1337 tstamp next = 86400 * 365;
1234 dns_snd *send = 0; 1338 dns_snd *send = 0;
1235 1339
1236 for (vector<dns_snd *>::iterator i = vpn->dns_sndpq.begin (); 1340 for (vector<dns_snd *>::iterator i = vpn->dns_sndpq.begin ();
1237 i != vpn->dns_sndpq.end (); 1341 i != vpn->dns_sndpq.end ();
1238 ++i) 1342 ++i)
1244 if (!send) 1348 if (!send)
1245 { 1349 {
1246 send = r; 1350 send = r;
1247 1351
1248 r->retry++; 1352 r->retry++;
1249 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;
1250 //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
1251 1355
1252 // the following code changes the query section a bit, forcing 1356 // the following code changes the query section a bit, forcing
1253 // the forwarder to generate a new request 1357 // the forwarder to generate a new request
1254 if (r->stdhdr) 1358 if (r->stdhdr)
1255 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);
1256 } 1360 }
1257 } 1361 }
1258 else 1362 else
1259 NEXT (r->timeout); 1363 min_it (next, r->timeout - ev_now ());
1260 } 1364 }
1261 1365
1262 if (!send) 1366 if (!send)
1263 { 1367 {
1264 // generate a new packet, if wise 1368 // generate a new packet, if wise
1268 if (vpn->dns_sndpq.empty ()) 1372 if (vpn->dns_sndpq.empty ())
1269 { 1373 {
1270 send = new dns_snd (this); 1374 send = new dns_snd (this);
1271 1375
1272 cfg.reset (THISNODE->id); 1376 cfg.reset (THISNODE->id);
1377 set_cfg ();
1273 send->gen_syn_req (); 1378 send->gen_syn_req ();
1274 } 1379 }
1275 } 1380 }
1276 else if (vpn->dns_sndpq.size () < conf.dns_max_outstanding 1381 else if (vpn->dns_sndpq.size () < conf.dns_max_outstanding
1277 && !SEQNO_EQ (rcvseq, sndseq - (MAX_WINDOW - 1))) 1382 && !SEQNO_EQ (rcvseq, sndseq - (MAX_WINDOW - 1)))
1278 { 1383 {
1279 if (last_sent + send_interval <= ev_now ()) 1384 if (last_sent + send_interval <= ev_now ())
1280 { 1385 {
1281 //printf ("sending data request etc.\n"); //D 1386 //printf ("sending data request etc.\n"); //D
1282 if (!snddq.empty () || last_received + 1. > ev_now ()) 1387 if (!snddq.empty ())
1283 {
1284 poll_interval = send_interval; 1388 min_it (next, send_interval);
1285 NEXT (ev_now () + send_interval);
1286 }
1287 1389
1288 send = new dns_snd (this); 1390 send = new dns_snd (this);
1289 send->gen_stream_req (sndseq, snddq); 1391 send->gen_stream_req (sndseq, snddq);
1290 send->timeout = ev_now () + min_latency * conf.dns_timeout_factor; 1392 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 1393 //printf ("SEND %x (%f)\n", send->seqno, send->timeout - ev_now (), min_latency, conf.dns_timeout_factor);//D
1292 1394
1293 sndseq = (sndseq + 1) & SEQNO_MASK; 1395 sndseq = (sndseq + 1) & SEQNO_MASK;
1294 } 1396 }
1295 else 1397 else
1296 NEXT (last_sent + send_interval); 1398 min_it (next, last_sent + send_interval - ev_now ());
1297 } 1399 }
1298 1400
1299 if (send) 1401 if (send)
1300 vpn->dns_sndpq.push_back (send); 1402 vpn->dns_sndpq.push_back (send);
1301 } 1403 }
1306 sendto (vpn->dnsv4_fd, 1408 sendto (vpn->dnsv4_fd,
1307 send->pkt->at (0), send->pkt->len, 0, 1409 send->pkt->at (0), send->pkt->len, 0,
1308 vpn->dns_forwarder.sav4 (), vpn->dns_forwarder.salenv4 ()); 1410 vpn->dns_forwarder.sav4 (), vpn->dns_forwarder.salenv4 ());
1309 } 1411 }
1310 1412
1413 min_it (next, last_sent + max (poll_interval, send_interval) - ev_now ());
1414
1311 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)",
1312 poll_interval, send_interval, next - ev_now (), 1416 poll_interval, send_interval, next - ev_now (),
1313 vpn->dns_sndpq.size (), snddq.size (), 1417 vpn->dns_sndpq.size (), snddq.size (),
1314 rcvpq.size ()); 1418 rcvpq.size ());
1315 1419
1316 // TODO: no idea when this happens, but when next < ev_now (), we have a problem 1420 w.start (next);
1317 // doesn't seem to happen anymore
1318 if (next < ev_now () + 0.001)
1319 next = ev_now () + 0.1;
1320
1321 w.start (next - ev_now ());
1322} 1421}
1323 1422
1324#endif 1423#endif
1325 1424

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines