ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/vpn_dns.C
Revision: 1.47
Committed: Thu Aug 7 17:54:27 2008 UTC (15 years, 9 months ago) by pcg
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_2, rel-2_21, rel-2_22
Changes since 1.46: +24 -14 lines
Log Message:
update to gplv3, finally

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