ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/vpn_dns.C
Revision: 1.48
Committed: Tue Jul 28 00:42:14 2009 UTC (14 years, 10 months ago) by pcg
Content type: text/plain
Branch: MAIN
Changes since 1.47: +1 -0 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 pcg 1.1 /*
2     vpn_dns.C -- handle the dns tunnel part of the protocol.
3 pcg 1.47 Copyright (C) 2003-2008 Marc Lehmann <gvpe@schmorp.de>
4 pcg 1.1
5 pcg 1.7 This file is part of GVPE.
6    
7 pcg 1.47 GVPE is free software; you can redistribute it and/or modify it
8     under the terms of the GNU General Public License as published by the
9     Free Software Foundation; either version 3 of the License, or (at your
10     option) any later version.
11    
12     This program is distributed in the hope that it will be useful, but
13     WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15     Public License for more details.
16    
17     You should have received a copy of the GNU General Public License along
18     with this program; if not, see <http://www.gnu.org/licenses/>.
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.
30 pcg 1.1 */
31    
32 pcg 1.38 // 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.
35    
36 pcg 1.1 #include "config.h"
37    
38     #if ENABLE_DNS
39    
40     // dns processing is EXTREMELY ugly. For obvious(?) reasons.
41     // it's a hack, use only in emergency situations please.
42    
43     #include <cstring>
44 pcg 1.20 #include <cassert>
45 pcg 1.1
46     #include <sys/types.h>
47     #include <sys/socket.h>
48     #include <sys/wait.h>
49     #include <sys/uio.h>
50     #include <errno.h>
51     #include <time.h>
52     #include <unistd.h>
53     #include <fcntl.h>
54    
55     #include <map>
56    
57 pcg 1.44 #include <cstdio> /* bug in libgmp: gmp.h relies on cstdio being included */
58 pcg 1.8 #include <gmp.h>
59    
60 pcg 1.1 #include "netcompat.h"
61    
62     #include "vpn.h"
63    
64 pcg 1.30 #define MAX_POLL_INTERVAL 5. // how often to poll minimally when the server has no data
65 pcg 1.10 #define ACTIVITY_INTERVAL 5.
66    
67 pcg 1.17 #define INITIAL_TIMEOUT 0.1 // retry timeouts
68 pcg 1.36 #define INITIAL_SYN_TIMEOUT 2. // retry timeout for initial syn
69 pcg 1.10
70 pcg 1.27 #define MAX_SEND_INTERVAL 2. // optimistic?
71 pcg 1.1
72 pcg 1.17 #define MAX_WINDOW 1000 // max. for MAX_OUTSTANDING, and backlog
73 pcg 1.35 #define MAX_BACKLOG (64*1024) // size of gvpe protocol backlog (bytes), must be > MAXSIZE
74 pcg 1.5
75 pcg 1.34 #define MAX_DOMAIN_SIZE 240 // 255 is legal limit, but bind doesn't compress well
76 pcg 1.5 // 240 leaves about 4 bytes of server reply data
77 pcg 1.33 // every request byte less give room for two reply bytes
78 pcg 1.5
79 pcg 1.32 #define SEQNO_MASK 0x3fff
80 pcg 1.8 #define SEQNO_EQ(a,b) ( 0 == ( ((a) ^ (b)) & SEQNO_MASK) )
81 pcg 1.1
82 pcg 1.8 #define MAX_LBL_SIZE 63
83     #define MAX_PKT_SIZE 512
84 pcg 1.1
85 pcg 1.10 #define RR_TYPE_A 1
86     #define RR_TYPE_NULL 10
87     #define RR_TYPE_TXT 16
88 pcg 1.48 #define RR_TYPE_AAAA 28
89 pcg 1.8 #define RR_TYPE_ANY 255
90 pcg 1.10
91     #define RR_CLASS_IN 1
92    
93     #define CMD_IP_1 207
94     #define CMD_IP_2 46
95     #define CMD_IP_3 236
96     #define CMD_IP_RST 29
97     #define CMD_IP_SYN 113
98     #define CMD_IP_REJ 32
99 pcg 1.1
100 pcg 1.8 // works for cmaps up to 255 (not 256!)
101     struct charmap
102     {
103     enum { INVALID = (u8)255 };
104 pcg 1.1
105 pcg 1.8 char encode [256]; // index => char
106     u8 decode [256]; // char => index
107     unsigned int size;
108 pcg 1.2
109 pcg 1.8 charmap (const char *cmap);
110     };
111    
112     charmap::charmap (const char *cmap)
113     {
114     char *enc = encode;
115     u8 *dec = decode;
116 pcg 1.2
117 pcg 1.8 memset (enc, (char) 0, 256);
118     memset (dec, (char)INVALID, 256);
119 pcg 1.1
120 pcg 1.8 for (size = 0; cmap [size]; size++)
121     {
122     enc [size] = cmap [size];
123     dec [(u8)enc [size]] = size;
124     }
125 pcg 1.1
126 pcg 1.8 assert (size < 256);
127     }
128 pcg 1.2
129 pcg 1.8 #define MAX_DEC_LEN 500
130     #define MAX_ENC_LEN (MAX_DEC_LEN * 2)
131     #define MAX_LIMBS ((MAX_DEC_LEN * 8 + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS)
132 pcg 1.2
133 pcg 1.8 // ugly. minimum base is 16(!)
134     struct basecoder
135 pcg 1.2 {
136 pcg 1.8 charmap cmap;
137     unsigned int enc_len [MAX_DEC_LEN];
138     unsigned int dec_len [MAX_ENC_LEN];
139 pcg 1.2
140 pcg 1.8 unsigned int encode_len (unsigned int len);
141     unsigned int decode_len (unsigned int len);
142    
143     unsigned int encode (char *dst, u8 *src, unsigned int len);
144     unsigned int decode (u8 *dst, char *src, unsigned int len);
145    
146     basecoder (const char *cmap);
147     };
148    
149     basecoder::basecoder (const char *cmap)
150     : cmap (cmap)
151     {
152     for (unsigned int len = 0; len < MAX_DEC_LEN; ++len)
153     {
154     u8 src [MAX_DEC_LEN];
155     u8 dst [MAX_ENC_LEN];
156 pcg 1.2
157 pcg 1.8 memset (src, 255, len);
158 pcg 1.2
159 pcg 1.8 mp_limb_t m [MAX_LIMBS];
160     mp_size_t n;
161    
162     n = mpn_set_str (m, src, len, 256);
163     n = mpn_get_str (dst, this->cmap.size, m, n);
164    
165     for (int i = 0; !dst [i]; ++i)
166     n--;
167    
168     enc_len [len] = n;
169     dec_len [n] = len;
170     }
171     }
172    
173     unsigned int basecoder::encode_len (unsigned int len)
174     {
175     return enc_len [len];
176     }
177 pcg 1.2
178 pcg 1.8 unsigned int basecoder::decode_len (unsigned int len)
179 pcg 1.2 {
180 pcg 1.8 while (len && !dec_len [len])
181     --len;
182    
183     return dec_len [len];
184 pcg 1.2 }
185    
186 pcg 1.8 unsigned int basecoder::encode (char *dst, u8 *src, unsigned int len)
187 pcg 1.2 {
188 pcg 1.10 if (!len || len > MAX_DEC_LEN)
189 pcg 1.8 return 0;
190    
191     int elen = encode_len (len);
192    
193     mp_limb_t m [MAX_LIMBS];
194     mp_size_t n;
195    
196     u8 dst_ [MAX_ENC_LEN];
197    
198     n = mpn_set_str (m, src, len, 256);
199     n = mpn_get_str (dst_, cmap.size, m, n);
200    
201     int plen = elen; // for padding
202 pcg 1.2
203 pcg 1.8 while (n < plen)
204 pcg 1.2 {
205 pcg 1.8 *dst++ = cmap.encode [0];
206     plen--;
207 pcg 1.2 }
208    
209 pcg 1.8 for (unsigned int i = n - plen; i < n; ++i)
210     *dst++ = cmap.encode [dst_ [i]];
211 pcg 1.4
212 pcg 1.8 return elen;
213 pcg 1.2 }
214    
215 pcg 1.8 unsigned int basecoder::decode (u8 *dst, char *src, unsigned int len)
216 pcg 1.2 {
217 pcg 1.10 if (!len || len > MAX_ENC_LEN)
218 pcg 1.8 return 0;
219    
220     u8 src_ [MAX_ENC_LEN];
221     unsigned int elen = 0;
222 pcg 1.2
223     while (len--)
224     {
225 pcg 1.8 u8 val = cmap.decode [(u8)*src++];
226 pcg 1.2
227 pcg 1.8 if (val != charmap::INVALID)
228     src_ [elen++] = val;
229     }
230    
231     int dlen = decode_len (elen);
232    
233     mp_limb_t m [MAX_LIMBS];
234     mp_size_t n;
235    
236     u8 dst_ [MAX_DEC_LEN];
237 pcg 1.2
238 pcg 1.8 n = mpn_set_str (m, src_, elen, cmap.size);
239     n = mpn_get_str (dst_, 256, m, n);
240 pcg 1.2
241 pcg 1.8 if (n < dlen)
242     {
243     memset (dst, 0, dlen - n);
244     memcpy (dst + dlen - n, dst_, n);
245 pcg 1.2 }
246 pcg 1.8 else
247     memcpy (dst, dst_ + n - dlen, dlen);
248 pcg 1.4
249 pcg 1.8 return dlen;
250     }
251    
252     #if 0
253     struct test { test (); } test;
254    
255     test::test ()
256     {
257     basecoder cdc ("0123456789abcdefghijklmnopqrstuvwxyz");
258    
259     u8 in[] = "0123456789abcdefghijklmnopqrstuvwxyz";
260     static char enc[200];
261     static u8 dec[200];
262    
263     for (int i = 1; i < 20; i++)
264     {
265     int elen = cdc.encode (enc, in, i);
266     int dlen = cdc.decode (dec, enc, elen);
267    
268     printf ("%d>%d>%d (%s>%s)\n", i, elen, dlen, enc, dec);
269     }
270     abort ();
271     }
272     #endif
273    
274 pcg 1.10 //static basecoder cdc64 ("_dDpPhHzZrR06QqMmjJkKBb34TtSsvVlL81xXaAeEFf92WwGgYyoO57UucCNniI-");
275 pcg 1.8 //static basecoder cdc63 ("_dDpPhHzZrR06QqMmjJkKBb34TtSsvVlL81xXaAeEFf92WwGgYyoO57UucCNniI");
276     static basecoder cdc62 ("dDpPhHzZrR06QqMmjJkKBb34TtSsvVlL81xXaAeEFf92WwGgYyoO57UucCNniI");
277     //static basecoder cdc36 ("dphzr06qmjkb34tsvl81xaef92wgyo57ucni"); // unused as of yet
278     static basecoder cdc26 ("dPhZrQmJkBtSvLxAeFwGyO");
279    
280     /////////////////////////////////////////////////////////////////////////////
281    
282     #define HDRSIZE 6
283 pcg 1.24
284 pcg 1.17 inline void encode_header (char *data, int clientid, int seqno, int retry = 0)
285 pcg 1.8 {
286 pcg 1.17 seqno &= SEQNO_MASK;
287    
288     u8 hdr[3] = {
289     clientid,
290     (seqno >> 8) | (retry << 6),
291     seqno,
292     };
293 pcg 1.8
294     assert (clientid < 256);
295    
296     cdc26.encode (data, hdr, 3);
297     }
298    
299     inline void decode_header (char *data, int &clientid, int &seqno)
300     {
301     u8 hdr[3];
302    
303     cdc26.decode (hdr, data, HDRSIZE);
304    
305     clientid = hdr[0];
306 pcg 1.17 seqno = ((hdr[1] << 8) | hdr[2]) & SEQNO_MASK;
307 pcg 1.4 }
308    
309     /////////////////////////////////////////////////////////////////////////////
310    
311     struct byte_stream
312     {
313     u8 *data;
314     int maxsize;
315     int fill;
316    
317     byte_stream (int maxsize);
318     ~byte_stream ();
319    
320     bool empty () { return !fill; }
321     int size () { return fill; }
322    
323 pcg 1.5 bool put (u8 *data, unsigned int datalen);
324 pcg 1.4 bool put (vpn_packet *pkt);
325     vpn_packet *get ();
326    
327     u8 *begin () { return data; }
328     void remove (int count);
329     };
330    
331     byte_stream::byte_stream (int maxsize)
332     : maxsize (maxsize), fill (0)
333     {
334     data = new u8 [maxsize];
335     }
336    
337     byte_stream::~byte_stream ()
338     {
339     delete data;
340     }
341    
342     void byte_stream::remove (int count)
343     {
344     if (count > fill)
345 pcg 1.17 assert (count <= fill);
346 pcg 1.4
347     memmove (data, data + count, fill -= count);
348     }
349    
350 pcg 1.5 bool byte_stream::put (u8 *data, unsigned int datalen)
351     {
352     if (maxsize - fill < datalen)
353     return false;
354    
355     memcpy (this->data + fill, data, datalen); fill += datalen;
356    
357     return true;
358     }
359    
360 pcg 1.4 bool byte_stream::put (vpn_packet *pkt)
361     {
362     if (maxsize - fill < pkt->len + 2)
363     return false;
364    
365     data [fill++] = pkt->len >> 8;
366     data [fill++] = pkt->len;
367    
368 pcg 1.10 memcpy (data + fill, pkt->at (0), pkt->len); fill += pkt->len;
369 pcg 1.4
370     return true;
371     }
372    
373     vpn_packet *byte_stream::get ()
374     {
375 pcg 1.18 unsigned int len;
376    
377     for (;;)
378     {
379     len = (data [0] << 8) | data [1];
380 pcg 1.4
381 pcg 1.18 if (len <= MAXSIZE || fill < 2)
382     break;
383 pcg 1.5
384 pcg 1.18 // TODO: handle this better than skipping, e.g. by reset
385     slog (L_DEBUG, _("DNS: corrupted packet stream skipping a byte..."));
386     remove (1);
387     }
388    
389 pcg 1.4 if (fill < len + 2)
390     return 0;
391    
392     vpn_packet *pkt = new vpn_packet;
393 pcg 1.5
394     pkt->len = len;
395 pcg 1.10 memcpy (pkt->at (0), data + 2, len);
396 pcg 1.4 remove (len + 2);
397    
398     return pkt;
399 pcg 1.2 }
400    
401 pcg 1.3 /////////////////////////////////////////////////////////////////////////////
402    
403 pcg 1.2 #define FLAG_QUERY ( 0 << 15)
404     #define FLAG_RESPONSE ( 1 << 15)
405 pcg 1.9 #define FLAG_OP_MASK (15 << 11)
406 pcg 1.2 #define FLAG_OP_QUERY ( 0 << 11)
407     #define FLAG_AA ( 1 << 10)
408     #define FLAG_TC ( 1 << 9)
409     #define FLAG_RD ( 1 << 8)
410     #define FLAG_RA ( 1 << 7)
411 pcg 1.5 #define FLAG_AUTH ( 1 << 5)
412 pcg 1.2 #define FLAG_RCODE_MASK (15 << 0)
413     #define FLAG_RCODE_OK ( 0 << 0)
414     #define FLAG_RCODE_FORMERR ( 1 << 0)
415     #define FLAG_RCODE_SERVFAIL ( 2 << 0)
416     #define FLAG_RCODE_NXDOMAIN ( 3 << 0)
417     #define FLAG_RCODE_REFUSED ( 5 << 0)
418    
419     #define DEFAULT_CLIENT_FLAGS (FLAG_QUERY | FLAG_OP_QUERY | FLAG_RD)
420 pcg 1.5 #define DEFAULT_SERVER_FLAGS (FLAG_RESPONSE | FLAG_OP_QUERY | FLAG_AA | FLAG_RD | FLAG_RA)
421 pcg 1.2
422 pcg 1.10 struct dns_cfg
423     {
424     static int next_uid;
425    
426     u8 id1, id2, id3, id4;
427 pcg 1.24
428 pcg 1.10 u8 version;
429 pcg 1.24 u8 flags;
430 pcg 1.10 u8 rrtype;
431     u8 def_ttl;
432 pcg 1.24
433 pcg 1.10 u16 client;
434     u16 uid; // to make request unique
435    
436 pcg 1.24 u16 max_size;
437     u8 seq_cdc;
438     u8 req_cdc;
439    
440     u8 rep_cdc;
441 pcg 1.30 u8 delay; // time in 0.01s units that the server may delay replying packets
442     u8 r3, r4;
443 pcg 1.24
444     u8 r5, r6, r7, r8;
445 pcg 1.10
446     void reset (int clientid);
447     bool valid ();
448     };
449    
450     int dns_cfg::next_uid;
451    
452     void dns_cfg::reset (int clientid)
453     {
454     id1 = 'G';
455     id2 = 'V';
456     id3 = 'P';
457     id4 = 'E';
458    
459     version = 1;
460    
461     rrtype = RR_TYPE_TXT;
462     flags = 0;
463 pcg 1.24 def_ttl = 0;
464     seq_cdc = 26;
465     req_cdc = 62;
466     rep_cdc = 0;
467 pcg 1.27 max_size = htons (MAX_PKT_SIZE);
468     client = htons (clientid);
469 pcg 1.10 uid = next_uid++;
470 pcg 1.30 delay = 0;
471 pcg 1.10
472 pcg 1.30 r3 = r4 = 0;
473 pcg 1.24 r4 = r5 = r6 = r7 = 0;
474 pcg 1.10 }
475    
476     bool dns_cfg::valid ()
477     {
478 pcg 1.40 // although the protocol itself allows for some configurability,
479     // only the following encoding/decoding settings are implemented.
480 pcg 1.10 return id1 == 'G'
481     && id2 == 'V'
482     && id3 == 'P'
483     && id4 == 'E'
484 pcg 1.24 && seq_cdc == 26
485     && req_cdc == 62
486     && rep_cdc == 0
487 pcg 1.27 && version == 1;
488 pcg 1.10 }
489    
490 pcg 1.2 struct dns_packet : net_packet
491     {
492     u16 id;
493     u16 flags; // QR:1 Opcode:4 AA:1 TC:1 RD:1 RA:1 Z:3 RCODE:4
494     u16 qdcount, ancount, nscount, arcount;
495    
496 pcg 1.24 u8 data [MAXSIZE - 6 * 2];
497 pcg 1.2
498     int decode_label (char *data, int size, int &offs);
499     };
500    
501     int dns_packet::decode_label (char *data, int size, int &offs)
502     {
503     char *orig = data;
504    
505     memset (data, 0, size);
506    
507     while (offs < size - 1)
508     {
509     u8 len = (*this)[offs++];
510    
511     if (!len)
512     break;
513     else if (len < 64)
514     {
515     if (size < len + 1 || offs + len >= MAXSIZE - 1)
516     break;
517    
518     memcpy (data, &((*this)[offs]), len);
519    
520     data += len; size -= len; offs += len;
521     *data++ = '.'; size--;
522     }
523     else
524     {
525     int offs2 = ((len & 63) << 8) + (*this)[offs++];
526    
527     data += decode_label (data, size, offs2);
528     break;
529     }
530     }
531    
532     return data - orig;
533     }
534    
535 pcg 1.3 /////////////////////////////////////////////////////////////////////////////
536    
537 pcg 1.18 static u16 dns_id = 0; // TODO: should be per-vpn
538    
539     static u16 next_id ()
540     {
541     if (!dns_id)
542     dns_id = time (0);
543    
544     // the simplest lsfr with periodicity 65535 i could find
545     dns_id = (dns_id << 1)
546     | (((dns_id >> 1)
547     ^ (dns_id >> 2)
548     ^ (dns_id >> 4)
549     ^ (dns_id >> 15)) & 1);
550    
551     return dns_id;
552     }
553    
554     struct dns_rcv;
555     struct dns_snd;
556    
557     struct dns_connection
558     {
559     connection *c;
560     struct vpn *vpn;
561    
562     dns_cfg cfg;
563    
564     bool established;
565    
566     tstamp last_received;
567     tstamp last_sent;
568 pcg 1.25 double min_latency;
569 pcg 1.18 double poll_interval, send_interval;
570    
571     vector<dns_rcv *> rcvpq;
572    
573 pcg 1.31 byte_stream rcvdq; int rcvseq; int repseq;
574 pcg 1.18 byte_stream snddq; int sndseq;
575    
576 pcg 1.46 inline void time_cb (ev::timer &w, int revents); ev::timer tw;
577 pcg 1.18 void receive_rep (dns_rcv *r);
578    
579     dns_connection (connection *c);
580     ~dns_connection ();
581     };
582    
583 pcg 1.10 struct dns_snd
584 pcg 1.3 {
585     dns_packet *pkt;
586 pcg 1.10 tstamp timeout, sent;
587 pcg 1.3 int retry;
588 pcg 1.9 struct dns_connection *dns;
589 pcg 1.5 int seqno;
590 pcg 1.17 bool stdhdr;
591 pcg 1.3
592 pcg 1.9 void gen_stream_req (int seqno, byte_stream &stream);
593 pcg 1.18 void gen_syn_req ();
594 pcg 1.11
595     dns_snd (dns_connection *dns);
596     ~dns_snd ();
597 pcg 1.3 };
598    
599 pcg 1.10 dns_snd::dns_snd (dns_connection *dns)
600 pcg 1.9 : dns (dns)
601 pcg 1.3 {
602 pcg 1.10 timeout = 0;
603 pcg 1.3 retry = 0;
604 pcg 1.10 seqno = 0;
605 pcg 1.43 sent = ev_now ();
606 pcg 1.17 stdhdr = false;
607 pcg 1.3
608     pkt = new dns_packet;
609    
610 pcg 1.5 pkt->id = next_id ();
611     }
612    
613 pcg 1.11 dns_snd::~dns_snd ()
614     {
615     delete pkt;
616     }
617    
618 pcg 1.10 static void append_domain (dns_packet &pkt, int &offs, const char *domain)
619     {
620     // add tunnel domain
621     for (;;)
622     {
623     const char *end = strchr (domain, '.');
624    
625     if (!end)
626     end = domain + strlen (domain);
627    
628     int len = end - domain;
629    
630     pkt [offs++] = len;
631     memcpy (pkt.at (offs), domain, len);
632     offs += len;
633    
634     if (!*end)
635     break;
636    
637     domain = end + 1;
638     }
639     }
640    
641     void dns_snd::gen_stream_req (int seqno, byte_stream &stream)
642 pcg 1.5 {
643 pcg 1.17 stdhdr = true;
644 pcg 1.5 this->seqno = seqno;
645    
646 pcg 1.43 timeout = ev_now () + INITIAL_TIMEOUT;
647 pcg 1.10
648 pcg 1.5 pkt->flags = htons (DEFAULT_CLIENT_FLAGS);
649 pcg 1.4 pkt->qdcount = htons (1);
650 pcg 1.3
651 pcg 1.4 int offs = 6*2;
652 pcg 1.19 int dlen = MAX_DOMAIN_SIZE - (strlen (dns->c->conf->domain) + 2);
653 pcg 1.5 // MAX_DOMAIN_SIZE is technically 255, but bind doesn't compress responses well,
654     // so we need to have space for 2*MAX_DOMAIN_SIZE + header + extra
655    
656 pcg 1.8 char enc[256], *encp = enc;
657     encode_header (enc, THISNODE->id, seqno);
658 pcg 1.4
659 pcg 1.8 int datalen = cdc62.decode_len (dlen - (dlen + MAX_LBL_SIZE - 1) / MAX_LBL_SIZE - HDRSIZE);
660 pcg 1.4
661 pcg 1.9 if (datalen > stream.size ())
662     datalen = stream.size ();
663 pcg 1.8
664 pcg 1.9 int enclen = cdc62.encode (enc + HDRSIZE, stream.begin (), datalen) + HDRSIZE;
665     stream.remove (datalen);
666 pcg 1.4
667 pcg 1.5 while (enclen)
668     {
669     int lbllen = enclen < MAX_LBL_SIZE ? enclen : MAX_LBL_SIZE;
670    
671     (*pkt)[offs++] = lbllen;
672     memcpy (pkt->at (offs), encp, lbllen);
673 pcg 1.4
674 pcg 1.5 offs += lbllen;
675     encp += lbllen;
676 pcg 1.4
677 pcg 1.5 enclen -= lbllen;
678 pcg 1.4 }
679    
680 pcg 1.19 append_domain (*pkt, offs, dns->c->conf->domain);
681 pcg 1.3
682 pcg 1.10 (*pkt)[offs++] = 0;
683     (*pkt)[offs++] = RR_TYPE_ANY >> 8; (*pkt)[offs++] = RR_TYPE_ANY;
684     (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN;
685    
686     pkt->len = offs;
687     }
688    
689 pcg 1.18 void dns_snd::gen_syn_req ()
690 pcg 1.10 {
691 pcg 1.43 timeout = ev_now () + INITIAL_SYN_TIMEOUT;
692 pcg 1.4
693 pcg 1.10 pkt->flags = htons (DEFAULT_CLIENT_FLAGS);
694     pkt->qdcount = htons (1);
695 pcg 1.4
696 pcg 1.18 int offs = 6 * 2;
697 pcg 1.4
698 pcg 1.18 int elen = cdc26.encode ((char *)pkt->at (offs + 1), (u8 *)&dns->cfg, sizeof (dns_cfg));
699 pcg 1.4
700 pcg 1.10 assert (elen <= MAX_LBL_SIZE);
701 pcg 1.4
702 pcg 1.10 (*pkt)[offs] = elen;
703     offs += elen + 1;
704 pcg 1.19 append_domain (*pkt, offs, dns->c->conf->domain);
705 pcg 1.4
706     (*pkt)[offs++] = 0;
707 pcg 1.10 (*pkt)[offs++] = RR_TYPE_A >> 8; (*pkt)[offs++] = RR_TYPE_A;
708 pcg 1.4 (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN;
709    
710     pkt->len = offs;
711 pcg 1.5 }
712    
713     struct dns_rcv
714     {
715     int seqno;
716     dns_packet *pkt; // reply packet
717     u8 data [MAXSIZE]; // actually part of the reply packet...
718     int datalen;
719    
720 pcg 1.6 dns_rcv (int seqno, u8 *data, int datalen);
721 pcg 1.5 ~dns_rcv ();
722     };
723    
724 pcg 1.6 dns_rcv::dns_rcv (int seqno, u8 *data, int datalen)
725 pcg 1.5 : seqno (seqno), pkt (new dns_packet), datalen (datalen)
726     {
727     memcpy (this->data, data, datalen);
728     }
729 pcg 1.4
730 pcg 1.5 dns_rcv::~dns_rcv ()
731     {
732     delete pkt;
733 pcg 1.3 }
734    
735     /////////////////////////////////////////////////////////////////////////////
736 pcg 1.9
737     dns_connection::dns_connection (connection *c)
738     : c (c)
739     , rcvdq (MAX_BACKLOG * 2)
740 pcg 1.31 , snddq (MAX_BACKLOG)
741 pcg 1.9 {
742 pcg 1.45 tw.set<dns_connection, &dns_connection::time_cb> (this);
743    
744 pcg 1.9 vpn = c->vpn;
745    
746 pcg 1.10 established = false;
747    
748 pcg 1.31 rcvseq = repseq = sndseq = 0;
749 pcg 1.10
750     last_sent = last_received = 0;
751 pcg 1.30 poll_interval = 0.5; // starting here
752 pcg 1.17 send_interval = 0.5; // starting rate
753 pcg 1.25 min_latency = INITIAL_TIMEOUT;
754 pcg 1.9 }
755    
756     dns_connection::~dns_connection ()
757     {
758     for (vector<dns_rcv *>::iterator i = rcvpq.begin ();
759     i != rcvpq.end ();
760     ++i)
761     delete *i;
762     }
763 pcg 1.3
764 pcg 1.10 void dns_connection::receive_rep (dns_rcv *r)
765 pcg 1.2 {
766 pcg 1.10 if (r->datalen)
767     {
768 pcg 1.43 last_received = ev_now ();
769 pcg 1.42 tw ();
770 pcg 1.10
771 pcg 1.12 poll_interval = send_interval;
772 pcg 1.10 }
773     else
774     {
775 pcg 1.17 poll_interval *= 1.5;
776 pcg 1.25
777 pcg 1.10 if (poll_interval > MAX_POLL_INTERVAL)
778     poll_interval = MAX_POLL_INTERVAL;
779     }
780 pcg 1.2
781 pcg 1.9 rcvpq.push_back (r);
782 pcg 1.5
783     redo:
784    
785 pcg 1.8 // find next packet
786 pcg 1.9 for (vector<dns_rcv *>::iterator i = rcvpq.end (); i-- != rcvpq.begin (); )
787     if (SEQNO_EQ (rcvseq, (*i)->seqno))
788 pcg 1.5 {
789 pcg 1.41 //printf ("seqno eq %x %x\n", rcvseq, (*i)->seqno);//D
790 pcg 1.8 // enter the packet into our input stream
791     r = *i;
792    
793     // remove the oldest packet, look forward, as it's oldest first
794 pcg 1.9 for (vector<dns_rcv *>::iterator j = rcvpq.begin (); j != rcvpq.end (); ++j)
795     if (SEQNO_EQ ((*j)->seqno, rcvseq - MAX_WINDOW))
796 pcg 1.8 {
797 pcg 1.41 //printf ("seqno RR %x %x\n", (*j)->seqno, rcvseq - MAX_WINDOW);//D
798 pcg 1.8 delete *j;
799 pcg 1.9 rcvpq.erase (j);
800 pcg 1.8 break;
801     }
802 pcg 1.5
803 pcg 1.9 rcvseq = (rcvseq + 1) & SEQNO_MASK;
804 pcg 1.5
805 pcg 1.9 if (!rcvdq.put (r->data, r->datalen))
806 pcg 1.17 {
807     slog (L_ERR, "DNS: !rcvdq.put (r->data, r->datalen)");
808     abort (); // MUST never overflow, can be caused by data corruption, TODO
809     }
810 pcg 1.5
811 pcg 1.9 while (vpn_packet *pkt = rcvdq.get ())
812 pcg 1.5 {
813     sockinfo si;
814 pcg 1.33 si.host = htonl (c->conf->id); si.port = 0; si.prot = PROT_DNSv4;
815 pcg 1.5
816     vpn->recv_vpn_packet (pkt, si);
817 pcg 1.11
818     delete pkt;
819 pcg 1.5 }
820 pcg 1.8
821     // check for further packets
822 pcg 1.5 goto redo;
823     }
824     }
825    
826 pcg 1.10 void
827     vpn::dnsv4_server (dns_packet &pkt)
828 pcg 1.2 {
829 pcg 1.10 u16 flags = ntohs (pkt.flags);
830 pcg 1.2
831 pcg 1.4 int offs = 6 * 2; // skip header
832 pcg 1.2
833 pcg 1.10 pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR);
834 pcg 1.2
835 pcg 1.10 if (0 == (flags & (FLAG_RESPONSE | FLAG_OP_MASK))
836     && pkt.qdcount == htons (1))
837 pcg 1.4 {
838 pcg 1.24 char qname [MAXSIZE];
839 pcg 1.10 int qlen = pkt.decode_label ((char *)qname, MAXSIZE - offs, offs);
840 pcg 1.4
841 pcg 1.10 u16 qtype = pkt [offs++] << 8; qtype |= pkt [offs++];
842     u16 qclass = pkt [offs++] << 8; qclass |= pkt [offs++];
843 pcg 1.2
844 pcg 1.10 pkt.qdcount = htons (1);
845     pkt.ancount = 0;
846     pkt.nscount = 0; // should be self, as other nameservers reply like this
847     pkt.arcount = 0; // a record for self, as other nameservers reply like this
848 pcg 1.2
849 pcg 1.16 pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_SERVFAIL);
850 pcg 1.2
851 pcg 1.4 int dlen = strlen (THISNODE->domain);
852 pcg 1.2
853 pcg 1.4 if (qclass == RR_CLASS_IN
854 pcg 1.10 && qlen > dlen + 1
855 pcg 1.24 && !memcmp (qname + qlen - (dlen + 1), THISNODE->domain, dlen))
856 pcg 1.2 {
857 pcg 1.10 // now generate reply
858     pkt.ancount = htons (1); // one answer RR
859     pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_OK);
860    
861     if ((qtype == RR_TYPE_ANY
862     || qtype == RR_TYPE_TXT
863     || qtype == RR_TYPE_NULL)
864     && qlen > dlen + 1 + HDRSIZE)
865 pcg 1.5 {
866 pcg 1.10 // correct class, domain: parse
867     int client, seqno;
868     decode_header (qname, client, seqno);
869 pcg 1.5
870 pcg 1.10 u8 data[MAXSIZE];
871     int datalen = cdc62.decode (data, qname + HDRSIZE, qlen - (dlen + 1 + HDRSIZE));
872 pcg 1.9
873 pcg 1.10 if (0 < client && client <= conns.size ())
874     {
875     connection *c = conns [client - 1];
876     dns_connection *dns = c->dns;
877     dns_rcv *rcv;
878    
879     if (dns)
880     {
881     for (vector<dns_rcv *>::iterator i = dns->rcvpq.end (); i-- != dns->rcvpq.begin (); )
882     if (SEQNO_EQ ((*i)->seqno, seqno))
883     {
884     // already seen that request: simply reply with the cached reply
885     dns_rcv *r = *i;
886    
887 pcg 1.17 slog (L_DEBUG, "DNS: duplicate packet received ID %d, SEQ %d", htons (r->pkt->id), seqno);
888    
889     // refresh header & id, as the retry count could have changed
890     memcpy (r->pkt->at (6 * 2 + 1), pkt.at (6 * 2 + 1), HDRSIZE);
891     r->pkt->id = pkt.id;
892 pcg 1.10
893     memcpy (pkt.at (0), r->pkt->at (0), offs = r->pkt->len);
894 pcg 1.17
895 pcg 1.10 goto duplicate_request;
896     }
897    
898     // new packet, queue
899     rcv = new dns_rcv (seqno, data, datalen);
900     dns->receive_rep (rcv);
901     }
902    
903 pcg 1.21 {
904     pkt [offs++] = 0xc0; pkt [offs++] = 6 * 2; // refer to name in query section
905    
906     int rtype = dns ? dns->cfg.rrtype : RR_TYPE_A;
907     pkt [offs++] = rtype >> 8; pkt [offs++] = rtype; // type
908     pkt [offs++] = RR_CLASS_IN >> 8; pkt [offs++] = RR_CLASS_IN; // class
909     pkt [offs++] = 0; pkt [offs++] = 0;
910     pkt [offs++] = 0; pkt [offs++] = dns ? dns->cfg.def_ttl : 0; // TTL
911    
912     int rdlen_offs = offs += 2;
913 pcg 1.10
914 pcg 1.21 if (dns)
915     {
916 pcg 1.27 int dlen = ntohs (dns->cfg.max_size) - offs;
917    
918     // bind doesn't compress well, so reduce further by one label length
919     dlen -= qlen;
920    
921 pcg 1.21 // only put data into in-order sequence packets, if
922     // we receive out-of-order packets we generate empty
923     // replies
924 pcg 1.31 //printf ("%d - %d & %x (=%d) < %d\n", seqno, dns->repseq, SEQNO_MASK, (seqno - dns->repseq) & SEQNO_MASK, MAX_WINDOW);//D
925     if (((seqno - dns->repseq) & SEQNO_MASK) <= MAX_WINDOW)
926 pcg 1.21 {
927 pcg 1.31 dns->repseq = seqno;
928 pcg 1.10
929 pcg 1.31 while (dlen > 1 && !dns->snddq.empty ())
930     {
931     int txtlen = dlen <= 255 ? dlen - 1 : 255;
932    
933     if (txtlen > dns->snddq.size ())
934     txtlen = dns->snddq.size ();
935    
936     pkt[offs++] = txtlen;
937     memcpy (pkt.at (offs), dns->snddq.begin (), txtlen);
938     offs += txtlen;
939     dns->snddq.remove (txtlen);
940 pcg 1.10
941 pcg 1.31 dlen -= txtlen + 1;
942     }
943 pcg 1.21 }
944    
945 pcg 1.31 // avoid completely empty TXT rdata
946 pcg 1.21 if (offs == rdlen_offs)
947     pkt[offs++] = 0;
948 pcg 1.15
949 pcg 1.21 slog (L_NOISE, "DNS: snddq %d", dns->snddq.size ());
950     }
951     else
952     {
953     // send RST
954     pkt [offs++] = CMD_IP_1; pkt [offs++] = CMD_IP_2; pkt [offs++] = CMD_IP_3;
955     pkt [offs++] = CMD_IP_RST;
956     }
957 pcg 1.10
958 pcg 1.21 int rdlen = offs - rdlen_offs;
959 pcg 1.10
960 pcg 1.21 pkt [rdlen_offs - 2] = rdlen >> 8;
961     pkt [rdlen_offs - 1] = rdlen;
962 pcg 1.10
963 pcg 1.21 if (dns)
964     {
965     // now update dns_rcv copy
966     rcv->pkt->len = offs;
967     memcpy (rcv->pkt->at (0), pkt.at (0), offs);
968     }
969     }
970 pcg 1.9
971 pcg 1.10 duplicate_request: ;
972     }
973     else
974     pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR);
975     }
976     else if (qtype == RR_TYPE_A
977     && qlen > dlen + 1 + cdc26.encode_len (sizeof (dns_cfg)))
978     {
979     dns_cfg cfg;
980     cdc26.decode ((u8 *)&cfg, qname, cdc26.encode_len (sizeof (dns_cfg)));
981     int client = ntohs (cfg.client);
982 pcg 1.4
983 pcg 1.10 pkt [offs++] = 0xc0; pkt [offs++] = 6 * 2; // refer to name in query section
984 pcg 1.2
985 pcg 1.10 pkt [offs++] = RR_TYPE_A >> 8; pkt [offs++] = RR_TYPE_A; // type
986     pkt [offs++] = RR_CLASS_IN >> 8; pkt [offs++] = RR_CLASS_IN; // class
987     pkt [offs++] = 0; pkt [offs++] = 0;
988     pkt [offs++] = 0; pkt [offs++] = cfg.def_ttl; // TTL
989     pkt [offs++] = 0; pkt [offs++] = 4; // rdlength
990 pcg 1.2
991 pcg 1.24 slog (L_INFO, _("DNS: client %d connects"), client);
992 pcg 1.2
993 pcg 1.10 pkt [offs++] = CMD_IP_1; pkt [offs++] = CMD_IP_2; pkt [offs++] = CMD_IP_3;
994     pkt [offs++] = CMD_IP_REJ;
995 pcg 1.2
996 pcg 1.10 if (0 < client && client <= conns.size ())
997 pcg 1.5 {
998 pcg 1.10 connection *c = conns [client - 1];
999 pcg 1.2
1000 pcg 1.10 if (cfg.valid ())
1001     {
1002     pkt [offs - 1] = CMD_IP_SYN;
1003    
1004     delete c->dns;
1005     c->dns = new dns_connection (c);
1006     c->dns->cfg = cfg;
1007     }
1008 pcg 1.5 }
1009     }
1010 pcg 1.2 }
1011 pcg 1.6
1012 pcg 1.10 pkt.len = offs;
1013 pcg 1.4 }
1014     }
1015    
1016     void
1017 pcg 1.10 vpn::dnsv4_client (dns_packet &pkt)
1018 pcg 1.4 {
1019 pcg 1.10 u16 flags = ntohs (pkt.flags);
1020 pcg 1.4 int offs = 6 * 2; // skip header
1021    
1022 pcg 1.10 pkt.qdcount = ntohs (pkt.qdcount);
1023     pkt.ancount = ntohs (pkt.ancount);
1024 pcg 1.4
1025 pcg 1.5 // go through our request list and find the corresponding request
1026 pcg 1.10 for (vector<dns_snd *>::iterator i = dns_sndpq.begin ();
1027 pcg 1.4 i != dns_sndpq.end ();
1028     ++i)
1029 pcg 1.10 if ((*i)->pkt->id == pkt.id)
1030 pcg 1.4 {
1031 pcg 1.9 dns_connection *dns = (*i)->dns;
1032 pcg 1.12 connection *c = dns->c;
1033 pcg 1.5 int seqno = (*i)->seqno;
1034     u8 data[MAXSIZE], *datap = data;
1035 pcg 1.41 //printf ("rcv pkt %x\n", seqno);//D
1036 pcg 1.5
1037 pcg 1.10 if ((*i)->retry)
1038     {
1039 pcg 1.17 dns->send_interval *= 1.01;
1040 pcg 1.12 if (dns->send_interval > MAX_SEND_INTERVAL)
1041 pcg 1.10 dns->send_interval = MAX_SEND_INTERVAL;
1042     }
1043     else
1044     {
1045 pcg 1.26 #if 0
1046 pcg 1.17 dns->send_interval *= 0.999;
1047 pcg 1.12 #endif
1048 pcg 1.10 // the latency surely puts an upper bound on
1049     // the minimum send interval
1050 pcg 1.43 double latency = ev_now () - (*i)->sent;
1051 pcg 1.12
1052 pcg 1.25 if (latency < dns->min_latency)
1053     dns->min_latency = latency;
1054    
1055 pcg 1.37 if (dns->send_interval > dns->min_latency * conf.dns_overlap_factor)
1056     dns->send_interval = dns->min_latency * conf.dns_overlap_factor;
1057 pcg 1.27
1058 pcg 1.37 if (dns->send_interval < conf.dns_send_interval)
1059     dns->send_interval = conf.dns_send_interval;
1060 pcg 1.10 }
1061    
1062 pcg 1.4 delete *i;
1063     dns_sndpq.erase (i);
1064    
1065 pcg 1.10 if (flags & FLAG_RESPONSE && !(flags & FLAG_OP_MASK))
1066 pcg 1.4 {
1067     char qname[MAXSIZE];
1068    
1069 pcg 1.10 while (pkt.qdcount-- && offs < MAXSIZE - 4)
1070 pcg 1.4 {
1071 pcg 1.10 int qlen = pkt.decode_label ((char *)qname, MAXSIZE - offs, offs);
1072 pcg 1.4 offs += 4; // skip qtype, qclass
1073     }
1074    
1075 pcg 1.10 while (pkt.ancount-- && offs < MAXSIZE - 10 && datap)
1076 pcg 1.4 {
1077 pcg 1.10 int qlen = pkt.decode_label ((char *)qname, MAXSIZE - offs, offs);
1078    
1079     u16 qtype = pkt [offs++] << 8; qtype |= pkt [offs++];
1080     u16 qclass = pkt [offs++] << 8; qclass |= pkt [offs++];
1081     u32 ttl = pkt [offs++] << 24;
1082     ttl |= pkt [offs++] << 16;
1083     ttl |= pkt [offs++] << 8;
1084     ttl |= pkt [offs++];
1085     u16 rdlen = pkt [offs++] << 8; rdlen |= pkt [offs++];
1086 pcg 1.8
1087 pcg 1.10 if (qtype == RR_TYPE_NULL || qtype == RR_TYPE_TXT)
1088     {
1089     if (rdlen <= MAXSIZE - offs)
1090     {
1091     // decode bytes, finally
1092    
1093     while (rdlen)
1094     {
1095     int txtlen = pkt [offs++];
1096 pcg 1.4
1097 pcg 1.10 assert (txtlen + offs < MAXSIZE - 1);
1098 pcg 1.4
1099 pcg 1.10 memcpy (datap, pkt.at (offs), txtlen);
1100     datap += txtlen; offs += txtlen;
1101    
1102     rdlen -= txtlen + 1;
1103     }
1104     }
1105     }
1106     else if (qtype == RR_TYPE_A)
1107 pcg 1.5 {
1108 pcg 1.10 u8 ip [4];
1109 pcg 1.5
1110 pcg 1.10 ip [0] = pkt [offs++];
1111     ip [1] = pkt [offs++];
1112     ip [2] = pkt [offs++];
1113     ip [3] = pkt [offs++];
1114    
1115     if (ip [0] == CMD_IP_1
1116     && ip [1] == CMD_IP_2
1117     && ip [2] == CMD_IP_3)
1118 pcg 1.5 {
1119 pcg 1.17 slog (L_TRACE, _("DNS: got tunnel meta command %02x"), ip [3]);
1120 pcg 1.5
1121 pcg 1.10 if (ip [3] == CMD_IP_RST)
1122     {
1123 pcg 1.17 slog (L_DEBUG, _("DNS: got tunnel RST request"));
1124 pcg 1.10
1125 pcg 1.12 delete dns; c->dns = 0;
1126 pcg 1.10
1127     return;
1128     }
1129     else if (ip [3] == CMD_IP_SYN)
1130 pcg 1.12 {
1131 pcg 1.17 slog (L_DEBUG, _("DNS: got tunnel SYN reply, server likes us."));
1132 pcg 1.12 dns->established = true;
1133     }
1134     else if (ip [3] == CMD_IP_REJ)
1135     {
1136 pcg 1.17 slog (L_DEBUG, _("DNS: got tunnel REJ reply, server does not like us, aborting."));
1137 pcg 1.12 abort ();
1138     }
1139 pcg 1.10 else
1140 pcg 1.17 slog (L_INFO, _("DNS: got unknown meta command %02x"), ip [3]);
1141 pcg 1.10 }
1142     else
1143 pcg 1.17 slog (L_INFO, _("DNS: got spurious a record %d.%d.%d.%d"),
1144 pcg 1.10 ip [0], ip [1], ip [2], ip [3]);
1145 pcg 1.5
1146 pcg 1.10 return;
1147 pcg 1.9 }
1148 pcg 1.4
1149 pcg 1.9 int client, rseqno;
1150     decode_header (qname, client, rseqno);
1151    
1152     if (client != THISNODE->id)
1153     {
1154 pcg 1.17 slog (L_INFO, _("DNS: got dns tunnel response with wrong clientid, ignoring"));
1155 pcg 1.9 datap = 0;
1156     }
1157     else if (rseqno != seqno)
1158     {
1159 pcg 1.17 slog (L_DEBUG, _("DNS: got dns tunnel response with wrong seqno, badly caching nameserver?"));
1160 pcg 1.9 datap = 0;
1161 pcg 1.4 }
1162     }
1163     }
1164    
1165 pcg 1.6 // todo: pkt now used
1166 pcg 1.9 if (datap)
1167     dns->receive_rep (new dns_rcv (seqno, data, datap - data));
1168 pcg 1.5
1169 pcg 1.4 break;
1170     }
1171     }
1172    
1173     void
1174 pcg 1.42 vpn::dnsv4_ev (ev::io &w, int revents)
1175 pcg 1.4 {
1176 pcg 1.42 if (revents & EV_READ)
1177 pcg 1.4 {
1178     dns_packet *pkt = new dns_packet;
1179     struct sockaddr_in sa;
1180     socklen_t sa_len = sizeof (sa);
1181    
1182 pcg 1.10 pkt->len = recvfrom (w.fd, pkt->at (0), MAXSIZE, 0, (sockaddr *)&sa, &sa_len);
1183 pcg 1.4
1184     if (pkt->len > 0)
1185 pcg 1.5 {
1186 pcg 1.24 if (ntohs (pkt->flags) & FLAG_RESPONSE)
1187     dnsv4_client (*pkt);
1188     else
1189 pcg 1.5 {
1190 pcg 1.10 dnsv4_server (*pkt);
1191     sendto (w.fd, pkt->at (0), pkt->len, 0, (sockaddr *)&sa, sa_len);
1192 pcg 1.5 }
1193 pcg 1.10
1194     delete pkt;
1195 pcg 1.5 }
1196 pcg 1.1 }
1197     }
1198    
1199     bool
1200 pcg 1.18 vpn::send_dnsv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
1201 pcg 1.3 {
1202 pcg 1.33 int client = ntohl (si.host);
1203 pcg 1.18
1204     assert (0 < client && client <= conns.size ());
1205    
1206     connection *c = conns [client - 1];
1207    
1208     if (!c->dns)
1209     c->dns = new dns_connection (c);
1210 pcg 1.4
1211 pcg 1.31 if (c->dns->snddq.put (pkt))
1212 pcg 1.42 c->dns->tw ();
1213 pcg 1.3
1214 pcg 1.31 // always return true even if the buffer overflows
1215 pcg 1.3 return true;
1216     }
1217    
1218 pcg 1.12 void
1219     connection::dnsv4_reset_connection ()
1220     {
1221     //delete dns; dns = 0; //TODO
1222     }
1223    
1224 pcg 1.10 #define NEXT(w) do { if (next > (w)) next = w; } while (0)
1225    
1226 pcg 1.3 void
1227 pcg 1.42 dns_connection::time_cb (ev::timer &w, int revents)
1228 pcg 1.1 {
1229 pcg 1.10 // servers have to be polled
1230     if (THISNODE->dns_port)
1231     return;
1232    
1233 pcg 1.3 // check for timeouts and (re)transmit
1234 pcg 1.42 tstamp next = ev::now () + poll_interval;
1235 pcg 1.10 dns_snd *send = 0;
1236 pcg 1.3
1237 pcg 1.10 for (vector<dns_snd *>::iterator i = vpn->dns_sndpq.begin ();
1238 pcg 1.4 i != vpn->dns_sndpq.end ();
1239 pcg 1.3 ++i)
1240     {
1241 pcg 1.10 dns_snd *r = *i;
1242 pcg 1.3
1243 pcg 1.43 if (r->timeout <= ev_now ())
1244 pcg 1.3 {
1245 pcg 1.4 if (!send)
1246     {
1247     send = r;
1248    
1249     r->retry++;
1250 pcg 1.43 r->timeout = ev_now () + (r->retry * min_latency * conf.dns_timeout_factor);
1251     //printf ("RETRY %x (%d, %f)\n", r->seqno, r->retry, r->timeout - ev_now ());//D
1252 pcg 1.17
1253     // the following code changes the query section a bit, forcing
1254     // the forwarder to generate a new request
1255     if (r->stdhdr)
1256 pcg 1.41 encode_header ((char *)r->pkt->at (6 * 2 + 1), THISNODE->id, r->seqno, r->retry);
1257 pcg 1.4 }
1258 pcg 1.3 }
1259 pcg 1.11 else
1260 pcg 1.10 NEXT (r->timeout);
1261 pcg 1.3 }
1262    
1263 pcg 1.28 if (!send)
1264 pcg 1.5 {
1265 pcg 1.29 // generate a new packet, if wise
1266    
1267     if (!established)
1268 pcg 1.10 {
1269 pcg 1.29 if (vpn->dns_sndpq.empty ())
1270 pcg 1.10 {
1271 pcg 1.29 send = new dns_snd (this);
1272 pcg 1.10
1273 pcg 1.29 cfg.reset (THISNODE->id);
1274     send->gen_syn_req ();
1275 pcg 1.10 }
1276 pcg 1.29 }
1277 pcg 1.37 else if (vpn->dns_sndpq.size () < conf.dns_max_outstanding
1278 pcg 1.29 && !SEQNO_EQ (rcvseq, sndseq - (MAX_WINDOW - 1)))
1279     {
1280 pcg 1.43 if (last_sent + send_interval <= ev_now ())
1281 pcg 1.10 {
1282 pcg 1.18 //printf ("sending data request etc.\n"); //D
1283 pcg 1.43 if (!snddq.empty () || last_received + 1. > ev_now ())
1284 pcg 1.17 {
1285     poll_interval = send_interval;
1286 pcg 1.43 NEXT (ev_now () + send_interval);
1287 pcg 1.17 }
1288    
1289 pcg 1.10 send = new dns_snd (this);
1290     send->gen_stream_req (sndseq, snddq);
1291 pcg 1.43 send->timeout = ev_now () + min_latency * conf.dns_timeout_factor;
1292     //printf ("SEND %x (%f)\n", send->seqno, send->timeout - ev_now (), min_latency, conf.dns_timeout_factor);//D
1293 pcg 1.5
1294 pcg 1.10 sndseq = (sndseq + 1) & SEQNO_MASK;
1295     }
1296 pcg 1.29 else
1297     NEXT (last_sent + send_interval);
1298     }
1299 pcg 1.4
1300 pcg 1.29 if (send)
1301     vpn->dns_sndpq.push_back (send);
1302 pcg 1.28 }
1303 pcg 1.4
1304 pcg 1.28 if (send)
1305     {
1306 pcg 1.43 last_sent = ev_now ();
1307 pcg 1.28 sendto (vpn->dnsv4_fd,
1308     send->pkt->at (0), send->pkt->len, 0,
1309     vpn->dns_forwarder.sav4 (), vpn->dns_forwarder.salenv4 ());
1310 pcg 1.4 }
1311 pcg 1.10
1312 pcg 1.27 slog (L_NOISE, "DNS: pi %f si %f N %f (%d:%d %d)",
1313 pcg 1.43 poll_interval, send_interval, next - ev_now (),
1314 pcg 1.27 vpn->dns_sndpq.size (), snddq.size (),
1315     rcvpq.size ());
1316 pcg 1.11
1317 pcg 1.43 // TODO: no idea when this happens, but when next < ev_now (), we have a problem
1318 pcg 1.37 // doesn't seem to happen anymore
1319 pcg 1.43 if (next < ev_now () + 0.001)
1320     next = ev_now () + 0.1;
1321 pcg 1.4
1322 pcg 1.43 w.start (next - ev_now ());
1323 pcg 1.1 }
1324    
1325     #endif
1326