Commit e910d180 authored by Witold Krecicki's avatar Witold Krecicki
Browse files

4545. [func] Make dnstap-read output more functionally usable.

			[RT #43642]

4544.	[func]		Add message/payload size to dnstap-read YAML output.
			[RT #43622]
parent 6f947472
4545. [func] Make dnstap-read output more functionally usable.
[RT #43642]
4544. [func] Add message/payload size to dnstap-read YAML output.
[RT #43622]
4543. [bug] dns_client_startupdate now delays sending the update
request until isc_app_ctxrun has been called.
[RT #43976]
......
......@@ -18,6 +18,8 @@ ns2.example. A 10.53.0.2
$ORIGIN example.
a A 10.0.0.1
a A 10.0.0.3
a A 10.0.0.5
MX 10 mail.example.
mail A 10.0.0.2
......@@ -344,6 +344,18 @@ ret=0
if [ $ret != 0 ]; then echo "I: failed"; fi
status=`expr $status + $ret`
HAS_PYYAML=0
if [ -n "$PYTHON" ] ; then
$PYTHON -c "import yaml" && HAS_PYYAML=1
fi
if [ $HAS_PYYAML ] ; then
echo "I:checking dnstap-read YAML output"
ret=0
$PYTHON ydump.py "$DNSTAPREAD" "ns3/dnstap.out.save" > /dev/null || ret=1
if [ $ret != 0 ]; then echo "I: failed"; fi
status=`expr $status + $ret`
fi
if [ -n "$FSTRM_CAPTURE" ] ; then
$DIG +short @10.53.0.4 -p 5300 a.example > dig.out
......
#!/usr/bin/python
try:
import yaml
except:
print "I: No python yaml module, skipping"
exit(1)
import subprocess
import pprint
import sys
DNSTAP_READ=sys.argv[1]
DATAFILE=sys.argv[2]
f = subprocess.Popen([DNSTAP_READ, '-y', DATAFILE], stdout=subprocess.PIPE)
pprint.pprint([l for l in yaml.load_all(f.stdout)])
......@@ -83,10 +83,68 @@ usage(void) {
}
static void
print_yaml(dns_dtdata_t *d) {
Dnstap__Dnstap *frame = d->frame;
print_dtdata(dns_dtdata_t *dt) {
isc_result_t result;
isc_buffer_t *b = NULL;
isc_buffer_allocate(mctx, &b, 2048);
if (b == NULL)
fatal("out of memory");
CHECKM(dns_dt_datatotext(dt, &b), "dns_dt_datatotext");
printf("%.*s\n", (int) isc_buffer_usedlength(b),
(char *) isc_buffer_base(b));
cleanup:
if (b != NULL)
isc_buffer_free(&b);
}
static void
print_packet(dns_dtdata_t *dt, const dns_master_style_t *style) {
isc_buffer_t *b = NULL;
isc_result_t result;
if (dt->msg != NULL) {
size_t textlen = 2048;
isc_buffer_allocate(mctx, &b, textlen);
if (b == NULL)
fatal("out of memory");
for (;;) {
isc_buffer_reserve(&b, textlen);
if (b == NULL)
fatal("out of memory");
result = dns_message_totext(dt->msg, style, 0, b);
if (result == ISC_R_NOSPACE) {
textlen *= 2;
continue;
} else if (result == ISC_R_SUCCESS) {
printf("%.*s",
(int) isc_buffer_usedlength(b),
(char *) isc_buffer_base(b));
isc_buffer_free(&b);
} else {
isc_buffer_free(&b);
CHECKM(result, "dns_message_totext");
}
break;
}
}
cleanup:
if (b != NULL)
isc_buffer_free(&b);
}
static void
print_yaml(dns_dtdata_t *dt) {
Dnstap__Dnstap *frame = dt->frame;
Dnstap__Message *m = frame->message;
const ProtobufCEnumValue *ftype, *mtype;
static isc_boolean_t first = ISC_TRUE;
ftype = protobuf_c_enum_descriptor_get_value(
&dnstap__dnstap__type__descriptor,
......@@ -94,6 +152,11 @@ print_yaml(dns_dtdata_t *d) {
if (ftype == NULL)
return;
if (!first)
printf("---\n");
else
first = ISC_FALSE;
printf("type: %s\n", ftype->name);
if (frame->has_identity)
......@@ -117,18 +180,23 @@ print_yaml(dns_dtdata_t *d) {
printf(" type: %s\n", mtype->name);
if (!isc_time_isepoch(&d->qtime)) {
if (!isc_time_isepoch(&dt->qtime)) {
char buf[100];
isc_time_formatISO8601(&d->qtime, buf, sizeof(buf));
isc_time_formatISO8601(&dt->qtime, buf, sizeof(buf));
printf(" query_time: !!timestamp %s\n", buf);
}
if (!isc_time_isepoch(&d->rtime)) {
if (!isc_time_isepoch(&dt->rtime)) {
char buf[100];
isc_time_formatISO8601(&d->rtime, buf, sizeof(buf));
isc_time_formatISO8601(&dt->rtime, buf, sizeof(buf));
printf(" response_time: !!timestamp %s\n", buf);
}
if (dt->msgdata.base != NULL) {
printf(" message_size: %zdb\n", (size_t) dt->msgdata.length);
} else
printf(" message_size: 0b\n");
if (m->has_socket_family) {
const ProtobufCEnumValue *type =
protobuf_c_enum_descriptor_get_value(
......@@ -138,7 +206,7 @@ print_yaml(dns_dtdata_t *d) {
printf(" socket_family: %s\n", type->name);
}
printf(" socket_protocol: %s\n", d->tcp ? "TCP" : "UDP");
printf(" socket_protocol: %s\n", dt->tcp ? "TCP" : "UDP");
if (m->has_query_address) {
ProtobufCBinaryData *ip = &m->query_address;
......@@ -186,9 +254,18 @@ print_yaml(dns_dtdata_t *d) {
}
}
if (d->msg != NULL)
printf(" %s: |\n", ((d->type & DNS_DTTYPE_QUERY) != 0)
? "query_message" : "response_message");
if (dt->msg != NULL) {
printf(" %s:\n", ((dt->type & DNS_DTTYPE_QUERY) != 0)
? "query_message_data"
: "response_message_data");
print_packet(dt, &dns_master_style_yaml);
printf(" %s: |\n", ((dt->type & DNS_DTTYPE_QUERY) != 0)
? "query_message"
: "response_message");
print_packet(dt, &dns_master_style_indent);
}
};
int
......@@ -197,7 +274,6 @@ main(int argc, char *argv[]) {
dns_message_t *message = NULL;
isc_buffer_t *b = NULL;
dns_dtdata_t *dt = NULL;
const dns_master_style_t *style = &dns_master_style_debug;
dns_dthandle_t *handle = NULL;
int rv = 0, ch;
......@@ -212,9 +288,8 @@ main(int argc, char *argv[]) {
break;
case 'y':
yaml = ISC_TRUE;
style = &dns_master_style_indent;
dns_master_indentstr = " ";
printmessage = ISC_TRUE;
dns_master_indentstr = " ";
dns_master_indent = 2;
break;
default:
usage();
......@@ -261,44 +336,15 @@ main(int argc, char *argv[]) {
continue;
}
if (yaml)
if (yaml) {
print_yaml(dt);
else {
CHECKM(dns_dt_datatotext(dt, &b), "dns_dt_datatotext");
printf("%.*s\n", (int) isc_buffer_usedlength(b),
(char *) isc_buffer_base(b));
} else if (printmessage) {
print_dtdata(dt);
print_packet(dt, &dns_master_style_debug);
} else {
print_dtdata(dt);
}
if (printmessage && dt->msg != NULL) {
size_t textlen = 2048;
isc_buffer_clear(b);
for (;;) {
isc_buffer_reserve(&b, textlen);
if (b == NULL)
fatal("out of memory");
result = dns_message_totext(dt->msg, style,
0, b);
if (result == ISC_R_NOSPACE) {
textlen *= 2;
continue;
} else if (result == ISC_R_SUCCESS) {
printf("%.*s",
(int) isc_buffer_usedlength(b),
(char *) isc_buffer_base(b));
isc_buffer_free(&b);
} else {
isc_buffer_free(&b);
CHECKM(result, "dns_message_totext");
}
break;
}
}
if (yaml)
printf("---\n");
dns_dtdata_free(&dt);
}
......
......@@ -86,7 +86,7 @@
<listitem>
<para>
Print <command>dnstap</command> data in a detailed YAML
format. Implies <option>-p</option>.
format.
</para>
</listitem>
</varlistentry>
......
......@@ -103,6 +103,9 @@ typedef struct dns_master_style dns_master_style_t;
/*% Indent output. */
#define DNS_STYLEFLAG_INDENT 0x40000000U
/*% Output in YAML style. */
#define DNS_STYLEFLAG_YAML 0x80000000U
ISC_LANG_BEGINDECLS
/***
......@@ -167,14 +170,32 @@ LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_indent;
*/
LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_keyzone;
/*%
* YAML-compatible output
*/
LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_yaml;
/*%
* The default indent string to prepend lines with when using
* styleflag DNS_STYLEFLAG_INDENT. This is set to "\t" by default.
* The indent preceeds everything else on the line, including comment
* characters (;).
* styleflag DNS_STYLEFLAG_INDENT or DNS_STYLEFLAG_YAML.
* This is set to "\t" by default. The indent is repeated
* 'dns_master_indent' times. This precedes everything else
* on the line, including comment characters (;).
*
* XXX: Changing this value at runtime is not thread-safe.
*/
LIBDNS_EXTERNAL_DATA extern const char *dns_master_indentstr;
/*%
* The number of copies of the indent string to put at the beginning
* of the line when using DNS_STYLEFLAG_INDENT or DNS_STYLEFLAG_YAML.
* This is set to 1 by default. It is increased and decreased
* to adjust indentation levels when producing YAML output.
*
* XXX: This is not thread-safe.
*/
LIBDNS_EXTERNAL_DATA extern unsigned int dns_master_indent;
/***
*** Functions
***/
......@@ -394,6 +415,7 @@ dns_master_stylecreate2(dns_master_style_t **style, unsigned int flags,
unsigned int type_column, unsigned int rdata_column,
unsigned int line_length, unsigned int tab_width,
unsigned int split_width, isc_mem_t *mctx);
void
dns_master_styledestroy(dns_master_style_t **style, isc_mem_t *mctx);
......
......@@ -12,6 +12,7 @@
#include <stdlib.h>
#include <isc/buffer.h>
#include <isc/event.h>
#include <isc/file.h>
#include <isc/magic.h>
......@@ -185,11 +186,22 @@ dns_master_style_comment = {
24, 32, 40, 48, 80, 8, UINT_MAX
};
/*%
* YAML style
*/
LIBDNS_EXTERNAL_DATA const dns_master_style_t
dns_master_style_yaml = {
DNS_STYLEFLAG_YAML |
DNS_STYLEFLAG_REL_OWNER |
DNS_STYLEFLAG_INDENT,
24, 32, 40, 48, 80, 8, UINT_MAX
};
/*%
* Default indent string.
*/
LIBDNS_EXTERNAL_DATA const char *dns_master_indentstr = "\t";
LIBDNS_EXTERNAL_DATA unsigned int dns_master_indent = 1;
#define N_SPACES 10
static char spaces[N_SPACES+1] = " ";
......@@ -321,14 +333,15 @@ totext_ctx_init(const dns_master_style_t *style, dns_totext_ctx_t *ctx) {
r.base[0] = '\n';
isc_buffer_add(&buf, 1);
if ((ctx->style.flags & DNS_STYLEFLAG_INDENT) != 0) {
unsigned int ilen = strlen(dns_master_indentstr);
isc_buffer_availableregion(&buf, &r);
if (r.length < ilen)
return (DNS_R_TEXTTOOLONG);
isc_buffer_putmem(&buf,
(const isc_uint8_t *) dns_master_indentstr,
(unsigned int)ilen);
if ((ctx->style.flags & DNS_STYLEFLAG_INDENT) != 0 ||
(ctx->style.flags & DNS_STYLEFLAG_YAML) != 0)
{
unsigned int i, len = strlen(dns_master_indentstr);
for (i = 0; i < dns_master_indent; i++) {
if (isc_buffer_availablelength(&buf) < len)
return (DNS_R_TEXTTOOLONG);
isc_buffer_putstr(&buf, dns_master_indentstr);
}
}
if ((ctx->style.flags & DNS_STYLEFLAG_COMMENTDATA) != 0) {
......@@ -373,7 +386,11 @@ totext_ctx_init(const dns_master_style_t *style, dns_totext_ctx_t *ctx) {
#define INDENT_TO(col) \
do { \
if ((result = indent(&column, ctx->style.col, \
if ((ctx->style.flags & DNS_STYLEFLAG_YAML) != 0) { \
if ((result = str_totext(" ", target)) \
!= ISC_R_SUCCESS) \
return (result); \
} else if ((result = indent(&column, ctx->style.col, \
ctx->style.tab_width, target)) \
!= ISC_R_SUCCESS) \
return (result); \
......@@ -465,6 +482,7 @@ rdataset_totext(dns_rdataset_t *rdataset,
unsigned int type_start;
dns_fixedname_t fixed;
dns_name_t *name = NULL;
unsigned int i;
REQUIRE(DNS_RDATASET_VALID(rdataset));
......@@ -487,8 +505,18 @@ rdataset_totext(dns_rdataset_t *rdataset,
/*
* Indent?
*/
if ((ctx->style.flags & DNS_STYLEFLAG_INDENT) != 0)
RETERR(str_totext(dns_master_indentstr, target));
if ((ctx->style.flags & DNS_STYLEFLAG_INDENT) != 0 ||
(ctx->style.flags & DNS_STYLEFLAG_YAML) != 0)
for (i = 0; i < dns_master_indent; i++)
RETERR(str_totext(dns_master_indentstr,
target));
/*
* YAML enumerator?
*/
if ((ctx->style.flags & DNS_STYLEFLAG_YAML) != 0) {
RETERR(str_totext("- ", target));
}
/*
* Comment?
......@@ -612,9 +640,13 @@ rdataset_totext(dns_rdataset_t *rdataset,
*/
INDENT_TO(rdata_column);
if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
if ((ctx->style.flags & DNS_STYLEFLAG_INDENT) != 0)
RETERR(str_totext(dns_master_indentstr,
target));
if ((ctx->style.flags & DNS_STYLEFLAG_INDENT) != 0 ||
(ctx->style.flags & DNS_STYLEFLAG_YAML) != 0)
{
for (i = 0; i < dns_master_indent; i++)
RETERR(str_totext(dns_master_indentstr,
target));
}
if (NXDOMAIN(rdataset))
RETERR(str_totext(";-$NXDOMAIN\n", target));
else
......@@ -984,11 +1016,16 @@ dump_rdatasets_text(isc_mem_t *mctx, dns_name_t *name,
for (i = 0; i < n; i++) {
dns_rdataset_t *rds = sorted[i];
if (ctx->style.flags & DNS_STYLEFLAG_TRUST)
fprintf(f, "%s; %s\n",
(ctx->style.flags & DNS_STYLEFLAG_INDENT)
? dns_master_indentstr : "",
dns_trust_totext(rds->trust));
if (ctx->style.flags & DNS_STYLEFLAG_TRUST) {
if ((ctx->style.flags & DNS_STYLEFLAG_INDENT) != 0 ||
(ctx->style.flags & DNS_STYLEFLAG_YAML) != 0)
{
unsigned int j;
for (j = 0; j < dns_master_indent; j++)
fprintf(f, "%s", dns_master_indentstr);
}
fprintf(f, "; %s\n", dns_trust_totext(rds->trust));
}
if (((rds->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) &&
(ctx->style.flags & DNS_STYLEFLAG_NCACHE) == 0) {
/* Omit negative cache entries */
......@@ -1008,10 +1045,14 @@ dump_rdatasets_text(isc_mem_t *mctx, dns_name_t *name,
memset(buf, 0, sizeof(buf));
isc_buffer_init(&b, buf, sizeof(buf) - 1);
dns_time64_totext((isc_uint64_t)rds->resign, &b);
fprintf(f, "%s; resign=%s\n",
(ctx->style.flags & DNS_STYLEFLAG_INDENT)
? dns_master_indentstr : "",
buf);
if ((ctx->style.flags & DNS_STYLEFLAG_INDENT) != 0 ||
(ctx->style.flags & DNS_STYLEFLAG_YAML) != 0)
{
unsigned int j;
for (j = 0; j < dns_master_indent; j++)
fprintf(f, "%s", dns_master_indentstr);
}
fprintf(f, "; resign=%s\n", buf);
}
dns_rdataset_disassociate(rds);
}
......@@ -2066,7 +2107,6 @@ dns_master_stylecreate2(dns_master_style_t **stylep, unsigned int flags,
style->line_length = line_length;
style->tab_width = tab_width;
style->split_width = split_width;
*stylep = style;
return (ISC_R_SUCCESS);
}
......
......@@ -80,8 +80,10 @@ hexdump(const char *msg, const char *msg2, void *base, size_t len) {
#define VALID_SECTION(s) (((s) >= DNS_SECTION_ANY) \
&& ((s) < DNS_SECTION_MAX))
#define ADD_STRING(b, s) {if (strlen(s) >= \
isc_buffer_availablelength(b)) \
return(ISC_R_NOSPACE); else \
isc_buffer_availablelength(b)) { \
result = ISC_R_NOSPACE; \
goto cleanup; \
} else \
isc_buffer_putstr(b, s);}
#define VALID_PSEUDOSECTION(s) (((s) >= DNS_PSEUDOSECTION_ANY) \
&& ((s) < DNS_PSEUDOSECTION_MAX))
......@@ -3160,6 +3162,17 @@ dns_message_checksig(dns_message_t *msg, dns_view_t *view) {
}
}
#define INDENT(sp) \
do { \
unsigned int __i, __flags = dns_master_styleflags(sp); \
if ((__flags & DNS_STYLEFLAG_INDENT) == 0 && \
(__flags & DNS_STYLEFLAG_YAML) == 0) \
break; \
for (__i = 0; __i < dns_master_indent; __i++) { \
ADD_STRING(target, dns_master_indentstr); \
} \
} while (0)
isc_result_t
dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
const dns_master_style_t *style,
......@@ -3167,20 +3180,29 @@ dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
isc_buffer_t *target) {
dns_name_t *name, empty_name;
dns_rdataset_t *rdataset;
isc_result_t result;
isc_result_t result = ISC_R_SUCCESS;
isc_boolean_t seensoa = ISC_FALSE;
unsigned int sflags = dns_master_styleflags(style);
unsigned int sflags, saveindent;
REQUIRE(DNS_MESSAGE_VALID(msg));
REQUIRE(target != NULL);
REQUIRE(VALID_SECTION(section));
saveindent = dns_master_indent;
sflags = dns_master_styleflags(style);
if (ISC_LIST_EMPTY(msg->sections[section]))
return (ISC_R_SUCCESS);
goto cleanup;
if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) {
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target, dns_master_indentstr);
INDENT(style);
if ((sflags & DNS_STYLEFLAG_YAML) != 0) {
if (msg->opcode != dns_opcode_update) {
ADD_STRING(target, sectiontext[section]);
} else {
ADD_STRING(target, updsectiontext[section]);
}
ADD_STRING(target, "_SECTION:\n");
} else if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) {
ADD_STRING(target, ";; ");
if (msg->opcode != dns_opcode_update) {
ADD_STRING(target, sectiontext[section]);
......@@ -3193,7 +3215,10 @@ dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
dns_name_init(&empty_name, NULL);
result = dns_message_firstname(msg, section);
if (result != ISC_R_SUCCESS) {
return (result);
goto cleanup;
}
if ((sflags & DNS_STYLEFLAG_YAML) != 0) {
dns_master_indent++;
}
do {
name = NULL;
......@@ -3211,10 +3236,12 @@ dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
seensoa = ISC_TRUE;
}
if (section == DNS_SECTION_QUESTION) {
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target,
dns_master_indentstr);
ADD_STRING(target, ";");
INDENT(style);
if ((sflags & DNS_STYLEFLAG_YAML) != 0) {
ADD_STRING(target, "- ");
} else {
ADD_STRING(target, ";");
}
result = dns_master_questiontotext(name,
rdataset,
style,
......@@ -3226,18 +3253,25 @@ dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
target);
}
if (result != ISC_R_SUCCESS)
return (result);
goto cleanup;
}
result = dns_message_nextname(msg, section);
} while (result == ISC_R_SUCCESS);
if ((sflags & DNS_STYLEFLAG_YAML) != 0) {
dns_master_indent--;
}
if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 &&
(flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) {
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target, dns_master_indentstr);
(flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0 &&
(sflags & DNS_STYLEFLAG_YAML) == 0)
{
INDENT(style);
ADD_STRING(target, "\n");
}
if (result == ISC_R_NOMORE)
result = ISC_R_SUCCESS;
cleanup:
dns_master_indent = saveindent;
return (result);
}
......@@ -3247,6 +3281,7 @@ render_ecs(isc_buffer_t *ecsbuf, isc_buffer_t *target) {
char addr[16], addr_text[64];
isc_uint16_t family;
isc_uint8_t addrlen, addrbytes, scopelen;
isc_result_t result;
/*
* Note: This routine needs to handle malformed ECS options.
......@@ -3293,7 +3328,256 @@ render_ecs(isc_buffer_t *ecsbuf, isc_buffer_t *target) {