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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines