… | |
… | |
25 | |
25 | |
26 | // dns processing is EXTREMELY ugly. For obvious(?) reasons. |
26 | // dns processing is EXTREMELY ugly. For obvious(?) reasons. |
27 | // it's a hack, use only in emergency situations please. |
27 | // it's a hack, use only in emergency situations please. |
28 | |
28 | |
29 | #include <cstring> |
29 | #include <cstring> |
|
|
30 | #include <cassert> |
30 | |
31 | |
31 | #include <sys/types.h> |
32 | #include <sys/types.h> |
32 | #include <sys/socket.h> |
33 | #include <sys/socket.h> |
33 | #include <sys/wait.h> |
34 | #include <sys/wait.h> |
34 | #include <sys/uio.h> |
35 | #include <sys/uio.h> |
… | |
… | |
663 | |
664 | |
664 | void dns_snd::gen_syn_req () |
665 | void dns_snd::gen_syn_req () |
665 | { |
666 | { |
666 | timeout = NOW + INITIAL_SYN_TIMEOUT; |
667 | timeout = NOW + INITIAL_SYN_TIMEOUT; |
667 | |
668 | |
668 | printf ("send syn\n");//D |
|
|
669 | |
|
|
670 | pkt->flags = htons (DEFAULT_CLIENT_FLAGS); |
669 | pkt->flags = htons (DEFAULT_CLIENT_FLAGS); |
671 | pkt->qdcount = htons (1); |
670 | pkt->qdcount = htons (1); |
672 | |
671 | |
673 | int offs = 6 * 2; |
672 | int offs = 6 * 2; |
674 | |
673 | |
… | |
… | |
874 | // new packet, queue |
873 | // new packet, queue |
875 | rcv = new dns_rcv (seqno, data, datalen); |
874 | rcv = new dns_rcv (seqno, data, datalen); |
876 | dns->receive_rep (rcv); |
875 | dns->receive_rep (rcv); |
877 | } |
876 | } |
878 | |
877 | |
|
|
878 | { |
879 | pkt [offs++] = 0xc0; pkt [offs++] = 6 * 2; // refer to name in query section |
879 | pkt [offs++] = 0xc0; pkt [offs++] = 6 * 2; // refer to name in query section |
880 | |
880 | |
881 | int rtype = dns ? dns->cfg.rrtype : RR_TYPE_A; |
881 | int rtype = dns ? dns->cfg.rrtype : RR_TYPE_A; |
882 | pkt [offs++] = rtype >> 8; pkt [offs++] = rtype; // type |
882 | pkt [offs++] = rtype >> 8; pkt [offs++] = rtype; // type |
883 | pkt [offs++] = RR_CLASS_IN >> 8; pkt [offs++] = RR_CLASS_IN; // class |
883 | pkt [offs++] = RR_CLASS_IN >> 8; pkt [offs++] = RR_CLASS_IN; // class |
884 | pkt [offs++] = 0; pkt [offs++] = 0; |
884 | pkt [offs++] = 0; pkt [offs++] = 0; |
885 | pkt [offs++] = 0; pkt [offs++] = dns ? dns->cfg.def_ttl : 0; // TTL |
885 | pkt [offs++] = 0; pkt [offs++] = dns ? dns->cfg.def_ttl : 0; // TTL |
886 | |
886 | |
887 | int rdlen_offs = offs += 2; |
887 | int rdlen_offs = offs += 2; |
888 | |
888 | |
889 | int dlen = (dns ? ntohs (dns->cfg.max_size) : MAX_PKT_SIZE) - offs; |
889 | int dlen = (dns ? ntohs (dns->cfg.max_size) : MAX_PKT_SIZE) - offs; |
890 | // bind doesn't compress well, so reduce further by one label length |
890 | // bind doesn't compress well, so reduce further by one label length |
891 | dlen -= qlen; |
891 | dlen -= qlen; |
892 | |
892 | |
893 | if (dns) |
893 | if (dns) |
894 | { |
894 | { |
895 | // only put data into in-order sequence packets, if |
895 | // only put data into in-order sequence packets, if |
896 | // we receive out-of-order packets we generate empty |
896 | // we receive out-of-order packets we generate empty |
897 | // replies |
897 | // replies |
898 | while (dlen > 1 && !dns->snddq.empty () && in_seq) |
898 | while (dlen > 1 && !dns->snddq.empty () && in_seq) |
899 | { |
899 | { |
900 | int txtlen = dlen <= 255 ? dlen - 1 : 255; |
900 | int txtlen = dlen <= 255 ? dlen - 1 : 255; |
901 | |
901 | |
902 | if (txtlen > dns->snddq.size ()) |
902 | if (txtlen > dns->snddq.size ()) |
903 | txtlen = dns->snddq.size (); |
903 | txtlen = dns->snddq.size (); |
904 | |
904 | |
905 | pkt[offs++] = txtlen; |
905 | pkt[offs++] = txtlen; |
906 | memcpy (pkt.at (offs), dns->snddq.begin (), txtlen); |
906 | memcpy (pkt.at (offs), dns->snddq.begin (), txtlen); |
907 | offs += txtlen; |
907 | offs += txtlen; |
908 | dns->snddq.remove (txtlen); |
908 | dns->snddq.remove (txtlen); |
909 | |
909 | |
910 | dlen -= txtlen + 1; |
910 | dlen -= txtlen + 1; |
911 | } |
911 | } |
912 | |
912 | |
913 | // avoid empty TXT rdata |
913 | // avoid empty TXT rdata |
914 | if (offs == rdlen_offs) |
914 | if (offs == rdlen_offs) |
915 | pkt[offs++] = 0; |
915 | pkt[offs++] = 0; |
916 | |
916 | |
917 | slog (L_NOISE, "DNS: snddq %d", dns->snddq.size ()); |
917 | slog (L_NOISE, "DNS: snddq %d", dns->snddq.size ()); |
918 | } |
918 | } |
919 | else |
919 | else |
920 | { |
920 | { |
921 | // send RST |
921 | // send RST |
922 | pkt [offs++] = CMD_IP_1; pkt [offs++] = CMD_IP_2; pkt [offs++] = CMD_IP_3; |
922 | pkt [offs++] = CMD_IP_1; pkt [offs++] = CMD_IP_2; pkt [offs++] = CMD_IP_3; |
923 | pkt [offs++] = CMD_IP_RST; |
923 | pkt [offs++] = CMD_IP_RST; |
924 | } |
924 | } |
925 | |
925 | |
926 | int rdlen = offs - rdlen_offs; |
926 | int rdlen = offs - rdlen_offs; |
927 | |
927 | |
928 | pkt [rdlen_offs - 2] = rdlen >> 8; |
928 | pkt [rdlen_offs - 2] = rdlen >> 8; |
929 | pkt [rdlen_offs - 1] = rdlen; |
929 | pkt [rdlen_offs - 1] = rdlen; |
930 | |
930 | |
931 | if (dns) |
931 | if (dns) |
932 | { |
932 | { |
933 | // now update dns_rcv copy |
933 | // now update dns_rcv copy |
934 | rcv->pkt->len = offs; |
934 | rcv->pkt->len = offs; |
935 | memcpy (rcv->pkt->at (0), pkt.at (0), offs); |
935 | memcpy (rcv->pkt->at (0), pkt.at (0), offs); |
936 | } |
936 | } |
|
|
937 | } |
937 | |
938 | |
938 | duplicate_request: ; |
939 | duplicate_request: ; |
939 | } |
940 | } |
940 | else |
941 | else |
941 | pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR); |
942 | pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR); |