ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/vpn_dns.C
(Generate patch)

Comparing gvpe/src/vpn_dns.C (file contents):
Revision 1.6 by pcg, Thu Mar 3 08:38:32 2005 UTC vs.
Revision 1.9 by pcg, Fri Mar 4 04:52:38 2005 UTC

1/* 1/*
2 vpn_dns.C -- handle the dns tunnel part of the protocol. 2 vpn_dns.C -- handle the dns tunnel part of the protocol.
3 Copyright (C) 2003-2004 Marc Lehmann <pcg@goof.com> 3 Copyright (C) 2003-2005 Marc Lehmann <gvpe@schmorp.de>
4 4
5 This file is part of GVPE.
6
5 This program is free software; you can redistribute it and/or modify 7 GVPE is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by 8 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or 9 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version. 10 (at your option) any later version.
9 11
10 This program is distributed in the hope that it will be useful, 12 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details. 15 GNU General Public License for more details.
14 16
15 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software 18 along with gvpe; if not, write to the Free Software
17 Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18*/ 20*/
19 21
20#include "config.h" 22#include "config.h"
21 23
35#include <unistd.h> 37#include <unistd.h>
36#include <fcntl.h> 38#include <fcntl.h>
37 39
38#include <map> 40#include <map>
39 41
42#include <gmp.h>
43
40#include "netcompat.h" 44#include "netcompat.h"
41 45
42#include "vpn.h" 46#include "vpn.h"
43 47
44#define MIN_RETRY 1. 48#define MIN_RETRY 1.
45#define MAX_RETRY 60. 49#define MAX_RETRY 6.
46 50
47#define MAX_OUTSTANDING 40 // max. outstanding requests 51#define MAX_OUTSTANDING 400 // max. outstanding requests
48#define MAX_WINDOW 100 // max. for MAX_OUTSTANDING 52#define MAX_WINDOW 1000 // max. for MAX_OUTSTANDING
49#define MAX_RATE 1000 // requests/s 53#define MAX_RATE 100 // requests/s
50#define MAX_BACKLOG (10*1024) // size of protocol backlog, must be > MAXSIZE 54#define MAX_BACKLOG (10*1024) // size of protocol backlog, must be > MAXSIZE
51 55
52#define MAX_DOMAIN_SIZE 220 // 255 is legal limit, but bind doesn't compress well 56#define MAX_DOMAIN_SIZE 220 // 255 is legal limit, but bind doesn't compress well
53// 240 leaves about 4 bytes of server reply data 57// 240 leaves about 4 bytes of server reply data
54// every two request byte sless give room for one reply byte 58// every two request byte sless give room for one reply byte
55 59
56// seqno has 12 bits, but the lower bit is always left as zero
57// as bind caches ttl=0 records and we have to generate
58// sequence numbers that always differ case-insensitively
59#define SEQNO_MASK 0x07ff 60#define SEQNO_MASK 0xffff
60 61#define SEQNO_EQ(a,b) ( 0 == ( ((a) ^ (b)) & SEQNO_MASK) )
61/*
62
63protocol, in shorthand :)
64
65client -> server <req> ANY?
66server -> client <req> TXT <rep>
67
68<req> is dns64-encoded <client-id:12><recv-seqno:10>[<send-seqno:10><data>]
69<rep> is dns64-encoded <0:12><recv-seqno:10>[<send-seqno:10><data>]
70
71if <client-id> is zero, the connection will be configured:
72
73<0:12><0:4>client-id:12><default-ttl:8><max-size:16><flags:16>
74
75*/
76 62
77#define MAX_LBL_SIZE 63 63#define MAX_LBL_SIZE 63
78#define MAX_PKT_SIZE 512 64#define MAX_PKT_SIZE 512
79 65
80#define RR_TYPE_TXT 16 66#define RR_TYPE_TXT 16
81#define RR_TYPE_ANY 255 67#define RR_TYPE_ANY 255
82#define RR_CLASS_IN 1 68#define RR_CLASS_IN 1
83 69
84// the "_" is not valid but widely accepted (all octets should be supported, but let's be conservative) 70// works for cmaps up to 255 (not 256!)
85struct dns64 71struct charmap
86{ 72{
87 static const char encode_chars[64 + 1]; 73 enum { INVALID = (u8)255 };
88 static s8 decode_chars[256];
89 74
90 static int encode_len (int bytes) { return (bytes * 8 + 5) / 6; } 75 char encode [256]; // index => char
91 static int decode_len (int bytes) { return (bytes * 6) / 8; } 76 u8 decode [256]; // char => index
77 unsigned int size;
78
79 charmap (const char *cmap);
80};
81
82charmap::charmap (const char *cmap)
83{
84 char *enc = encode;
85 u8 *dec = decode;
86
87 memset (enc, (char) 0, 256);
88 memset (dec, (char)INVALID, 256);
89
90 for (size = 0; cmap [size]; size++)
91 {
92 enc [size] = cmap [size];
93 dec [(u8)enc [size]] = size;
94 }
95
96 assert (size < 256);
97}
98
99#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
103// ugly. minimum base is 16(!)
104struct basecoder
105{
106 charmap cmap;
107 unsigned int enc_len [MAX_DEC_LEN];
108 unsigned int dec_len [MAX_ENC_LEN];
109
110 unsigned int encode_len (unsigned int len);
111 unsigned int decode_len (unsigned int len);
112
92 static int encode (char *dst, u8 *src, int len); 113 unsigned int encode (char *dst, u8 *src, unsigned int len);
93 static int decode (u8 *dst, char *src, int len); 114 unsigned int decode (u8 *dst, char *src, unsigned int len);
94 115
95 dns64 (); 116 basecoder (const char *cmap);
96} dns64; 117};
118
119basecoder::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
127 memset (src, 255, len);
128
129 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
143unsigned int basecoder::encode_len (unsigned int len)
144{
145 return enc_len [len];
146}
147
148unsigned int basecoder::decode_len (unsigned int len)
149{
150 while (len && !dec_len [len])
151 --len;
152
153 return dec_len [len];
154}
155
156unsigned int basecoder::encode (char *dst, u8 *src, unsigned int len)
157{
158 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
173 while (n < plen)
174 {
175 *dst++ = cmap.encode [0];
176 plen--;
177 }
178
179 for (unsigned int i = n - plen; i < n; ++i)
180 *dst++ = cmap.encode [dst_ [i]];
181
182 return elen;
183}
184
185unsigned int basecoder::decode (u8 *dst, char *src, unsigned int len)
186{
187 if (!len)
188 return 0;
189
190 u8 src_ [MAX_ENC_LEN];
191 unsigned int elen = 0;
192
193 while (len--)
194 {
195 u8 val = cmap.decode [(u8)*src++];
196
197 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
208 n = mpn_set_str (m, src_, elen, cmap.size);
209 n = mpn_get_str (dst_, 256, m, n);
210
211 if (n < dlen)
212 {
213 memset (dst, 0, dlen - n);
214 memcpy (dst + dlen - n, dst_, n);
215 }
216 else
217 memcpy (dst, dst_ + n - dlen, dlen);
218
219 return dlen;
220}
221
222#if 0
223struct test { test (); } test;
224
225test::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
97 243
98// the following sequence has been crafted to 244// the following sequence has been crafted to
99// a) look somewhat random 245// a) look somewhat random
100// b) the even (and odd) indices never share the same character as upper/lowercase 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");
101const char dns64::encode_chars[64 + 1] = "_-dDpPhHzZrR06QqMmjJkKBb34TtSsvVlL81xXaAeEFf92WwGgYyoO57UucCNniI"; 250static basecoder cdc62 ("dDpPhHzZrR06QqMmjJkKBb34TtSsvVlL81xXaAeEFf92WwGgYyoO57UucCNniI");
102s8 dns64::decode_chars[256]; 251//static basecoder cdc36 ("dphzr06qmjkb34tsvl81xaef92wgyo57ucni"); // unused as of yet
252static basecoder cdc26 ("dPhZrQmJkBtSvLxAeFwGyO");
103 253
104dns64::dns64 () 254/////////////////////////////////////////////////////////////////////////////
105{
106 for (int i = 0; i < 64; i++)
107 decode_chars [encode_chars [i]] = i + 1;
108}
109 255
110int dns64::encode (char *dst, u8 *src, int len) 256#define HDRSIZE 6
111{
112 // slow, but easy to debug
113 char *beg = dst;
114 unsigned int accum, bits = 0;
115 257
116 while (len--) 258inline void encode_header (char *data, int clientid, int seqno)
117 {
118 accum <<= 8;
119 accum |= *src++;
120 bits += 8;
121
122 while (bits >= 6)
123 {
124 *dst++ = encode_chars [(accum >> (bits - 6)) & 63];
125 bits -= 6;
126 }
127 }
128
129 if (bits)
130 *dst++ = encode_chars [(accum << (6 - bits)) & 63];
131
132 return dst - beg;
133}
134
135int dns64::decode (u8 *dst, char *src, int len)
136{ 259{
137 // slow, but easy to debug 260 u8 hdr[3] = { clientid, seqno >> 8, seqno };
138 u8 *beg = dst;
139 unsigned int accum, bits = 0;
140 261
141 while (len--) 262 assert (clientid < 256);
142 {
143 s8 chr = decode_chars [(u8)*src++];
144 263
145 if (!chr) 264 cdc26.encode (data, hdr, 3);
146 continue; 265}
147 266
148 accum <<= 6; 267inline void decode_header (char *data, int &clientid, int &seqno)
149 accum |= chr - 1; 268{
150 bits += 6; 269 u8 hdr[3];
151 270
152 while (bits >= 8) 271 cdc26.decode (hdr, data, HDRSIZE);
153 {
154 *dst++ = accum >> (bits - 8);
155 bits -= 8;
156 }
157 }
158 272
159 return dst - beg; 273 clientid = hdr[0];
274 seqno = (hdr[1] << 8) | hdr[2];
160} 275}
161 276
162///////////////////////////////////////////////////////////////////////////// 277/////////////////////////////////////////////////////////////////////////////
163 278
164struct byte_stream 279struct byte_stream
244 359
245///////////////////////////////////////////////////////////////////////////// 360/////////////////////////////////////////////////////////////////////////////
246 361
247#define FLAG_QUERY ( 0 << 15) 362#define FLAG_QUERY ( 0 << 15)
248#define FLAG_RESPONSE ( 1 << 15) 363#define FLAG_RESPONSE ( 1 << 15)
249#define FLAG_OP_MASK (15 << 14) 364#define FLAG_OP_MASK (15 << 11)
250#define FLAG_OP_QUERY ( 0 << 11) 365#define FLAG_OP_QUERY ( 0 << 11)
251#define FLAG_AA ( 1 << 10) 366#define FLAG_AA ( 1 << 10)
252#define FLAG_TC ( 1 << 9) 367#define FLAG_TC ( 1 << 9)
253#define FLAG_RD ( 1 << 8) 368#define FLAG_RD ( 1 << 8)
254#define FLAG_RA ( 1 << 7) 369#define FLAG_RA ( 1 << 7)
313struct dns_req 428struct dns_req
314{ 429{
315 dns_packet *pkt; 430 dns_packet *pkt;
316 tstamp next; 431 tstamp next;
317 int retry; 432 int retry;
318 connection *conn; 433 struct dns_connection *dns;
319 int seqno; 434 int seqno;
320 435
321 dns_req (connection *c); 436 dns_req (dns_connection *dns);
322 void gen_stream_req (int seqno, byte_stream *stream); 437 void gen_stream_req (int seqno, byte_stream &stream);
323}; 438};
324 439
325static u16 dns_id = 12098; // TODO: should be per-vpn 440static u16 dns_id = 12098; // TODO: should be per-vpn
326 441
327static u16 next_id () 442static u16 next_id ()
334 ^ (dns_id >> 15)) & 1); 449 ^ (dns_id >> 15)) & 1);
335 450
336 return dns_id; 451 return dns_id;
337} 452}
338 453
339dns_req::dns_req (connection *c) 454dns_req::dns_req (dns_connection *dns)
340: conn (c) 455: dns (dns)
341{ 456{
342 next = 0; 457 next = 0;
343 retry = 0; 458 retry = 0;
344 459
345 pkt = new dns_packet; 460 pkt = new dns_packet;
346 461
347 pkt->id = next_id (); 462 pkt->id = next_id ();
348} 463}
349 464
350void dns_req::gen_stream_req (int seqno, byte_stream *stream) 465void dns_req::gen_stream_req (int seqno, byte_stream &stream)
351{ 466{
352 this->seqno = seqno; 467 this->seqno = seqno;
353 468
354 pkt->flags = htons (DEFAULT_CLIENT_FLAGS); 469 pkt->flags = htons (DEFAULT_CLIENT_FLAGS);
355 pkt->qdcount = htons (1); 470 pkt->qdcount = htons (1);
356 471
357 int offs = 6*2; 472 int offs = 6*2;
358 int dlen = MAX_DOMAIN_SIZE - strlen (THISNODE->domain) - 2; 473 int dlen = MAX_DOMAIN_SIZE - (strlen (THISNODE->domain) + 2);
359 // MAX_DOMAIN_SIZE is technically 255, but bind doesn't compress responses well, 474 // MAX_DOMAIN_SIZE is technically 255, but bind doesn't compress responses well,
360 // so we need to have space for 2*MAX_DOMAIN_SIZE + header + extra 475 // so we need to have space for 2*MAX_DOMAIN_SIZE + header + extra
361 476
362 u8 data[256]; //TODO
363
364 data[0] = THISNODE->id; //TODO
365 data[1] = seqno >> 7; //TODO
366 data[2] = seqno << 1; //TODO
367
368 int datalen = dns64::decode_len (dlen - (dlen + MAX_LBL_SIZE - 1) / MAX_LBL_SIZE) - 3;
369
370 if (datalen > stream->size ())
371 datalen = stream->size ();
372
373 char enc[256], *encp = enc; 477 char enc[256], *encp = enc;
374 478 encode_header (enc, THISNODE->id, seqno);
375 memcpy (data + 3, stream->begin (), datalen); 479
376 int enclen = dns64::encode (enc, data, datalen + 3); 480 int datalen = cdc62.decode_len (dlen - (dlen + MAX_LBL_SIZE - 1) / MAX_LBL_SIZE - HDRSIZE);
481
482 if (datalen > stream.size ())
483 datalen = stream.size ();
484
485 int enclen = cdc62.encode (enc + HDRSIZE, stream.begin (), datalen) + HDRSIZE;
377 stream->remove (datalen); 486 stream.remove (datalen);
378 487
379 while (enclen) 488 while (enclen)
380 { 489 {
381 int lbllen = enclen < MAX_LBL_SIZE ? enclen : MAX_LBL_SIZE; 490 int lbllen = enclen < MAX_LBL_SIZE ? enclen : MAX_LBL_SIZE;
382 491
439{ 548{
440 delete pkt; 549 delete pkt;
441} 550}
442 551
443///////////////////////////////////////////////////////////////////////////// 552/////////////////////////////////////////////////////////////////////////////
553
554struct 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
574dns_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
585dns_connection::~dns_connection ()
586{
587 for (vector<dns_rcv *>::iterator i = rcvpq.begin ();
588 i != rcvpq.end ();
589 ++i)
590 delete *i;
591}
444 592
445struct dns_cfg 593struct dns_cfg
446{ 594{
447 u8 id1, id2, id3; 595 u8 id1, id2, id3;
448 u8 def_ttl; 596 u8 def_ttl;
449 u8 unused1; 597 u8 unused1;
450 u16 max_size; 598 u16 max_size;
451 u8 flags1, flags2; 599 u8 flags1, flags2;
452}; 600};
453 601
454void connection::dnsv4_receive_rep (struct dns_rcv *r) 602void dns_connection::receive_rep (dns_rcv *r)
455{ 603{
456 dns_rcvpq.push_back (r); 604 rcvpq.push_back (r);
457 605
458 redo: 606 redo:
459 607
608 // find next packet
460 for (vector<dns_rcv *>::iterator i = dns_rcvpq.begin (); 609 for (vector<dns_rcv *>::iterator i = rcvpq.end (); i-- != rcvpq.begin (); )
461 i != dns_rcvpq.end ();
462 ++i)
463 if (dns_rcvseq == (*i)->seqno) 610 if (SEQNO_EQ (rcvseq, (*i)->seqno))
464 { 611 {
612 // enter the packet into our input stream
465 dns_rcv *r = *i; 613 r = *i;
466 614
467 dns_rcvseq = (dns_rcvseq + 1) & SEQNO_MASK; 615 // remove the oldest packet, look forward, as it's oldest first
468 616 for (vector<dns_rcv *>::iterator j = rcvpq.begin (); j != rcvpq.end (); ++j)
469 if (!dns_snddq && !dns_rcvdq) 617 if (SEQNO_EQ ((*j)->seqno, rcvseq - MAX_WINDOW))
470 { 618 {
471 dns_rcvdq = new byte_stream (MAX_BACKLOG * 2); 619 delete *j;
472 dns_snddq = new byte_stream (MAX_BACKLOG); 620 rcvpq.erase (j);
473 621 break;
474 dns_si.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4);
475 } 622 }
476 623
624 rcvseq = (rcvseq + 1) & SEQNO_MASK;
625
477 if (!dns_rcvdq->put (r->data, r->datalen)) 626 if (!rcvdq.put (r->data, r->datalen))
478 abort (); // MUST never overflow, can be caused by data corruption, TODO 627 abort (); // MUST never overflow, can be caused by data corruption, TODO
479 628
480 while (vpn_packet *pkt = dns_rcvdq->get ()) 629 while (vpn_packet *pkt = rcvdq.get ())
481 { 630 {
482 sockinfo si; 631 sockinfo si;
483 si.host = 0; si.port = 0; si.prot = PROT_DNSv4; 632 si.host = 0; si.port = 0; si.prot = PROT_DNSv4;
484 633
485 vpn->recv_vpn_packet (pkt, si); 634 vpn->recv_vpn_packet (pkt, si);
486 } 635 }
487 } 636
488 else if ((u32)(*i)->seqno - (u32)dns_rcvseq + MAX_WINDOW > MAX_WINDOW * 2) 637 // check for further packets
489 {
490 //D
491 //abort();
492 printf ("%d erasing %d (%d)\n", THISNODE->id, (u32)(*i)->seqno, dns_rcvseq);
493 dns_rcvpq.erase (i);
494 goto redo; 638 goto redo;
495 } 639 }
496} 640}
497 641
498dns_packet * 642dns_packet *
503 //memcpy (&((*rep)[0]), &((*pkt)[0]), pkt->len); 647 //memcpy (&((*rep)[0]), &((*pkt)[0]), pkt->len);
504 int offs = 6 * 2; // skip header 648 int offs = 6 * 2; // skip header
505 649
506 pkt->flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR); 650 pkt->flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR);
507 651
508 if (!(flags & (FLAG_RESPONSE | FLAG_OP_MASK | FLAG_TC)) 652 if (0 == (flags & (FLAG_RESPONSE | FLAG_OP_MASK | FLAG_TC))
509 && pkt->qdcount == htons (1)) 653 && pkt->qdcount == htons (1))
510 { 654 {
511 char qname[MAXSIZE]; 655 char qname[MAXSIZE];
512 int qlen = pkt->decode_label ((char *)qname, MAXSIZE - offs, offs); 656 int qlen = pkt->decode_label ((char *)qname, MAXSIZE - offs, offs);
513 657
523 667
524 int dlen = strlen (THISNODE->domain); 668 int dlen = strlen (THISNODE->domain);
525 669
526 if (qclass == RR_CLASS_IN 670 if (qclass == RR_CLASS_IN
527 && (qtype == RR_TYPE_ANY || qtype == RR_TYPE_TXT) 671 && (qtype == RR_TYPE_ANY || qtype == RR_TYPE_TXT)
528 && qlen > dlen + 1 672 && qlen > dlen + 1 + HDRSIZE
529 && !memcmp (qname + qlen - dlen - 1, THISNODE->domain, dlen)) 673 && !memcmp (qname + qlen - dlen - 1, THISNODE->domain, dlen))
530 { 674 {
531 // correct class, domain: parse 675 // correct class, domain: parse
676 int client, seqno;
677 decode_header (qname, client, seqno);
678
532 u8 data[MAXSIZE]; 679 u8 data[MAXSIZE];
533 int datalen = dns64::decode (data, qname, qlen - dlen - 1); 680 int datalen = cdc62.decode (data, qname + HDRSIZE, qlen - (dlen + 1 + HDRSIZE));
534
535 int client = data[0];
536 int seqno = ((data[1] << 7) | (data[2] >> 1)) & SEQNO_MASK;
537 681
538 if (0 < client && client <= conns.size ()) 682 if (0 < client && client <= conns.size ())
539 { 683 {
540 connection *c = conns [client - 1]; 684 connection *c = conns [client - 1];
541 685
542 redo: 686 if (!c->dns)
687 c->dns = new dns_connection (c);
543 688
689 dns_connection *dns = c->dns;
690
544 for (vector<dns_rcv *>::iterator i = c->dns_rcvpq.begin (); 691 for (vector<dns_rcv *>::iterator i = dns->rcvpq.end (); i-- != dns->rcvpq.begin (); )
545 i != c->dns_rcvpq.end ();
546 ++i)
547 if ((*i)->seqno == seqno) 692 if (SEQNO_EQ ((*i)->seqno, seqno))
548 { 693 {
549 // already seen that request: simply reply with the cached reply 694 // already seen that request: simply reply with the cached reply
550 dns_rcv *r = *i; 695 dns_rcv *r = *i;
551 696
552 printf ("DUPLICATE %d\n", htons (r->pkt->id));//D 697 printf ("DUPLICATE %d\n", htons (r->pkt->id));//D
553 698
554 offs = r->pkt->len;
555 memcpy (pkt->at (0), r->pkt->at (0), offs); 699 memcpy (pkt->at (0), r->pkt->at (0), offs = r->pkt->len);
700 pkt->id = r->pkt->id;
556 goto duplicate_request; 701 goto duplicate_request;
557 } 702 }
558 703
559 // new packet, queue 704 // new packet, queue
560 dns_rcv *rcv = new dns_rcv (seqno, data + 3, datalen - 3); 705 dns_rcv *rcv = new dns_rcv (seqno, data, datalen);
561 c->dnsv4_receive_rep (rcv); 706 dns->receive_rep (rcv);
562 707
563 // now generate reply 708 // now generate reply
564 pkt->ancount = htons (1); // one answer RR 709 pkt->ancount = htons (1); // one answer RR
565 pkt->flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_OK); 710 pkt->flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_OK);
566 711
578 // bind doesn't compress well, so reduce further by one label length 723 // bind doesn't compress well, so reduce further by one label length
579 dlen -= qlen; 724 dlen -= qlen;
580 725
581 int rdlen_offs = offs += 2; 726 int rdlen_offs = offs += 2;
582 727
583 while (c->dns_snddq 728 while (dlen > 1 && !dns->snddq.empty ())
584 && !c->dns_snddq->empty ()
585 && dlen > 1)
586 { 729 {
587 int txtlen = dlen <= 255 ? dlen - 1 : 255; 730 int txtlen = dlen <= 255 ? dlen - 1 : 255;
588 731
589 if (txtlen > c->dns_snddq->size ()) 732 if (txtlen > dns->snddq.size ())
590 txtlen = c->dns_snddq->size (); 733 txtlen = dns->snddq.size ();
591 734
592 (*pkt)[offs++] = txtlen; 735 (*pkt)[offs++] = txtlen;
593 memcpy (pkt->at (offs), c->dns_snddq->begin (), txtlen); 736 memcpy (pkt->at (offs), dns->snddq.begin (), txtlen);
594 offs += txtlen; 737 offs += txtlen;
595 c->dns_snddq->remove (txtlen); 738 dns->snddq.remove (txtlen);
596 739
597 dlen -= txtlen + 1; 740 dlen -= txtlen + 1;
598 } 741 }
599 742
600 // avoid empty TXT rdata 743 // avoid empty TXT rdata
635 for (vector<dns_req *>::iterator i = dns_sndpq.begin (); 778 for (vector<dns_req *>::iterator i = dns_sndpq.begin ();
636 i != dns_sndpq.end (); 779 i != dns_sndpq.end ();
637 ++i) 780 ++i)
638 if ((*i)->pkt->id == pkt->id) 781 if ((*i)->pkt->id == pkt->id)
639 { 782 {
640 connection *c = (*i)->conn; 783 dns_connection *dns = (*i)->dns;
641 int seqno = (*i)->seqno; 784 int seqno = (*i)->seqno;
642 u8 data[MAXSIZE], *datap = data; 785 u8 data[MAXSIZE], *datap = data;
643 786
644 delete *i; 787 delete *i;
645 dns_sndpq.erase (i); 788 dns_sndpq.erase (i);
646 789
647 if (flags & (FLAG_RESPONSE | FLAG_OP_MASK | FLAG_TC)) 790 if (flags & FLAG_RESPONSE && !(flags & (FLAG_OP_MASK | FLAG_TC)))
648 { 791 {
649 char qname[MAXSIZE]; 792 char qname[MAXSIZE];
650 793
651 while (pkt->qdcount-- && offs < MAXSIZE - 4) 794 while (pkt->qdcount-- && offs < MAXSIZE - 4)
652 { 795 {
653 int qlen = pkt->decode_label ((char *)qname, MAXSIZE - offs, offs); 796 int qlen = pkt->decode_label ((char *)qname, MAXSIZE - offs, offs);
654 offs += 4; // skip qtype, qclass 797 offs += 4; // skip qtype, qclass
655 } 798 }
656 799
657 while (pkt->ancount-- && offs < MAXSIZE - 10) 800 while (pkt->ancount-- && offs < MAXSIZE - 10 && datap)
658 { 801 {
659 pkt->decode_label ((char *)qname, MAXSIZE - offs, offs); 802 int qlen = pkt->decode_label ((char *)qname, MAXSIZE - offs, offs);
660 803
661 u16 qtype = (*pkt) [offs++] << 8; qtype |= (*pkt) [offs++]; 804 u16 qtype = (*pkt) [offs++] << 8; qtype |= (*pkt) [offs++];
662 u16 qclass = (*pkt) [offs++] << 8; qclass |= (*pkt) [offs++]; 805 u16 qclass = (*pkt) [offs++] << 8; qclass |= (*pkt) [offs++];
663 u32 ttl = (*pkt) [offs++] << 24; 806 u32 ttl = (*pkt) [offs++] << 24;
664 ttl |= (*pkt) [offs++] << 16; 807 ttl |= (*pkt) [offs++] << 16;
680 memcpy (datap, pkt->at (offs), txtlen); 823 memcpy (datap, pkt->at (offs), txtlen);
681 datap += txtlen; offs += txtlen; 824 datap += txtlen; offs += txtlen;
682 825
683 rdlen -= txtlen + 1; 826 rdlen -= txtlen + 1;
684 } 827 }
685
686 } 828 }
687 829
830 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 }
688 } 843 }
689 } 844 }
690 845
691 // todo: pkt now used 846 // todo: pkt now used
847 if (datap)
692 c->dnsv4_receive_rep (new dns_rcv (seqno, data, datap - data)); 848 dns->receive_rep (new dns_rcv (seqno, data, datap - data));
693 849
694 break; 850 break;
695 } 851 }
696 852
697 delete pkt; 853 delete pkt;
728} 884}
729 885
730bool 886bool
731connection::send_dnsv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 887connection::send_dnsv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
732{ 888{
733 // never initialized 889 if (!dns)
734 if (!dns_snddq && !dns_rcvdq) 890 dns = new dns_connection (this);
735 {
736 dns_rcvdq = new byte_stream (MAX_BACKLOG * 2);
737 dns_snddq = new byte_stream (MAX_BACKLOG);
738
739 //dns_rcvseq = dns_sndseq = 0;
740
741 dns_si.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4);
742 }
743 891
744 if (!dns_snddq->put (pkt)) 892 if (!dns->snddq.put (pkt))
745 return false; 893 return false;
746 894
747 // start timer if neccessary 895 // start timer if neccessary
748 if (!THISNODE->dns_port && !dnsv4_tw.active) 896 if (!THISNODE->dns_port && !dns->tw.active)
749 dnsv4_cb (dnsv4_tw); 897 dns->tw.trigger ();
750 898
751 return true; 899 return true;
752} 900}
753 901
754void 902void
755connection::dnsv4_cb (time_watcher &w) 903dns_connection::time_cb (time_watcher &w)
756{ 904{
757 // check for timeouts and (re)transmit 905 // check for timeouts and (re)transmit
758 tstamp next = NOW + 60; 906 tstamp next = NOW + 60;
759 dns_req *send = 0; 907 dns_req *send = 0;
760 908
769 if (!send) 917 if (!send)
770 { 918 {
771 send = r; 919 send = r;
772 920
773 if (r->retry)//D 921 if (r->retry)//D
774 printf ("req %d, retry %d\n", r->pkt->id, r->retry); 922 printf ("req %d:%d, retry %d\n", r->seqno, r->pkt->id, r->retry);
775 r->retry++; 923 r->retry++;
776 r->next = NOW + r->retry; 924 r->next = NOW + r->retry;
777 } 925 }
778 } 926 }
779 927
783 931
784 if (!send 932 if (!send
785 && vpn->dns_sndpq.size () < MAX_OUTSTANDING) 933 && vpn->dns_sndpq.size () < MAX_OUTSTANDING)
786 { 934 {
787 send = new dns_req (this); 935 send = new dns_req (this);
788 send->gen_stream_req (dns_sndseq, dns_snddq); 936 send->gen_stream_req (sndseq, snddq);
789 vpn->dns_sndpq.push_back (send); 937 vpn->dns_sndpq.push_back (send);
790 938
791 dns_sndseq = (dns_sndseq + 1) & SEQNO_MASK; 939 sndseq = (sndseq + 1) & SEQNO_MASK;
792 } 940 }
793 941
794 tstamp min_next = NOW + (1. / (tstamp)MAX_RATE); 942 tstamp min_next = NOW + (1. / (tstamp)MAX_RATE);
795 943
796 if (send) 944 if (send)
797 { 945 {
798 dns_packet *pkt = send->pkt; 946 dns_packet *pkt = send->pkt;
799 947
800 next = min_next; 948 next = min_next;
801 949
802 sendto (vpn->dnsv4_fd, &((*pkt)[0]), pkt->len, 0, dns_si.sav4 (), dns_si.salenv4 ()); 950 sendto (vpn->dnsv4_fd, &((*pkt)[0]), pkt->len, 0,
951 vpn->dns_forwarder.sav4 (), vpn->dns_forwarder.salenv4 ());
803 } 952 }
804 else if (next < min_next) 953 else if (next < min_next)
805 next = min_next; 954 next = min_next;
806 955
807 w.start (next); 956 w.start (next);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines