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.9 by pcg, Fri Mar 4 04:52:38 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_RETRY 1. 64#define MAX_POLL_INTERVAL 5. // how often to poll minimally when the server has no data
49#define MAX_RETRY 6. 65#define ACTIVITY_INTERVAL 5.
50 66
51#define MAX_OUTSTANDING 400 // max. outstanding requests 67#define INITIAL_TIMEOUT 0.1 // retry timeouts
68#define INITIAL_SYN_TIMEOUT 2. // retry timeout for initial syn
69
70#define MAX_SEND_INTERVAL 2. // optimistic?
71
52#define MAX_WINDOW 1000 // max. for MAX_OUTSTANDING 72#define MAX_WINDOW 1000 // max. for MAX_OUTSTANDING, and backlog
53#define MAX_RATE 100 // requests/s
54#define MAX_BACKLOG (10*1024) // size of protocol backlog, must be > MAXSIZE 73#define MAX_BACKLOG (64*1024) // size of gvpe protocol backlog (bytes), must be > MAXSIZE
55 74
56#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
57// 240 leaves about 4 bytes of server reply data 76// 240 leaves about 4 bytes of server reply data
58// every two request byte sless give room for one reply byte 77// every request byte less give room for two reply bytes
59 78
60#define SEQNO_MASK 0xffff 79#define SEQNO_MASK 0x3fff
61#define SEQNO_EQ(a,b) ( 0 == ( ((a) ^ (b)) & SEQNO_MASK) ) 80#define SEQNO_EQ(a,b) ( 0 == ( ((a) ^ (b)) & SEQNO_MASK) )
62 81
63#define MAX_LBL_SIZE 63 82#define MAX_LBL_SIZE 63
64#define MAX_PKT_SIZE 512 83#define MAX_PKT_SIZE 512
65 84
85#define RR_TYPE_A 1
86#define RR_TYPE_NULL 10
66#define RR_TYPE_TXT 16 87#define RR_TYPE_TXT 16
67#define RR_TYPE_ANY 255 88#define RR_TYPE_ANY 255
89
68#define RR_CLASS_IN 1 90#define RR_CLASS_IN 1
91
92#define CMD_IP_1 207
93#define CMD_IP_2 46
94#define CMD_IP_3 236
95#define CMD_IP_RST 29
96#define CMD_IP_SYN 113
97#define CMD_IP_REJ 32
69 98
70// works for cmaps up to 255 (not 256!) 99// works for cmaps up to 255 (not 256!)
71struct charmap 100struct charmap
72{ 101{
73 enum { INVALID = (u8)255 }; 102 enum { INVALID = (u8)255 };
153 return dec_len [len]; 182 return dec_len [len];
154} 183}
155 184
156unsigned int basecoder::encode (char *dst, u8 *src, unsigned int len) 185unsigned int basecoder::encode (char *dst, u8 *src, unsigned int len)
157{ 186{
158 if (!len) 187 if (!len || len > MAX_DEC_LEN)
159 return 0; 188 return 0;
160 189
161 int elen = encode_len (len); 190 int elen = encode_len (len);
162 191
163 mp_limb_t m [MAX_LIMBS]; 192 mp_limb_t m [MAX_LIMBS];
182 return elen; 211 return elen;
183} 212}
184 213
185unsigned int basecoder::decode (u8 *dst, char *src, unsigned int len) 214unsigned int basecoder::decode (u8 *dst, char *src, unsigned int len)
186{ 215{
187 if (!len) 216 if (!len || len > MAX_ENC_LEN)
188 return 0; 217 return 0;
189 218
190 u8 src_ [MAX_ENC_LEN]; 219 u8 src_ [MAX_ENC_LEN];
191 unsigned int elen = 0; 220 unsigned int elen = 0;
192 221
239 } 268 }
240 abort (); 269 abort ();
241} 270}
242#endif 271#endif
243 272
244// the following sequence has been crafted to 273//static basecoder cdc64 ("_dDpPhHzZrR06QqMmjJkKBb34TtSsvVlL81xXaAeEFf92WwGgYyoO57UucCNniI-");
245// a) look somewhat random
246// b) the even (and odd) indices never share the same character as upper/lowercase
247// the "_" is not valid but widely accepted (all octets should be supported, but let's be conservative)
248// the other sequences are obviously derived
249//static basecoder cdc63 ("_dDpPhHzZrR06QqMmjJkKBb34TtSsvVlL81xXaAeEFf92WwGgYyoO57UucCNniI"); 274//static basecoder cdc63 ("_dDpPhHzZrR06QqMmjJkKBb34TtSsvVlL81xXaAeEFf92WwGgYyoO57UucCNniI");
250static basecoder cdc62 ("dDpPhHzZrR06QqMmjJkKBb34TtSsvVlL81xXaAeEFf92WwGgYyoO57UucCNniI"); 275static basecoder cdc62 ("dDpPhHzZrR06QqMmjJkKBb34TtSsvVlL81xXaAeEFf92WwGgYyoO57UucCNniI");
251//static basecoder cdc36 ("dphzr06qmjkb34tsvl81xaef92wgyo57ucni"); // unused as of yet 276//static basecoder cdc36 ("dphzr06qmjkb34tsvl81xaef92wgyo57ucni"); // unused as of yet
252static basecoder cdc26 ("dPhZrQmJkBtSvLxAeFwGyO"); 277static basecoder cdc26 ("dPhZrQmJkBtSvLxAeFwGyO");
253 278
254///////////////////////////////////////////////////////////////////////////// 279/////////////////////////////////////////////////////////////////////////////
255 280
256#define HDRSIZE 6 281#define HDRSIZE 6
257 282
258inline void encode_header (char *data, int clientid, int seqno) 283inline void encode_header (char *data, int clientid, int seqno, int retry = 0)
259{ 284{
260 u8 hdr[3] = { clientid, seqno >> 8, seqno }; 285 seqno &= SEQNO_MASK;
286
287 u8 hdr[3] = {
288 clientid,
289 (seqno >> 8) | (retry << 6),
290 seqno,
291 };
261 292
262 assert (clientid < 256); 293 assert (clientid < 256);
263 294
264 cdc26.encode (data, hdr, 3); 295 cdc26.encode (data, hdr, 3);
265} 296}
269 u8 hdr[3]; 300 u8 hdr[3];
270 301
271 cdc26.decode (hdr, data, HDRSIZE); 302 cdc26.decode (hdr, data, HDRSIZE);
272 303
273 clientid = hdr[0]; 304 clientid = hdr[0];
274 seqno = (hdr[1] << 8) | hdr[2]; 305 seqno = ((hdr[1] << 8) | hdr[2]) & SEQNO_MASK;
275} 306}
276 307
277///////////////////////////////////////////////////////////////////////////// 308/////////////////////////////////////////////////////////////////////////////
278 309
279struct byte_stream 310struct byte_stream
308} 339}
309 340
310void byte_stream::remove (int count) 341void byte_stream::remove (int count)
311{ 342{
312 if (count > fill) 343 if (count > fill)
313 abort (); 344 assert (count <= fill);
314 345
315 memmove (data, data + count, fill -= count); 346 memmove (data, data + count, fill -= count);
316} 347}
317 348
318bool byte_stream::put (u8 *data, unsigned int datalen) 349bool byte_stream::put (u8 *data, unsigned int datalen)
331 return false; 362 return false;
332 363
333 data [fill++] = pkt->len >> 8; 364 data [fill++] = pkt->len >> 8;
334 data [fill++] = pkt->len; 365 data [fill++] = pkt->len;
335 366
336 memcpy (data + fill, &((*pkt)[0]), pkt->len); fill += pkt->len; 367 memcpy (data + fill, pkt->at (0), pkt->len); fill += pkt->len;
337 368
338 return true; 369 return true;
339} 370}
340 371
341vpn_packet *byte_stream::get () 372vpn_packet *byte_stream::get ()
342{ 373{
374 unsigned int len;
375
376 for (;;)
377 {
343 int len = (data [0] << 8) | data [1]; 378 len = (data [0] << 8) | data [1];
344 379
345 if (len > MAXSIZE && fill >= 2) 380 if (len <= MAXSIZE || fill < 2)
346 abort (); // TODO handle this gracefully, connection reset 381 break;
347 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
348 if (fill < len + 2) 388 if (fill < len + 2)
349 return 0; 389 return 0;
350 390
351 vpn_packet *pkt = new vpn_packet; 391 vpn_packet *pkt = new vpn_packet;
352 392
353 pkt->len = len; 393 pkt->len = len;
354 memcpy (&((*pkt)[0]), data + 2, len); 394 memcpy (pkt->at (0), data + 2, len);
355 remove (len + 2); 395 remove (len + 2);
356 396
357 return pkt; 397 return pkt;
358} 398}
359 399
376#define FLAG_RCODE_REFUSED ( 5 << 0) 416#define FLAG_RCODE_REFUSED ( 5 << 0)
377 417
378#define DEFAULT_CLIENT_FLAGS (FLAG_QUERY | FLAG_OP_QUERY | FLAG_RD) 418#define DEFAULT_CLIENT_FLAGS (FLAG_QUERY | FLAG_OP_QUERY | FLAG_RD)
379#define DEFAULT_SERVER_FLAGS (FLAG_RESPONSE | FLAG_OP_QUERY | FLAG_AA | FLAG_RD | FLAG_RA) 419#define DEFAULT_SERVER_FLAGS (FLAG_RESPONSE | FLAG_OP_QUERY | FLAG_AA | FLAG_RD | FLAG_RA)
380 420
421struct dns_cfg
422{
423 static int next_uid;
424
425 u8 id1, id2, id3, id4;
426
427 u8 version;
428 u8 flags;
429 u8 rrtype;
430 u8 def_ttl;
431
432 u16 client;
433 u16 uid; // to make request unique
434
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;
444
445 void reset (int clientid);
446 bool valid ();
447};
448
449int dns_cfg::next_uid;
450
451void dns_cfg::reset (int clientid)
452{
453 id1 = 'G';
454 id2 = 'V';
455 id3 = 'P';
456 id4 = 'E';
457
458 version = 1;
459
460 rrtype = RR_TYPE_TXT;
461 flags = 0;
462 def_ttl = 0;
463 seq_cdc = 26;
464 req_cdc = 62;
465 rep_cdc = 0;
466 max_size = htons (MAX_PKT_SIZE);
467 client = htons (clientid);
468 uid = next_uid++;
469 delay = 0;
470
471 r3 = r4 = 0;
472 r4 = r5 = r6 = r7 = 0;
473}
474
475bool dns_cfg::valid ()
476{
477 // although the protocol itself allows for some configurability,
478 // only the following encoding/decoding settings are implemented.
479 return id1 == 'G'
480 && id2 == 'V'
481 && id3 == 'P'
482 && id4 == 'E'
483 && seq_cdc == 26
484 && req_cdc == 62
485 && rep_cdc == 0
486 && version == 1;
487}
488
381struct dns_packet : net_packet 489struct dns_packet : net_packet
382{ 490{
383 u16 id; 491 u16 id;
384 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
385 u16 qdcount, ancount, nscount, arcount; 493 u16 qdcount, ancount, nscount, arcount;
386 494
387 u8 data[MAXSIZE - 6 * 2]; 495 u8 data [MAXSIZE - 6 * 2];
388 496
389 int decode_label (char *data, int size, int &offs); 497 int decode_label (char *data, int size, int &offs);
390}; 498};
391 499
392int dns_packet::decode_label (char *data, int size, int &offs) 500int dns_packet::decode_label (char *data, int size, int &offs)
423 return data - orig; 531 return data - orig;
424} 532}
425 533
426///////////////////////////////////////////////////////////////////////////// 534/////////////////////////////////////////////////////////////////////////////
427 535
428struct dns_req
429{
430 dns_packet *pkt;
431 tstamp next;
432 int retry;
433 struct dns_connection *dns;
434 int seqno;
435
436 dns_req (dns_connection *dns);
437 void gen_stream_req (int seqno, byte_stream &stream);
438};
439
440static u16 dns_id = 12098; // TODO: should be per-vpn 536static u16 dns_id = 0; // TODO: should be per-vpn
441 537
442static u16 next_id () 538static u16 next_id ()
443{ 539{
540 if (!dns_id)
541 dns_id = time (0);
542
444 // the simplest lsfr with periodicity 65535 i could find 543 // the simplest lsfr with periodicity 65535 i could find
445 dns_id = (dns_id << 1) 544 dns_id = (dns_id << 1)
446 | (((dns_id >> 1) 545 | (((dns_id >> 1)
447 ^ (dns_id >> 2) 546 ^ (dns_id >> 2)
448 ^ (dns_id >> 4) 547 ^ (dns_id >> 4)
449 ^ (dns_id >> 15)) & 1); 548 ^ (dns_id >> 15)) & 1);
450 549
451 return dns_id; 550 return dns_id;
452} 551}
453 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
582struct dns_snd
583{
584 dns_packet *pkt;
585 tstamp timeout, sent;
586 int retry;
587 struct dns_connection *dns;
588 int seqno;
589 bool stdhdr;
590
591 void gen_stream_req (int seqno, byte_stream &stream);
592 void gen_syn_req ();
593
594 dns_snd (dns_connection *dns);
595 ~dns_snd ();
596};
597
454dns_req::dns_req (dns_connection *dns) 598dns_snd::dns_snd (dns_connection *dns)
455: dns (dns) 599: dns (dns)
456{ 600{
457 next = 0; 601 timeout = 0;
458 retry = 0; 602 retry = 0;
603 seqno = 0;
604 sent = ev_now ();
605 stdhdr = false;
459 606
460 pkt = new dns_packet; 607 pkt = new dns_packet;
461 608
462 pkt->id = next_id (); 609 pkt->id = next_id ();
463} 610}
464 611
612dns_snd::~dns_snd ()
613{
614 delete pkt;
615}
616
617static void append_domain (dns_packet &pkt, int &offs, const char *domain)
618{
619 // add tunnel domain
620 for (;;)
621 {
622 const char *end = strchr (domain, '.');
623
624 if (!end)
625 end = domain + strlen (domain);
626
627 int len = end - domain;
628
629 pkt [offs++] = len;
630 memcpy (pkt.at (offs), domain, len);
631 offs += len;
632
633 if (!*end)
634 break;
635
636 domain = end + 1;
637 }
638}
639
465void dns_req::gen_stream_req (int seqno, byte_stream &stream) 640void dns_snd::gen_stream_req (int seqno, byte_stream &stream)
466{ 641{
642 stdhdr = true;
467 this->seqno = seqno; 643 this->seqno = seqno;
644
645 timeout = ev_now () + INITIAL_TIMEOUT;
468 646
469 pkt->flags = htons (DEFAULT_CLIENT_FLAGS); 647 pkt->flags = htons (DEFAULT_CLIENT_FLAGS);
470 pkt->qdcount = htons (1); 648 pkt->qdcount = htons (1);
471 649
472 int offs = 6*2; 650 int offs = 6*2;
473 int dlen = MAX_DOMAIN_SIZE - (strlen (THISNODE->domain) + 2); 651 int dlen = MAX_DOMAIN_SIZE - (strlen (dns->c->conf->domain) + 2);
474 // 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,
475 // 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
476 654
477 char enc[256], *encp = enc; 655 char enc[256], *encp = enc;
478 encode_header (enc, THISNODE->id, seqno); 656 encode_header (enc, THISNODE->id, seqno);
496 encp += lbllen; 674 encp += lbllen;
497 675
498 enclen -= lbllen; 676 enclen -= lbllen;
499 } 677 }
500 678
501 const char *suffix = THISNODE->domain; 679 append_domain (*pkt, offs, dns->c->conf->domain);
502
503 // add tunnel domain
504 for (;;)
505 {
506 const char *end = strchr (suffix, '.');
507
508 if (!end)
509 end = suffix + strlen (suffix);
510
511 int len = end - suffix;
512
513 (*pkt)[offs++] = len;
514 memcpy (&((*pkt)[offs]), suffix, len);
515 offs += len;
516
517 if (!*end)
518 break;
519
520 suffix = end + 1;
521 }
522 680
523 (*pkt)[offs++] = 0; 681 (*pkt)[offs++] = 0;
524 (*pkt)[offs++] = RR_TYPE_ANY >> 8; (*pkt)[offs++] = RR_TYPE_ANY; 682 (*pkt)[offs++] = RR_TYPE_ANY >> 8; (*pkt)[offs++] = RR_TYPE_ANY;
683 (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN;
684
685 pkt->len = offs;
686}
687
688void dns_snd::gen_syn_req ()
689{
690 timeout = ev_now () + INITIAL_SYN_TIMEOUT;
691
692 pkt->flags = htons (DEFAULT_CLIENT_FLAGS);
693 pkt->qdcount = htons (1);
694
695 int offs = 6 * 2;
696
697 int elen = cdc26.encode ((char *)pkt->at (offs + 1), (u8 *)&dns->cfg, sizeof (dns_cfg));
698
699 assert (elen <= MAX_LBL_SIZE);
700
701 (*pkt)[offs] = elen;
702 offs += elen + 1;
703 append_domain (*pkt, offs, dns->c->conf->domain);
704
705 (*pkt)[offs++] = 0;
706 (*pkt)[offs++] = RR_TYPE_A >> 8; (*pkt)[offs++] = RR_TYPE_A;
525 (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN; 707 (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN;
526 708
527 pkt->len = offs; 709 pkt->len = offs;
528} 710}
529 711
549 delete pkt; 731 delete pkt;
550} 732}
551 733
552///////////////////////////////////////////////////////////////////////////// 734/////////////////////////////////////////////////////////////////////////////
553 735
554struct dns_connection
555{
556 connection *c;
557 struct vpn *vpn;
558
559 vector<dns_rcv *> rcvpq;
560
561 int rcvseq;
562 int sndseq;
563
564 byte_stream rcvdq;
565 byte_stream snddq;
566
567 void time_cb (time_watcher &w); time_watcher tw;
568 void receive_rep (dns_rcv *r);
569
570 dns_connection (connection *c);
571 ~dns_connection ();
572};
573
574dns_connection::dns_connection (connection *c) 736dns_connection::dns_connection (connection *c)
575: c (c) 737: c (c)
576, rcvdq (MAX_BACKLOG * 2) 738, rcvdq (MAX_BACKLOG * 2)
577, snddq (MAX_BACKLOG * 2) 739, snddq (MAX_BACKLOG)
578, tw (this, &dns_connection::time_cb)
579{ 740{
741 tw.set<dns_connection, &dns_connection::time_cb> (this);
742
580 vpn = c->vpn; 743 vpn = c->vpn;
581 744
745 established = false;
746
582 rcvseq = sndseq = 0; 747 rcvseq = repseq = sndseq = 0;
748
749 last_sent = last_received = 0;
750 poll_interval = 0.5; // starting here
751 send_interval = 0.5; // starting rate
752 min_latency = INITIAL_TIMEOUT;
583} 753}
584 754
585dns_connection::~dns_connection () 755dns_connection::~dns_connection ()
586{ 756{
587 for (vector<dns_rcv *>::iterator i = rcvpq.begin (); 757 for (vector<dns_rcv *>::iterator i = rcvpq.begin ();
588 i != rcvpq.end (); 758 i != rcvpq.end ();
589 ++i) 759 ++i)
590 delete *i; 760 delete *i;
591} 761}
592 762
593struct dns_cfg
594{
595 u8 id1, id2, id3;
596 u8 def_ttl;
597 u8 unused1;
598 u16 max_size;
599 u8 flags1, flags2;
600};
601
602void dns_connection::receive_rep (dns_rcv *r) 763void dns_connection::receive_rep (dns_rcv *r)
603{ 764{
765 if (r->datalen)
766 {
767 last_received = ev_now ();
768 tw ();
769
770 poll_interval = send_interval;
771 }
772 else
773 {
774 poll_interval *= 1.5;
775
776 if (poll_interval > MAX_POLL_INTERVAL)
777 poll_interval = MAX_POLL_INTERVAL;
778 }
779
604 rcvpq.push_back (r); 780 rcvpq.push_back (r);
605 781
606 redo: 782 redo:
607 783
608 // find next packet 784 // find next packet
609 for (vector<dns_rcv *>::iterator i = rcvpq.end (); i-- != rcvpq.begin (); ) 785 for (vector<dns_rcv *>::iterator i = rcvpq.end (); i-- != rcvpq.begin (); )
610 if (SEQNO_EQ (rcvseq, (*i)->seqno)) 786 if (SEQNO_EQ (rcvseq, (*i)->seqno))
611 { 787 {
788 //printf ("seqno eq %x %x\n", rcvseq, (*i)->seqno);//D
612 // enter the packet into our input stream 789 // enter the packet into our input stream
613 r = *i; 790 r = *i;
614 791
615 // remove the oldest packet, look forward, as it's oldest first 792 // remove the oldest packet, look forward, as it's oldest first
616 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)
617 if (SEQNO_EQ ((*j)->seqno, rcvseq - MAX_WINDOW)) 794 if (SEQNO_EQ ((*j)->seqno, rcvseq - MAX_WINDOW))
618 { 795 {
796 //printf ("seqno RR %x %x\n", (*j)->seqno, rcvseq - MAX_WINDOW);//D
619 delete *j; 797 delete *j;
620 rcvpq.erase (j); 798 rcvpq.erase (j);
621 break; 799 break;
622 } 800 }
623 801
624 rcvseq = (rcvseq + 1) & SEQNO_MASK; 802 rcvseq = (rcvseq + 1) & SEQNO_MASK;
625 803
626 if (!rcvdq.put (r->data, r->datalen)) 804 if (!rcvdq.put (r->data, r->datalen))
805 {
806 slog (L_ERR, "DNS: !rcvdq.put (r->data, r->datalen)");
627 abort (); // MUST never overflow, can be caused by data corruption, TODO 807 abort (); // MUST never overflow, can be caused by data corruption, TODO
808 }
628 809
629 while (vpn_packet *pkt = rcvdq.get ()) 810 while (vpn_packet *pkt = rcvdq.get ())
630 { 811 {
631 sockinfo si; 812 sockinfo si;
632 si.host = 0; si.port = 0; si.prot = PROT_DNSv4; 813 si.host = htonl (c->conf->id); si.port = 0; si.prot = PROT_DNSv4;
633 814
634 vpn->recv_vpn_packet (pkt, si); 815 vpn->recv_vpn_packet (pkt, si);
816
817 delete pkt;
635 } 818 }
636 819
637 // check for further packets 820 // check for further packets
638 goto redo; 821 goto redo;
639 } 822 }
640} 823}
641 824
642dns_packet * 825void
643vpn::dnsv4_server (dns_packet *pkt) 826vpn::dnsv4_server (dns_packet &pkt)
644{ 827{
645 u16 flags = ntohs (pkt->flags); 828 u16 flags = ntohs (pkt.flags);
646 829
647 //memcpy (&((*rep)[0]), &((*pkt)[0]), pkt->len);
648 int offs = 6 * 2; // skip header 830 int offs = 6 * 2; // skip header
649 831
650 pkt->flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR); 832 pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR);
651 833
652 if (0 == (flags & (FLAG_RESPONSE | FLAG_OP_MASK | FLAG_TC)) 834 if (0 == (flags & (FLAG_RESPONSE | FLAG_OP_MASK))
653 && pkt->qdcount == htons (1)) 835 && pkt.qdcount == htons (1))
654 { 836 {
655 char qname[MAXSIZE]; 837 char qname [MAXSIZE];
656 int qlen = pkt->decode_label ((char *)qname, MAXSIZE - offs, offs); 838 int qlen = pkt.decode_label ((char *)qname, MAXSIZE - offs, offs);
657 839
658 u16 qtype = (*pkt) [offs++] << 8; qtype |= (*pkt) [offs++]; 840 u16 qtype = pkt [offs++] << 8; qtype |= pkt [offs++];
659 u16 qclass = (*pkt) [offs++] << 8; qclass |= (*pkt) [offs++]; 841 u16 qclass = pkt [offs++] << 8; qclass |= pkt [offs++];
660 842
661 pkt->qdcount = htons (1); 843 pkt.qdcount = htons (1);
662 pkt->ancount = 0; 844 pkt.ancount = 0;
663 pkt->nscount = 0; // should be self, as other nameservers reply like this 845 pkt.nscount = 0; // should be self, as other nameservers reply like this
664 pkt->arcount = 0; // a record for self, as other nameservers reply like this 846 pkt.arcount = 0; // a record for self, as other nameservers reply like this
665 847
666 pkt->flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_NXDOMAIN); 848 pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_SERVFAIL);
667 849
668 int dlen = strlen (THISNODE->domain); 850 int dlen = strlen (THISNODE->domain);
669 851
670 if (qclass == RR_CLASS_IN 852 if (qclass == RR_CLASS_IN
671 && (qtype == RR_TYPE_ANY || qtype == RR_TYPE_TXT)
672 && qlen > dlen + 1 + HDRSIZE 853 && qlen > dlen + 1
673 && !memcmp (qname + qlen - dlen - 1, THISNODE->domain, dlen)) 854 && !memcmp (qname + qlen - (dlen + 1), THISNODE->domain, dlen))
674 { 855 {
675 // correct class, domain: parse 856 // now generate reply
676 int client, seqno; 857 pkt.ancount = htons (1); // one answer RR
677 decode_header (qname, client, seqno); 858 pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_OK);
678 859
679 u8 data[MAXSIZE]; 860 if ((qtype == RR_TYPE_ANY
680 int datalen = cdc62.decode (data, qname + HDRSIZE, qlen - (dlen + 1 + HDRSIZE)); 861 || qtype == RR_TYPE_TXT
681 862 || qtype == RR_TYPE_NULL)
682 if (0 < client && client <= conns.size ()) 863 && qlen > dlen + 1 + HDRSIZE)
683 { 864 {
865 // correct class, domain: parse
866 int client, seqno;
867 decode_header (qname, client, seqno);
868
869 u8 data[MAXSIZE];
870 int datalen = cdc62.decode (data, qname + HDRSIZE, qlen - (dlen + 1 + HDRSIZE));
871
872 if (0 < client && client <= conns.size ())
873 {
684 connection *c = conns [client - 1]; 874 connection *c = conns [client - 1];
685
686 if (!c->dns)
687 c->dns = new dns_connection (c);
688
689 dns_connection *dns = c->dns; 875 dns_connection *dns = c->dns;
876 dns_rcv *rcv;
690 877
878 if (dns)
879 {
691 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 (); )
692 if (SEQNO_EQ ((*i)->seqno, seqno)) 881 if (SEQNO_EQ ((*i)->seqno, seqno))
882 {
883 // already seen that request: simply reply with the cached reply
884 dns_rcv *r = *i;
885
886 slog (L_DEBUG, "DNS: duplicate packet received ID %d, SEQ %d", htons (r->pkt->id), seqno);
887
888 // refresh header & id, as the retry count could have changed
889 memcpy (r->pkt->at (6 * 2 + 1), pkt.at (6 * 2 + 1), HDRSIZE);
890 r->pkt->id = pkt.id;
891
892 memcpy (pkt.at (0), r->pkt->at (0), offs = r->pkt->len);
893
894 goto duplicate_request;
895 }
896
897 // new packet, queue
898 rcv = new dns_rcv (seqno, data, datalen);
899 dns->receive_rep (rcv);
900 }
901
693 { 902 {
694 // already seen that request: simply reply with the cached reply 903 pkt [offs++] = 0xc0; pkt [offs++] = 6 * 2; // refer to name in query section
695 dns_rcv *r = *i;
696 904
697 printf ("DUPLICATE %d\n", htons (r->pkt->id));//D 905 int rtype = dns ? dns->cfg.rrtype : RR_TYPE_A;
906 pkt [offs++] = rtype >> 8; pkt [offs++] = rtype; // type
907 pkt [offs++] = RR_CLASS_IN >> 8; pkt [offs++] = RR_CLASS_IN; // class
908 pkt [offs++] = 0; pkt [offs++] = 0;
909 pkt [offs++] = 0; pkt [offs++] = dns ? dns->cfg.def_ttl : 0; // TTL
698 910
699 memcpy (pkt->at (0), r->pkt->at (0), offs = r->pkt->len); 911 int rdlen_offs = offs += 2;
700 pkt->id = r->pkt->id; 912
701 goto duplicate_request; 913 if (dns)
914 {
915 int dlen = ntohs (dns->cfg.max_size) - offs;
916
917 // bind doesn't compress well, so reduce further by one label length
918 dlen -= qlen;
919
920 // only put data into in-order sequence packets, if
921 // we receive out-of-order packets we generate empty
922 // replies
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)
925 {
926 dns->repseq = seqno;
927
928 while (dlen > 1 && !dns->snddq.empty ())
929 {
930 int txtlen = dlen <= 255 ? dlen - 1 : 255;
931
932 if (txtlen > dns->snddq.size ())
933 txtlen = dns->snddq.size ();
934
935 pkt[offs++] = txtlen;
936 memcpy (pkt.at (offs), dns->snddq.begin (), txtlen);
937 offs += txtlen;
938 dns->snddq.remove (txtlen);
939
940 dlen -= txtlen + 1;
941 }
942 }
943
944 // avoid completely empty TXT rdata
945 if (offs == rdlen_offs)
946 pkt[offs++] = 0;
947
948 slog (L_NOISE, "DNS: snddq %d", dns->snddq.size ());
949 }
950 else
951 {
952 // send RST
953 pkt [offs++] = CMD_IP_1; pkt [offs++] = CMD_IP_2; pkt [offs++] = CMD_IP_3;
954 pkt [offs++] = CMD_IP_RST;
955 }
956
957 int rdlen = offs - rdlen_offs;
958
959 pkt [rdlen_offs - 2] = rdlen >> 8;
960 pkt [rdlen_offs - 1] = rdlen;
961
962 if (dns)
963 {
964 // now update dns_rcv copy
965 rcv->pkt->len = offs;
966 memcpy (rcv->pkt->at (0), pkt.at (0), offs);
967 }
702 } 968 }
703 969
704 // new packet, queue 970 duplicate_request: ;
705 dns_rcv *rcv = new dns_rcv (seqno, data, datalen); 971 }
706 dns->receive_rep (rcv); 972 else
707
708 // now generate reply
709 pkt->ancount = htons (1); // one answer RR
710 pkt->flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_OK); 973 pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR);
974 }
975 else if (qtype == RR_TYPE_A
976 && qlen > dlen + 1 + cdc26.encode_len (sizeof (dns_cfg)))
977 {
978 dns_cfg cfg;
979 cdc26.decode ((u8 *)&cfg, qname, cdc26.encode_len (sizeof (dns_cfg)));
980 int client = ntohs (cfg.client);
711 981
712 (*pkt) [offs++] = 0xc0;
713 (*pkt) [offs++] = 6 * 2; // same as in query section 982 pkt [offs++] = 0xc0; pkt [offs++] = 6 * 2; // refer to name in query section
714 983
715 (*pkt) [offs++] = RR_TYPE_TXT >> 8; (*pkt) [offs++] = RR_TYPE_TXT; 984 pkt [offs++] = RR_TYPE_A >> 8; pkt [offs++] = RR_TYPE_A; // type
716 (*pkt) [offs++] = RR_CLASS_IN >> 8; (*pkt) [offs++] = RR_CLASS_IN; 985 pkt [offs++] = RR_CLASS_IN >> 8; pkt [offs++] = RR_CLASS_IN; // class
717
718 (*pkt) [offs++] = 0; (*pkt) [offs++] = 0; 986 pkt [offs++] = 0; pkt [offs++] = 0;
719 (*pkt) [offs++] = 0; (*pkt) [offs++] = 0; // TTL 987 pkt [offs++] = 0; pkt [offs++] = cfg.def_ttl; // TTL
988 pkt [offs++] = 0; pkt [offs++] = 4; // rdlength
720 989
721 int dlen = MAX_PKT_SIZE - offs - 2; 990 slog (L_INFO, _("DNS: client %d connects"), client);
722 991
723 // bind doesn't compress well, so reduce further by one label length 992 pkt [offs++] = CMD_IP_1; pkt [offs++] = CMD_IP_2; pkt [offs++] = CMD_IP_3;
724 dlen -= qlen; 993 pkt [offs++] = CMD_IP_REJ;
725 994
726 int rdlen_offs = offs += 2; 995 if (0 < client && client <= conns.size ())
727
728 while (dlen > 1 && !dns->snddq.empty ())
729 { 996 {
730 int txtlen = dlen <= 255 ? dlen - 1 : 255; 997 connection *c = conns [client - 1];
731 998
732 if (txtlen > dns->snddq.size ()) 999 if (cfg.valid ())
733 txtlen = dns->snddq.size (); 1000 {
1001 pkt [offs - 1] = CMD_IP_SYN;
734 1002
735 (*pkt)[offs++] = txtlen; 1003 delete c->dns;
736 memcpy (pkt->at (offs), dns->snddq.begin (), txtlen); 1004 c->dns = new dns_connection (c);
737 offs += txtlen; 1005 c->dns->cfg = cfg;
738 dns->snddq.remove (txtlen); 1006 }
739
740 dlen -= txtlen + 1;
741 } 1007 }
742
743 // avoid empty TXT rdata
744 if (offs == rdlen_offs)
745 (*pkt)[offs++] = 0;
746
747 int rdlen = offs - rdlen_offs;
748
749 (*pkt) [rdlen_offs - 2] = rdlen >> 8;
750 (*pkt) [rdlen_offs - 1] = rdlen;
751
752 // now update dns_rcv copy
753 rcv->pkt->len = offs;
754 memcpy (rcv->pkt->at (0), pkt->at (0), offs);
755
756 duplicate_request: ;
757 } 1008 }
758 else
759 pkt->flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR);
760 } 1009 }
761 1010
762 pkt->len = offs; 1011 pkt.len = offs;
763 } 1012 }
764
765 return pkt;
766} 1013}
767 1014
768void 1015void
769vpn::dnsv4_client (dns_packet *pkt) 1016vpn::dnsv4_client (dns_packet &pkt)
770{ 1017{
771 u16 flags = ntohs (pkt->flags); 1018 u16 flags = ntohs (pkt.flags);
772 int offs = 6 * 2; // skip header 1019 int offs = 6 * 2; // skip header
773 1020
774 pkt->qdcount = ntohs (pkt->qdcount); 1021 pkt.qdcount = ntohs (pkt.qdcount);
775 pkt->ancount = ntohs (pkt->ancount); 1022 pkt.ancount = ntohs (pkt.ancount);
776 1023
777 // go through our request list and find the corresponding request 1024 // go through our request list and find the corresponding request
778 for (vector<dns_req *>::iterator i = dns_sndpq.begin (); 1025 for (vector<dns_snd *>::iterator i = dns_sndpq.begin ();
779 i != dns_sndpq.end (); 1026 i != dns_sndpq.end ();
780 ++i) 1027 ++i)
781 if ((*i)->pkt->id == pkt->id) 1028 if ((*i)->pkt->id == pkt.id)
782 { 1029 {
783 dns_connection *dns = (*i)->dns; 1030 dns_connection *dns = (*i)->dns;
1031 connection *c = dns->c;
784 int seqno = (*i)->seqno; 1032 int seqno = (*i)->seqno;
785 u8 data[MAXSIZE], *datap = data; 1033 u8 data[MAXSIZE], *datap = data;
1034 //printf ("rcv pkt %x\n", seqno);//D
1035
1036 if ((*i)->retry)
1037 {
1038 dns->send_interval *= 1.01;
1039 if (dns->send_interval > MAX_SEND_INTERVAL)
1040 dns->send_interval = MAX_SEND_INTERVAL;
1041 }
1042 else
1043 {
1044#if 0
1045 dns->send_interval *= 0.999;
1046#endif
1047 // the latency surely puts an upper bound on
1048 // the minimum send interval
1049 double latency = ev_now () - (*i)->sent;
1050
1051 if (latency < dns->min_latency)
1052 dns->min_latency = latency;
1053
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)
1058 dns->send_interval = conf.dns_send_interval;
1059 }
786 1060
787 delete *i; 1061 delete *i;
788 dns_sndpq.erase (i); 1062 dns_sndpq.erase (i);
789 1063
790 if (flags & FLAG_RESPONSE && !(flags & (FLAG_OP_MASK | FLAG_TC))) 1064 if (flags & FLAG_RESPONSE && !(flags & FLAG_OP_MASK))
791 { 1065 {
792 char qname[MAXSIZE]; 1066 char qname[MAXSIZE];
793 1067
794 while (pkt->qdcount-- && offs < MAXSIZE - 4) 1068 while (pkt.qdcount-- && offs < MAXSIZE - 4)
795 { 1069 {
796 int qlen = pkt->decode_label ((char *)qname, MAXSIZE - offs, offs); 1070 int qlen = pkt.decode_label ((char *)qname, MAXSIZE - offs, offs);
797 offs += 4; // skip qtype, qclass 1071 offs += 4; // skip qtype, qclass
798 } 1072 }
799 1073
800 while (pkt->ancount-- && offs < MAXSIZE - 10 && datap) 1074 while (pkt.ancount-- && offs < MAXSIZE - 10 && datap)
801 { 1075 {
802 int qlen = pkt->decode_label ((char *)qname, MAXSIZE - offs, offs); 1076 int qlen = pkt.decode_label ((char *)qname, MAXSIZE - offs, offs);
803 1077
804 u16 qtype = (*pkt) [offs++] << 8; qtype |= (*pkt) [offs++]; 1078 u16 qtype = pkt [offs++] << 8; qtype |= pkt [offs++];
805 u16 qclass = (*pkt) [offs++] << 8; qclass |= (*pkt) [offs++]; 1079 u16 qclass = pkt [offs++] << 8; qclass |= pkt [offs++];
806 u32 ttl = (*pkt) [offs++] << 24; 1080 u32 ttl = pkt [offs++] << 24;
807 ttl |= (*pkt) [offs++] << 16; 1081 ttl |= pkt [offs++] << 16;
808 ttl |= (*pkt) [offs++] << 8; 1082 ttl |= pkt [offs++] << 8;
809 ttl |= (*pkt) [offs++]; 1083 ttl |= pkt [offs++];
810
811 u16 rdlen = (*pkt) [offs++] << 8; rdlen |= (*pkt) [offs++]; 1084 u16 rdlen = pkt [offs++] << 8; rdlen |= pkt [offs++];
812 1085
813 if (rdlen <= MAXSIZE - offs) 1086 if (qtype == RR_TYPE_NULL || qtype == RR_TYPE_TXT)
814 { 1087 {
815 // decode bytes, finally 1088 if (rdlen <= MAXSIZE - offs)
816
817 while (rdlen)
818 { 1089 {
1090 // decode bytes, finally
1091
1092 while (rdlen)
1093 {
819 int txtlen = (*pkt) [offs++]; 1094 int txtlen = pkt [offs++];
820 1095
821 assert (txtlen + offs < MAXSIZE - 1); 1096 assert (txtlen + offs < MAXSIZE - 1);
822 1097
823 memcpy (datap, pkt->at (offs), txtlen); 1098 memcpy (datap, pkt.at (offs), txtlen);
824 datap += txtlen; offs += txtlen; 1099 datap += txtlen; offs += txtlen;
825 1100
826 rdlen -= txtlen + 1; 1101 rdlen -= txtlen + 1;
1102 }
827 } 1103 }
828 } 1104 }
1105 else if (qtype == RR_TYPE_A)
1106 {
1107 u8 ip [4];
1108
1109 ip [0] = pkt [offs++];
1110 ip [1] = pkt [offs++];
1111 ip [2] = pkt [offs++];
1112 ip [3] = pkt [offs++];
1113
1114 if (ip [0] == CMD_IP_1
1115 && ip [1] == CMD_IP_2
1116 && ip [2] == CMD_IP_3)
1117 {
1118 slog (L_TRACE, _("DNS: got tunnel meta command %02x"), ip [3]);
1119
1120 if (ip [3] == CMD_IP_RST)
1121 {
1122 slog (L_DEBUG, _("DNS: got tunnel RST request"));
1123
1124 delete dns; c->dns = 0;
1125
1126 return;
1127 }
1128 else if (ip [3] == CMD_IP_SYN)
1129 {
1130 slog (L_DEBUG, _("DNS: got tunnel SYN reply, server likes us."));
1131 dns->established = true;
1132 }
1133 else if (ip [3] == CMD_IP_REJ)
1134 {
1135 slog (L_DEBUG, _("DNS: got tunnel REJ reply, server does not like us, aborting."));
1136 abort ();
1137 }
1138 else
1139 slog (L_INFO, _("DNS: got unknown meta command %02x"), ip [3]);
1140 }
1141 else
1142 slog (L_INFO, _("DNS: got spurious a record %d.%d.%d.%d"),
1143 ip [0], ip [1], ip [2], ip [3]);
1144
1145 return;
1146 }
829 1147
830 int client, rseqno; 1148 int client, rseqno;
831 decode_header (qname, client, rseqno); 1149 decode_header (qname, client, rseqno);
832 1150
833 if (client != THISNODE->id) 1151 if (client != THISNODE->id)
834 { 1152 {
835 slog (L_INFO, _("got dns tunnel response with wrong clientid, ignoring")); 1153 slog (L_INFO, _("DNS: got dns tunnel response with wrong clientid, ignoring"));
836 datap = 0; 1154 datap = 0;
837 } 1155 }
838 else if (rseqno != seqno) 1156 else if (rseqno != seqno)
839 { 1157 {
840 slog (L_DEBUG, _("got dns tunnel response with wrong seqno, badly caching nameserver?")); 1158 slog (L_DEBUG, _("DNS: got dns tunnel response with wrong seqno, badly caching nameserver?"));
841 datap = 0; 1159 datap = 0;
842 } 1160 }
843 } 1161 }
844 } 1162 }
845 1163
847 if (datap) 1165 if (datap)
848 dns->receive_rep (new dns_rcv (seqno, data, datap - data)); 1166 dns->receive_rep (new dns_rcv (seqno, data, datap - data));
849 1167
850 break; 1168 break;
851 } 1169 }
852
853 delete pkt;
854} 1170}
855 1171
856void 1172void
857vpn::dnsv4_ev (io_watcher &w, short revents) 1173vpn::dnsv4_ev (ev::io &w, int revents)
858{ 1174{
859 if (revents & EVENT_READ) 1175 if (revents & EV_READ)
860 { 1176 {
861 dns_packet *pkt = new dns_packet; 1177 dns_packet *pkt = new dns_packet;
862 struct sockaddr_in sa; 1178 struct sockaddr_in sa;
863 socklen_t sa_len = sizeof (sa); 1179 socklen_t sa_len = sizeof (sa);
864 1180
865 pkt->len = recvfrom (w.fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len); 1181 pkt->len = recvfrom (w.fd, pkt->at (0), MAXSIZE, 0, (sockaddr *)&sa, &sa_len);
866 1182
867 if (pkt->len > 0) 1183 if (pkt->len > 0)
868 { 1184 {
869 if (pkt->flags & htons (FLAG_TC)) 1185 if (ntohs (pkt->flags) & FLAG_RESPONSE)
1186 dnsv4_client (*pkt);
1187 else
870 { 1188 {
871 slog (L_WARN, _("DNS request/response truncated, check protocol settings.")); 1189 dnsv4_server (*pkt);
872 //TODO connection reset 1190 sendto (w.fd, pkt->at (0), pkt->len, 0, (sockaddr *)&sa, sa_len);
873 } 1191 }
874 1192
875 if (THISNODE->dns_port) 1193 delete pkt;
876 {
877 pkt = dnsv4_server (pkt);
878 sendto (w.fd, &((*pkt)[0]), pkt->len, 0, (sockaddr *)&sa, sa_len);
879 }
880 else
881 dnsv4_client (pkt);
882 } 1194 }
883 } 1195 }
884} 1196}
885 1197
886bool 1198bool
887connection::send_dnsv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 1199vpn::send_dnsv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
888{ 1200{
1201 int client = ntohl (si.host);
1202
1203 assert (0 < client && client <= conns.size ());
1204
1205 connection *c = conns [client - 1];
1206
889 if (!dns) 1207 if (!c->dns)
890 dns = new dns_connection (this); 1208 c->dns = new dns_connection (c);
891 1209
892 if (!dns->snddq.put (pkt)) 1210 if (c->dns->snddq.put (pkt))
893 return false; 1211 c->dns->tw ();
894 1212
895 // start timer if neccessary 1213 // always return true even if the buffer overflows
896 if (!THISNODE->dns_port && !dns->tw.active)
897 dns->tw.trigger ();
898
899 return true; 1214 return true;
900} 1215}
901 1216
902void 1217void
903dns_connection::time_cb (time_watcher &w) 1218connection::dnsv4_reset_connection ()
904{ 1219{
1220 //delete dns; dns = 0; //TODO
1221}
1222
1223#define NEXT(w) do { if (next > (w)) next = w; } while (0)
1224
1225void
1226dns_connection::time_cb (ev::timer &w, int revents)
1227{
1228 // servers have to be polled
1229 if (THISNODE->dns_port)
1230 return;
1231
905 // check for timeouts and (re)transmit 1232 // check for timeouts and (re)transmit
906 tstamp next = NOW + 60; 1233 tstamp next = ev::now () + poll_interval;
907 dns_req *send = 0; 1234 dns_snd *send = 0;
908 1235
909 for (vector<dns_req *>::iterator i = vpn->dns_sndpq.begin (); 1236 for (vector<dns_snd *>::iterator i = vpn->dns_sndpq.begin ();
910 i != vpn->dns_sndpq.end (); 1237 i != vpn->dns_sndpq.end ();
911 ++i) 1238 ++i)
912 { 1239 {
913 dns_req *r = *i; 1240 dns_snd *r = *i;
914 1241
915 if (r->next <= NOW) 1242 if (r->timeout <= ev_now ())
916 { 1243 {
917 if (!send) 1244 if (!send)
918 { 1245 {
919 send = r; 1246 send = r;
920 1247
921 if (r->retry)//D
922 printf ("req %d:%d, retry %d\n", r->seqno, r->pkt->id, r->retry);
923 r->retry++; 1248 r->retry++;
924 r->next = NOW + r->retry; 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
1251
1252 // the following code changes the query section a bit, forcing
1253 // the forwarder to generate a new request
1254 if (r->stdhdr)
1255 encode_header ((char *)r->pkt->at (6 * 2 + 1), THISNODE->id, r->seqno, r->retry);
925 } 1256 }
926 } 1257 }
927 1258 else
928 if (r->next < next) 1259 NEXT (r->timeout);
929 next = r->next;
930 } 1260 }
931 1261
932 if (!send 1262 if (!send)
933 && vpn->dns_sndpq.size () < MAX_OUTSTANDING)
934 { 1263 {
1264 // generate a new packet, if wise
1265
1266 if (!established)
1267 {
1268 if (vpn->dns_sndpq.empty ())
1269 {
935 send = new dns_req (this); 1270 send = new dns_snd (this);
1271
1272 cfg.reset (THISNODE->id);
1273 send->gen_syn_req ();
1274 }
1275 }
1276 else if (vpn->dns_sndpq.size () < conf.dns_max_outstanding
1277 && !SEQNO_EQ (rcvseq, sndseq - (MAX_WINDOW - 1)))
1278 {
1279 if (last_sent + send_interval <= ev_now ())
1280 {
1281 //printf ("sending data request etc.\n"); //D
1282 if (!snddq.empty () || last_received + 1. > ev_now ())
1283 {
1284 poll_interval = send_interval;
1285 NEXT (ev_now () + send_interval);
1286 }
1287
1288 send = new dns_snd (this);
936 send->gen_stream_req (sndseq, snddq); 1289 send->gen_stream_req (sndseq, snddq);
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
1292
1293 sndseq = (sndseq + 1) & SEQNO_MASK;
1294 }
1295 else
1296 NEXT (last_sent + send_interval);
1297 }
1298
1299 if (send)
937 vpn->dns_sndpq.push_back (send); 1300 vpn->dns_sndpq.push_back (send);
938
939 sndseq = (sndseq + 1) & SEQNO_MASK;
940 } 1301 }
941
942 tstamp min_next = NOW + (1. / (tstamp)MAX_RATE);
943 1302
944 if (send) 1303 if (send)
945 { 1304 {
946 dns_packet *pkt = send->pkt; 1305 last_sent = ev_now ();
947 1306 sendto (vpn->dnsv4_fd,
948 next = min_next; 1307 send->pkt->at (0), send->pkt->len, 0,
949
950 sendto (vpn->dnsv4_fd, &((*pkt)[0]), pkt->len, 0,
951 vpn->dns_forwarder.sav4 (), vpn->dns_forwarder.salenv4 ()); 1308 vpn->dns_forwarder.sav4 (), vpn->dns_forwarder.salenv4 ());
952 } 1309 }
953 else if (next < min_next)
954 next = min_next;
955 1310
956 w.start (next); 1311 slog (L_NOISE, "DNS: pi %f si %f N %f (%d:%d %d)",
1312 poll_interval, send_interval, next - ev_now (),
1313 vpn->dns_sndpq.size (), snddq.size (),
1314 rcvpq.size ());
1315
1316 // TODO: no idea when this happens, but when next < ev_now (), we have a problem
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 ());
957} 1322}
958 1323
959#endif 1324#endif
960 1325

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines