示例#1
0
static int dns_transaction_make_packet(DnsTransaction *t) {
        _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
        int r;

        assert(t);

        if (t->sent)
                return 0;

        r = dns_packet_new_query(&p, t->scope->protocol, 0);
        if (r < 0)
                return r;

        r = dns_scope_good_key(t->scope, t->key);
        if (r < 0)
                return r;
        if (r == 0)
                return -EDOM;

        r = dns_packet_append_key(p, t->key, NULL);
        if (r < 0)
                return r;

        DNS_PACKET_HEADER(p)->qdcount = htobe16(1);
        DNS_PACKET_HEADER(p)->id = t->id;

        t->sent = p;
        p = NULL;

        return 0;
}
示例#2
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_transaction_make_packet(DnsTransaction *t) {
        _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
        unsigned n, added = 0;
        int r;

        assert(t);

        if (t->sent)
                return 0;

        r = dns_packet_new_query(&p, t->scope->protocol, 0);
        if (r < 0)
                return r;

        for (n = 0; n < t->question->n_keys; n++) {
                r = dns_scope_good_key(t->scope, t->question->keys[n]);
                if (r < 0)
                        return r;
                if (r == 0)
                        continue;

                r = dns_packet_append_key(p, t->question->keys[n], NULL);
                if (r < 0)
                        return r;

                added++;
        }

        if (added <= 0)
                return -EDOM;

        DNS_PACKET_HEADER(p)->qdcount = htobe16(added);
        DNS_PACKET_HEADER(p)->id = t->id;

        t->sent = p;
        p = NULL;

        return 0;
}
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++;
    }