… | |
… | |
875 | // new packet, queue |
875 | // new packet, queue |
876 | rcv = new dns_rcv (seqno, data, datalen); |
876 | rcv = new dns_rcv (seqno, data, datalen); |
877 | dns->receive_rep (rcv); |
877 | dns->receive_rep (rcv); |
878 | } |
878 | } |
879 | |
879 | |
|
|
880 | { |
880 | pkt [offs++] = 0xc0; pkt [offs++] = 6 * 2; // refer to name in query section |
881 | pkt [offs++] = 0xc0; pkt [offs++] = 6 * 2; // refer to name in query section |
881 | |
882 | |
882 | int rtype = dns ? dns->cfg.rrtype : RR_TYPE_A; |
883 | int rtype = dns ? dns->cfg.rrtype : RR_TYPE_A; |
883 | pkt [offs++] = rtype >> 8; pkt [offs++] = rtype; // type |
884 | pkt [offs++] = rtype >> 8; pkt [offs++] = rtype; // type |
884 | pkt [offs++] = RR_CLASS_IN >> 8; pkt [offs++] = RR_CLASS_IN; // class |
885 | pkt [offs++] = RR_CLASS_IN >> 8; pkt [offs++] = RR_CLASS_IN; // class |
885 | pkt [offs++] = 0; pkt [offs++] = 0; |
886 | pkt [offs++] = 0; pkt [offs++] = 0; |
886 | pkt [offs++] = 0; pkt [offs++] = dns ? dns->cfg.def_ttl : 0; // TTL |
887 | pkt [offs++] = 0; pkt [offs++] = dns ? dns->cfg.def_ttl : 0; // TTL |
887 | |
888 | |
888 | int rdlen_offs = offs += 2; |
889 | int rdlen_offs = offs += 2; |
889 | |
890 | |
890 | int dlen = (dns ? ntohs (dns->cfg.max_size) : MAX_PKT_SIZE) - offs; |
891 | int dlen = (dns ? ntohs (dns->cfg.max_size) : MAX_PKT_SIZE) - offs; |
891 | // bind doesn't compress well, so reduce further by one label length |
892 | // bind doesn't compress well, so reduce further by one label length |
892 | dlen -= qlen; |
893 | dlen -= qlen; |
893 | |
894 | |
894 | if (dns) |
895 | if (dns) |
895 | { |
896 | { |
896 | // only put data into in-order sequence packets, if |
897 | // only put data into in-order sequence packets, if |
897 | // we receive out-of-order packets we generate empty |
898 | // we receive out-of-order packets we generate empty |
898 | // replies |
899 | // replies |
899 | while (dlen > 1 && !dns->snddq.empty () && in_seq) |
900 | while (dlen > 1 && !dns->snddq.empty () && in_seq) |
900 | { |
901 | { |
901 | int txtlen = dlen <= 255 ? dlen - 1 : 255; |
902 | int txtlen = dlen <= 255 ? dlen - 1 : 255; |
902 | |
903 | |
903 | if (txtlen > dns->snddq.size ()) |
904 | if (txtlen > dns->snddq.size ()) |
904 | txtlen = dns->snddq.size (); |
905 | txtlen = dns->snddq.size (); |
905 | |
906 | |
906 | pkt[offs++] = txtlen; |
907 | pkt[offs++] = txtlen; |
907 | memcpy (pkt.at (offs), dns->snddq.begin (), txtlen); |
908 | memcpy (pkt.at (offs), dns->snddq.begin (), txtlen); |
908 | offs += txtlen; |
909 | offs += txtlen; |
909 | dns->snddq.remove (txtlen); |
910 | dns->snddq.remove (txtlen); |
910 | |
911 | |
911 | dlen -= txtlen + 1; |
912 | dlen -= txtlen + 1; |
912 | } |
913 | } |
913 | |
914 | |
914 | // avoid empty TXT rdata |
915 | // avoid empty TXT rdata |
915 | if (offs == rdlen_offs) |
916 | if (offs == rdlen_offs) |
916 | pkt[offs++] = 0; |
917 | pkt[offs++] = 0; |
917 | |
918 | |
918 | slog (L_NOISE, "DNS: snddq %d", dns->snddq.size ()); |
919 | slog (L_NOISE, "DNS: snddq %d", dns->snddq.size ()); |
919 | } |
920 | } |
920 | else |
921 | else |
921 | { |
922 | { |
922 | // send RST |
923 | // send RST |
923 | pkt [offs++] = CMD_IP_1; pkt [offs++] = CMD_IP_2; pkt [offs++] = CMD_IP_3; |
924 | pkt [offs++] = CMD_IP_1; pkt [offs++] = CMD_IP_2; pkt [offs++] = CMD_IP_3; |
924 | pkt [offs++] = CMD_IP_RST; |
925 | pkt [offs++] = CMD_IP_RST; |
925 | } |
926 | } |
926 | |
927 | |
927 | int rdlen = offs - rdlen_offs; |
928 | int rdlen = offs - rdlen_offs; |
928 | |
929 | |
929 | pkt [rdlen_offs - 2] = rdlen >> 8; |
930 | pkt [rdlen_offs - 2] = rdlen >> 8; |
930 | pkt [rdlen_offs - 1] = rdlen; |
931 | pkt [rdlen_offs - 1] = rdlen; |
931 | |
932 | |
932 | if (dns) |
933 | if (dns) |
933 | { |
934 | { |
934 | // now update dns_rcv copy |
935 | // now update dns_rcv copy |
935 | rcv->pkt->len = offs; |
936 | rcv->pkt->len = offs; |
936 | memcpy (rcv->pkt->at (0), pkt.at (0), offs); |
937 | memcpy (rcv->pkt->at (0), pkt.at (0), offs); |
937 | } |
938 | } |
|
|
939 | } |
938 | |
940 | |
939 | duplicate_request: ; |
941 | duplicate_request: ; |
940 | } |
942 | } |
941 | else |
943 | else |
942 | pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR); |
944 | pkt.flags = htons (DEFAULT_SERVER_FLAGS | FLAG_RCODE_FORMERR); |