LOC records are special. The first octet of a LOC record is a version
number. According to RFC 1876:
VERSION Version number of the representation. This must be zero.
Implementations are required to check this field and make
no assumptions about the format of unrecognized versions.
This means that if a LOC record's VERSION field is not zero, the RR
cannot be presented in the canonical presentation format, but it is
still a valid wire-format RR.
Currently, kdig prints a warning message "can't print whole section" and
a LOC record with a blank RDATA when it attempts to dump a LOC record
with a non-zero VERSION field.
This commit modifies the version check in wire_loc_to_str() to fall back
to the generic presentation format if the VERSION field is not 0. This
particular case is even explicitly described as a use case for the
generic presentation format in RFC 3597:
Using the generic representation for the RDATA of an RR of known type
can also be useful in the case of an RR type where the text format
varies depending on a version, protocol, or similar field (or
several) embedded in the RDATA when such a field has a value for
which no text format is known, e.g., a LOC RR [RFC1876] with a
VERSION other than 0.
---
src/libknot/rrset-dump.c | 95 +++++++++++++++++++++++++-----------------------
1 file changed, 49 insertions(+), 46 deletions(-)
diff --git a/src/libknot/rrset-dump.c b/src/libknot/rrset-dump.c
index c71eae1..ffdd825 100644
--- a/src/libknot/rrset-dump.c
+++ b/src/libknot/rrset-dump.c
@@ -508,6 +508,47 @@ static void wire_len_data_encode_to_str(rrset_dump_params_t *p,
p->ret = 0;
}
+static void wire_unknown_to_str(rrset_dump_params_t *p)
+{
+ int ret;
+ size_t in_len = p->in_max;
+ size_t out_len = 0;
+
+ // Write unknown length header.
+ if (in_len > 0) {
+ ret = snprintf(p->out, p->out_max, "\\# %zu ", in_len);
+ } else {
+ ret = snprintf(p->out, p->out_max, "\\# 0");
+ }
+ if (ret <= 0 || (size_t)ret >= p->out_max) {
+ return;
+ }
+ out_len = ret;
+
+ // Fill in output.
+ p->out += out_len;
+ p->out_max -= out_len;
+ p->total += out_len;
+
+ // Write hex data if any.
+ if (in_len > 0) {
+ // If wrap mode wrap line.
+ if (p->style->wrap) {
+ dump_string(p, BLOCK_INDENT);
+ if (p->ret != 0) {
+ return;
+ }
+ }
+
+ wire_data_encode_to_str(p, &hex_encode, &hex_encode_alloc);
+ if (p->ret != 0) {
+ return;
+ }
+ }
+
+ p->ret = 0;
+}
+
static void wire_text_to_str(rrset_dump_params_t *p)
{
// First byte is string length.
@@ -938,6 +979,14 @@ static void wire_loc_to_str(rrset_dump_params_t *p)
// Read values.
wire_ctx_t wire = wire_ctx_init_const(p->in, p->in_max);
uint8_t version = wire_ctx_read_u8(&wire);
+
+ // Version check.
+ if (version != 0) {
+ wire_unknown_to_str(p);
+ return;
+ }
+
+ // Continue to read values.
uint8_t size_w = wire_ctx_read_u8(&wire);
uint8_t hpre_w = wire_ctx_read_u8(&wire);
uint8_t vpre_w = wire_ctx_read_u8(&wire);
@@ -953,11 +1002,6 @@ static void wire_loc_to_str(rrset_dump_params_t *p)
p->in += wire_ctx_offset(&wire);
p->in_max = wire_ctx_available(&wire);
- // Version check.
- if (version != 0) {
- return;
- }
-
// Latitude calculation.
char lat_mark;
uint32_t lat;
@@ -1210,47 +1254,6 @@ static void wire_tsig_rcode_to_str(rrset_dump_params_t *p)
p->ret = 0;
}
-static void wire_unknown_to_str(rrset_dump_params_t *p)
-{
- int ret;
- size_t in_len = p->in_max;
- size_t out_len = 0;
-
- // Write unknown length header.
- if (in_len > 0) {
- ret = snprintf(p->out, p->out_max, "\\# %zu ", in_len);
- } else {
- ret = snprintf(p->out, p->out_max, "\\# 0");
- }
- if (ret <= 0 || (size_t)ret >= p->out_max) {
- return;
- }
- out_len = ret;
-
- // Fill in output.
- p->out += out_len;
- p->out_max -= out_len;
- p->total += out_len;
-
- // Write hex data if any.
- if (in_len > 0) {
- // If wrap mode wrap line.
- if (p->style->wrap) {
- dump_string(p, BLOCK_INDENT);
- if (p->ret != 0) {
- return;
- }
- }
-
- wire_data_encode_to_str(p, &hex_encode, &hex_encode_alloc);
- if (p->ret != 0) {
- return;
- }
- }
-
- p->ret = 0;
-}
-
static size_t dnskey_len(const uint8_t *rdata,
const size_t rdata_len)
{
--
2.7.0