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.8 by pcg, Fri Mar 4 03:43:09 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 60. 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 10000 // 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// seqno has 12 bits (3 bytes a 4 bits in the header)
61#define SEQNO_MASK 0x7fff 79#define SEQNO_MASK 0x3fff
62#define SEQNO_EQ(a,b) ( 0 == ( ((a) ^ (b)) & SEQNO_MASK) ) 80#define SEQNO_EQ(a,b) ( 0 == ( ((a) ^ (b)) & SEQNO_MASK) )
63 81
64#define MAX_LBL_SIZE 63 82#define MAX_LBL_SIZE 63
65#define MAX_PKT_SIZE 512 83#define MAX_PKT_SIZE 512
66 84
85#define RR_TYPE_A 1
86#define RR_TYPE_NULL 10
67#define RR_TYPE_TXT 16 87#define RR_TYPE_TXT 16
68#define RR_TYPE_ANY 255 88#define RR_TYPE_ANY 255
89
69#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
70 98
71// works for cmaps up to 255 (not 256!) 99// works for cmaps up to 255 (not 256!)
72struct charmap 100struct charmap
73{ 101{
74 enum { INVALID = (u8)255 }; 102 enum { INVALID = (u8)255 };
154 return dec_len [len]; 182 return dec_len [len];
155} 183}
156 184
157unsigned int basecoder::encode (char *dst, u8 *src, unsigned int len) 185unsigned int basecoder::encode (char *dst, u8 *src, unsigned int len)
158{ 186{
159 if (!len) 187 if (!len || len > MAX_DEC_LEN)
160 return 0; 188 return 0;
161 189
162 int elen = encode_len (len); 190 int elen = encode_len (len);
163 191
164 mp_limb_t m [MAX_LIMBS]; 192 mp_limb_t m [MAX_LIMBS];
183 return elen; 211 return elen;
184} 212}
185 213
186unsigned int basecoder::decode (u8 *dst, char *src, unsigned int len) 214unsigned int basecoder::decode (u8 *dst, char *src, unsigned int len)
187{ 215{
188 if (!len) 216 if (!len || len > MAX_ENC_LEN)
189 return 0; 217 return 0;
190 218
191 u8 src_ [MAX_ENC_LEN]; 219 u8 src_ [MAX_ENC_LEN];
192 unsigned int elen = 0; 220 unsigned int elen = 0;
193 221
240 } 268 }
241 abort (); 269 abort ();
242} 270}
243#endif 271#endif
244 272
245// the following sequence has been crafted to 273//static basecoder cdc64 ("_dDpPhHzZrR06QqMmjJkKBb34TtSsvVlL81xXaAeEFf92WwGgYyoO57UucCNniI-");
246// a) look somewhat random
247// b) the even (and odd) indices never share the same character as upper/lowercase
248// the "_" is not valid but widely accepted (all octets should be supported, but let's be conservative)
249// the other sequences are obviously derived
250//static basecoder cdc63 ("_dDpPhHzZrR06QqMmjJkKBb34TtSsvVlL81xXaAeEFf92WwGgYyoO57UucCNniI"); 274//static basecoder cdc63 ("_dDpPhHzZrR06QqMmjJkKBb34TtSsvVlL81xXaAeEFf92WwGgYyoO57UucCNniI");
251static basecoder cdc62 ("dDpPhHzZrR06QqMmjJkKBb34TtSsvVlL81xXaAeEFf92WwGgYyoO57UucCNniI"); 275static basecoder cdc62 ("dDpPhHzZrR06QqMmjJkKBb34TtSsvVlL81xXaAeEFf92WwGgYyoO57UucCNniI");
252//static basecoder cdc36 ("dphzr06qmjkb34tsvl81xaef92wgyo57ucni"); // unused as of yet 276//static basecoder cdc36 ("dphzr06qmjkb34tsvl81xaef92wgyo57ucni"); // unused as of yet
253static basecoder cdc26 ("dPhZrQmJkBtSvLxAeFwGyO"); 277static basecoder cdc26 ("dPhZrQmJkBtSvLxAeFwGyO");
254 278
255///////////////////////////////////////////////////////////////////////////// 279/////////////////////////////////////////////////////////////////////////////
256 280
257#define HDRSIZE 6 281#define HDRSIZE 6
258 282
259inline void encode_header (char *data, int clientid, int seqno) 283inline void encode_header (char *data, int clientid, int seqno, int retry = 0)
260{ 284{
261 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 };
262 292
263 assert (clientid < 256); 293 assert (clientid < 256);
264 294
265 cdc26.encode (data, hdr, 3); 295 cdc26.encode (data, hdr, 3);
266} 296}
269{ 299{
270 u8 hdr[3]; 300 u8 hdr[3];
271 301
272 cdc26.decode (hdr, data, HDRSIZE); 302 cdc26.decode (hdr, data, HDRSIZE);
273 303
274 printf ("DEC %02x %02x %02x %02x\n", hdr[0], hdr[1], hdr[2], hdr[3]);
275
276 clientid = hdr[0]; 304 clientid = hdr[0];
277 seqno = (hdr[1] << 8) | hdr[2]; 305 seqno = ((hdr[1] << 8) | hdr[2]) & SEQNO_MASK;
278} 306}
279 307
280///////////////////////////////////////////////////////////////////////////// 308/////////////////////////////////////////////////////////////////////////////
281 309
282struct byte_stream 310struct byte_stream
311} 339}
312 340
313void byte_stream::remove (int count) 341void byte_stream::remove (int count)
314{ 342{
315 if (count > fill) 343 if (count > fill)
316 abort (); 344 assert (count <= fill);
317 345
318 memmove (data, data + count, fill -= count); 346 memmove (data, data + count, fill -= count);
319} 347}
320 348
321bool byte_stream::put (u8 *data, unsigned int datalen) 349bool byte_stream::put (u8 *data, unsigned int datalen)
334 return false; 362 return false;
335 363
336 data [fill++] = pkt->len >> 8; 364 data [fill++] = pkt->len >> 8;
337 data [fill++] = pkt->len; 365 data [fill++] = pkt->len;
338 366
339 memcpy (data + fill, &((*pkt)[0]), pkt->len); fill += pkt->len; 367 memcpy (data + fill, pkt->at (0), pkt->len); fill += pkt->len;
340 368
341 return true; 369 return true;
342} 370}
343 371
344vpn_packet *byte_stream::get () 372vpn_packet *byte_stream::get ()
345{ 373{
374 unsigned int len;
375
376 for (;;)
377 {
346 int len = (data [0] << 8) | data [1]; 378 len = (data [0] << 8) | data [1];
347 379
348 if (len > MAXSIZE && fill >= 2) 380 if (len <= MAXSIZE || fill < 2)
349 abort (); // TODO handle this gracefully, connection reset 381 break;
350 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
351 if (fill < len + 2) 388 if (fill < len + 2)
352 return 0; 389 return 0;
353 390
354 vpn_packet *pkt = new vpn_packet; 391 vpn_packet *pkt = new vpn_packet;
355 392
356 pkt->len = len; 393 pkt->len = len;
357 memcpy (&((*pkt)[0]), data + 2, len); 394 memcpy (pkt->at (0), data + 2, len);
358 remove (len + 2); 395 remove (len + 2);
359 396
360 return pkt; 397 return pkt;
361} 398}
362 399
363///////////////////////////////////////////////////////////////////////////// 400/////////////////////////////////////////////////////////////////////////////
364 401
365#define FLAG_QUERY ( 0 << 15) 402#define FLAG_QUERY ( 0 << 15)
366#define FLAG_RESPONSE ( 1 << 15) 403#define FLAG_RESPONSE ( 1 << 15)
367#define FLAG_OP_MASK (15 << 14) 404#define FLAG_OP_MASK (15 << 11)
368#define FLAG_OP_QUERY ( 0 << 11) 405#define FLAG_OP_QUERY ( 0 << 11)
369#define FLAG_AA ( 1 << 10) 406#define FLAG_AA ( 1 << 10)
370#define FLAG_TC ( 1 << 9) 407#define FLAG_TC ( 1 << 9)
371#define FLAG_RD ( 1 << 8) 408#define FLAG_RD ( 1 << 8)
372#define FLAG_RA ( 1 << 7) 409#define FLAG_RA ( 1 << 7)
379#define FLAG_RCODE_REFUSED ( 5 << 0) 416#define FLAG_RCODE_REFUSED ( 5 << 0)
380 417
381#define DEFAULT_CLIENT_FLAGS (FLAG_QUERY | FLAG_OP_QUERY | FLAG_RD) 418#define DEFAULT_CLIENT_FLAGS (FLAG_QUERY | FLAG_OP_QUERY | FLAG_RD)
382#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)
383 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
384struct dns_packet : net_packet 489struct dns_packet : net_packet
385{ 490{
386 u16 id; 491 u16 id;
387 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
388 u16 qdcount, ancount, nscount, arcount; 493 u16 qdcount, ancount, nscount, arcount;
389 494
390 u8 data[MAXSIZE - 6 * 2]; 495 u8 data [MAXSIZE - 6 * 2];
391 496
392 int decode_label (char *data, int size, int &offs); 497 int decode_label (char *data, int size, int &offs);
393}; 498};
394 499
395int dns_packet::decode_label (char *data, int size, int &offs) 500int dns_packet::decode_label (char *data, int size, int &offs)
426 return data - orig; 531 return data - orig;
427} 532}
428 533
429///////////////////////////////////////////////////////////////////////////// 534/////////////////////////////////////////////////////////////////////////////
430 535
431struct dns_req
432{
433 dns_packet *pkt;
434 tstamp next;
435 int retry;
436 connection *conn;
437 int seqno;
438
439 dns_req (connection *c);
440 void gen_stream_req (int seqno, byte_stream *stream);
441};
442
443static u16 dns_id = 12098; // TODO: should be per-vpn 536static u16 dns_id = 0; // TODO: should be per-vpn
444 537
445static u16 next_id () 538static u16 next_id ()
446{ 539{
540 if (!dns_id)
541 dns_id = time (0);
542
447 // the simplest lsfr with periodicity 65535 i could find 543 // the simplest lsfr with periodicity 65535 i could find
448 dns_id = (dns_id << 1) 544 dns_id = (dns_id << 1)
449 | (((dns_id >> 1) 545 | (((dns_id >> 1)
450 ^ (dns_id >> 2) 546 ^ (dns_id >> 2)
451 ^ (dns_id >> 4) 547 ^ (dns_id >> 4)
452 ^ (dns_id >> 15)) & 1); 548 ^ (dns_id >> 15)) & 1);
453 549
454 return dns_id; 550 return dns_id;
455} 551}
456 552
457dns_req::dns_req (connection *c) 553struct dns_rcv;
458: conn (c) 554struct dns_snd;
555
556struct dns_connection
459{ 557{
460 next = 0; 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
598dns_snd::dns_snd (dns_connection *dns)
599: dns (dns)
600{
601 timeout = 0;
461 retry = 0; 602 retry = 0;
603 seqno = 0;
604 sent = ev_now ();
605 stdhdr = false;
462 606
463 pkt = new dns_packet; 607 pkt = new dns_packet;
464 608
465 pkt->id = next_id (); 609 pkt->id = next_id ();
466} 610}
467 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
468void dns_req::gen_stream_req (int seqno, byte_stream *stream) 640void dns_snd::gen_stream_req (int seqno, byte_stream &stream)
469{ 641{
642 stdhdr = true;
470 this->seqno = seqno; 643 this->seqno = seqno;
644
645 timeout = ev_now () + INITIAL_TIMEOUT;
471 646
472 pkt->flags = htons (DEFAULT_CLIENT_FLAGS); 647 pkt->flags = htons (DEFAULT_CLIENT_FLAGS);
473 pkt->qdcount = htons (1); 648 pkt->qdcount = htons (1);
474 649
475 int offs = 6*2; 650 int offs = 6*2;
476 int dlen = MAX_DOMAIN_SIZE - (strlen (THISNODE->domain) + 2); 651 int dlen = MAX_DOMAIN_SIZE - (strlen (dns->c->conf->domain) + 2);
477 // 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,
478 // 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
479 654
480 char enc[256], *encp = enc; 655 char enc[256], *encp = enc;
481 encode_header (enc, THISNODE->id, seqno); 656 encode_header (enc, THISNODE->id, seqno);
482 657
483 int datalen = cdc62.decode_len (dlen - (dlen + MAX_LBL_SIZE - 1) / MAX_LBL_SIZE - HDRSIZE); 658 int datalen = cdc62.decode_len (dlen - (dlen + MAX_LBL_SIZE - 1) / MAX_LBL_SIZE - HDRSIZE);
484 659
485 if (datalen > stream->size ()) 660 if (datalen > stream.size ())
486 datalen = stream->size (); 661 datalen = stream.size ();
487 662
488 int enclen = cdc62.encode (enc + HDRSIZE, stream->begin (), datalen) + HDRSIZE; 663 int enclen = cdc62.encode (enc + HDRSIZE, stream.begin (), datalen) + HDRSIZE;
489
490 printf ("cdc62.encode %d->%d:%02x %02x %02x %02x\n", datalen, enclen,
491 stream->begin ()[0],
492 stream->begin ()[1],
493 stream->begin ()[2],
494 stream->begin ()[3]);
495
496 stream->remove (datalen); 664 stream.remove (datalen);
497 665
498 while (enclen) 666 while (enclen)
499 { 667 {
500 int lbllen = enclen < MAX_LBL_SIZE ? enclen : MAX_LBL_SIZE; 668 int lbllen = enclen < MAX_LBL_SIZE ? enclen : MAX_LBL_SIZE;
501 669
506 encp += lbllen; 674 encp += lbllen;
507 675
508 enclen -= lbllen; 676 enclen -= lbllen;
509 } 677 }
510 678
511 const char *suffix = THISNODE->domain; 679 append_domain (*pkt, offs, dns->c->conf->domain);
512
513 // add tunnel domain
514 for (;;)
515 {
516 const char *end = strchr (suffix, '.');
517
518 if (!end)
519 end = suffix + strlen (suffix);
520
521 int len = end - suffix;
522
523 (*pkt)[offs++] = len;
524 memcpy (&((*pkt)[offs]), suffix, len);
525 offs += len;
526
527 if (!*end)
528 break;
529
530 suffix = end + 1;
531 }
532 680
533 (*pkt)[offs++] = 0; 681 (*pkt)[offs++] = 0;
534 (*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;
535 (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN; 707 (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN;
536 708
537 pkt->len = offs; 709 pkt->len = offs;
538} 710}
539 711
558{ 730{
559 delete pkt; 731 delete pkt;
560} 732}
561 733
562///////////////////////////////////////////////////////////////////////////// 734/////////////////////////////////////////////////////////////////////////////
563 735
564struct dns_cfg 736dns_connection::dns_connection (connection *c)
737: c (c)
738, rcvdq (MAX_BACKLOG * 2)
739, snddq (MAX_BACKLOG)
565{ 740{
566 u8 id1, id2, id3; 741 tw.set<dns_connection, &dns_connection::time_cb> (this);
567 u8 def_ttl;
568 u8 unused1;
569 u16 max_size;
570 u8 flags1, flags2;
571};
572 742
743 vpn = c->vpn;
744
745 established = false;
746
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;
753}
754
755dns_connection::~dns_connection ()
756{
757 for (vector<dns_rcv *>::iterator i = rcvpq.begin ();
758 i != rcvpq.end ();
759 ++i)
760 delete *i;
761}
762
573void connection::dnsv4_receive_rep (struct dns_rcv *r) 763void dns_connection::receive_rep (dns_rcv *r)
574{ 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
575 dns_rcvpq.push_back (r); 780 rcvpq.push_back (r);
576 781
577 printf ("%d got inketc %d (%02x %02x %02x %02x)\n", THISNODE->id, r->seqno
578 ,r->data[0]
579 ,r->data[1]
580 ,r->data[2]
581 ,r->data[3]
582 );
583 redo: 782 redo:
584 783
585 // find next packet 784 // find next packet
586 for (vector<dns_rcv *>::iterator i = dns_rcvpq.end (); i-- != dns_rcvpq.begin (); ) 785 for (vector<dns_rcv *>::iterator i = rcvpq.end (); i-- != rcvpq.begin (); )
587 if (SEQNO_EQ (dns_rcvseq, (*i)->seqno)) 786 if (SEQNO_EQ (rcvseq, (*i)->seqno))
588 { 787 {
788 //printf ("seqno eq %x %x\n", rcvseq, (*i)->seqno);//D
589 // enter the packet into our input stream 789 // enter the packet into our input stream
590 r = *i; 790 r = *i;
591 791
592 printf ("%d checking for older packet %d\n", THISNODE->id, dns_rcvseq);
593 // remove the oldest packet, look forward, as it's oldest first 792 // remove the oldest packet, look forward, as it's oldest first
594 for (vector<dns_rcv *>::iterator j = dns_rcvpq.begin (); j != dns_rcvpq.end (); ++j) 793 for (vector<dns_rcv *>::iterator j = rcvpq.begin (); j != rcvpq.end (); ++j)
595 if (SEQNO_EQ ((*j)->seqno, dns_rcvseq - MAX_WINDOW)) 794 if (SEQNO_EQ ((*j)->seqno, rcvseq - MAX_WINDOW))
596 { 795 {
597 printf ("%d removing %d\n", THISNODE->id, (*j)->seqno); 796 //printf ("seqno RR %x %x\n", (*j)->seqno, rcvseq - MAX_WINDOW);//D
598 delete *j; 797 delete *j;
599 dns_rcvpq.erase (j); 798 rcvpq.erase (j);
600 break; 799 break;
601 } 800 }
602 801
603 dns_rcvseq = (dns_rcvseq + 1) & SEQNO_MASK; 802 rcvseq = (rcvseq + 1) & SEQNO_MASK;
604 803
605 if (!dns_snddq && !dns_rcvdq) 804 if (!rcvdq.put (r->data, r->datalen))
606 { 805 {
607 dns_rcvdq = new byte_stream (MAX_BACKLOG * 2); 806 slog (L_ERR, "DNS: !rcvdq.put (r->data, r->datalen)");
608 dns_snddq = new byte_stream (MAX_BACKLOG); 807 abort (); // MUST never overflow, can be caused by data corruption, TODO
609
610 dns_si.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4);
611 } 808 }
612 809
613 if (!dns_rcvdq->put (r->data, r->datalen))
614 abort (); // MUST never overflow, can be caused by data corruption, TODO
615
616 while (vpn_packet *pkt = dns_rcvdq->get ()) 810 while (vpn_packet *pkt = rcvdq.get ())
617 { 811 {
618 sockinfo si; 812 sockinfo si;
619 si.host = 0; si.port = 0; si.prot = PROT_DNSv4; 813 si.host = htonl (c->conf->id); si.port = 0; si.prot = PROT_DNSv4;
620 814
621 vpn->recv_vpn_packet (pkt, si); 815 vpn->recv_vpn_packet (pkt, si);
816
817 delete pkt;
622 } 818 }
623 819
624 // check for further packets 820 // check for further packets
625 goto redo; 821 goto redo;
626 } 822 }
627} 823}
628 824
629dns_packet * 825void
630vpn::dnsv4_server (dns_packet *pkt) 826vpn::dnsv4_server (dns_packet &pkt)
631{ 827{
632 u16 flags = ntohs (pkt->flags); 828 u16 flags = ntohs (pkt.flags);
633 829
634 //memcpy (&((*rep)[0]), &((*pkt)[0]), pkt->len);
635 int offs = 6 * 2; // skip header 830 int offs = 6 * 2; // skip header
636 831
637 pkt->flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR); 832 pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR);
638 833
639 if (!(flags & (FLAG_RESPONSE | FLAG_OP_MASK | FLAG_TC)) 834 if (0 == (flags & (FLAG_RESPONSE | FLAG_OP_MASK))
640 && pkt->qdcount == htons (1)) 835 && pkt.qdcount == htons (1))
641 { 836 {
642 char qname[MAXSIZE]; 837 char qname [MAXSIZE];
643 int qlen = pkt->decode_label ((char *)qname, MAXSIZE - offs, offs); 838 int qlen = pkt.decode_label ((char *)qname, MAXSIZE - offs, offs);
644 839
645 u16 qtype = (*pkt) [offs++] << 8; qtype |= (*pkt) [offs++]; 840 u16 qtype = pkt [offs++] << 8; qtype |= pkt [offs++];
646 u16 qclass = (*pkt) [offs++] << 8; qclass |= (*pkt) [offs++]; 841 u16 qclass = pkt [offs++] << 8; qclass |= pkt [offs++];
647 842
648 pkt->qdcount = htons (1); 843 pkt.qdcount = htons (1);
649 pkt->ancount = 0; 844 pkt.ancount = 0;
650 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
651 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
652 847
653 pkt->flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_NXDOMAIN); 848 pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_SERVFAIL);
654 849
655 int dlen = strlen (THISNODE->domain); 850 int dlen = strlen (THISNODE->domain);
656 851
657 if (qclass == RR_CLASS_IN 852 if (qclass == RR_CLASS_IN
658 && (qtype == RR_TYPE_ANY || qtype == RR_TYPE_TXT)
659 && qlen > dlen + 1 + HDRSIZE 853 && qlen > dlen + 1
660 && !memcmp (qname + qlen - dlen - 1, THISNODE->domain, dlen)) 854 && !memcmp (qname + qlen - (dlen + 1), THISNODE->domain, dlen))
661 { 855 {
662 // correct class, domain: parse 856 // now generate reply
663 int client, seqno; 857 pkt.ancount = htons (1); // one answer RR
664 decode_header (qname, client, seqno); 858 pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_OK);
665 859
666 u8 data[MAXSIZE]; 860 if ((qtype == RR_TYPE_ANY
667 int datalen = cdc62.decode (data, qname + HDRSIZE, qlen - (dlen + 1 + HDRSIZE)); 861 || qtype == RR_TYPE_TXT
668 862 || qtype == RR_TYPE_NULL)
669 printf ("cdc62.decode %d(%d): %02x %02x %02x %02x\n",
670 qlen - (dlen + 1 + HDRSIZE), datalen 863 && qlen > dlen + 1 + HDRSIZE)
671 ,data[0]
672 ,data[1]
673 ,data[2]
674 ,data[3]);
675
676 printf ("SRV got %d <%.*s>\n", seqno, qlen, qname + HDRSIZE);//D
677 printf ("SRV got %d <%.*s>\n", seqno, qlen - (dlen + 1 + HDRSIZE), qname + HDRSIZE);//D
678
679 if (0 < client && client <= conns.size ())
680 { 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 {
681 connection *c = conns [client - 1]; 874 connection *c = conns [client - 1];
875 dns_connection *dns = c->dns;
876 dns_rcv *rcv;
682 877
878 if (dns)
879 {
683 for (vector<dns_rcv *>::iterator i = c->dns_rcvpq.end (); i-- != c->dns_rcvpq.begin (); ) 880 for (vector<dns_rcv *>::iterator i = dns->rcvpq.end (); i-- != dns->rcvpq.begin (); )
684 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
685 { 902 {
686 // already seen that request: simply reply with the cached reply 903 pkt [offs++] = 0xc0; pkt [offs++] = 6 * 2; // refer to name in query section
687 dns_rcv *r = *i;
688 904
689 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
690 910
691 memcpy (pkt->at (0), r->pkt->at (0), offs = r->pkt->len); 911 int rdlen_offs = offs += 2;
692 pkt->id = r->pkt->id; 912
693 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 }
694 } 968 }
695 969
696 // new packet, queue 970 duplicate_request: ;
697 dns_rcv *rcv = new dns_rcv (seqno, data, datalen); 971 }
698 c->dnsv4_receive_rep (rcv); 972 else
699
700 // now generate reply
701 pkt->ancount = htons (1); // one answer RR
702 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);
703 981
704 (*pkt) [offs++] = 0xc0;
705 (*pkt) [offs++] = 6 * 2; // same as in query section 982 pkt [offs++] = 0xc0; pkt [offs++] = 6 * 2; // refer to name in query section
706 983
707 (*pkt) [offs++] = RR_TYPE_TXT >> 8; (*pkt) [offs++] = RR_TYPE_TXT; 984 pkt [offs++] = RR_TYPE_A >> 8; pkt [offs++] = RR_TYPE_A; // type
708 (*pkt) [offs++] = RR_CLASS_IN >> 8; (*pkt) [offs++] = RR_CLASS_IN; 985 pkt [offs++] = RR_CLASS_IN >> 8; pkt [offs++] = RR_CLASS_IN; // class
709
710 (*pkt) [offs++] = 0; (*pkt) [offs++] = 0; 986 pkt [offs++] = 0; pkt [offs++] = 0;
711 (*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
712 989
713 int dlen = MAX_PKT_SIZE - offs - 2; 990 slog (L_INFO, _("DNS: client %d connects"), client);
714 991
715 // 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;
716 dlen -= qlen; 993 pkt [offs++] = CMD_IP_REJ;
717 994
718 int rdlen_offs = offs += 2; 995 if (0 < client && client <= conns.size ())
719
720 while (c->dns_snddq
721 && !c->dns_snddq->empty ()
722 && dlen > 1)
723 { 996 {
724 int txtlen = dlen <= 255 ? dlen - 1 : 255; 997 connection *c = conns [client - 1];
725 998
726 if (txtlen > c->dns_snddq->size ()) 999 if (cfg.valid ())
727 txtlen = c->dns_snddq->size (); 1000 {
1001 pkt [offs - 1] = CMD_IP_SYN;
728 1002
729 (*pkt)[offs++] = txtlen; 1003 delete c->dns;
730 memcpy (pkt->at (offs), c->dns_snddq->begin (), txtlen); 1004 c->dns = new dns_connection (c);
731 offs += txtlen; 1005 c->dns->cfg = cfg;
732 c->dns_snddq->remove (txtlen); 1006 }
733
734 dlen -= txtlen + 1;
735 } 1007 }
736
737 // avoid empty TXT rdata
738 if (offs == rdlen_offs)
739 (*pkt)[offs++] = 0;
740
741 int rdlen = offs - rdlen_offs;
742
743 (*pkt) [rdlen_offs - 2] = rdlen >> 8;
744 (*pkt) [rdlen_offs - 1] = rdlen;
745
746 // now update dns_rcv copy
747 rcv->pkt->len = offs;
748 memcpy (rcv->pkt->at (0), pkt->at (0), offs);
749
750 duplicate_request: ;
751 } 1008 }
752 else
753 pkt->flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR);
754 } 1009 }
755 1010
756 pkt->len = offs; 1011 pkt.len = offs;
757 } 1012 }
758
759 return pkt;
760} 1013}
761 1014
762void 1015void
763vpn::dnsv4_client (dns_packet *pkt) 1016vpn::dnsv4_client (dns_packet &pkt)
764{ 1017{
765 u16 flags = ntohs (pkt->flags); 1018 u16 flags = ntohs (pkt.flags);
766 int offs = 6 * 2; // skip header 1019 int offs = 6 * 2; // skip header
767 1020
768 pkt->qdcount = ntohs (pkt->qdcount); 1021 pkt.qdcount = ntohs (pkt.qdcount);
769 pkt->ancount = ntohs (pkt->ancount); 1022 pkt.ancount = ntohs (pkt.ancount);
770 1023
771 // go through our request list and find the corresponding request 1024 // go through our request list and find the corresponding request
772 for (vector<dns_req *>::iterator i = dns_sndpq.begin (); 1025 for (vector<dns_snd *>::iterator i = dns_sndpq.begin ();
773 i != dns_sndpq.end (); 1026 i != dns_sndpq.end ();
774 ++i) 1027 ++i)
775 if ((*i)->pkt->id == pkt->id) 1028 if ((*i)->pkt->id == pkt.id)
776 { 1029 {
1030 dns_connection *dns = (*i)->dns;
777 connection *c = (*i)->conn; 1031 connection *c = dns->c;
778 int seqno = (*i)->seqno; 1032 int seqno = (*i)->seqno;
779 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 }
780 1060
781 delete *i; 1061 delete *i;
782 dns_sndpq.erase (i); 1062 dns_sndpq.erase (i);
783 1063
784 if (flags & (FLAG_RESPONSE | FLAG_OP_MASK | FLAG_TC)) 1064 if (flags & FLAG_RESPONSE && !(flags & FLAG_OP_MASK))
785 { 1065 {
786 char qname[MAXSIZE]; 1066 char qname[MAXSIZE];
787 1067
788 while (pkt->qdcount-- && offs < MAXSIZE - 4) 1068 while (pkt.qdcount-- && offs < MAXSIZE - 4)
789 { 1069 {
790 int qlen = pkt->decode_label ((char *)qname, MAXSIZE - offs, offs); 1070 int qlen = pkt.decode_label ((char *)qname, MAXSIZE - offs, offs);
791 offs += 4; // skip qtype, qclass 1071 offs += 4; // skip qtype, qclass
792 } 1072 }
793 1073
794 while (pkt->ancount-- && offs < MAXSIZE - 10) 1074 while (pkt.ancount-- && offs < MAXSIZE - 10 && datap)
795 { 1075 {
796 int qlen = //D
797 pkt->decode_label ((char *)qname, MAXSIZE - offs, offs); 1076 int qlen = pkt.decode_label ((char *)qname, MAXSIZE - offs, offs);
798 1077
799 printf ("got reply to <%.*s>\n", qlen, qname);//D
800
801 u16 qtype = (*pkt) [offs++] << 8; qtype |= (*pkt) [offs++]; 1078 u16 qtype = pkt [offs++] << 8; qtype |= pkt [offs++];
802 u16 qclass = (*pkt) [offs++] << 8; qclass |= (*pkt) [offs++]; 1079 u16 qclass = pkt [offs++] << 8; qclass |= pkt [offs++];
803 u32 ttl = (*pkt) [offs++] << 24; 1080 u32 ttl = pkt [offs++] << 24;
804 ttl |= (*pkt) [offs++] << 16; 1081 ttl |= pkt [offs++] << 16;
805 ttl |= (*pkt) [offs++] << 8; 1082 ttl |= pkt [offs++] << 8;
806 ttl |= (*pkt) [offs++]; 1083 ttl |= pkt [offs++];
807
808 u16 rdlen = (*pkt) [offs++] << 8; rdlen |= (*pkt) [offs++]; 1084 u16 rdlen = pkt [offs++] << 8; rdlen |= pkt [offs++];
809 1085
810 if (rdlen <= MAXSIZE - offs) 1086 if (qtype == RR_TYPE_NULL || qtype == RR_TYPE_TXT)
811 { 1087 {
812 // decode bytes, finally 1088 if (rdlen <= MAXSIZE - offs)
813
814 while (rdlen)
815 { 1089 {
1090 // decode bytes, finally
1091
1092 while (rdlen)
1093 {
816 int txtlen = (*pkt) [offs++]; 1094 int txtlen = pkt [offs++];
817 1095
818 assert (txtlen + offs < MAXSIZE - 1); 1096 assert (txtlen + offs < MAXSIZE - 1);
819 1097
820 memcpy (datap, pkt->at (offs), txtlen); 1098 memcpy (datap, pkt.at (offs), txtlen);
821 datap += txtlen; offs += txtlen; 1099 datap += txtlen; offs += txtlen;
822 1100
823 rdlen -= txtlen + 1; 1101 rdlen -= txtlen + 1;
1102 }
824 } 1103 }
825
826 } 1104 }
1105 else if (qtype == RR_TYPE_A)
1106 {
1107 u8 ip [4];
827 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 }
1147
1148 int client, rseqno;
1149 decode_header (qname, client, rseqno);
1150
1151 if (client != THISNODE->id)
1152 {
1153 slog (L_INFO, _("DNS: got dns tunnel response with wrong clientid, ignoring"));
1154 datap = 0;
1155 }
1156 else if (rseqno != seqno)
1157 {
1158 slog (L_DEBUG, _("DNS: got dns tunnel response with wrong seqno, badly caching nameserver?"));
1159 datap = 0;
1160 }
828 } 1161 }
829 } 1162 }
830 1163
831 // todo: pkt now used 1164 // todo: pkt now used
1165 if (datap)
832 c->dnsv4_receive_rep (new dns_rcv (seqno, data, datap - data)); 1166 dns->receive_rep (new dns_rcv (seqno, data, datap - data));
833 1167
834 break; 1168 break;
835 } 1169 }
836
837 delete pkt;
838} 1170}
839 1171
840void 1172void
841vpn::dnsv4_ev (io_watcher &w, short revents) 1173vpn::dnsv4_ev (ev::io &w, int revents)
842{ 1174{
843 if (revents & EVENT_READ) 1175 if (revents & EV_READ)
844 { 1176 {
845 dns_packet *pkt = new dns_packet; 1177 dns_packet *pkt = new dns_packet;
846 struct sockaddr_in sa; 1178 struct sockaddr_in sa;
847 socklen_t sa_len = sizeof (sa); 1179 socklen_t sa_len = sizeof (sa);
848 1180
849 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);
850 1182
851 if (pkt->len > 0) 1183 if (pkt->len > 0)
852 { 1184 {
853 if (pkt->flags & htons (FLAG_TC)) 1185 if (ntohs (pkt->flags) & FLAG_RESPONSE)
1186 dnsv4_client (*pkt);
1187 else
854 { 1188 {
855 slog (L_WARN, _("DNS request/response truncated, check protocol settings.")); 1189 dnsv4_server (*pkt);
856 //TODO connection reset 1190 sendto (w.fd, pkt->at (0), pkt->len, 0, (sockaddr *)&sa, sa_len);
857 } 1191 }
858 1192
859 if (THISNODE->dns_port) 1193 delete pkt;
860 {
861 pkt = dnsv4_server (pkt);
862 sendto (w.fd, &((*pkt)[0]), pkt->len, 0, (sockaddr *)&sa, sa_len);
863 }
864 else
865 dnsv4_client (pkt);
866 } 1194 }
867 } 1195 }
868} 1196}
869 1197
870bool 1198bool
871connection::send_dnsv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 1199vpn::send_dnsv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
872{ 1200{
873 // never initialized 1201 int client = ntohl (si.host);
874 if (!dns_snddq && !dns_rcvdq)
875 {
876 dns_rcvdq = new byte_stream (MAX_BACKLOG * 2);
877 dns_snddq = new byte_stream (MAX_BACKLOG);
878 1202
879 //dns_rcvseq = dns_sndseq = 0; 1203 assert (0 < client && client <= conns.size ());
880 1204
881 dns_si.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4); 1205 connection *c = conns [client - 1];
882 } 1206
1207 if (!c->dns)
1208 c->dns = new dns_connection (c);
883 1209
884 if (!dns_snddq->put (pkt)) 1210 if (c->dns->snddq.put (pkt))
885 return false; 1211 c->dns->tw ();
886 1212
887 // start timer if neccessary 1213 // always return true even if the buffer overflows
888 if (!THISNODE->dns_port && !dnsv4_tw.active)
889 dnsv4_cb (dnsv4_tw);
890
891 return true; 1214 return true;
892} 1215}
893 1216
894void 1217void
895connection::dnsv4_cb (time_watcher &w) 1218connection::dnsv4_reset_connection ()
896{ 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
897 // check for timeouts and (re)transmit 1232 // check for timeouts and (re)transmit
898 tstamp next = NOW + 60; 1233 tstamp next = ev::now () + poll_interval;
899 dns_req *send = 0; 1234 dns_snd *send = 0;
900 1235
901 for (vector<dns_req *>::iterator i = vpn->dns_sndpq.begin (); 1236 for (vector<dns_snd *>::iterator i = vpn->dns_sndpq.begin ();
902 i != vpn->dns_sndpq.end (); 1237 i != vpn->dns_sndpq.end ();
903 ++i) 1238 ++i)
904 { 1239 {
905 dns_req *r = *i; 1240 dns_snd *r = *i;
906 1241
907 if (r->next <= NOW) 1242 if (r->timeout <= ev_now ())
908 { 1243 {
909 if (!send) 1244 if (!send)
910 { 1245 {
911 send = r; 1246 send = r;
912 1247
913 if (r->retry)//D
914 printf ("req %d:%d, retry %d\n", r->seqno, r->pkt->id, r->retry);
915 r->retry++; 1248 r->retry++;
916 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);
917 } 1256 }
918 } 1257 }
919 1258 else
920 if (r->next < next) 1259 NEXT (r->timeout);
921 next = r->next;
922 } 1260 }
923 1261
924 if (!send 1262 if (!send)
925 && vpn->dns_sndpq.size () < MAX_OUTSTANDING)
926 { 1263 {
1264 // generate a new packet, if wise
1265
1266 if (!established)
1267 {
1268 if (vpn->dns_sndpq.empty ())
1269 {
927 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);
928 send->gen_stream_req (dns_sndseq, dns_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)
929 vpn->dns_sndpq.push_back (send); 1300 vpn->dns_sndpq.push_back (send);
930
931 dns_sndseq = (dns_sndseq + 1) & SEQNO_MASK;
932 } 1301 }
933
934 tstamp min_next = NOW + (1. / (tstamp)MAX_RATE);
935 1302
936 if (send) 1303 if (send)
937 { 1304 {
938 dns_packet *pkt = send->pkt; 1305 last_sent = ev_now ();
939 1306 sendto (vpn->dnsv4_fd,
940 next = min_next; 1307 send->pkt->at (0), send->pkt->len, 0,
941 1308 vpn->dns_forwarder.sav4 (), vpn->dns_forwarder.salenv4 ());
942 sendto (vpn->dnsv4_fd, &((*pkt)[0]), pkt->len, 0, dns_si.sav4 (), dns_si.salenv4 ());
943 } 1309 }
944 else if (next < min_next)
945 next = min_next;
946 1310
947 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 ());
948} 1322}
949 1323
950#endif 1324#endif
951 1325

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines