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.37 by pcg, Wed Mar 23 17:03:58 2005 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-2005 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 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
38#include <unistd.h> 52#include <unistd.h>
39#include <fcntl.h> 53#include <fcntl.h>
40 54
41#include <map> 55#include <map>
42 56
57#include <cstdio> /* bug in libgmp: gmp.h relies on cstdio being included */
43#include <gmp.h> 58#include <gmp.h>
44 59
45#include "netcompat.h" 60#include "netcompat.h"
46 61
47#include "vpn.h" 62#include "vpn.h"
48 63
64#define MIN_POLL_INTERVAL 0.025 // poll at most this often when no data received
49#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
50#define ACTIVITY_INTERVAL 5.
51 66
52#define INITIAL_TIMEOUT 0.1 // retry timeouts 67#define INITIAL_TIMEOUT 0.1 // retry timeouts
53#define INITIAL_SYN_TIMEOUT 2. // retry timeout for initial syn 68#define INITIAL_SYN_TIMEOUT 2. // retry timeout for initial syn
54 69
55#define MAX_SEND_INTERVAL 2. // optimistic? 70#define MAX_SEND_INTERVAL 5. // optimistic?
56 71
57#define MAX_WINDOW 1000 // max. for MAX_OUTSTANDING, and backlog 72#define MAX_WINDOW 1000 // max. for MAX_OUTSTANDING, and backlog
58#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
59 74
60#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
61// 240 leaves about 4 bytes of server reply data 76// 240 leaves about 4 bytes of server reply data
62// every request byte less give room for two reply bytes 77// every request byte less give room for two reply bytes
63 78
64#define SEQNO_MASK 0x3fff 79#define SEQNO_MASK 0x3fff
65#define SEQNO_EQ(a,b) ( 0 == ( ((a) ^ (b)) & SEQNO_MASK) ) 80#define SEQNO_EQ(a,b) ( 0 == ( ((a) ^ (b)) & SEQNO_MASK) )
68#define MAX_PKT_SIZE 512 83#define MAX_PKT_SIZE 512
69 84
70#define RR_TYPE_A 1 85#define RR_TYPE_A 1
71#define RR_TYPE_NULL 10 86#define RR_TYPE_NULL 10
72#define RR_TYPE_TXT 16 87#define RR_TYPE_TXT 16
88#define RR_TYPE_AAAA 28
73#define RR_TYPE_ANY 255 89#define RR_TYPE_ANY 255
74 90
75#define RR_CLASS_IN 1 91#define RR_CLASS_IN 1
76 92
77#define CMD_IP_1 207 93#define CMD_IP_1 207
78#define CMD_IP_2 46 94#define CMD_IP_2 46
79#define CMD_IP_3 236 95#define CMD_IP_3 236
80#define CMD_IP_RST 29 96
81#define CMD_IP_SYN 113 97#define CMD_IP_RST 29 // some error, reset and retry
82#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}
83 113
84// works for cmaps up to 255 (not 256!) 114// works for cmaps up to 255 (not 256!)
85struct charmap 115struct charmap
86{ 116{
87 enum { INVALID = (u8)255 }; 117 enum { INVALID = (u8)255 };
101 memset (enc, (char) 0, 256); 131 memset (enc, (char) 0, 256);
102 memset (dec, (char)INVALID, 256); 132 memset (dec, (char)INVALID, 256);
103 133
104 for (size = 0; cmap [size]; size++) 134 for (size = 0; cmap [size]; size++)
105 { 135 {
136 char c = cmap [size];
137
106 enc [size] = cmap [size]; 138 enc [size] = c;
107 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;
108 } 144 }
109 145
110 assert (size < 256); 146 assert (size < 256);
111} 147}
112 148
119{ 155{
120 charmap cmap; 156 charmap cmap;
121 unsigned int enc_len [MAX_DEC_LEN]; 157 unsigned int enc_len [MAX_DEC_LEN];
122 unsigned int dec_len [MAX_ENC_LEN]; 158 unsigned int dec_len [MAX_ENC_LEN];
123 159
124 unsigned int encode_len (unsigned int len); 160 unsigned int encode_len (unsigned int len) const;
125 unsigned int decode_len (unsigned int len); 161 unsigned int decode_len (unsigned int len) const;
126 162
127 unsigned int encode (char *dst, u8 *src, unsigned int len); 163 unsigned int encode (char *dst, u8 *src, unsigned int len) const;
128 unsigned int decode (u8 *dst, char *src, unsigned int len); 164 unsigned int decode (u8 *dst, char *src, unsigned int len) const;
129 165
130 basecoder (const char *cmap); 166 basecoder (const char *cmap);
131}; 167};
132 168
133basecoder::basecoder (const char *cmap) 169basecoder::basecoder (const char *cmap)
152 enc_len [len] = n; 188 enc_len [len] = n;
153 dec_len [n] = len; 189 dec_len [n] = len;
154 } 190 }
155} 191}
156 192
193unsigned int
157unsigned int basecoder::encode_len (unsigned int len) 194basecoder::encode_len (unsigned int len) const
158{ 195{
159 return enc_len [len]; 196 return enc_len [len];
160} 197}
161 198
199unsigned int
162unsigned int basecoder::decode_len (unsigned int len) 200basecoder::decode_len (unsigned int len) const
163{ 201{
164 while (len && !dec_len [len]) 202 while (len && !dec_len [len])
165 --len; 203 --len;
166 204
167 return dec_len [len]; 205 return dec_len [len];
168} 206}
169 207
208unsigned int
170unsigned int basecoder::encode (char *dst, u8 *src, unsigned int len) 209basecoder::encode (char *dst, u8 *src, unsigned int len) const
171{ 210{
172 if (!len || len > MAX_DEC_LEN) 211 if (!len || len > MAX_DEC_LEN)
173 return 0; 212 return 0;
174 213
175 int elen = encode_len (len); 214 int elen = encode_len (len);
194 *dst++ = cmap.encode [dst_ [i]]; 233 *dst++ = cmap.encode [dst_ [i]];
195 234
196 return elen; 235 return elen;
197} 236}
198 237
238unsigned int
199unsigned int basecoder::decode (u8 *dst, char *src, unsigned int len) 239basecoder::decode (u8 *dst, char *src, unsigned int len) const
200{ 240{
201 if (!len || len > MAX_ENC_LEN) 241 if (!len || len > MAX_ENC_LEN)
202 return 0; 242 return 0;
203 243
204 u8 src_ [MAX_ENC_LEN]; 244 u8 src_ [MAX_ENC_LEN];
253 } 293 }
254 abort (); 294 abort ();
255} 295}
256#endif 296#endif
257 297
258//static basecoder cdc64 ("_dDpPhHzZrR06QqMmjJkKBb34TtSsvVlL81xXaAeEFf92WwGgYyoO57UucCNniI-");
259//static basecoder cdc63 ("_dDpPhHzZrR06QqMmjJkKBb34TtSsvVlL81xXaAeEFf92WwGgYyoO57UucCNniI");
260static basecoder cdc62 ("dDpPhHzZrR06QqMmjJkKBb34TtSsvVlL81xXaAeEFf92WwGgYyoO57UucCNniI"); 298static basecoder cdc62 ("dDpPhHzZrR06QqMmjJkKBb34TtSsvVlL81xXaAeEFf92WwGgYyoO57UucCNniI"); // a-zA-Z0-9
261//static basecoder cdc36 ("dphzr06qmjkb34tsvl81xaef92wgyo57ucni"); // unused as of yet 299static basecoder cdc36 ("dPhZr06QmJkB34tSvL81xAeF92wGyO57uCnI"); // a-z0-9 for case-changers
262static basecoder cdc26 ("dPhZrQmJkBtSvLxAeFwGyO"); 300static basecoder cdc26 ("dPhZrQmJkBtSvLxAeFwGyOuCnI"); // a-z
263 301
264///////////////////////////////////////////////////////////////////////////// 302/////////////////////////////////////////////////////////////////////////////
265 303
266#define HDRSIZE 6 304#define HDRSIZE 5
267 305
306inline void
268inline void encode_header (char *data, int clientid, int seqno, int retry = 0) 307encode_header (char *data, int clientid, int seqno, int retry = 0)
269{ 308{
309 assert (clientid < 256);
310
270 seqno &= SEQNO_MASK; 311 seqno &= SEQNO_MASK;
271 312
272 u8 hdr[3] = { 313 u8 hdr[3] = {
314 seqno,
315 (seqno >> 8) | (retry << 6),
273 clientid, 316 clientid,
274 (seqno >> 8) | (retry << 6),
275 seqno,
276 }; 317 };
277 318
278 assert (clientid < 256);
279
280 cdc26.encode (data, hdr, 3); 319 cdc36.encode (data, hdr, 3);
281} 320}
282 321
322inline void
283inline void decode_header (char *data, int &clientid, int &seqno) 323decode_header (char *data, int &clientid, int &seqno)
284{ 324{
285 u8 hdr[3]; 325 u8 hdr[3];
286 326
287 cdc26.decode (hdr, data, HDRSIZE); 327 cdc36.decode (hdr, data, HDRSIZE);
288 328
289 clientid = hdr[0]; 329 clientid = hdr[2];
290 seqno = ((hdr[1] << 8) | hdr[2]) & SEQNO_MASK; 330 seqno = ((hdr[1] << 8) | hdr[0]) & SEQNO_MASK;
291} 331}
292 332
293///////////////////////////////////////////////////////////////////////////// 333/////////////////////////////////////////////////////////////////////////////
294 334
295struct byte_stream 335struct byte_stream
321byte_stream::~byte_stream () 361byte_stream::~byte_stream ()
322{ 362{
323 delete data; 363 delete data;
324} 364}
325 365
366void
326void byte_stream::remove (int count) 367byte_stream::remove (int count)
327{ 368{
328 if (count > fill) 369 if (count > fill)
329 assert (count <= fill); 370 assert (count <= fill);
330 371
331 memmove (data, data + count, fill -= count); 372 memmove (data, data + count, fill -= count);
332} 373}
333 374
375bool
334bool byte_stream::put (u8 *data, unsigned int datalen) 376byte_stream::put (u8 *data, unsigned int datalen)
335{ 377{
336 if (maxsize - fill < datalen) 378 if (maxsize - fill < datalen)
337 return false; 379 return false;
338 380
339 memcpy (this->data + fill, data, datalen); fill += datalen; 381 memcpy (this->data + fill, data, datalen); fill += datalen;
340 382
341 return true; 383 return true;
342} 384}
343 385
386bool
344bool byte_stream::put (vpn_packet *pkt) 387byte_stream::put (vpn_packet *pkt)
345{ 388{
346 if (maxsize - fill < pkt->len + 2) 389 if (maxsize - fill < pkt->len + 2)
347 return false; 390 return false;
348 391
349 data [fill++] = pkt->len >> 8; 392 data [fill++] = pkt->len >> 8;
354 return true; 397 return true;
355} 398}
356 399
357vpn_packet *byte_stream::get () 400vpn_packet *byte_stream::get ()
358{ 401{
402 if (fill < 2)
403 return 0;
404
359 unsigned int len; 405 unsigned int len;
360 406
361 for (;;) 407 for (;;)
362 { 408 {
363 len = (data [0] << 8) | data [1]; 409 len = (data [0] << 8) | data [1];
364 410
365 if (len <= MAXSIZE || fill < 2) 411 if (len <= MAXSIZE)
366 break; 412 break;
367 413
368 // TODO: handle this better than skipping, e.g. by reset 414 // TODO: handle this better than skipping, e.g. by reset
369 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]);
370 remove (1); 416 remove (1);
371 } 417 }
372 418
373 if (fill < len + 2) 419 if (fill < len + 2)
374 return 0; 420 return 0;
405 451
406struct dns_cfg 452struct dns_cfg
407{ 453{
408 static int next_uid; 454 static int next_uid;
409 455
410 u8 id1, id2, id3, id4; 456 u8 chksum;
457 u8 rrtype;
458 u16 uid; // to make request unique
411 459
412 u8 version; 460 u8 version;
413 u8 flags; 461 u8 flags;
414 u8 rrtype; 462 u16 max_size;
463
464 u8 id1, id2, id3, id4;
465
466 u16 client;
415 u8 def_ttl; 467 u8 def_ttl;
468 u8 r0;
416 469
417 u16 client; 470 u8 syn_cdc; // cdc en/decoder for syn (A?) requests
418 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
419 474
420 u16 max_size;
421 u8 seq_cdc;
422 u8 req_cdc;
423
424 u8 rep_cdc;
425 u8 delay; // time in 0.01s units that the server may delay replying packets
426 u8 r3, r4;
427
428 u8 r5, r6, r7, r8; 475 u8 r1, r2, r3, r4;
429 476
430 void reset (int clientid); 477 void reset (int clientid);
431 bool valid (); 478 bool valid ();
479 u8 get_chksum ();
432}; 480};
433 481
434int dns_cfg::next_uid; 482int dns_cfg::next_uid;
435 483
484void
436void dns_cfg::reset (int clientid) 485dns_cfg::reset (int clientid)
437{ 486{
487 // this ID must result in some mixed-case characters in cdc26-encoding
438 id1 = 'G'; 488 id1 = 'G';
439 id2 = 'V'; 489 id2 = 'V';
440 id3 = 'P'; 490 id3 = 'P';
441 id4 = 'E'; 491 id4 = 'E';
442 492
443 version = 1; 493 version = 2;
444 494
445 rrtype = RR_TYPE_TXT; 495 rrtype = RR_TYPE_TXT;
446 flags = 0; 496 flags = 0;
447 def_ttl = 0; 497 def_ttl = 0;
448 seq_cdc = 26; 498 syn_cdc = 26;
449 req_cdc = 62; 499 hdr_cdc = 36;
500 req_cdc = conf.dns_case_preserving ? 62 : 36;
450 rep_cdc = 0; 501 rep_cdc = 0;
451 max_size = htons (MAX_PKT_SIZE); 502 max_size = htons (MAX_PKT_SIZE);
452 client = htons (clientid); 503 client = htons (clientid);
453 uid = next_uid++; 504 uid = ++next_uid;
454 delay = 0;
455 505
456 r3 = r4 = 0; 506 r0 = r1 = r2 = r3 = r4 = 0;
457 r4 = r5 = r6 = r7 = 0;
458}
459 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
460bool dns_cfg::valid () 529dns_cfg::valid ()
461{ 530{
531 // although the protocol itself allows for some configurability,
532 // only the following encoding/decoding settings are implemented.
462 return id1 == 'G' 533 return id1 == 'G'
463 && id2 == 'V' 534 && id2 == 'V'
464 && id3 == 'P' 535 && id3 == 'P'
465 && id4 == 'E' 536 && id4 == 'E'
537 && version == 2
466 && seq_cdc == 26 538 && syn_cdc == 26
467 && req_cdc == 62 539 && hdr_cdc == 36
540 && (req_cdc == 36 || req_cdc == 62)
468 && rep_cdc == 0 541 && rep_cdc == 0
469 && version == 1; 542 && chksum == get_chksum ();
470} 543}
471 544
472struct dns_packet : net_packet 545struct dns_packet : net_packet
473{ 546{
474 u16 id; 547 u16 id;
478 u8 data [MAXSIZE - 6 * 2]; 551 u8 data [MAXSIZE - 6 * 2];
479 552
480 int decode_label (char *data, int size, int &offs); 553 int decode_label (char *data, int size, int &offs);
481}; 554};
482 555
556int
483int dns_packet::decode_label (char *data, int size, int &offs) 557dns_packet::decode_label (char *data, int size, int &offs)
484{ 558{
485 char *orig = data; 559 char *orig = data;
486 560
487 memset (data, 0, size); 561 memset (data, 0, size);
488 562
514 return data - orig; 588 return data - orig;
515} 589}
516 590
517///////////////////////////////////////////////////////////////////////////// 591/////////////////////////////////////////////////////////////////////////////
518 592
593static
594u16 next_id ()
595{
519static u16 dns_id = 0; // TODO: should be per-vpn 596 static u16 dns_id = 0; // TODO: should be per-vpn
520 597
521static u16 next_id () 598#if 1
522{
523 if (!dns_id) 599 if (!dns_id)
524 dns_id = time (0); 600 dns_id = time (0);
525 601
526 // the simplest lsfr with periodicity 65535 i could find 602 // the simplest lsfr with periodicity 65535 i could find
527 dns_id = (dns_id << 1) 603 dns_id = (dns_id << 1)
529 ^ (dns_id >> 2) 605 ^ (dns_id >> 2)
530 ^ (dns_id >> 4) 606 ^ (dns_id >> 4)
531 ^ (dns_id >> 15)) & 1); 607 ^ (dns_id >> 15)) & 1);
532 608
533 return dns_id; 609 return dns_id;
610#else
611 dns_id++;//D
612
613 return htons (dns_id);
614#endif
534} 615}
535 616
536struct dns_rcv; 617struct dns_rcv;
537struct dns_snd; 618struct dns_snd;
538 619
542 struct vpn *vpn; 623 struct vpn *vpn;
543 624
544 dns_cfg cfg; 625 dns_cfg cfg;
545 626
546 bool established; 627 bool established;
628 const basecoder *cdc;
547 629
548 tstamp last_received; 630 tstamp last_received;
549 tstamp last_sent; 631 tstamp last_sent;
550 double min_latency; 632 double min_latency;
551 double poll_interval, send_interval; 633 double poll_interval, send_interval;
553 vector<dns_rcv *> rcvpq; 635 vector<dns_rcv *> rcvpq;
554 636
555 byte_stream rcvdq; int rcvseq; int repseq; 637 byte_stream rcvdq; int rcvseq; int repseq;
556 byte_stream snddq; int sndseq; 638 byte_stream snddq; int sndseq;
557 639
558 void time_cb (time_watcher &w); time_watcher tw; 640 inline void time_cb (ev::timer &w, int revents); ev::timer tw;
559 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
560 645
561 dns_connection (connection *c); 646 dns_connection (connection *c);
562 ~dns_connection (); 647 ~dns_connection ();
563}; 648};
564 649
582: dns (dns) 667: dns (dns)
583{ 668{
584 timeout = 0; 669 timeout = 0;
585 retry = 0; 670 retry = 0;
586 seqno = 0; 671 seqno = 0;
587 sent = NOW; 672 sent = ev_now ();
588 stdhdr = false; 673 stdhdr = false;
589 674
590 pkt = new dns_packet; 675 pkt = new dns_packet;
591 676
592 pkt->id = next_id (); 677 pkt->id = next_id ();
595dns_snd::~dns_snd () 680dns_snd::~dns_snd ()
596{ 681{
597 delete pkt; 682 delete pkt;
598} 683}
599 684
685static void
600static void append_domain (dns_packet &pkt, int &offs, const char *domain) 686append_domain (dns_packet &pkt, int &offs, const char *domain)
601{ 687{
602 // add tunnel domain 688 // add tunnel domain
603 for (;;) 689 for (;;)
604 { 690 {
605 const char *end = strchr (domain, '.'); 691 const char *end = strchr (domain, '.');
618 704
619 domain = end + 1; 705 domain = end + 1;
620 } 706 }
621} 707}
622 708
709void
623void dns_snd::gen_stream_req (int seqno, byte_stream &stream) 710dns_snd::gen_stream_req (int seqno, byte_stream &stream)
624{ 711{
625 stdhdr = true; 712 stdhdr = true;
626 this->seqno = seqno; 713 this->seqno = seqno;
627 714
628 timeout = NOW + INITIAL_TIMEOUT; 715 timeout = ev_now () + INITIAL_TIMEOUT;
629 716
630 pkt->flags = htons (DEFAULT_CLIENT_FLAGS); 717 pkt->flags = htons (DEFAULT_CLIENT_FLAGS);
631 pkt->qdcount = htons (1); 718 pkt->qdcount = htons (1);
632 719
633 int offs = 6*2; 720 int offs = 6*2;
636 // 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
637 724
638 char enc[256], *encp = enc; 725 char enc[256], *encp = enc;
639 encode_header (enc, THISNODE->id, seqno); 726 encode_header (enc, THISNODE->id, seqno);
640 727
641 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);
642 729
643 if (datalen > stream.size ()) 730 if (datalen > stream.size ())
644 datalen = stream.size (); 731 datalen = stream.size ();
645 732
646 int enclen = cdc62.encode (enc + HDRSIZE, stream.begin (), datalen) + HDRSIZE; 733 int enclen = dns->cdc->encode (enc + HDRSIZE, stream.begin (), datalen) + HDRSIZE;
647 stream.remove (datalen); 734 stream.remove (datalen);
648 735
649 while (enclen) 736 while (enclen)
650 { 737 {
651 int lbllen = enclen < MAX_LBL_SIZE ? enclen : MAX_LBL_SIZE; 738 int lbllen = enclen < MAX_LBL_SIZE ? enclen : MAX_LBL_SIZE;
666 (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN; 753 (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN;
667 754
668 pkt->len = offs; 755 pkt->len = offs;
669} 756}
670 757
758void
671void dns_snd::gen_syn_req () 759dns_snd::gen_syn_req ()
672{ 760{
673 timeout = NOW + INITIAL_SYN_TIMEOUT; 761 timeout = ev_now () + INITIAL_SYN_TIMEOUT;
674 762
675 pkt->flags = htons (DEFAULT_CLIENT_FLAGS); 763 pkt->flags = htons (DEFAULT_CLIENT_FLAGS);
676 pkt->qdcount = htons (1); 764 pkt->qdcount = htons (1);
677 765
678 int offs = 6 * 2; 766 int offs = 6 * 2;
718 806
719dns_connection::dns_connection (connection *c) 807dns_connection::dns_connection (connection *c)
720: c (c) 808: c (c)
721, rcvdq (MAX_BACKLOG * 2) 809, rcvdq (MAX_BACKLOG * 2)
722, snddq (MAX_BACKLOG) 810, snddq (MAX_BACKLOG)
723, tw (this, &dns_connection::time_cb)
724{ 811{
812 tw.set<dns_connection, &dns_connection::time_cb> (this);
813
725 vpn = c->vpn; 814 vpn = c->vpn;
726 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
727 established = false; 840 established = false;
728 841
729 rcvseq = repseq = sndseq = 0; 842 rcvseq = repseq = sndseq = 0;
730 843
731 last_sent = last_received = 0; 844 last_sent = 0;
732 poll_interval = 0.5; // starting here 845 poll_interval = 0.5; // starting here
733 send_interval = 0.5; // starting rate 846 send_interval = 0.5; // starting rate
734 min_latency = INITIAL_TIMEOUT; 847 min_latency = INITIAL_TIMEOUT;
735} 848}
736 849
737dns_connection::~dns_connection () 850void
851dns_connection::set_cfg ()
738{ 852{
739 for (vector<dns_rcv *>::iterator i = rcvpq.begin (); 853 cdc = cfg.req_cdc == 36 ? &cdc36 : &cdc62;
740 i != rcvpq.end ();
741 ++i)
742 delete *i;
743} 854}
744 855
856void
745void dns_connection::receive_rep (dns_rcv *r) 857dns_connection::receive_rep (dns_rcv *r)
746{ 858{
747 if (r->datalen) 859 if (r->datalen)
748 { 860 poll_interval = max (poll_interval * (1. / 1.2), MIN_POLL_INTERVAL);
749 last_received = NOW;
750 tw.trigger ();
751
752 poll_interval = send_interval;
753 }
754 else 861 else
755 { 862 poll_interval = min (poll_interval * 1.1, MAX_POLL_INTERVAL);
756 poll_interval *= 1.5;
757
758 if (poll_interval > MAX_POLL_INTERVAL)
759 poll_interval = MAX_POLL_INTERVAL;
760 }
761 863
762 rcvpq.push_back (r); 864 rcvpq.push_back (r);
763 865
764 redo: 866 redo:
765 867
766 // find next packet 868 // find next packet
767 for (vector<dns_rcv *>::iterator i = rcvpq.end (); i-- != rcvpq.begin (); ) 869 for (vector<dns_rcv *>::iterator i = rcvpq.end (); i-- != rcvpq.begin (); )
768 if (SEQNO_EQ (rcvseq, (*i)->seqno)) 870 if (SEQNO_EQ (rcvseq, (*i)->seqno))
769 { 871 {
872 //printf ("seqno eq %x %x\n", rcvseq, (*i)->seqno);//D
770 // enter the packet into our input stream 873 // enter the packet into our input stream
771 r = *i; 874 r = *i;
772 875
773 // remove the oldest packet, look forward, as it's oldest first 876 // remove the oldest packet, look forward, as it's oldest first
774 for (vector<dns_rcv *>::iterator j = rcvpq.begin (); j != rcvpq.end (); ++j) 877 for (vector<dns_rcv *>::iterator j = rcvpq.begin (); j != rcvpq.end (); ++j)
775 if (SEQNO_EQ ((*j)->seqno, rcvseq - MAX_WINDOW)) 878 if (SEQNO_EQ ((*j)->seqno, rcvseq - MAX_WINDOW))
776 { 879 {
880 //printf ("seqno RR %x %x\n", (*j)->seqno, rcvseq - MAX_WINDOW);//D
777 delete *j; 881 delete *j;
778 rcvpq.erase (j); 882 rcvpq.erase (j);
779 break; 883 break;
780 } 884 }
781 885
782 rcvseq = (rcvseq + 1) & SEQNO_MASK; 886 rcvseq = (rcvseq + 1) & SEQNO_MASK;
783 887
784 if (!rcvdq.put (r->data, r->datalen)) 888 if (!rcvdq.put (r->data, r->datalen))
785 { 889 {
890 // MUST never overflow, can be caused by data corruption, TODO
786 slog (L_ERR, "DNS: !rcvdq.put (r->data, r->datalen)"); 891 slog (L_CRIT, "DNS: !rcvdq.put (r->data, r->datalen)");
787 abort (); // MUST never overflow, can be caused by data corruption, TODO 892 reset ();
893 return;
788 } 894 }
789 895
790 while (vpn_packet *pkt = rcvdq.get ()) 896 while (vpn_packet *pkt = rcvdq.get ())
791 { 897 {
792 sockinfo si; 898 sockinfo si;
793 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;
794 900
795 vpn->recv_vpn_packet (pkt, si); 901 vpn->recv_vpn_packet (pkt, si);
796
797 delete pkt; 902 delete pkt;
798 } 903 }
799 904
800 // check for further packets 905 // check for further packets
801 goto redo; 906 goto redo;
844 { 949 {
845 // correct class, domain: parse 950 // correct class, domain: parse
846 int client, seqno; 951 int client, seqno;
847 decode_header (qname, client, seqno); 952 decode_header (qname, client, seqno);
848 953
849 u8 data[MAXSIZE];
850 int datalen = cdc62.decode (data, qname + HDRSIZE, qlen - (dlen + 1 + HDRSIZE));
851
852 if (0 < client && client <= conns.size ()) 954 if (0 < client && client <= conns.size ())
853 { 955 {
854 connection *c = conns [client - 1]; 956 connection *c = conns [client - 1];
855 dns_connection *dns = c->dns; 957 dns_connection *dns = c->dns;
856 dns_rcv *rcv; 958 dns_rcv *rcv;
857 959
858 if (dns) 960 if (dns)
859 { 961 {
962 u8 data[MAXSIZE];
963 int datalen = dns->cdc->decode (data, qname + HDRSIZE, qlen - (dlen + 1 + HDRSIZE));
964
860 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 (); )
861 if (SEQNO_EQ ((*i)->seqno, seqno)) 966 if (SEQNO_EQ ((*i)->seqno, seqno))
862 { 967 {
863 // already seen that request: simply reply with the cached reply 968 // already seen that request: simply reply with the cached reply
864 dns_rcv *r = *i; 969 dns_rcv *r = *i;
965 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
966 pkt [offs++] = 0; pkt [offs++] = 0; 1071 pkt [offs++] = 0; pkt [offs++] = 0;
967 pkt [offs++] = 0; pkt [offs++] = cfg.def_ttl; // TTL 1072 pkt [offs++] = 0; pkt [offs++] = cfg.def_ttl; // TTL
968 pkt [offs++] = 0; pkt [offs++] = 4; // rdlength 1073 pkt [offs++] = 0; pkt [offs++] = 4; // rdlength
969 1074
970 slog (L_INFO, _("DNS: client %d connects"), client);
971
972 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;
973 pkt [offs++] = CMD_IP_REJ; 1076 pkt [offs++] = CMD_IP_REJ;
974 1077
975 if (0 < client && client <= conns.size ()) 1078 if (0 < client && client <= conns.size ())
976 { 1079 {
977 connection *c = conns [client - 1]; 1080 connection *c = conns [client - 1];
978 1081
979 if (cfg.valid ()) 1082 if (cfg.valid ())
980 { 1083 {
981 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));
982 1089
983 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
984 c->dns = new dns_connection (c); 1095 c->dns = new dns_connection (c);
985 c->dns->cfg = cfg; 1096 c->dns->cfg = cfg;
1097 c->dns->set_cfg ();
986 } 1098 }
987 } 1099 }
988 } 1100 }
989 } 1101 }
990 1102
1009 { 1121 {
1010 dns_connection *dns = (*i)->dns; 1122 dns_connection *dns = (*i)->dns;
1011 connection *c = dns->c; 1123 connection *c = dns->c;
1012 int seqno = (*i)->seqno; 1124 int seqno = (*i)->seqno;
1013 u8 data[MAXSIZE], *datap = data; 1125 u8 data[MAXSIZE], *datap = data;
1126 //printf ("rcv pkt %x\n", seqno);//D
1014 1127
1015 if ((*i)->retry) 1128 if ((*i)->retry)
1016 { 1129 {
1017 dns->send_interval *= 1.01; 1130 dns->send_interval *= 1.01;
1018 if (dns->send_interval > MAX_SEND_INTERVAL) 1131 if (dns->send_interval > MAX_SEND_INTERVAL)
1023#if 0 1136#if 0
1024 dns->send_interval *= 0.999; 1137 dns->send_interval *= 0.999;
1025#endif 1138#endif
1026 // the latency surely puts an upper bound on 1139 // the latency surely puts an upper bound on
1027 // the minimum send interval 1140 // the minimum send interval
1028 double latency = NOW - (*i)->sent; 1141 double latency = ev_now () - (*i)->sent;
1029 1142
1030 if (latency < dns->min_latency) 1143 if (latency < dns->min_latency)
1031 dns->min_latency = latency; 1144 dns->min_latency = latency;
1032 1145
1033 if (dns->send_interval > dns->min_latency * conf.dns_overlap_factor) 1146 if (dns->send_interval > dns->min_latency * conf.dns_overlap_factor)
1060 ttl |= pkt [offs++] << 16; 1173 ttl |= pkt [offs++] << 16;
1061 ttl |= pkt [offs++] << 8; 1174 ttl |= pkt [offs++] << 8;
1062 ttl |= pkt [offs++]; 1175 ttl |= pkt [offs++];
1063 u16 rdlen = pkt [offs++] << 8; rdlen |= pkt [offs++]; 1176 u16 rdlen = pkt [offs++] << 8; rdlen |= pkt [offs++];
1064 1177
1065 if (qtype == RR_TYPE_NULL || qtype == RR_TYPE_TXT) 1178 if (qtype == RR_TYPE_NULL || qtype == RR_TYPE_TXT || qtype == dns->cfg.rrtype)
1066 { 1179 {
1067 if (rdlen <= MAXSIZE - offs) 1180 if (rdlen <= MAXSIZE - offs)
1068 { 1181 {
1069 // decode bytes, finally 1182 // decode bytes, finally
1070 1183
1096 { 1209 {
1097 slog (L_TRACE, _("DNS: got tunnel meta command %02x"), ip [3]); 1210 slog (L_TRACE, _("DNS: got tunnel meta command %02x"), ip [3]);
1098 1211
1099 if (ip [3] == CMD_IP_RST) 1212 if (ip [3] == CMD_IP_RST)
1100 { 1213 {
1101 slog (L_DEBUG, _("DNS: got tunnel RST request")); 1214 slog (L_DEBUG, _("DNS: got tunnel RST request."));
1102 1215
1103 delete dns; c->dns = 0; 1216 dns->reset ();
1104
1105 return; 1217 return;
1106 } 1218 }
1107 else if (ip [3] == CMD_IP_SYN) 1219 else if (ip [3] == CMD_IP_SYN)
1108 { 1220 {
1109 slog (L_DEBUG, _("DNS: got tunnel SYN reply, server likes us.")); 1221 slog (L_DEBUG, _("DNS: got tunnel SYN reply, server likes us."));
1110 dns->established = true; 1222 dns->established = true;
1111 } 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 }
1112 else if (ip [3] == CMD_IP_REJ) 1239 else if (ip [3] == CMD_IP_REJ)
1113 { 1240 {
1114 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."));
1115 abort (); 1242 dns->tw.start (60.);
1116 } 1243 }
1117 else 1244 else
1245 {
1118 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 }
1119 } 1249 }
1120 else 1250 else
1121 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"),
1122 ip [0], ip [1], ip [2], ip [3]); 1252 ip [0], ip [1], ip [2], ip [3]);
1123 1253
1147 break; 1277 break;
1148 } 1278 }
1149} 1279}
1150 1280
1151void 1281void
1152vpn::dnsv4_ev (io_watcher &w, short revents) 1282vpn::dnsv4_ev (ev::io &w, int revents)
1153{ 1283{
1154 if (revents & EVENT_READ) 1284 if (revents & EV_READ)
1155 { 1285 {
1156 dns_packet *pkt = new dns_packet; 1286 dns_packet *pkt = new dns_packet;
1157 struct sockaddr_in sa; 1287 struct sockaddr_in sa;
1158 socklen_t sa_len = sizeof (sa); 1288 socklen_t sa_len = sizeof (sa);
1159 1289
1185 1315
1186 if (!c->dns) 1316 if (!c->dns)
1187 c->dns = new dns_connection (c); 1317 c->dns = new dns_connection (c);
1188 1318
1189 if (c->dns->snddq.put (pkt)) 1319 if (c->dns->snddq.put (pkt))
1320 {
1321 min_it (c->dns->poll_interval, 0.25);
1190 c->dns->tw.trigger (); 1322 c->dns->tw ();
1323 }
1191 1324
1192 // always return true even if the buffer overflows 1325 // always return true even if the buffer overflows
1193 return true; 1326 return true;
1194} 1327}
1195 1328
1196void 1329void
1197connection::dnsv4_reset_connection () 1330dns_connection::time_cb (ev::timer &w, int revents)
1198{
1199 //delete dns; dns = 0; //TODO
1200}
1201
1202#define NEXT(w) do { if (next > (w)) next = w; } while (0)
1203
1204void
1205dns_connection::time_cb (time_watcher &w)
1206{ 1331{
1207 // servers have to be polled 1332 // servers have to be polled
1208 if (THISNODE->dns_port) 1333 if (THISNODE->dns_port)
1209 return; 1334 return;
1210 1335
1211 // check for timeouts and (re)transmit 1336 // check for timeouts and (re)transmit
1212 tstamp next = NOW + poll_interval; 1337 tstamp next = 86400 * 365;
1213 dns_snd *send = 0; 1338 dns_snd *send = 0;
1214 1339
1215 for (vector<dns_snd *>::iterator i = vpn->dns_sndpq.begin (); 1340 for (vector<dns_snd *>::iterator i = vpn->dns_sndpq.begin ();
1216 i != vpn->dns_sndpq.end (); 1341 i != vpn->dns_sndpq.end ();
1217 ++i) 1342 ++i)
1218 { 1343 {
1219 dns_snd *r = *i; 1344 dns_snd *r = *i;
1220 1345
1221 if (r->timeout <= NOW) 1346 if (r->timeout <= ev_now ())
1222 { 1347 {
1223 if (!send) 1348 if (!send)
1224 { 1349 {
1225 send = r; 1350 send = r;
1226 1351
1227 r->retry++; 1352 r->retry++;
1228 r->timeout = NOW + (r->retry * min_latency * conf.dns_timeout_factor); 1353 r->timeout = ev_now () + r->retry * min_latency * conf.dns_timeout_factor;
1354 //printf ("RETRY %x (%d, %f)\n", r->seqno, r->retry, r->timeout - ev_now ());//D
1229 1355
1230 // the following code changes the query section a bit, forcing 1356 // the following code changes the query section a bit, forcing
1231 // the forwarder to generate a new request 1357 // the forwarder to generate a new request
1232 if (r->stdhdr) 1358 if (r->stdhdr)
1233 {
1234 //printf ("reencoded header for ID %d retry %d:%d:%d (%p)\n", htons (r->pkt->id), THISNODE->id, r->seqno, r->retry);
1235 //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);
1236 }
1237 } 1360 }
1238 } 1361 }
1239 else 1362 else
1240 NEXT (r->timeout); 1363 min_it (next, r->timeout - ev_now ());
1241 } 1364 }
1242 1365
1243 if (!send) 1366 if (!send)
1244 { 1367 {
1245 // generate a new packet, if wise 1368 // generate a new packet, if wise
1249 if (vpn->dns_sndpq.empty ()) 1372 if (vpn->dns_sndpq.empty ())
1250 { 1373 {
1251 send = new dns_snd (this); 1374 send = new dns_snd (this);
1252 1375
1253 cfg.reset (THISNODE->id); 1376 cfg.reset (THISNODE->id);
1377 set_cfg ();
1254 send->gen_syn_req (); 1378 send->gen_syn_req ();
1255 } 1379 }
1256 } 1380 }
1257 else if (vpn->dns_sndpq.size () < conf.dns_max_outstanding 1381 else if (vpn->dns_sndpq.size () < conf.dns_max_outstanding
1258 && !SEQNO_EQ (rcvseq, sndseq - (MAX_WINDOW - 1))) 1382 && !SEQNO_EQ (rcvseq, sndseq - (MAX_WINDOW - 1)))
1259 { 1383 {
1260 if (last_sent + send_interval <= NOW) 1384 if (last_sent + send_interval <= ev_now ())
1261 { 1385 {
1262 //printf ("sending data request etc.\n"); //D 1386 //printf ("sending data request etc.\n"); //D
1263 if (!snddq.empty () || last_received + 1. > NOW) 1387 if (!snddq.empty ())
1264 {
1265 poll_interval = send_interval;
1266 NEXT (NOW + send_interval); 1388 min_it (next, send_interval);
1267 }
1268 1389
1269 send = new dns_snd (this); 1390 send = new dns_snd (this);
1270 send->gen_stream_req (sndseq, snddq); 1391 send->gen_stream_req (sndseq, snddq);
1271 send->timeout = NOW + min_latency * conf.dns_timeout_factor; 1392 send->timeout = ev_now () + min_latency * conf.dns_timeout_factor;
1393 //printf ("SEND %x (%f)\n", send->seqno, send->timeout - ev_now (), min_latency, conf.dns_timeout_factor);//D
1272 1394
1273 sndseq = (sndseq + 1) & SEQNO_MASK; 1395 sndseq = (sndseq + 1) & SEQNO_MASK;
1274 } 1396 }
1275 else 1397 else
1276 NEXT (last_sent + send_interval); 1398 min_it (next, last_sent + send_interval - ev_now ());
1277 } 1399 }
1278 1400
1279 if (send) 1401 if (send)
1280 vpn->dns_sndpq.push_back (send); 1402 vpn->dns_sndpq.push_back (send);
1281 } 1403 }
1282 1404
1283 if (send) 1405 if (send)
1284 { 1406 {
1285 last_sent = NOW; 1407 last_sent = ev_now ();
1286 sendto (vpn->dnsv4_fd, 1408 sendto (vpn->dnsv4_fd,
1287 send->pkt->at (0), send->pkt->len, 0, 1409 send->pkt->at (0), send->pkt->len, 0,
1288 vpn->dns_forwarder.sav4 (), vpn->dns_forwarder.salenv4 ()); 1410 vpn->dns_forwarder.sav4 (), vpn->dns_forwarder.salenv4 ());
1289 } 1411 }
1290 1412
1413 min_it (next, last_sent + max (poll_interval, send_interval) - ev_now ());
1414
1291 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)",
1292 poll_interval, send_interval, next - NOW, 1416 poll_interval, send_interval, next - ev_now (),
1293 vpn->dns_sndpq.size (), snddq.size (), 1417 vpn->dns_sndpq.size (), snddq.size (),
1294 rcvpq.size ()); 1418 rcvpq.size ());
1295 1419
1296 // TODO: no idea when this happens, but when next < NOW, we have a problem
1297 // doesn't seem to happen anymore
1298 if (next < NOW + 0.001)
1299 next = NOW + 0.1;
1300
1301 w.start (next); 1420 w.start (next);
1302} 1421}
1303 1422
1304#endif 1423#endif
1305 1424

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines