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.7 by pcg, Thu Mar 3 16:54:34 2005 UTC vs.
Revision 1.9 by pcg, Fri Mar 4 04:52:38 2005 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines