From dc913c9a1f243bca291d47b1a5d8e270c471d113 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Mon, 13 Jul 2015 01:51:03 +0200 Subject: resolved: rr - add OPT pseudo-rr support Needed for EDNS0. --- src/resolve/resolved-dns-packet.c | 55 +++++++++++++++++++++++++++++++++++++++ src/resolve/resolved-dns-packet.h | 1 + 2 files changed, 56 insertions(+) diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index 40b662246f..49c36e38f3 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -609,6 +609,57 @@ fail: return r; } +/* Append the OPT pseudo-RR described in RFC6891 */ +int dns_packet_append_opt_rr(DnsPacket *p, uint16_t max_udp_size, size_t *start) { + size_t saved_size; + int r; + + assert(p); + /* we must never advertise supported packet size smaller than the legacy max */ + assert(max_udp_size >= DNS_PACKET_UNICAST_SIZE_MAX); + + saved_size = p->size; + + /* empty name */ + r = dns_packet_append_uint8(p, 0, NULL); + if (r < 0) + return r; + + /* type */ + r = dns_packet_append_uint16(p, DNS_TYPE_OPT, NULL); + if (r < 0) + goto fail; + + /* maximum udp packet that can be received */ + r = dns_packet_append_uint16(p, max_udp_size, NULL); + if (r < 0) + goto fail; + + /* extended RCODE and VERSION */ + r = dns_packet_append_uint16(p, 0, NULL); + if (r < 0) + goto fail; + + /* flags */ + r = dns_packet_append_uint16(p, 0, NULL); + if (r < 0) + goto fail; + + /* RDLENGTH */ + r = dns_packet_append_uint16(p, 0, NULL); + if (r < 0) + goto fail; + + if (start) + *start = saved_size; + + return 0; + +fail: + dns_packet_truncate(p, saved_size); + return r; +} + int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *start) { size_t saved_size, rdlength_offset, end, rdlength; int r; @@ -1450,6 +1501,10 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) { r = dns_packet_read_name(p, &rr->ptr.name, true, NULL); break; + case DNS_TYPE_OPT: /* we only care about the header */ + r = 0; + break; + case DNS_TYPE_HINFO: r = dns_packet_read_string(p, &rr->hinfo.cpu, NULL); if (r < 0) diff --git a/src/resolve/resolved-dns-packet.h b/src/resolve/resolved-dns-packet.h index 90b5a7c8bd..ca94a208ba 100644 --- a/src/resolve/resolved-dns-packet.h +++ b/src/resolve/resolved-dns-packet.h @@ -160,6 +160,7 @@ int dns_packet_append_label(DnsPacket *p, const char *s, size_t l, size_t *start int dns_packet_append_name(DnsPacket *p, const char *name, bool allow_compression, size_t *start); int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *key, size_t *start); int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *start); +int dns_packet_append_opt_rr(DnsPacket *p, uint16_t max_udp_size, size_t *start); int dns_packet_read(DnsPacket *p, size_t sz, const void **ret, size_t *start); int dns_packet_read_blob(DnsPacket *p, void *d, size_t sz, size_t *start); -- cgit v1.2.3-54-g00ecf