… | |
… | |
51 | |
51 | |
52 | #define MAX_DOMAIN_SIZE 220 // 255 is legal limit, but bind doesn't compress well |
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 |
53 | // 240 leaves about 4 bytes of server reply data |
54 | // every two request byte sless give room for one reply byte |
54 | // every two request byte sless give room for one reply byte |
55 | |
55 | |
|
|
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 |
56 | #define SEQNO_MASK 0xffff |
59 | #define SEQNO_MASK 0x07ff |
57 | |
60 | |
58 | /* |
61 | /* |
59 | |
62 | |
60 | protocol, in shorthand :) |
63 | protocol, in shorthand :) |
61 | |
64 | |
… | |
… | |
90 | static int decode (u8 *dst, char *src, int len); |
93 | static int decode (u8 *dst, char *src, int len); |
91 | |
94 | |
92 | dns64 (); |
95 | dns64 (); |
93 | } dns64; |
96 | } dns64; |
94 | |
97 | |
95 | const char dns64::encode_chars[64 + 1] = "_4B9dLphHzrqQmGjkTbJt5svlZX8xSaReEYfwKgF1DP2W6NyVOU70IouACcMn3i-"; |
98 | // the following sequence has been crafted to |
|
|
99 | // a) look somewhat random |
|
|
100 | // b) the even (and odd) indices never share the same character as upper/lowercase |
|
|
101 | const char dns64::encode_chars[64 + 1] = "_-dDpPhHzZrR06QqMmjJkKBb34TtSsvVlL81xXaAeEFf92WwGgYyoO57UucCNniI"; |
96 | s8 dns64::decode_chars[256]; |
102 | s8 dns64::decode_chars[256]; |
97 | |
103 | |
98 | dns64::dns64 () |
104 | dns64::dns64 () |
99 | { |
105 | { |
100 | for (int i = 0; i < 64; i++) |
106 | for (int i = 0; i < 64; i++) |
… | |
… | |
218 | } |
224 | } |
219 | |
225 | |
220 | vpn_packet *byte_stream::get () |
226 | vpn_packet *byte_stream::get () |
221 | { |
227 | { |
222 | int len = (data [0] << 8) | data [1]; |
228 | int len = (data [0] << 8) | data [1]; |
223 | |
|
|
224 | printf ("get len %d, fill %d\n", len, fill);//D |
|
|
225 | |
229 | |
226 | if (len > MAXSIZE && fill >= 2) |
230 | if (len > MAXSIZE && fill >= 2) |
227 | abort (); // TODO handle this gracefully, connection reset |
231 | abort (); // TODO handle this gracefully, connection reset |
228 | |
232 | |
229 | if (fill < len + 2) |
233 | if (fill < len + 2) |
… | |
… | |
356 | // so we need to have space for 2*MAX_DOMAIN_SIZE + header + extra |
360 | // so we need to have space for 2*MAX_DOMAIN_SIZE + header + extra |
357 | |
361 | |
358 | u8 data[256]; //TODO |
362 | u8 data[256]; //TODO |
359 | |
363 | |
360 | data[0] = THISNODE->id; //TODO |
364 | data[0] = THISNODE->id; //TODO |
361 | data[1] = seqno >> 8; //TODO |
365 | data[1] = seqno >> 7; //TODO |
362 | data[2] = seqno; //TODO |
366 | data[2] = seqno << 1; //TODO |
363 | |
367 | |
364 | int datalen = dns64::decode_len (dlen - (dlen + MAX_LBL_SIZE - 1) / MAX_LBL_SIZE) - 3; |
368 | int datalen = dns64::decode_len (dlen - (dlen + MAX_LBL_SIZE - 1) / MAX_LBL_SIZE) - 3; |
365 | |
369 | |
366 | if (datalen > stream->size ()) |
370 | if (datalen > stream->size ()) |
367 | datalen = stream->size (); |
371 | datalen = stream->size (); |
… | |
… | |
419 | int seqno; |
423 | int seqno; |
420 | dns_packet *pkt; // reply packet |
424 | dns_packet *pkt; // reply packet |
421 | u8 data [MAXSIZE]; // actually part of the reply packet... |
425 | u8 data [MAXSIZE]; // actually part of the reply packet... |
422 | int datalen; |
426 | int datalen; |
423 | |
427 | |
424 | dns_rcv (int seqno, dns_packet *req, u8 *data, int datalen); |
428 | dns_rcv (int seqno, u8 *data, int datalen); |
425 | ~dns_rcv (); |
429 | ~dns_rcv (); |
426 | }; |
430 | }; |
427 | |
431 | |
428 | dns_rcv::dns_rcv (int seqno, dns_packet *req, u8 *data, int datalen) |
432 | dns_rcv::dns_rcv (int seqno, u8 *data, int datalen) |
429 | : seqno (seqno), pkt (new dns_packet), datalen (datalen) |
433 | : seqno (seqno), pkt (new dns_packet), datalen (datalen) |
430 | { |
434 | { |
431 | memcpy (this->data, data, datalen); |
435 | memcpy (this->data, data, datalen); |
432 | pkt->len = req->len; |
|
|
433 | memcpy (pkt->at (0), req->at (0), req->len); |
|
|
434 | } |
436 | } |
435 | |
437 | |
436 | dns_rcv::~dns_rcv () |
438 | dns_rcv::~dns_rcv () |
437 | { |
439 | { |
438 | delete pkt; |
440 | delete pkt; |
… | |
… | |
481 | si.host = 0; si.port = 0; si.prot = PROT_DNSv4; |
483 | si.host = 0; si.port = 0; si.prot = PROT_DNSv4; |
482 | |
484 | |
483 | vpn->recv_vpn_packet (pkt, si); |
485 | vpn->recv_vpn_packet (pkt, si); |
484 | } |
486 | } |
485 | } |
487 | } |
486 | else if ((u32)dns_rcvseq - MAX_WINDOW - (u32)(*i)->seqno < MAX_WINDOW * 2) |
488 | else if ((u32)(*i)->seqno - (u32)dns_rcvseq + MAX_WINDOW > MAX_WINDOW * 2) |
487 | { |
489 | { |
|
|
490 | //D |
|
|
491 | //abort(); |
|
|
492 | printf ("%d erasing %d (%d)\n", THISNODE->id, (u32)(*i)->seqno, dns_rcvseq); |
488 | dns_rcvpq.erase (i); |
493 | dns_rcvpq.erase (i); |
489 | goto redo; |
494 | goto redo; |
490 | } |
495 | } |
491 | } |
496 | } |
492 | |
497 | |
… | |
… | |
526 | // correct class, domain: parse |
531 | // correct class, domain: parse |
527 | u8 data[MAXSIZE]; |
532 | u8 data[MAXSIZE]; |
528 | int datalen = dns64::decode (data, qname, qlen - dlen - 1); |
533 | int datalen = dns64::decode (data, qname, qlen - dlen - 1); |
529 | |
534 | |
530 | int client = data[0]; |
535 | int client = data[0]; |
531 | int seqno = ((data[1] << 8) | data[2]) & SEQNO_MASK; |
536 | int seqno = ((data[1] << 7) | (data[2] >> 1)) & SEQNO_MASK; |
532 | |
537 | |
533 | if (0 < client && client <= conns.size ()) |
538 | if (0 < client && client <= conns.size ()) |
534 | { |
539 | { |
535 | connection *c = conns [client - 1]; |
540 | connection *c = conns [client - 1]; |
|
|
541 | |
|
|
542 | redo: |
536 | |
543 | |
537 | for (vector<dns_rcv *>::iterator i = c->dns_rcvpq.begin (); |
544 | for (vector<dns_rcv *>::iterator i = c->dns_rcvpq.begin (); |
538 | i != c->dns_rcvpq.end (); |
545 | i != c->dns_rcvpq.end (); |
539 | ++i) |
546 | ++i) |
540 | if ((*i)->seqno == seqno) |
547 | if ((*i)->seqno == seqno) |
541 | { |
548 | { |
542 | // already seen that request, just reply with the original reply |
549 | // already seen that request: simply reply with the cached reply |
543 | dns_rcv *r = *i; |
550 | dns_rcv *r = *i; |
|
|
551 | |
|
|
552 | printf ("DUPLICATE %d\n", htons (r->pkt->id));//D |
544 | |
553 | |
545 | offs = r->pkt->len; |
554 | offs = r->pkt->len; |
546 | memcpy (pkt->at (0), r->pkt->at (0), offs); |
555 | memcpy (pkt->at (0), r->pkt->at (0), offs); |
547 | goto duplicate_request; |
556 | goto duplicate_request; |
548 | } |
557 | } |
549 | |
558 | |
550 | // new packet, queue |
559 | // new packet, queue |
551 | c->dnsv4_receive_rep (new dns_rcv (seqno, pkt, data + 3, datalen - 3)); |
560 | dns_rcv *rcv = new dns_rcv (seqno, data + 3, datalen - 3); |
|
|
561 | c->dnsv4_receive_rep (rcv); |
552 | |
562 | |
553 | // now generate reply |
563 | // now generate reply |
554 | pkt->ancount = htons (1); // one answer RR |
564 | pkt->ancount = htons (1); // one answer RR |
555 | pkt->flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_OK); |
565 | pkt->flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_OK); |
556 | |
566 | |
… | |
… | |
594 | int rdlen = offs - rdlen_offs; |
604 | int rdlen = offs - rdlen_offs; |
595 | |
605 | |
596 | (*pkt) [rdlen_offs - 2] = rdlen >> 8; |
606 | (*pkt) [rdlen_offs - 2] = rdlen >> 8; |
597 | (*pkt) [rdlen_offs - 1] = rdlen; |
607 | (*pkt) [rdlen_offs - 1] = rdlen; |
598 | |
608 | |
|
|
609 | // now update dns_rcv copy |
|
|
610 | rcv->pkt->len = offs; |
|
|
611 | memcpy (rcv->pkt->at (0), pkt->at (0), offs); |
|
|
612 | |
599 | duplicate_request: ; |
613 | duplicate_request: ; |
600 | } |
614 | } |
601 | else |
615 | else |
602 | pkt->flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR); |
616 | pkt->flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR); |
603 | } |
617 | } |
604 | } |
|
|
605 | else |
|
|
606 | offs = pkt->len; |
|
|
607 | |
618 | |
608 | pkt->len = offs; |
619 | pkt->len = offs; |
|
|
620 | } |
|
|
621 | |
609 | return pkt; |
622 | return pkt; |
610 | } |
623 | } |
611 | |
624 | |
612 | void |
625 | void |
613 | vpn::dnsv4_client (dns_packet *pkt) |
626 | vpn::dnsv4_client (dns_packet *pkt) |
… | |
… | |
673 | } |
686 | } |
674 | |
687 | |
675 | } |
688 | } |
676 | } |
689 | } |
677 | |
690 | |
678 | if (datap != data) |
691 | // todo: pkt now used |
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)); |
692 | c->dnsv4_receive_rep (new dns_rcv (seqno, data, datap - data)); |
687 | |
693 | |
688 | break; |
694 | break; |
689 | } |
695 | } |
690 | |
696 | |
691 | delete pkt; |
697 | delete pkt; |