… | |
… | |
117 | memset (enc, (char) 0, 256); |
117 | memset (enc, (char) 0, 256); |
118 | memset (dec, (char)INVALID, 256); |
118 | memset (dec, (char)INVALID, 256); |
119 | |
119 | |
120 | for (size = 0; cmap [size]; size++) |
120 | for (size = 0; cmap [size]; size++) |
121 | { |
121 | { |
|
|
122 | char c = cmap [size]; |
|
|
123 | |
122 | enc [size] = cmap [size]; |
124 | enc [size] = c; |
123 | dec [(u8)enc [size]] = size; |
125 | dec [(u8)c] = size; |
|
|
126 | |
|
|
127 | // allow lowercase/uppercase aliases if possible |
|
|
128 | if (c >= 'A' && c <= 'Z' && dec [c + ('a' - 'A')] == INVALID) dec [c + ('a' - 'A')] = size; |
|
|
129 | if (c >= 'a' && c <= 'z' && dec [c - ('a' - 'A')] == INVALID) dec [c - ('a' - 'A')] = size; |
124 | } |
130 | } |
125 | |
131 | |
126 | assert (size < 256); |
132 | assert (size < 256); |
127 | } |
133 | } |
128 | |
134 | |
… | |
… | |
168 | enc_len [len] = n; |
174 | enc_len [len] = n; |
169 | dec_len [n] = len; |
175 | dec_len [n] = len; |
170 | } |
176 | } |
171 | } |
177 | } |
172 | |
178 | |
|
|
179 | unsigned int |
173 | unsigned int basecoder::encode_len (unsigned int len) |
180 | basecoder::encode_len (unsigned int len) |
174 | { |
181 | { |
175 | return enc_len [len]; |
182 | return enc_len [len]; |
176 | } |
183 | } |
177 | |
184 | |
|
|
185 | unsigned int |
178 | unsigned int basecoder::decode_len (unsigned int len) |
186 | basecoder::decode_len (unsigned int len) |
179 | { |
187 | { |
180 | while (len && !dec_len [len]) |
188 | while (len && !dec_len [len]) |
181 | --len; |
189 | --len; |
182 | |
190 | |
183 | return dec_len [len]; |
191 | return dec_len [len]; |
184 | } |
192 | } |
185 | |
193 | |
|
|
194 | unsigned int |
186 | unsigned int basecoder::encode (char *dst, u8 *src, unsigned int len) |
195 | basecoder::encode (char *dst, u8 *src, unsigned int len) |
187 | { |
196 | { |
188 | if (!len || len > MAX_DEC_LEN) |
197 | if (!len || len > MAX_DEC_LEN) |
189 | return 0; |
198 | return 0; |
190 | |
199 | |
191 | int elen = encode_len (len); |
200 | int elen = encode_len (len); |
… | |
… | |
210 | *dst++ = cmap.encode [dst_ [i]]; |
219 | *dst++ = cmap.encode [dst_ [i]]; |
211 | |
220 | |
212 | return elen; |
221 | return elen; |
213 | } |
222 | } |
214 | |
223 | |
|
|
224 | unsigned int |
215 | unsigned int basecoder::decode (u8 *dst, char *src, unsigned int len) |
225 | basecoder::decode (u8 *dst, char *src, unsigned int len) |
216 | { |
226 | { |
217 | if (!len || len > MAX_ENC_LEN) |
227 | if (!len || len > MAX_ENC_LEN) |
218 | return 0; |
228 | return 0; |
219 | |
229 | |
220 | u8 src_ [MAX_ENC_LEN]; |
230 | u8 src_ [MAX_ENC_LEN]; |
… | |
… | |
279 | |
289 | |
280 | ///////////////////////////////////////////////////////////////////////////// |
290 | ///////////////////////////////////////////////////////////////////////////// |
281 | |
291 | |
282 | #define HDRSIZE 6 |
292 | #define HDRSIZE 6 |
283 | |
293 | |
|
|
294 | inline void |
284 | inline void encode_header (char *data, int clientid, int seqno, int retry = 0) |
295 | encode_header (char *data, int clientid, int seqno, int retry = 0) |
285 | { |
296 | { |
286 | seqno &= SEQNO_MASK; |
297 | seqno &= SEQNO_MASK; |
287 | |
298 | |
288 | u8 hdr[3] = { |
299 | u8 hdr[3] = { |
289 | clientid, |
300 | clientid, |
… | |
… | |
294 | assert (clientid < 256); |
305 | assert (clientid < 256); |
295 | |
306 | |
296 | cdc26.encode (data, hdr, 3); |
307 | cdc26.encode (data, hdr, 3); |
297 | } |
308 | } |
298 | |
309 | |
|
|
310 | inline void |
299 | inline void decode_header (char *data, int &clientid, int &seqno) |
311 | decode_header (char *data, int &clientid, int &seqno) |
300 | { |
312 | { |
301 | u8 hdr[3]; |
313 | u8 hdr[3]; |
302 | |
314 | |
303 | cdc26.decode (hdr, data, HDRSIZE); |
315 | cdc26.decode (hdr, data, HDRSIZE); |
304 | |
316 | |
… | |
… | |
337 | byte_stream::~byte_stream () |
349 | byte_stream::~byte_stream () |
338 | { |
350 | { |
339 | delete data; |
351 | delete data; |
340 | } |
352 | } |
341 | |
353 | |
|
|
354 | void |
342 | void byte_stream::remove (int count) |
355 | byte_stream::remove (int count) |
343 | { |
356 | { |
344 | if (count > fill) |
357 | if (count > fill) |
345 | assert (count <= fill); |
358 | assert (count <= fill); |
346 | |
359 | |
347 | memmove (data, data + count, fill -= count); |
360 | memmove (data, data + count, fill -= count); |
348 | } |
361 | } |
349 | |
362 | |
|
|
363 | bool |
350 | bool byte_stream::put (u8 *data, unsigned int datalen) |
364 | byte_stream::put (u8 *data, unsigned int datalen) |
351 | { |
365 | { |
352 | if (maxsize - fill < datalen) |
366 | if (maxsize - fill < datalen) |
353 | return false; |
367 | return false; |
354 | |
368 | |
355 | memcpy (this->data + fill, data, datalen); fill += datalen; |
369 | memcpy (this->data + fill, data, datalen); fill += datalen; |
356 | |
370 | |
357 | return true; |
371 | return true; |
358 | } |
372 | } |
359 | |
373 | |
|
|
374 | bool |
360 | bool byte_stream::put (vpn_packet *pkt) |
375 | byte_stream::put (vpn_packet *pkt) |
361 | { |
376 | { |
362 | if (maxsize - fill < pkt->len + 2) |
377 | if (maxsize - fill < pkt->len + 2) |
363 | return false; |
378 | return false; |
364 | |
379 | |
365 | data [fill++] = pkt->len >> 8; |
380 | data [fill++] = pkt->len >> 8; |
… | |
… | |
447 | bool valid (); |
462 | bool valid (); |
448 | }; |
463 | }; |
449 | |
464 | |
450 | int dns_cfg::next_uid; |
465 | int dns_cfg::next_uid; |
451 | |
466 | |
|
|
467 | void |
452 | void dns_cfg::reset (int clientid) |
468 | dns_cfg::reset (int clientid) |
453 | { |
469 | { |
454 | id1 = 'G'; |
470 | id1 = 'G'; |
455 | id2 = 'V'; |
471 | id2 = 'V'; |
456 | id3 = 'P'; |
472 | id3 = 'P'; |
457 | id4 = 'E'; |
473 | id4 = 'E'; |
… | |
… | |
471 | |
487 | |
472 | r3 = r4 = 0; |
488 | r3 = r4 = 0; |
473 | r4 = r5 = r6 = r7 = 0; |
489 | r4 = r5 = r6 = r7 = 0; |
474 | } |
490 | } |
475 | |
491 | |
|
|
492 | bool |
476 | bool dns_cfg::valid () |
493 | dns_cfg::valid () |
477 | { |
494 | { |
478 | // although the protocol itself allows for some configurability, |
495 | // although the protocol itself allows for some configurability, |
479 | // only the following encoding/decoding settings are implemented. |
496 | // only the following encoding/decoding settings are implemented. |
480 | return id1 == 'G' |
497 | return id1 == 'G' |
481 | && id2 == 'V' |
498 | && id2 == 'V' |
… | |
… | |
496 | u8 data [MAXSIZE - 6 * 2]; |
513 | u8 data [MAXSIZE - 6 * 2]; |
497 | |
514 | |
498 | int decode_label (char *data, int size, int &offs); |
515 | int decode_label (char *data, int size, int &offs); |
499 | }; |
516 | }; |
500 | |
517 | |
|
|
518 | int |
501 | int dns_packet::decode_label (char *data, int size, int &offs) |
519 | dns_packet::decode_label (char *data, int size, int &offs) |
502 | { |
520 | { |
503 | char *orig = data; |
521 | char *orig = data; |
504 | |
522 | |
505 | memset (data, 0, size); |
523 | memset (data, 0, size); |
506 | |
524 | |
… | |
… | |
532 | return data - orig; |
550 | return data - orig; |
533 | } |
551 | } |
534 | |
552 | |
535 | ///////////////////////////////////////////////////////////////////////////// |
553 | ///////////////////////////////////////////////////////////////////////////// |
536 | |
554 | |
|
|
555 | static |
|
|
556 | u16 next_id () |
|
|
557 | { |
537 | static u16 dns_id = 0; // TODO: should be per-vpn |
558 | static u16 dns_id = 0; // TODO: should be per-vpn |
538 | |
559 | |
539 | static u16 next_id () |
|
|
540 | { |
|
|
541 | if (!dns_id) |
560 | if (!dns_id) |
542 | dns_id = time (0); |
561 | dns_id = time (0); |
543 | |
562 | |
544 | // the simplest lsfr with periodicity 65535 i could find |
563 | // the simplest lsfr with periodicity 65535 i could find |
545 | dns_id = (dns_id << 1) |
564 | dns_id = (dns_id << 1) |
… | |
… | |
613 | dns_snd::~dns_snd () |
632 | dns_snd::~dns_snd () |
614 | { |
633 | { |
615 | delete pkt; |
634 | delete pkt; |
616 | } |
635 | } |
617 | |
636 | |
|
|
637 | static void |
618 | static void append_domain (dns_packet &pkt, int &offs, const char *domain) |
638 | append_domain (dns_packet &pkt, int &offs, const char *domain) |
619 | { |
639 | { |
620 | // add tunnel domain |
640 | // add tunnel domain |
621 | for (;;) |
641 | for (;;) |
622 | { |
642 | { |
623 | const char *end = strchr (domain, '.'); |
643 | const char *end = strchr (domain, '.'); |
… | |
… | |
636 | |
656 | |
637 | domain = end + 1; |
657 | domain = end + 1; |
638 | } |
658 | } |
639 | } |
659 | } |
640 | |
660 | |
|
|
661 | void |
641 | void dns_snd::gen_stream_req (int seqno, byte_stream &stream) |
662 | dns_snd::gen_stream_req (int seqno, byte_stream &stream) |
642 | { |
663 | { |
643 | stdhdr = true; |
664 | stdhdr = true; |
644 | this->seqno = seqno; |
665 | this->seqno = seqno; |
645 | |
666 | |
646 | timeout = ev_now () + INITIAL_TIMEOUT; |
667 | timeout = ev_now () + INITIAL_TIMEOUT; |
… | |
… | |
684 | (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN; |
705 | (*pkt)[offs++] = RR_CLASS_IN >> 8; (*pkt)[offs++] = RR_CLASS_IN; |
685 | |
706 | |
686 | pkt->len = offs; |
707 | pkt->len = offs; |
687 | } |
708 | } |
688 | |
709 | |
|
|
710 | void |
689 | void dns_snd::gen_syn_req () |
711 | dns_snd::gen_syn_req () |
690 | { |
712 | { |
691 | timeout = ev_now () + INITIAL_SYN_TIMEOUT; |
713 | timeout = ev_now () + INITIAL_SYN_TIMEOUT; |
692 | |
714 | |
693 | pkt->flags = htons (DEFAULT_CLIENT_FLAGS); |
715 | pkt->flags = htons (DEFAULT_CLIENT_FLAGS); |
694 | pkt->qdcount = htons (1); |
716 | pkt->qdcount = htons (1); |
… | |
… | |
759 | i != rcvpq.end (); |
781 | i != rcvpq.end (); |
760 | ++i) |
782 | ++i) |
761 | delete *i; |
783 | delete *i; |
762 | } |
784 | } |
763 | |
785 | |
|
|
786 | void |
764 | void dns_connection::receive_rep (dns_rcv *r) |
787 | dns_connection::receive_rep (dns_rcv *r) |
765 | { |
788 | { |
766 | if (r->datalen) |
789 | if (r->datalen) |
767 | { |
790 | { |
768 | last_received = ev_now (); |
791 | last_received = ev_now (); |
769 | tw (); |
792 | tw (); |
… | |
… | |
802 | |
825 | |
803 | rcvseq = (rcvseq + 1) & SEQNO_MASK; |
826 | rcvseq = (rcvseq + 1) & SEQNO_MASK; |
804 | |
827 | |
805 | if (!rcvdq.put (r->data, r->datalen)) |
828 | if (!rcvdq.put (r->data, r->datalen)) |
806 | { |
829 | { |
|
|
830 | // MUST never overflow, can be caused by data corruption, TODO |
807 | slog (L_ERR, "DNS: !rcvdq.put (r->data, r->datalen)"); |
831 | slog (L_CRIT, "DNS: !rcvdq.put (r->data, r->datalen)"); |
808 | abort (); // MUST never overflow, can be caused by data corruption, TODO |
832 | c->dnsv4_reset_connection (); |
|
|
833 | return; |
809 | } |
834 | } |
810 | |
835 | |
811 | while (vpn_packet *pkt = rcvdq.get ()) |
836 | while (vpn_packet *pkt = rcvdq.get ()) |
812 | { |
837 | { |
813 | sockinfo si; |
838 | sockinfo si; |
814 | si.host = htonl (c->conf->id); si.port = 0; si.prot = PROT_DNSv4; |
839 | si.host = htonl (c->conf->id); si.port = 0; si.prot = PROT_DNSv4; |
815 | |
840 | |
816 | vpn->recv_vpn_packet (pkt, si); |
841 | vpn->recv_vpn_packet (pkt, si); |
817 | |
|
|
818 | delete pkt; |
842 | delete pkt; |
819 | } |
843 | } |
820 | |
844 | |
821 | // check for further packets |
845 | // check for further packets |
822 | goto redo; |
846 | goto redo; |
… | |
… | |
1120 | |
1144 | |
1121 | if (ip [3] == CMD_IP_RST) |
1145 | if (ip [3] == CMD_IP_RST) |
1122 | { |
1146 | { |
1123 | slog (L_DEBUG, _("DNS: got tunnel RST request")); |
1147 | slog (L_DEBUG, _("DNS: got tunnel RST request")); |
1124 | |
1148 | |
1125 | delete dns; c->dns = 0; |
1149 | c->dnsv4_reset_connection (); |
1126 | |
|
|
1127 | return; |
|
|
1128 | } |
1150 | } |
1129 | else if (ip [3] == CMD_IP_SYN) |
1151 | else if (ip [3] == CMD_IP_SYN) |
1130 | { |
1152 | { |
1131 | slog (L_DEBUG, _("DNS: got tunnel SYN reply, server likes us.")); |
1153 | slog (L_DEBUG, _("DNS: got tunnel SYN reply, server likes us.")); |
1132 | dns->established = true; |
1154 | dns->established = true; |
1133 | } |
1155 | } |
1134 | else if (ip [3] == CMD_IP_REJ) |
1156 | else if (ip [3] == CMD_IP_REJ) |
1135 | { |
|
|
1136 | slog (L_DEBUG, _("DNS: got tunnel REJ reply, server does not like us, aborting.")); |
1157 | slog (L_ERR, _("DNS: got tunnel REJ reply, server does not like us.")); |
1137 | abort (); |
|
|
1138 | } |
|
|
1139 | else |
1158 | else |
1140 | slog (L_INFO, _("DNS: got unknown meta command %02x"), ip [3]); |
1159 | slog (L_INFO, _("DNS: got unknown meta command %02x"), ip [3]); |
1141 | } |
1160 | } |
1142 | else |
1161 | else |
1143 | slog (L_INFO, _("DNS: got spurious a record %d.%d.%d.%d"), |
1162 | slog (L_INFO, _("DNS: got spurious a record %d.%d.%d.%d"), |