diff options
Diffstat (limited to 'src/resolve/resolved-dns-packet.c')
-rw-r--r-- | src/resolve/resolved-dns-packet.c | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index 06464324d2..75f31b80f6 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -108,6 +108,8 @@ DnsPacket *dns_packet_ref(DnsPacket *p) { if (!p) return NULL; + assert(!p->on_stack); + assert(p->n_ref > 0); p->n_ref++; return p; @@ -126,7 +128,9 @@ static void dns_packet_free(DnsPacket *p) { hashmap_free(p->names); free(p->_data); - free(p); + + if (!p->on_stack) + free(p); } DnsPacket *dns_packet_unref(DnsPacket *p) { @@ -380,7 +384,7 @@ int dns_packet_append_raw_string(DnsPacket *p, const void *s, size_t size, size_ } int dns_packet_append_label(DnsPacket *p, const char *d, size_t l, size_t *start) { - void *w; + uint8_t *w; int r; assert(p); @@ -389,12 +393,29 @@ int dns_packet_append_label(DnsPacket *p, const char *d, size_t l, size_t *start if (l > DNS_LABEL_MAX) return -E2BIG; - r = dns_packet_extend(p, 1 + l, &w, start); + r = dns_packet_extend(p, 1 + l, (void**) &w, start); if (r < 0) return r; - ((uint8_t*) w)[0] = (uint8_t) l; - memcpy(((uint8_t*) w) + 1, d, l); + *(w++) = (uint8_t) l; + + if (p->canonical_form) { + size_t i; + + /* Generate in canonical form, as defined by DNSSEC + * RFC 4034, Section 6.2, i.e. all lower-case. */ + + for (i = 0; i < l; i++) { + if (d[i] >= 'A' && d[i] <= 'Z') + w[i] = (uint8_t) (d[i] - 'A' + 'a'); + else + w[i] = (uint8_t) d[i]; + } + } else + /* Otherwise, just copy the string unaltered. This is + * essential for DNS-SD, where the casing of labels + * matters and needs to be retained. */ + memcpy(w, d, l); return 0; } @@ -647,8 +668,8 @@ fail: return r; } -int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *start) { - size_t saved_size, rdlength_offset, end, rdlength; +int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *start, size_t *rdata_start) { + size_t saved_size, rdlength_offset, end, rdlength, rds; int r; assert(p); @@ -669,6 +690,8 @@ int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *star if (r < 0) goto fail; + rds = p->size - saved_size; + switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) { case DNS_TYPE_SRV: @@ -947,6 +970,9 @@ int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *star if (start) *start = saved_size; + if (rdata_start) + *rdata_start = rds; + return 0; fail: |