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.4 by pcg, Wed Mar 2 05:49:31 2005 UTC vs.
Revision 1.5 by pcg, Thu Mar 3 07:24:57 2005 UTC

42#include "vpn.h" 42#include "vpn.h"
43 43
44#define MIN_RETRY 1. 44#define MIN_RETRY 1.
45#define MAX_RETRY 60. 45#define MAX_RETRY 60.
46 46
47#define MAX_OUTSTANDING 10 // max. outstanding requests 47#define MAX_OUTSTANDING 40 // max. outstanding requests
48#define MAX_WINDOW 100 // max. for MAX_OUTSTANDING 48#define MAX_WINDOW 100 // max. for MAX_OUTSTANDING
49#define MAX_RATE 1 // requests/s 49#define MAX_RATE 1000 // requests/s
50#define MAX_BACKLOG (10*1024) // size of protocol backlog 50#define MAX_BACKLOG (10*1024) // size of protocol backlog, must be > MAXSIZE
51
52#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
54// every two request byte sless give room for one reply byte
55
56#define SEQNO_MASK 0xffff
51 57
52/* 58/*
53 59
54protocol, in shorthand :) 60protocol, in shorthand :)
55 61
84 static int decode (u8 *dst, char *src, int len); 90 static int decode (u8 *dst, char *src, int len);
85 91
86 dns64 (); 92 dns64 ();
87} dns64; 93} dns64;
88 94
89const char dns64::encode_chars[64 + 1] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-"; 95const char dns64::encode_chars[64 + 1] = "_4B9dLphHzrqQmGjkTbJt5svlZX8xSaReEYfwKgF1DP2W6NyVOU70IouACcMn3i-";
90s8 dns64::decode_chars[256]; 96s8 dns64::decode_chars[256];
91 97
92dns64::dns64 () 98dns64::dns64 ()
93{ 99{
94 for (int i = 0; i < 64; i++) 100 for (int i = 0; i < 64; i++)
129 while (len--) 135 while (len--)
130 { 136 {
131 s8 chr = decode_chars [(u8)*src++]; 137 s8 chr = decode_chars [(u8)*src++];
132 138
133 if (!chr) 139 if (!chr)
134 break; 140 continue;
135 141
136 accum <<= 6; 142 accum <<= 6;
137 accum |= chr - 1; 143 accum |= chr - 1;
138 bits += 6; 144 bits += 6;
139 145
159 ~byte_stream (); 165 ~byte_stream ();
160 166
161 bool empty () { return !fill; } 167 bool empty () { return !fill; }
162 int size () { return fill; } 168 int size () { return fill; }
163 169
170 bool put (u8 *data, unsigned int datalen);
164 bool put (vpn_packet *pkt); 171 bool put (vpn_packet *pkt);
165 vpn_packet *get (); 172 vpn_packet *get ();
166 173
167 u8 *begin () { return data; } 174 u8 *begin () { return data; }
168 void remove (int count); 175 void remove (int count);
185 abort (); 192 abort ();
186 193
187 memmove (data, data + count, fill -= count); 194 memmove (data, data + count, fill -= count);
188} 195}
189 196
197bool byte_stream::put (u8 *data, unsigned int datalen)
198{
199 if (maxsize - fill < datalen)
200 return false;
201
202 memcpy (this->data + fill, data, datalen); fill += datalen;
203
204 return true;
205}
206
190bool byte_stream::put (vpn_packet *pkt) 207bool byte_stream::put (vpn_packet *pkt)
191{ 208{
192 if (maxsize - fill < pkt->len + 2) 209 if (maxsize - fill < pkt->len + 2)
193 return false; 210 return false;
194 211
202 219
203vpn_packet *byte_stream::get () 220vpn_packet *byte_stream::get ()
204{ 221{
205 int len = (data [0] << 8) | data [1]; 222 int len = (data [0] << 8) | data [1];
206 223
224 printf ("get len %d, fill %d\n", len, fill);//D
225
226 if (len > MAXSIZE && fill >= 2)
227 abort (); // TODO handle this gracefully, connection reset
228
207 if (fill < len + 2) 229 if (fill < len + 2)
208 return 0; 230 return 0;
209 231
210 vpn_packet *pkt = new vpn_packet; 232 vpn_packet *pkt = new vpn_packet;
233
234 pkt->len = len;
211 memcpy (&((*pkt)[0]), data + 2, len); 235 memcpy (&((*pkt)[0]), data + 2, len);
212 remove (len + 2); 236 remove (len + 2);
213 237
214 return pkt; 238 return pkt;
215} 239}
222#define FLAG_OP_QUERY ( 0 << 11) 246#define FLAG_OP_QUERY ( 0 << 11)
223#define FLAG_AA ( 1 << 10) 247#define FLAG_AA ( 1 << 10)
224#define FLAG_TC ( 1 << 9) 248#define FLAG_TC ( 1 << 9)
225#define FLAG_RD ( 1 << 8) 249#define FLAG_RD ( 1 << 8)
226#define FLAG_RA ( 1 << 7) 250#define FLAG_RA ( 1 << 7)
251#define FLAG_AUTH ( 1 << 5)
227#define FLAG_RCODE_MASK (15 << 0) 252#define FLAG_RCODE_MASK (15 << 0)
228#define FLAG_RCODE_OK ( 0 << 0) 253#define FLAG_RCODE_OK ( 0 << 0)
229#define FLAG_RCODE_FORMERR ( 1 << 0) 254#define FLAG_RCODE_FORMERR ( 1 << 0)
230#define FLAG_RCODE_SERVFAIL ( 2 << 0) 255#define FLAG_RCODE_SERVFAIL ( 2 << 0)
231#define FLAG_RCODE_NXDOMAIN ( 3 << 0) 256#define FLAG_RCODE_NXDOMAIN ( 3 << 0)
232#define FLAG_RCODE_REFUSED ( 5 << 0) 257#define FLAG_RCODE_REFUSED ( 5 << 0)
233 258
234#define DEFAULT_CLIENT_FLAGS (FLAG_QUERY | FLAG_OP_QUERY | FLAG_RD) 259#define DEFAULT_CLIENT_FLAGS (FLAG_QUERY | FLAG_OP_QUERY | FLAG_RD)
235#define DEFAULT_SERVER_FLAGS (FLAG_RESPONSE | FLAG_OP_QUERY | FLAG_AA | FLAG_RD) 260#define DEFAULT_SERVER_FLAGS (FLAG_RESPONSE | FLAG_OP_QUERY | FLAG_AA | FLAG_RD | FLAG_RA)
236 261
237struct dns_packet : net_packet 262struct dns_packet : net_packet
238{ 263{
239 u16 id; 264 u16 id;
240 u16 flags; // QR:1 Opcode:4 AA:1 TC:1 RD:1 RA:1 Z:3 RCODE:4 265 u16 flags; // QR:1 Opcode:4 AA:1 TC:1 RD:1 RA:1 Z:3 RCODE:4
285{ 310{
286 dns_packet *pkt; 311 dns_packet *pkt;
287 tstamp next; 312 tstamp next;
288 int retry; 313 int retry;
289 connection *conn; 314 connection *conn;
315 int seqno;
290 316
317 dns_req (connection *c);
291 dns_req (connection *c, int seqno, byte_stream *stream); 318 void gen_stream_req (int seqno, byte_stream *stream);
292}; 319};
293 320
294struct dns_rep
295{
296};
297
298static u16 dns_id; // TODO: should be per-vpn 321static u16 dns_id = 12098; // TODO: should be per-vpn
299 322
300dns_req::dns_req (connection *c, int seqno, byte_stream *stream) 323static u16 next_id ()
324{
325 // the simplest lsfr with periodicity 65535 i could find
326 dns_id = (dns_id << 1)
327 | (((dns_id >> 1)
328 ^ (dns_id >> 2)
329 ^ (dns_id >> 4)
330 ^ (dns_id >> 15)) & 1);
331
332 return dns_id;
333}
334
335dns_req::dns_req (connection *c)
301: conn (c) 336: conn (c)
302{ 337{
303 next = 0; 338 next = 0;
304 retry = 0; 339 retry = 0;
305 340
306 pkt = new dns_packet; 341 pkt = new dns_packet;
307 342
308 pkt->id = dns_id++; 343 pkt->id = next_id ();
344}
345
346void dns_req::gen_stream_req (int seqno, byte_stream *stream)
347{
348 this->seqno = seqno;
349
309 pkt->flags = DEFAULT_CLIENT_FLAGS; 350 pkt->flags = htons (DEFAULT_CLIENT_FLAGS);
310 pkt->qdcount = htons (1); 351 pkt->qdcount = htons (1);
311 pkt->ancount = 0;
312 pkt->nscount = 0;
313 pkt->arcount = 0;
314 352
315 int offs = 6*2; 353 int offs = 6*2;
316 int dlen = 255 - strlen (THISNODE->domain) - 1; // here we always have room for the max. label length 354 int dlen = MAX_DOMAIN_SIZE - strlen (THISNODE->domain) - 2;
355 // MAX_DOMAIN_SIZE is technically 255, but bind doesn't compress responses well,
356 // so we need to have space for 2*MAX_DOMAIN_SIZE + header + extra
317 357
318 u8 lbl[64]; //D 358 u8 data[256]; //TODO
319 char enc[65]; 359
320 int lbllen = 3; 360 data[0] = THISNODE->id; //TODO
321 lbl[0] = c->conf->id; //D
322 lbl[1] = seqno >> 8; //D 361 data[1] = seqno >> 8; //TODO
323 lbl[2] = seqno; //D 362 data[2] = seqno; //TODO
324 363
325 while (dlen > 0) 364 int datalen = dns64::decode_len (dlen - (dlen + MAX_LBL_SIZE - 1) / MAX_LBL_SIZE) - 3;
326 {
327 int sndlen = dlen;
328 365
329 if (sndlen + lbllen > dns64::decode_len (MAX_LBL_SIZE))
330 sndlen = dns64::decode_len (MAX_LBL_SIZE) - lbllen;
331
332 if (sndlen > stream->size ()) 366 if (datalen > stream->size ())
333 sndlen = stream->size (); 367 datalen = stream->size ();
334 368
335 if (sndlen + lbllen == 0) 369 char enc[256], *encp = enc;
336 break; 370
337
338 memcpy (lbl + lbllen, stream->begin (), sndlen); 371 memcpy (data + 3, stream->begin (), datalen);
372 int enclen = dns64::encode (enc, data, datalen + 3);
339 stream->remove (sndlen); 373 stream->remove (datalen);
340 lbllen += sndlen;
341 374
342 dns64::encode (enc, lbl, lbllen); 375 while (enclen)
376 {
377 int lbllen = enclen < MAX_LBL_SIZE ? enclen : MAX_LBL_SIZE;
343 378
344 int elen = dns64::encode_len (lbllen);
345 (*pkt)[offs++] = elen; 379 (*pkt)[offs++] = lbllen;
346 memcpy (&((*pkt)[offs]), enc, elen); 380 memcpy (pkt->at (offs), encp, lbllen);
381
347 offs += elen; 382 offs += lbllen;
348 dlen -= elen + 1; 383 encp += lbllen;
349 384
350 lbllen = 0; 385 enclen -= lbllen;
351 } 386 }
352 387
353 const char *suffix = THISNODE->domain; 388 const char *suffix = THISNODE->domain;
354 389
355 // add tunnel domain 390 // add tunnel domain
375 (*pkt)[offs++] = 0; 410 (*pkt)[offs++] = 0;
376 (*pkt)[offs++] = RR_TYPE_ANY >> 8; (*pkt)[offs++] = RR_TYPE_ANY; 411 (*pkt)[offs++] = RR_TYPE_ANY >> 8; (*pkt)[offs++] = RR_TYPE_ANY;
377 (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN; 412 (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN;
378 413
379 pkt->len = offs; 414 pkt->len = offs;
415}
380 416
381 c->vpn->dns_sndpq.push_back (this); 417struct dns_rcv
418{
419 int seqno;
420 dns_packet *pkt; // reply packet
421 u8 data [MAXSIZE]; // actually part of the reply packet...
422 int datalen;
423
424 dns_rcv (int seqno, dns_packet *req, u8 *data, int datalen);
425 ~dns_rcv ();
426};
427
428dns_rcv::dns_rcv (int seqno, dns_packet *req, u8 *data, int datalen)
429: seqno (seqno), pkt (new dns_packet), datalen (datalen)
430{
431 memcpy (this->data, data, datalen);
432 pkt->len = req->len;
433 memcpy (pkt->at (0), req->at (0), req->len);
434}
435
436dns_rcv::~dns_rcv ()
437{
438 delete pkt;
382} 439}
383 440
384///////////////////////////////////////////////////////////////////////////// 441/////////////////////////////////////////////////////////////////////////////
385 442
386struct dns_cfg 443struct dns_cfg
390 u8 unused1; 447 u8 unused1;
391 u16 max_size; 448 u16 max_size;
392 u8 flags1, flags2; 449 u8 flags1, flags2;
393}; 450};
394 451
452void connection::dnsv4_receive_rep (struct dns_rcv *r)
453{
454 dns_rcvpq.push_back (r);
455
456 redo:
457
458 for (vector<dns_rcv *>::iterator i = dns_rcvpq.begin ();
459 i != dns_rcvpq.end ();
460 ++i)
461 if (dns_rcvseq == (*i)->seqno)
462 {
463 dns_rcv *r = *i;
464
465 dns_rcvseq = (dns_rcvseq + 1) & SEQNO_MASK;
466
467 if (!dns_snddq && !dns_rcvdq)
468 {
469 dns_rcvdq = new byte_stream (MAX_BACKLOG * 2);
470 dns_snddq = new byte_stream (MAX_BACKLOG);
471
472 dns_si.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4);
473 }
474
475 if (!dns_rcvdq->put (r->data, r->datalen))
476 abort (); // MUST never overflow, can be caused by data corruption, TODO
477
478 while (vpn_packet *pkt = dns_rcvdq->get ())
479 {
480 sockinfo si;
481 si.host = 0; si.port = 0; si.prot = PROT_DNSv4;
482
483 vpn->recv_vpn_packet (pkt, si);
484 }
485 }
486 else if ((u32)dns_rcvseq - MAX_WINDOW - (u32)(*i)->seqno < MAX_WINDOW * 2)
487 {
488 dns_rcvpq.erase (i);
489 goto redo;
490 }
491}
492
395dns_packet * 493dns_packet *
396vpn::dnsv4_server (dns_packet *pkt) 494vpn::dnsv4_server (dns_packet *pkt)
397{ 495{
398 u16 flags = ntohs (pkt->flags); 496 u16 flags = ntohs (pkt->flags);
399 497
405 if (!(flags & (FLAG_RESPONSE | FLAG_OP_MASK | FLAG_TC)) 503 if (!(flags & (FLAG_RESPONSE | FLAG_OP_MASK | FLAG_TC))
406 && pkt->qdcount == htons (1)) 504 && pkt->qdcount == htons (1))
407 { 505 {
408 char qname[MAXSIZE]; 506 char qname[MAXSIZE];
409 int qlen = pkt->decode_label ((char *)qname, MAXSIZE - offs, offs); 507 int qlen = pkt->decode_label ((char *)qname, MAXSIZE - offs, offs);
410
411 printf ("rcvd packet len %d, id%04x flags%04x q%04x a%04x n%04x a%04x <%s>\n", pkt->len,
412 pkt->id, flags, pkt->qdcount, pkt->ancount, pkt->nscount, pkt->arcount, qname);//D
413 508
414 u16 qtype = (*pkt) [offs++] << 8; qtype |= (*pkt) [offs++]; 509 u16 qtype = (*pkt) [offs++] << 8; qtype |= (*pkt) [offs++];
415 u16 qclass = (*pkt) [offs++] << 8; qclass |= (*pkt) [offs++]; 510 u16 qclass = (*pkt) [offs++] << 8; qclass |= (*pkt) [offs++];
416 511
417 pkt->qdcount = htons (1); 512 pkt->qdcount = htons (1);
426 if (qclass == RR_CLASS_IN 521 if (qclass == RR_CLASS_IN
427 && (qtype == RR_TYPE_ANY || qtype == RR_TYPE_TXT) 522 && (qtype == RR_TYPE_ANY || qtype == RR_TYPE_TXT)
428 && qlen > dlen + 1 523 && qlen > dlen + 1
429 && !memcmp (qname + qlen - dlen - 1, THISNODE->domain, dlen)) 524 && !memcmp (qname + qlen - dlen - 1, THISNODE->domain, dlen))
430 { 525 {
431 // correct class, domain, parse 526 // correct class, domain: parse
432 u8 data[MAXSIZE]; 527 u8 data[MAXSIZE];
433 int datalen = dns64::decode (data, qname, qlen - dlen - 1); 528 int datalen = dns64::decode (data, qname, qlen - dlen - 1);
434 529
435 for (int i = 0; i < datalen; i++)
436 printf ("%02x ", data[i]);
437 printf ("\n");
438
439
440
441
442#if 0
443 // now generate reply
444 rep->ancount = htons (1); // one answer RR
445 rep->flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_OK);
446
447 (*rep) [offs++] = 0xc0;
448 (*rep) [offs++] = 6 * 2; // same as in query section
449
450 (*rep) [offs++] = RR_TYPE_TXT >> 8; (*rep) [offs++] = RR_TYPE_TXT;
451 (*rep) [offs++] = RR_CLASS_IN >> 8; (*rep) [offs++] = RR_CLASS_IN;
452
453 (*rep) [offs++] = 0; (*rep) [offs++] = 0;
454 (*rep) [offs++] = 0; (*rep) [offs++] = 0; // TTL
455
456 int dlen = MAX_PKT_SIZE - offs - 2;
457
458 printf ("we have room for %d bytes\n", dlen);
459
460 int rdlen_offs = offs += 2;
461
462 u8 txt[255];
463 txt[0] = 0;
464 txt[1] = 0;
465
466 int txtlen = 2; 530 int client = data[0];
531 int seqno = ((data[1] << 8) | data[2]) & SEQNO_MASK;
467 532
468 while (dlen > 1) 533 if (0 < client && client <= conns.size ())
469 { 534 {
470 int sndlen = --dlen; 535 connection *c = conns [client - 1];
471 536
472 if (sndlen + txtlen > 255) 537 for (vector<dns_rcv *>::iterator i = c->dns_rcvpq.begin ();
473 sndlen = 255 - txtlen; 538 i != c->dns_rcvpq.end ();
539 ++i)
540 if ((*i)->seqno == seqno)
541 {
542 // already seen that request, just reply with the original reply
543 dns_rcv *r = *i;
474 544
545 offs = r->pkt->len;
546 memcpy (pkt->at (0), r->pkt->at (0), offs);
547 goto duplicate_request;
548 }
549
550 // new packet, queue
551 c->dnsv4_receive_rep (new dns_rcv (seqno, pkt, data + 3, datalen - 3));
552
553 // now generate reply
554 pkt->ancount = htons (1); // one answer RR
555 pkt->flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_OK);
556
557 (*pkt) [offs++] = 0xc0;
558 (*pkt) [offs++] = 6 * 2; // same as in query section
559
560 (*pkt) [offs++] = RR_TYPE_TXT >> 8; (*pkt) [offs++] = RR_TYPE_TXT;
561 (*pkt) [offs++] = RR_CLASS_IN >> 8; (*pkt) [offs++] = RR_CLASS_IN;
562
563 (*pkt) [offs++] = 0; (*pkt) [offs++] = 0;
564 (*pkt) [offs++] = 0; (*pkt) [offs++] = 0; // TTL
565
566 int dlen = MAX_PKT_SIZE - offs - 2;
567
568 // bind doesn't compress well, so reduce further by one label length
475 sndlen = 0; 569 dlen -= qlen;
476 570
571 int rdlen_offs = offs += 2;
572
573 while (c->dns_snddq
574 && !c->dns_snddq->empty ()
575 && dlen > 1)
576 {
577 int txtlen = dlen <= 255 ? dlen - 1 : 255;
578
579 if (txtlen > c->dns_snddq->size ())
580 txtlen = c->dns_snddq->size ();
581
477 (*rep)[offs++] = sndlen + txtlen; 582 (*pkt)[offs++] = txtlen;
478 memcpy (&((*rep)[offs]), txt, txtlen); 583 memcpy (pkt->at (offs), c->dns_snddq->begin (), txtlen);
479 offs += txtlen; 584 offs += txtlen;
585 c->dns_snddq->remove (txtlen);
480 586
481 //if (sndlen + txtlen > dns_snddq. 587 dlen -= txtlen + 1;
588 }
589
590 // avoid empty TXT rdata
591 if (offs == rdlen_offs)
592 (*pkt)[offs++] = 0;
593
594 int rdlen = offs - rdlen_offs;
595
596 (*pkt) [rdlen_offs - 2] = rdlen >> 8;
597 (*pkt) [rdlen_offs - 1] = rdlen;
598
599 duplicate_request: ;
482 } 600 }
483 601 else
484 int rdlen = offs - rdlen_offs; 602 pkt->flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR);
485
486 (*rep) [rdlen_offs - 2] = rdlen >> 8;
487 (*rep) [rdlen_offs - 1] = rdlen;
488#endif
489 } 603 }
490 } 604 }
605 else
606 offs = pkt->len;
491 607
492 pkt->len = offs; 608 pkt->len = offs;
493 return pkt; 609 return pkt;
494} 610}
495 611
500 int offs = 6 * 2; // skip header 616 int offs = 6 * 2; // skip header
501 617
502 pkt->qdcount = ntohs (pkt->qdcount); 618 pkt->qdcount = ntohs (pkt->qdcount);
503 pkt->ancount = ntohs (pkt->ancount); 619 pkt->ancount = ntohs (pkt->ancount);
504 620
621 // go through our request list and find the corresponding request
505 for (vector<dns_req *>::iterator i = dns_sndpq.begin (); 622 for (vector<dns_req *>::iterator i = dns_sndpq.begin ();
506 i != dns_sndpq.end (); 623 i != dns_sndpq.end ();
507 ++i) 624 ++i)
508 if ((*i)->pkt->id == pkt->id) 625 if ((*i)->pkt->id == pkt->id)
509 { 626 {
510 connection *c = (*i)->conn; 627 connection *c = (*i)->conn;
511 printf ("GOT RESPONSE id %x %p\n", pkt->id, c);//D 628 int seqno = (*i)->seqno;
629 u8 data[MAXSIZE], *datap = data;
630
512 delete *i; 631 delete *i;
513 dns_sndpq.erase (i); 632 dns_sndpq.erase (i);
514 633
515 if (flags & (FLAG_RESPONSE | FLAG_OP_MASK | FLAG_TC)) 634 if (flags & (FLAG_RESPONSE | FLAG_OP_MASK | FLAG_TC))
516 { 635 {
533 ttl |= (*pkt) [offs++] << 8; 652 ttl |= (*pkt) [offs++] << 8;
534 ttl |= (*pkt) [offs++]; 653 ttl |= (*pkt) [offs++];
535 654
536 u16 rdlen = (*pkt) [offs++] << 8; rdlen |= (*pkt) [offs++]; 655 u16 rdlen = (*pkt) [offs++] << 8; rdlen |= (*pkt) [offs++];
537 656
538 printf ("REPLY %d:%d TTL %d RD %d\n", qtype, qclass, ttl, rdlen);
539
540 offs += rdlen;
541
542 if (MAXSIZE - offs < rdlen) 657 if (rdlen <= MAXSIZE - offs)
543 { 658 {
544 // decode bytes, finally 659 // decode bytes, finally
660
661 while (rdlen)
662 {
663 int txtlen = (*pkt) [offs++];
664
665 assert (txtlen + offs < MAXSIZE - 1);
666
667 memcpy (datap, pkt->at (offs), txtlen);
668 datap += txtlen; offs += txtlen;
669
670 rdlen -= txtlen + 1;
671 }
672
545 } 673 }
674
546 } 675 }
547 } 676 }
548 677
678 if (datap != data)
679 printf ("%02x %02x %02x %02x\n",
680 data[0],
681 data[1],
682 data[2],
683 data[3]);
684
685 printf ("recv %d,%d\n", pkt->id, seqno, datap - data);//D
686 c->dnsv4_receive_rep (new dns_rcv (seqno, pkt, data, datap - data));
687
549 break; 688 break;
550 } 689 }
690
691 delete pkt;
551} 692}
552 693
553void 694void
554vpn::dnsv4_ev (io_watcher &w, short revents) 695vpn::dnsv4_ev (io_watcher &w, short revents)
555{ 696{
560 socklen_t sa_len = sizeof (sa); 701 socklen_t sa_len = sizeof (sa);
561 702
562 pkt->len = recvfrom (w.fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len); 703 pkt->len = recvfrom (w.fd, &((*pkt)[0]), MAXSIZE, 0, (sockaddr *)&sa, &sa_len);
563 704
564 if (pkt->len > 0) 705 if (pkt->len > 0)
706 {
707 if (pkt->flags & htons (FLAG_TC))
708 {
709 slog (L_WARN, _("DNS request/response truncated, check protocol settings."));
710 //TODO connection reset
711 }
712
565 if (THISNODE->dns_port) 713 if (THISNODE->dns_port)
566 { 714 {
567 pkt = dnsv4_server (pkt); 715 pkt = dnsv4_server (pkt);
568 sendto (w.fd, &((*pkt)[0]), pkt->len, 0, (sockaddr *)&sa, sa_len); 716 sendto (w.fd, &((*pkt)[0]), pkt->len, 0, (sockaddr *)&sa, sa_len);
569 } 717 }
570 else 718 else
571 dnsv4_client (pkt); 719 dnsv4_client (pkt);
720 }
572 } 721 }
573} 722}
574 723
575bool 724bool
576connection::send_dnsv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 725connection::send_dnsv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
579 if (!dns_snddq && !dns_rcvdq) 728 if (!dns_snddq && !dns_rcvdq)
580 { 729 {
581 dns_rcvdq = new byte_stream (MAX_BACKLOG * 2); 730 dns_rcvdq = new byte_stream (MAX_BACKLOG * 2);
582 dns_snddq = new byte_stream (MAX_BACKLOG); 731 dns_snddq = new byte_stream (MAX_BACKLOG);
583 732
584 dns_rcvseq = dns_sndseq = 0; 733 //dns_rcvseq = dns_sndseq = 0;
585 734
586 dns_si.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4); 735 dns_si.set (::conf.dns_forw_host, ::conf.dns_forw_port, PROT_DNSv4);
587 } 736 }
588 737
589 if (!dns_snddq->put (pkt)) 738 if (!dns_snddq->put (pkt))
590 return false; 739 return false;
591 740
592 // start timer if neccessary 741 // start timer if neccessary
593 if (!dnsv4_tw.active) 742 if (!THISNODE->dns_port && !dnsv4_tw.active)
594 dnsv4_cb (dnsv4_tw); 743 dnsv4_cb (dnsv4_tw);
595 744
596 return true; 745 return true;
597} 746}
598 747
601{ 750{
602 // check for timeouts and (re)transmit 751 // check for timeouts and (re)transmit
603 tstamp next = NOW + 60; 752 tstamp next = NOW + 60;
604 dns_req *send = 0; 753 dns_req *send = 0;
605 754
606 slog (L_NOISE, _("dnsv4, %d packets in send queue\n"), vpn->dns_sndpq.size ());
607
608 for (vector<dns_req *>::iterator i = vpn->dns_sndpq.begin (); 755 for (vector<dns_req *>::iterator i = vpn->dns_sndpq.begin ();
609 i != vpn->dns_sndpq.end (); 756 i != vpn->dns_sndpq.end ();
610 ++i) 757 ++i)
611 { 758 {
612 dns_req *r = *i; 759 dns_req *r = *i;
615 { 762 {
616 if (!send) 763 if (!send)
617 { 764 {
618 send = r; 765 send = r;
619 766
620 slog (L_NOISE, _("dnsv4, send req %d\n"), r->pkt->id); 767 if (r->retry)//D
768 printf ("req %d, retry %d\n", r->pkt->id, r->retry);
621 r->retry++; 769 r->retry++;
622 r->next = NOW + r->retry; 770 r->next = NOW + r->retry;
623 } 771 }
624 } 772 }
625 773
627 next = r->next; 775 next = r->next;
628 } 776 }
629 777
630 if (!send 778 if (!send
631 && vpn->dns_sndpq.size () < MAX_OUTSTANDING) 779 && vpn->dns_sndpq.size () < MAX_OUTSTANDING)
632 send = new dns_req (this, dns_sndseq++, dns_snddq); 780 {
781 send = new dns_req (this);
782 send->gen_stream_req (dns_sndseq, dns_snddq);
783 vpn->dns_sndpq.push_back (send);
784
785 dns_sndseq = (dns_sndseq + 1) & SEQNO_MASK;
786 }
633 787
634 tstamp min_next = NOW + (1. / (tstamp)MAX_RATE); 788 tstamp min_next = NOW + (1. / (tstamp)MAX_RATE);
635 789
636 if (send) 790 if (send)
637 { 791 {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines