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