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