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