ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/vpn_dns.C
Revision: 1.9
Committed: Fri Mar 4 04:52:38 2005 UTC (19 years, 2 months ago) by pcg
Content type: text/plain
Branch: MAIN
Changes since 1.8: +105 -96 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.7 Copyright (C) 2003-2005 Marc Lehmann <gvpe@schmorp.de>
4 pcg 1.1
5 pcg 1.7 This file is part of GVPE.
6    
7     GVPE is free software; you can redistribute it and/or modify
8 pcg 1.1 it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11    
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     GNU General Public License for more details.
16    
17     You should have received a copy of the GNU General Public License
18 pcg 1.7 along with gvpe; if not, write to the Free Software
19 pcg 1.1 Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20     */
21    
22     #include "config.h"
23    
24     #if ENABLE_DNS
25    
26     // dns processing is EXTREMELY ugly. For obvious(?) reasons.
27     // it's a hack, use only in emergency situations please.
28    
29     #include <cstring>
30    
31     #include <sys/types.h>
32     #include <sys/socket.h>
33     #include <sys/wait.h>
34     #include <sys/uio.h>
35     #include <errno.h>
36     #include <time.h>
37     #include <unistd.h>
38     #include <fcntl.h>
39    
40     #include <map>
41    
42 pcg 1.8 #include <gmp.h>
43    
44 pcg 1.1 #include "netcompat.h"
45    
46     #include "vpn.h"
47    
48     #define MIN_RETRY 1.
49 pcg 1.9 #define MAX_RETRY 6.
50 pcg 1.1
51 pcg 1.8 #define MAX_OUTSTANDING 400 // max. outstanding requests
52     #define MAX_WINDOW 1000 // max. for MAX_OUTSTANDING
53 pcg 1.9 #define MAX_RATE 100 // requests/s
54 pcg 1.5 #define MAX_BACKLOG (10*1024) // size of protocol backlog, must be > MAXSIZE
55    
56     #define MAX_DOMAIN_SIZE 220 // 255 is legal limit, but bind doesn't compress well
57     // 240 leaves about 4 bytes of server reply data
58     // every two request byte sless give room for one reply byte
59    
60 pcg 1.9 #define SEQNO_MASK 0xffff
61 pcg 1.8 #define SEQNO_EQ(a,b) ( 0 == ( ((a) ^ (b)) & SEQNO_MASK) )
62 pcg 1.1
63 pcg 1.8 #define MAX_LBL_SIZE 63
64     #define MAX_PKT_SIZE 512
65 pcg 1.1
66 pcg 1.8 #define RR_TYPE_TXT 16
67     #define RR_TYPE_ANY 255
68     #define RR_CLASS_IN 1
69 pcg 1.1
70 pcg 1.8 // works for cmaps up to 255 (not 256!)
71     struct charmap
72     {
73     enum { INVALID = (u8)255 };
74 pcg 1.1
75 pcg 1.8 char encode [256]; // index => char
76     u8 decode [256]; // char => index
77     unsigned int size;
78 pcg 1.2
79 pcg 1.8 charmap (const char *cmap);
80     };
81    
82     charmap::charmap (const char *cmap)
83     {
84     char *enc = encode;
85     u8 *dec = decode;
86 pcg 1.2
87 pcg 1.8 memset (enc, (char) 0, 256);
88     memset (dec, (char)INVALID, 256);
89 pcg 1.1
90 pcg 1.8 for (size = 0; cmap [size]; size++)
91     {
92     enc [size] = cmap [size];
93     dec [(u8)enc [size]] = size;
94     }
95 pcg 1.1
96 pcg 1.8 assert (size < 256);
97     }
98 pcg 1.2
99 pcg 1.8 #define MAX_DEC_LEN 500
100     #define MAX_ENC_LEN (MAX_DEC_LEN * 2)
101     #define MAX_LIMBS ((MAX_DEC_LEN * 8 + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS)
102 pcg 1.2
103 pcg 1.8 // ugly. minimum base is 16(!)
104     struct basecoder
105 pcg 1.2 {
106 pcg 1.8 charmap cmap;
107     unsigned int enc_len [MAX_DEC_LEN];
108     unsigned int dec_len [MAX_ENC_LEN];
109 pcg 1.2
110 pcg 1.8 unsigned int encode_len (unsigned int len);
111     unsigned int decode_len (unsigned int len);
112    
113     unsigned int encode (char *dst, u8 *src, unsigned int len);
114     unsigned int decode (u8 *dst, char *src, unsigned int len);
115    
116     basecoder (const char *cmap);
117     };
118    
119     basecoder::basecoder (const char *cmap)
120     : cmap (cmap)
121     {
122     for (unsigned int len = 0; len < MAX_DEC_LEN; ++len)
123     {
124     u8 src [MAX_DEC_LEN];
125     u8 dst [MAX_ENC_LEN];
126 pcg 1.2
127 pcg 1.8 memset (src, 255, len);
128 pcg 1.2
129 pcg 1.8 mp_limb_t m [MAX_LIMBS];
130     mp_size_t n;
131    
132     n = mpn_set_str (m, src, len, 256);
133     n = mpn_get_str (dst, this->cmap.size, m, n);
134    
135     for (int i = 0; !dst [i]; ++i)
136     n--;
137    
138     enc_len [len] = n;
139     dec_len [n] = len;
140     }
141     }
142    
143     unsigned int basecoder::encode_len (unsigned int len)
144     {
145     return enc_len [len];
146     }
147 pcg 1.2
148 pcg 1.8 unsigned int basecoder::decode_len (unsigned int len)
149 pcg 1.2 {
150 pcg 1.8 while (len && !dec_len [len])
151     --len;
152    
153     return dec_len [len];
154 pcg 1.2 }
155    
156 pcg 1.8 unsigned int basecoder::encode (char *dst, u8 *src, unsigned int len)
157 pcg 1.2 {
158 pcg 1.8 if (!len)
159     return 0;
160    
161     int elen = encode_len (len);
162    
163     mp_limb_t m [MAX_LIMBS];
164     mp_size_t n;
165    
166     u8 dst_ [MAX_ENC_LEN];
167    
168     n = mpn_set_str (m, src, len, 256);
169     n = mpn_get_str (dst_, cmap.size, m, n);
170    
171     int plen = elen; // for padding
172 pcg 1.2
173 pcg 1.8 while (n < plen)
174 pcg 1.2 {
175 pcg 1.8 *dst++ = cmap.encode [0];
176     plen--;
177 pcg 1.2 }
178    
179 pcg 1.8 for (unsigned int i = n - plen; i < n; ++i)
180     *dst++ = cmap.encode [dst_ [i]];
181 pcg 1.4
182 pcg 1.8 return elen;
183 pcg 1.2 }
184    
185 pcg 1.8 unsigned int basecoder::decode (u8 *dst, char *src, unsigned int len)
186 pcg 1.2 {
187 pcg 1.8 if (!len)
188     return 0;
189    
190     u8 src_ [MAX_ENC_LEN];
191     unsigned int elen = 0;
192 pcg 1.2
193     while (len--)
194     {
195 pcg 1.8 u8 val = cmap.decode [(u8)*src++];
196 pcg 1.2
197 pcg 1.8 if (val != charmap::INVALID)
198     src_ [elen++] = val;
199     }
200    
201     int dlen = decode_len (elen);
202    
203     mp_limb_t m [MAX_LIMBS];
204     mp_size_t n;
205    
206     u8 dst_ [MAX_DEC_LEN];
207 pcg 1.2
208 pcg 1.8 n = mpn_set_str (m, src_, elen, cmap.size);
209     n = mpn_get_str (dst_, 256, m, n);
210 pcg 1.2
211 pcg 1.8 if (n < dlen)
212     {
213     memset (dst, 0, dlen - n);
214     memcpy (dst + dlen - n, dst_, n);
215 pcg 1.2 }
216 pcg 1.8 else
217     memcpy (dst, dst_ + n - dlen, dlen);
218 pcg 1.4
219 pcg 1.8 return dlen;
220     }
221    
222     #if 0
223     struct test { test (); } test;
224    
225     test::test ()
226     {
227     basecoder cdc ("0123456789abcdefghijklmnopqrstuvwxyz");
228    
229     u8 in[] = "0123456789abcdefghijklmnopqrstuvwxyz";
230     static char enc[200];
231     static u8 dec[200];
232    
233     for (int i = 1; i < 20; i++)
234     {
235     int elen = cdc.encode (enc, in, i);
236     int dlen = cdc.decode (dec, enc, elen);
237    
238     printf ("%d>%d>%d (%s>%s)\n", i, elen, dlen, enc, dec);
239     }
240     abort ();
241     }
242     #endif
243    
244     // the following sequence has been crafted to
245     // a) look somewhat random
246     // b) the even (and odd) indices never share the same character as upper/lowercase
247     // the "_" is not valid but widely accepted (all octets should be supported, but let's be conservative)
248     // the other sequences are obviously derived
249     //static basecoder cdc63 ("_dDpPhHzZrR06QqMmjJkKBb34TtSsvVlL81xXaAeEFf92WwGgYyoO57UucCNniI");
250     static basecoder cdc62 ("dDpPhHzZrR06QqMmjJkKBb34TtSsvVlL81xXaAeEFf92WwGgYyoO57UucCNniI");
251     //static basecoder cdc36 ("dphzr06qmjkb34tsvl81xaef92wgyo57ucni"); // unused as of yet
252     static basecoder cdc26 ("dPhZrQmJkBtSvLxAeFwGyO");
253    
254     /////////////////////////////////////////////////////////////////////////////
255    
256     #define HDRSIZE 6
257    
258     inline void encode_header (char *data, int clientid, int seqno)
259     {
260     u8 hdr[3] = { clientid, seqno >> 8, seqno };
261    
262     assert (clientid < 256);
263    
264     cdc26.encode (data, hdr, 3);
265     }
266    
267     inline void decode_header (char *data, int &clientid, int &seqno)
268     {
269     u8 hdr[3];
270    
271     cdc26.decode (hdr, data, HDRSIZE);
272    
273     clientid = hdr[0];
274     seqno = (hdr[1] << 8) | hdr[2];
275 pcg 1.4 }
276    
277     /////////////////////////////////////////////////////////////////////////////
278    
279     struct byte_stream
280     {
281     u8 *data;
282     int maxsize;
283     int fill;
284    
285     byte_stream (int maxsize);
286     ~byte_stream ();
287    
288     bool empty () { return !fill; }
289     int size () { return fill; }
290    
291 pcg 1.5 bool put (u8 *data, unsigned int datalen);
292 pcg 1.4 bool put (vpn_packet *pkt);
293     vpn_packet *get ();
294    
295     u8 *begin () { return data; }
296     void remove (int count);
297     };
298    
299     byte_stream::byte_stream (int maxsize)
300     : maxsize (maxsize), fill (0)
301     {
302     data = new u8 [maxsize];
303     }
304    
305     byte_stream::~byte_stream ()
306     {
307     delete data;
308     }
309    
310     void byte_stream::remove (int count)
311     {
312     if (count > fill)
313     abort ();
314    
315     memmove (data, data + count, fill -= count);
316     }
317    
318 pcg 1.5 bool byte_stream::put (u8 *data, unsigned int datalen)
319     {
320     if (maxsize - fill < datalen)
321     return false;
322    
323     memcpy (this->data + fill, data, datalen); fill += datalen;
324    
325     return true;
326     }
327    
328 pcg 1.4 bool byte_stream::put (vpn_packet *pkt)
329     {
330     if (maxsize - fill < pkt->len + 2)
331     return false;
332    
333     data [fill++] = pkt->len >> 8;
334     data [fill++] = pkt->len;
335    
336     memcpy (data + fill, &((*pkt)[0]), pkt->len); fill += pkt->len;
337    
338     return true;
339     }
340    
341     vpn_packet *byte_stream::get ()
342     {
343     int len = (data [0] << 8) | data [1];
344    
345 pcg 1.5 if (len > MAXSIZE && fill >= 2)
346     abort (); // TODO handle this gracefully, connection reset
347    
348 pcg 1.4 if (fill < len + 2)
349     return 0;
350    
351     vpn_packet *pkt = new vpn_packet;
352 pcg 1.5
353     pkt->len = len;
354 pcg 1.4 memcpy (&((*pkt)[0]), data + 2, len);
355     remove (len + 2);
356    
357     return pkt;
358 pcg 1.2 }
359    
360 pcg 1.3 /////////////////////////////////////////////////////////////////////////////
361    
362 pcg 1.2 #define FLAG_QUERY ( 0 << 15)
363     #define FLAG_RESPONSE ( 1 << 15)
364 pcg 1.9 #define FLAG_OP_MASK (15 << 11)
365 pcg 1.2 #define FLAG_OP_QUERY ( 0 << 11)
366     #define FLAG_AA ( 1 << 10)
367     #define FLAG_TC ( 1 << 9)
368     #define FLAG_RD ( 1 << 8)
369     #define FLAG_RA ( 1 << 7)
370 pcg 1.5 #define FLAG_AUTH ( 1 << 5)
371 pcg 1.2 #define FLAG_RCODE_MASK (15 << 0)
372     #define FLAG_RCODE_OK ( 0 << 0)
373     #define FLAG_RCODE_FORMERR ( 1 << 0)
374     #define FLAG_RCODE_SERVFAIL ( 2 << 0)
375     #define FLAG_RCODE_NXDOMAIN ( 3 << 0)
376     #define FLAG_RCODE_REFUSED ( 5 << 0)
377    
378     #define DEFAULT_CLIENT_FLAGS (FLAG_QUERY | FLAG_OP_QUERY | FLAG_RD)
379 pcg 1.5 #define DEFAULT_SERVER_FLAGS (FLAG_RESPONSE | FLAG_OP_QUERY | FLAG_AA | FLAG_RD | FLAG_RA)
380 pcg 1.2
381     struct dns_packet : net_packet
382     {
383     u16 id;
384     u16 flags; // QR:1 Opcode:4 AA:1 TC:1 RD:1 RA:1 Z:3 RCODE:4
385     u16 qdcount, ancount, nscount, arcount;
386    
387     u8 data[MAXSIZE - 6 * 2];
388    
389     int decode_label (char *data, int size, int &offs);
390     };
391    
392     int dns_packet::decode_label (char *data, int size, int &offs)
393     {
394     char *orig = data;
395    
396     memset (data, 0, size);
397    
398     while (offs < size - 1)
399     {
400     u8 len = (*this)[offs++];
401    
402     if (!len)
403     break;
404     else if (len < 64)
405     {
406     if (size < len + 1 || offs + len >= MAXSIZE - 1)
407     break;
408    
409     memcpy (data, &((*this)[offs]), len);
410    
411     data += len; size -= len; offs += len;
412     *data++ = '.'; size--;
413     }
414     else
415     {
416     int offs2 = ((len & 63) << 8) + (*this)[offs++];
417    
418     data += decode_label (data, size, offs2);
419     break;
420     }
421     }
422    
423     return data - orig;
424     }
425    
426 pcg 1.3 /////////////////////////////////////////////////////////////////////////////
427    
428     struct dns_req
429     {
430     dns_packet *pkt;
431     tstamp next;
432     int retry;
433 pcg 1.9 struct dns_connection *dns;
434 pcg 1.5 int seqno;
435 pcg 1.3
436 pcg 1.9 dns_req (dns_connection *dns);
437     void gen_stream_req (int seqno, byte_stream &stream);
438 pcg 1.3 };
439    
440 pcg 1.5 static u16 dns_id = 12098; // TODO: should be per-vpn
441    
442     static u16 next_id ()
443 pcg 1.3 {
444 pcg 1.5 // the simplest lsfr with periodicity 65535 i could find
445     dns_id = (dns_id << 1)
446     | (((dns_id >> 1)
447     ^ (dns_id >> 2)
448     ^ (dns_id >> 4)
449     ^ (dns_id >> 15)) & 1);
450 pcg 1.3
451 pcg 1.5 return dns_id;
452     }
453 pcg 1.3
454 pcg 1.9 dns_req::dns_req (dns_connection *dns)
455     : dns (dns)
456 pcg 1.3 {
457     next = 0;
458     retry = 0;
459    
460     pkt = new dns_packet;
461    
462 pcg 1.5 pkt->id = next_id ();
463     }
464    
465 pcg 1.9 void dns_req::gen_stream_req (int seqno, byte_stream &stream)
466 pcg 1.5 {
467     this->seqno = seqno;
468    
469     pkt->flags = htons (DEFAULT_CLIENT_FLAGS);
470 pcg 1.4 pkt->qdcount = htons (1);
471 pcg 1.3
472 pcg 1.4 int offs = 6*2;
473 pcg 1.8 int dlen = MAX_DOMAIN_SIZE - (strlen (THISNODE->domain) + 2);
474 pcg 1.5 // MAX_DOMAIN_SIZE is technically 255, but bind doesn't compress responses well,
475     // so we need to have space for 2*MAX_DOMAIN_SIZE + header + extra
476    
477 pcg 1.8 char enc[256], *encp = enc;
478     encode_header (enc, THISNODE->id, seqno);
479 pcg 1.4
480 pcg 1.8 int datalen = cdc62.decode_len (dlen - (dlen + MAX_LBL_SIZE - 1) / MAX_LBL_SIZE - HDRSIZE);
481 pcg 1.4
482 pcg 1.9 if (datalen > stream.size ())
483     datalen = stream.size ();
484 pcg 1.8
485 pcg 1.9 int enclen = cdc62.encode (enc + HDRSIZE, stream.begin (), datalen) + HDRSIZE;
486     stream.remove (datalen);
487 pcg 1.4
488 pcg 1.5 while (enclen)
489     {
490     int lbllen = enclen < MAX_LBL_SIZE ? enclen : MAX_LBL_SIZE;
491    
492     (*pkt)[offs++] = lbllen;
493     memcpy (pkt->at (offs), encp, lbllen);
494 pcg 1.4
495 pcg 1.5 offs += lbllen;
496     encp += lbllen;
497 pcg 1.4
498 pcg 1.5 enclen -= lbllen;
499 pcg 1.4 }
500    
501     const char *suffix = THISNODE->domain;
502 pcg 1.3
503 pcg 1.4 // add tunnel domain
504     for (;;)
505     {
506     const char *end = strchr (suffix, '.');
507    
508     if (!end)
509     end = suffix + strlen (suffix);
510    
511     int len = end - suffix;
512    
513     (*pkt)[offs++] = len;
514     memcpy (&((*pkt)[offs]), suffix, len);
515     offs += len;
516    
517     if (!*end)
518     break;
519    
520     suffix = end + 1;
521     }
522    
523     (*pkt)[offs++] = 0;
524     (*pkt)[offs++] = RR_TYPE_ANY >> 8; (*pkt)[offs++] = RR_TYPE_ANY;
525     (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN;
526    
527     pkt->len = offs;
528 pcg 1.5 }
529    
530     struct dns_rcv
531     {
532     int seqno;
533     dns_packet *pkt; // reply packet
534     u8 data [MAXSIZE]; // actually part of the reply packet...
535     int datalen;
536    
537 pcg 1.6 dns_rcv (int seqno, u8 *data, int datalen);
538 pcg 1.5 ~dns_rcv ();
539     };
540    
541 pcg 1.6 dns_rcv::dns_rcv (int seqno, u8 *data, int datalen)
542 pcg 1.5 : seqno (seqno), pkt (new dns_packet), datalen (datalen)
543     {
544     memcpy (this->data, data, datalen);
545     }
546 pcg 1.4
547 pcg 1.5 dns_rcv::~dns_rcv ()
548     {
549     delete pkt;
550 pcg 1.3 }
551    
552     /////////////////////////////////////////////////////////////////////////////
553 pcg 1.9
554     struct dns_connection
555     {
556     connection *c;
557     struct vpn *vpn;
558    
559     vector<dns_rcv *> rcvpq;
560    
561     int rcvseq;
562     int sndseq;
563    
564     byte_stream rcvdq;
565     byte_stream snddq;
566    
567     void time_cb (time_watcher &w); time_watcher tw;
568     void receive_rep (dns_rcv *r);
569    
570     dns_connection (connection *c);
571     ~dns_connection ();
572     };
573    
574     dns_connection::dns_connection (connection *c)
575     : c (c)
576     , rcvdq (MAX_BACKLOG * 2)
577     , snddq (MAX_BACKLOG * 2)
578     , tw (this, &dns_connection::time_cb)
579     {
580     vpn = c->vpn;
581    
582     rcvseq = sndseq = 0;
583     }
584    
585     dns_connection::~dns_connection ()
586     {
587     for (vector<dns_rcv *>::iterator i = rcvpq.begin ();
588     i != rcvpq.end ();
589     ++i)
590     delete *i;
591     }
592 pcg 1.3
593 pcg 1.2 struct dns_cfg
594     {
595     u8 id1, id2, id3;
596     u8 def_ttl;
597     u8 unused1;
598     u16 max_size;
599     u8 flags1, flags2;
600     };
601    
602 pcg 1.9 void dns_connection::receive_rep (dns_rcv *r)
603 pcg 1.5 {
604 pcg 1.9 rcvpq.push_back (r);
605 pcg 1.5
606     redo:
607    
608 pcg 1.8 // find next packet
609 pcg 1.9 for (vector<dns_rcv *>::iterator i = rcvpq.end (); i-- != rcvpq.begin (); )
610     if (SEQNO_EQ (rcvseq, (*i)->seqno))
611 pcg 1.5 {
612 pcg 1.8 // enter the packet into our input stream
613     r = *i;
614    
615     // remove the oldest packet, look forward, as it's oldest first
616 pcg 1.9 for (vector<dns_rcv *>::iterator j = rcvpq.begin (); j != rcvpq.end (); ++j)
617     if (SEQNO_EQ ((*j)->seqno, rcvseq - MAX_WINDOW))
618 pcg 1.8 {
619     delete *j;
620 pcg 1.9 rcvpq.erase (j);
621 pcg 1.8 break;
622     }
623 pcg 1.5
624 pcg 1.9 rcvseq = (rcvseq + 1) & SEQNO_MASK;
625 pcg 1.5
626 pcg 1.9 if (!rcvdq.put (r->data, r->datalen))
627 pcg 1.5 abort (); // MUST never overflow, can be caused by data corruption, TODO
628    
629 pcg 1.9 while (vpn_packet *pkt = rcvdq.get ())
630 pcg 1.5 {
631     sockinfo si;
632     si.host = 0; si.port = 0; si.prot = PROT_DNSv4;
633    
634     vpn->recv_vpn_packet (pkt, si);
635     }
636 pcg 1.8
637     // check for further packets
638 pcg 1.5 goto redo;
639     }
640     }
641    
642 pcg 1.4 dns_packet *
643     vpn::dnsv4_server (dns_packet *pkt)
644 pcg 1.2 {
645 pcg 1.4 u16 flags = ntohs (pkt->flags);
646 pcg 1.2
647 pcg 1.4 //memcpy (&((*rep)[0]), &((*pkt)[0]), pkt->len);
648     int offs = 6 * 2; // skip header
649 pcg 1.2
650 pcg 1.4 pkt->flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR);
651 pcg 1.2
652 pcg 1.9 if (0 == (flags & (FLAG_RESPONSE | FLAG_OP_MASK | FLAG_TC))
653 pcg 1.4 && pkt->qdcount == htons (1))
654     {
655     char qname[MAXSIZE];
656     int qlen = pkt->decode_label ((char *)qname, MAXSIZE - offs, offs);
657    
658     u16 qtype = (*pkt) [offs++] << 8; qtype |= (*pkt) [offs++];
659     u16 qclass = (*pkt) [offs++] << 8; qclass |= (*pkt) [offs++];
660 pcg 1.2
661 pcg 1.4 pkt->qdcount = htons (1);
662     pkt->ancount = 0;
663     pkt->nscount = 0; // should be self, as other nameservers reply like this
664     pkt->arcount = 0; // a record for self, as other nameservers reply like this
665 pcg 1.2
666 pcg 1.4 pkt->flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_NXDOMAIN);
667 pcg 1.2
668 pcg 1.4 int dlen = strlen (THISNODE->domain);
669 pcg 1.2
670 pcg 1.4 if (qclass == RR_CLASS_IN
671     && (qtype == RR_TYPE_ANY || qtype == RR_TYPE_TXT)
672 pcg 1.8 && qlen > dlen + 1 + HDRSIZE
673 pcg 1.4 && !memcmp (qname + qlen - dlen - 1, THISNODE->domain, dlen))
674 pcg 1.2 {
675 pcg 1.5 // correct class, domain: parse
676 pcg 1.8 int client, seqno;
677     decode_header (qname, client, seqno);
678    
679 pcg 1.4 u8 data[MAXSIZE];
680 pcg 1.8 int datalen = cdc62.decode (data, qname + HDRSIZE, qlen - (dlen + 1 + HDRSIZE));
681 pcg 1.2
682 pcg 1.5 if (0 < client && client <= conns.size ())
683     {
684     connection *c = conns [client - 1];
685    
686 pcg 1.9 if (!c->dns)
687     c->dns = new dns_connection (c);
688    
689     dns_connection *dns = c->dns;
690    
691     for (vector<dns_rcv *>::iterator i = dns->rcvpq.end (); i-- != dns->rcvpq.begin (); )
692 pcg 1.8 if (SEQNO_EQ ((*i)->seqno, seqno))
693 pcg 1.5 {
694 pcg 1.6 // already seen that request: simply reply with the cached reply
695 pcg 1.5 dns_rcv *r = *i;
696 pcg 1.4
697 pcg 1.6 printf ("DUPLICATE %d\n", htons (r->pkt->id));//D
698    
699 pcg 1.8 memcpy (pkt->at (0), r->pkt->at (0), offs = r->pkt->len);
700     pkt->id = r->pkt->id;
701 pcg 1.5 goto duplicate_request;
702     }
703 pcg 1.4
704 pcg 1.5 // new packet, queue
705 pcg 1.8 dns_rcv *rcv = new dns_rcv (seqno, data, datalen);
706 pcg 1.9 dns->receive_rep (rcv);
707 pcg 1.4
708 pcg 1.5 // now generate reply
709     pkt->ancount = htons (1); // one answer RR
710     pkt->flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_OK);
711 pcg 1.4
712 pcg 1.5 (*pkt) [offs++] = 0xc0;
713     (*pkt) [offs++] = 6 * 2; // same as in query section
714 pcg 1.4
715 pcg 1.5 (*pkt) [offs++] = RR_TYPE_TXT >> 8; (*pkt) [offs++] = RR_TYPE_TXT;
716     (*pkt) [offs++] = RR_CLASS_IN >> 8; (*pkt) [offs++] = RR_CLASS_IN;
717 pcg 1.2
718 pcg 1.5 (*pkt) [offs++] = 0; (*pkt) [offs++] = 0;
719     (*pkt) [offs++] = 0; (*pkt) [offs++] = 0; // TTL
720 pcg 1.2
721 pcg 1.5 int dlen = MAX_PKT_SIZE - offs - 2;
722 pcg 1.2
723 pcg 1.5 // bind doesn't compress well, so reduce further by one label length
724     dlen -= qlen;
725 pcg 1.2
726 pcg 1.5 int rdlen_offs = offs += 2;
727 pcg 1.2
728 pcg 1.9 while (dlen > 1 && !dns->snddq.empty ())
729 pcg 1.5 {
730     int txtlen = dlen <= 255 ? dlen - 1 : 255;
731 pcg 1.2
732 pcg 1.9 if (txtlen > dns->snddq.size ())
733     txtlen = dns->snddq.size ();
734 pcg 1.2
735 pcg 1.5 (*pkt)[offs++] = txtlen;
736 pcg 1.9 memcpy (pkt->at (offs), dns->snddq.begin (), txtlen);
737 pcg 1.5 offs += txtlen;
738 pcg 1.9 dns->snddq.remove (txtlen);
739 pcg 1.2
740 pcg 1.5 dlen -= txtlen + 1;
741     }
742 pcg 1.2
743 pcg 1.5 // avoid empty TXT rdata
744     if (offs == rdlen_offs)
745     (*pkt)[offs++] = 0;
746 pcg 1.2
747 pcg 1.5 int rdlen = offs - rdlen_offs;
748 pcg 1.2
749 pcg 1.5 (*pkt) [rdlen_offs - 2] = rdlen >> 8;
750     (*pkt) [rdlen_offs - 1] = rdlen;
751 pcg 1.4
752 pcg 1.6 // now update dns_rcv copy
753     rcv->pkt->len = offs;
754     memcpy (rcv->pkt->at (0), pkt->at (0), offs);
755    
756 pcg 1.5 duplicate_request: ;
757     }
758     else
759     pkt->flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR);
760 pcg 1.2 }
761 pcg 1.6
762     pkt->len = offs;
763 pcg 1.4 }
764    
765     return pkt;
766     }
767    
768     void
769     vpn::dnsv4_client (dns_packet *pkt)
770     {
771     u16 flags = ntohs (pkt->flags);
772     int offs = 6 * 2; // skip header
773    
774     pkt->qdcount = ntohs (pkt->qdcount);
775     pkt->ancount = ntohs (pkt->ancount);
776    
777 pcg 1.5 // go through our request list and find the corresponding request
778 pcg 1.4 for (vector<dns_req *>::iterator i = dns_sndpq.begin ();
779     i != dns_sndpq.end ();
780     ++i)
781     if ((*i)->pkt->id == pkt->id)
782     {
783 pcg 1.9 dns_connection *dns = (*i)->dns;
784 pcg 1.5 int seqno = (*i)->seqno;
785     u8 data[MAXSIZE], *datap = data;
786    
787 pcg 1.4 delete *i;
788     dns_sndpq.erase (i);
789    
790 pcg 1.9 if (flags & FLAG_RESPONSE && !(flags & (FLAG_OP_MASK | FLAG_TC)))
791 pcg 1.4 {
792     char qname[MAXSIZE];
793    
794     while (pkt->qdcount-- && offs < MAXSIZE - 4)
795     {
796     int qlen = pkt->decode_label ((char *)qname, MAXSIZE - offs, offs);
797     offs += 4; // skip qtype, qclass
798     }
799    
800 pcg 1.9 while (pkt->ancount-- && offs < MAXSIZE - 10 && datap)
801 pcg 1.4 {
802 pcg 1.9 int qlen = pkt->decode_label ((char *)qname, MAXSIZE - offs, offs);
803 pcg 1.8
804 pcg 1.4 u16 qtype = (*pkt) [offs++] << 8; qtype |= (*pkt) [offs++];
805     u16 qclass = (*pkt) [offs++] << 8; qclass |= (*pkt) [offs++];
806     u32 ttl = (*pkt) [offs++] << 24;
807     ttl |= (*pkt) [offs++] << 16;
808     ttl |= (*pkt) [offs++] << 8;
809     ttl |= (*pkt) [offs++];
810    
811     u16 rdlen = (*pkt) [offs++] << 8; rdlen |= (*pkt) [offs++];
812    
813 pcg 1.5 if (rdlen <= MAXSIZE - offs)
814     {
815     // decode bytes, finally
816    
817     while (rdlen)
818     {
819     int txtlen = (*pkt) [offs++];
820    
821     assert (txtlen + offs < MAXSIZE - 1);
822    
823     memcpy (datap, pkt->at (offs), txtlen);
824     datap += txtlen; offs += txtlen;
825 pcg 1.4
826 pcg 1.5 rdlen -= txtlen + 1;
827     }
828 pcg 1.9 }
829 pcg 1.4
830 pcg 1.9 int client, rseqno;
831     decode_header (qname, client, rseqno);
832    
833     if (client != THISNODE->id)
834     {
835     slog (L_INFO, _("got dns tunnel response with wrong clientid, ignoring"));
836     datap = 0;
837     }
838     else if (rseqno != seqno)
839     {
840     slog (L_DEBUG, _("got dns tunnel response with wrong seqno, badly caching nameserver?"));
841     datap = 0;
842 pcg 1.4 }
843     }
844     }
845    
846 pcg 1.6 // todo: pkt now used
847 pcg 1.9 if (datap)
848     dns->receive_rep (new dns_rcv (seqno, data, datap - data));
849 pcg 1.5
850 pcg 1.4 break;
851     }
852 pcg 1.5
853     delete pkt;
854 pcg 1.4 }
855    
856     void
857     vpn::dnsv4_ev (io_watcher &w, short revents)
858     {
859     if (revents & EVENT_READ)
860     {
861     dns_packet *pkt = new dns_packet;
862     struct sockaddr_in sa;
863     socklen_t sa_len = sizeof (sa);
864    
865     pkt->len = recvfrom (w.fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len);
866    
867     if (pkt->len > 0)
868 pcg 1.5 {
869     if (pkt->flags & htons (FLAG_TC))
870     {
871     slog (L_WARN, _("DNS request/response truncated, check protocol settings."));
872     //TODO connection reset
873     }
874    
875     if (THISNODE->dns_port)
876     {
877     pkt = dnsv4_server (pkt);
878     sendto (w.fd, &((*pkt)[0]), pkt->len, 0, (sockaddr *)&sa, sa_len);
879     }
880     else
881     dnsv4_client (pkt);
882     }
883 pcg 1.1 }
884     }
885    
886     bool
887 pcg 1.3 connection::send_dnsv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
888     {
889 pcg 1.9 if (!dns)
890     dns = new dns_connection (this);
891 pcg 1.4
892 pcg 1.9 if (!dns->snddq.put (pkt))
893 pcg 1.3 return false;
894    
895 pcg 1.4 // start timer if neccessary
896 pcg 1.9 if (!THISNODE->dns_port && !dns->tw.active)
897     dns->tw.trigger ();
898 pcg 1.3
899     return true;
900     }
901    
902     void
903 pcg 1.9 dns_connection::time_cb (time_watcher &w)
904 pcg 1.1 {
905 pcg 1.3 // check for timeouts and (re)transmit
906     tstamp next = NOW + 60;
907 pcg 1.4 dns_req *send = 0;
908 pcg 1.3
909 pcg 1.4 for (vector<dns_req *>::iterator i = vpn->dns_sndpq.begin ();
910     i != vpn->dns_sndpq.end ();
911 pcg 1.3 ++i)
912     {
913     dns_req *r = *i;
914    
915     if (r->next <= NOW)
916     {
917 pcg 1.4 if (!send)
918     {
919     send = r;
920    
921 pcg 1.5 if (r->retry)//D
922 pcg 1.8 printf ("req %d:%d, retry %d\n", r->seqno, r->pkt->id, r->retry);
923 pcg 1.4 r->retry++;
924     r->next = NOW + r->retry;
925     }
926 pcg 1.3 }
927    
928     if (r->next < next)
929     next = r->next;
930     }
931    
932 pcg 1.4 if (!send
933     && vpn->dns_sndpq.size () < MAX_OUTSTANDING)
934 pcg 1.5 {
935     send = new dns_req (this);
936 pcg 1.9 send->gen_stream_req (sndseq, snddq);
937 pcg 1.5 vpn->dns_sndpq.push_back (send);
938    
939 pcg 1.9 sndseq = (sndseq + 1) & SEQNO_MASK;
940 pcg 1.5 }
941 pcg 1.4
942     tstamp min_next = NOW + (1. / (tstamp)MAX_RATE);
943    
944     if (send)
945     {
946     dns_packet *pkt = send->pkt;
947    
948     next = min_next;
949    
950 pcg 1.9 sendto (vpn->dnsv4_fd, &((*pkt)[0]), pkt->len, 0,
951     vpn->dns_forwarder.sav4 (), vpn->dns_forwarder.salenv4 ());
952 pcg 1.4 }
953     else if (next < min_next)
954     next = min_next;
955    
956 pcg 1.3 w.start (next);
957 pcg 1.1 }
958    
959     #endif
960