示例#1
0
static int dns_stub_make_reply_packet(
                DnsPacket **p,
                size_t max_size,
                DnsQuestion *q,
                DnsAnswer *answer,
                bool *ret_truncated) {

        bool truncated = false;
        DnsResourceRecord *rr;
        unsigned c = 0;
        int r;

        assert(p);

        /* Note that we don't bother with any additional RRs, as this is stub is for local lookups only, and hence
         * roundtrips aren't expensive. */

        if (!*p) {
                r = dns_packet_new(p, DNS_PROTOCOL_DNS, 0, max_size);
                if (r < 0)
                        return r;

                r = dns_packet_append_question(*p, q);
                if (r < 0)
                        return r;

                DNS_PACKET_HEADER(*p)->qdcount = htobe16(dns_question_size(q));
        }

        DNS_ANSWER_FOREACH(rr, answer) {

                r = dns_question_matches_rr(q, rr, NULL);
                if (r < 0)
                        return r;
                if (r > 0)
                        goto add;

                r = dns_question_matches_cname_or_dname(q, rr, NULL);
                if (r < 0)
                        return r;
                if (r > 0)
                        goto add;

                continue;
        add:
                r = dns_packet_append_rr(*p, rr, 0, NULL, NULL);
                if (r == -EMSGSIZE) {
                        truncated = true;
                        break;
                }
                if (r < 0)
                        return r;

                c++;
        }
static int dns_stub_make_reply_packet(
    uint16_t id,
    int rcode,
    DnsQuestion *q,
    DnsAnswer *answer,
    bool add_opt,   /* add an OPT RR to this packet */
    bool edns0_do,  /* set the EDNS0 DNSSEC OK bit */
    bool ad,        /* set the DNSSEC authenticated data bit */
    DnsPacket **ret) {

    _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
    DnsResourceRecord *rr;
    unsigned c = 0;
    int r;

    /* Note that we don't bother with any additional RRs, as this is stub is for local lookups only, and hence
     * roundtrips aren't expensive. */

    r = dns_packet_new(&p, DNS_PROTOCOL_DNS, 0);
    if (r < 0)
        return r;

    /* If the client didn't do EDNS, clamp the rcode to 4 bit */
    if (!add_opt && rcode > 0xF)
        rcode = DNS_RCODE_SERVFAIL;

    DNS_PACKET_HEADER(p)->id = id;
    DNS_PACKET_HEADER(p)->flags = htobe16(DNS_PACKET_MAKE_FLAGS(
            1 /* qr */,
            0 /* opcode */,
            0 /* aa */,
            0 /* tc */,
            1 /* rd */,
            1 /* ra */,
            ad /* ad */,
            0 /* cd */,
            rcode));

    r = dns_packet_append_question(p, q);
    if (r < 0)
        return r;
    DNS_PACKET_HEADER(p)->qdcount = htobe16(dns_question_size(q));

    DNS_ANSWER_FOREACH(rr, answer) {
        r = dns_question_matches_rr(q, rr, NULL);
        if (r < 0)
            return r;
        if (r > 0)
            goto add;

        r = dns_question_matches_cname_or_dname(q, rr, NULL);
        if (r < 0)
            return r;
        if (r > 0)
            goto add;

        continue;
add:
        r = dns_packet_append_rr(p, rr, NULL, NULL);
        if (r < 0)
            return r;

        c++;
    }