Commit d0bc45be authored by Ondřej Surý's avatar Ondřej Surý
Browse files

Merge branch...

Merge branch '1354-threadsanitizer-data-race-message-c-3283-in-dns_message_sectiontotext' into 'master'

Resolve "ThreadSanitizer: data race message.c:3283 in dns_message_sectiontotext"

Closes #1354

See merge request !2578
parents caf18da7 f269585d
Pipeline #26423 passed with stages
in 1 minute and 13 seconds
......@@ -498,14 +498,17 @@ printdata(dns_rdataset_t *rdataset, dns_name_t *owner,
dns_rdata_reset(&rdata);
}
} else {
dns_indent_t indent = { " ", 2 };
if (!yaml && (rdataset->attributes &
DNS_RDATASETATTR_NEGATIVE) != 0)
{
isc_buffer_putstr(&target, "; ");
}
result = dns_master_rdatasettotext(owner, rdataset,
style, &target);
style,
yaml ? &indent :
NULL,
&target);
}
if (result == ISC_R_NOSPACE) {
......@@ -537,8 +540,6 @@ setup_style(dns_master_style_t **stylep) {
styleflags |= DNS_STYLEFLAG_REL_OWNER;
if (yaml) {
styleflags |= DNS_STYLEFLAG_YAML;
dns_master_indentstr = " ";
dns_master_indent = 2;
} else {
if (showcomments) {
styleflags |= DNS_STYLEFLAG_COMMENT;
......
......@@ -487,8 +487,8 @@ printmessage(dig_query_t *query, const isc_buffer_t *msgbuf,
styleflags |= DNS_STYLEFLAG_REL_OWNER;
if (yaml) {
dns_master_indentstr = " ";
dns_master_indent = 3;
msg->indent.string = " ";
msg->indent.count = 3;
styleflags |= DNS_STYLEFLAG_YAML;
} else {
if (query->lookup->comments) {
......
......@@ -372,7 +372,7 @@ formatset(dns_rdataset_t *rdataset) {
result = isc_buffer_allocate(mctx, &buf, MAX_CDS_RDATA_TEXT_SIZE);
check_result(result, "printing DS records");
result = dns_master_rdatasettotext(name, rdataset, style, buf);
result = dns_master_rdatasettotext(name, rdataset, style, NULL, buf);
if ((result == ISC_R_SUCCESS) && isc_buffer_availablelength(buf) < 1) {
result = ISC_R_NOSPACE;
......
......@@ -246,7 +246,8 @@ dumpnode(dns_name_t *name, dns_dbnode_t *node) {
for (;;) {
result = dns_master_rdatasettotext(name, &rds,
masterstyle, buffer);
masterstyle, NULL,
buffer);
if (result != ISC_R_NOSPACE)
break;
......
......@@ -752,6 +752,7 @@ if [ -x "$DIG" ] ; then
status=$((status+ret))
fi
n=$((n+1))
echo_i "check that dig +unexpected works ($n)"
ret=0
dig_with_opts @10.53.0.6 +unexpected a a.example > dig.out.test$n || ret=1
......
......@@ -291,6 +291,8 @@ print_yaml(dns_dtdata_t *dt) {
}
if (dt->msg != NULL) {
dt->msg->indent.count = 2;
dt->msg->indent.string = " ";
printf(" %s:\n", ((dt->type & DNS_DTTYPE_QUERY) != 0)
? "query_message_data"
: "response_message_data");
......@@ -327,8 +329,6 @@ main(int argc, char *argv[]) {
break;
case 'y':
yaml = true;
dns_master_indentstr = " ";
dns_master_indent = 2;
break;
default:
usage();
......
......@@ -248,9 +248,9 @@ recvresponse(isc_task_t *task, isc_event_t *event) {
styleflags |= DNS_STYLEFLAG_REL_OWNER;
if (yaml) {
dns_master_indentstr = " ";
dns_master_indent = 3;
styleflags |= DNS_STYLEFLAG_YAML;
response->indent.string = " ";
response->indent.count = 3;
} else {
if (display_comments) {
styleflags |= DNS_STYLEFLAG_COMMENT;
......
......@@ -165,8 +165,7 @@ LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_debug;
LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_comment;
/*%
* Similar to dns_master_style_debug but data is indented with
* dns_master_indentstr (defaults to tab).
* Similar to dns_master_style_debug but data is indented with "\t" (tab)
*/
LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_indent;
......@@ -180,27 +179,6 @@ LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_keyzone;
*/
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 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
***/
......@@ -341,7 +319,7 @@ isc_result_t
dns_master_rdatasettotext(const dns_name_t *owner_name,
dns_rdataset_t *rdataset,
const dns_master_style_t *style,
isc_buffer_t *target);
dns_indent_t *indent, isc_buffer_t *target);
/*%<
* Convert 'rdataset' to text format, storing the result in 'target'.
*
......
......@@ -269,6 +269,8 @@ struct dns_message {
dns_rdatasetorderfunc_t order;
dns_sortlist_arg_t order_arg;
dns_indent_t indent;
};
struct dns_ednsopt {
......
......@@ -388,6 +388,11 @@ typedef enum {
dns_stale_answer_conf
} dns_stale_answer_t;
typedef struct {
const char *string;
size_t count;
} dns_indent_t;
/*
* Functions.
*/
......
......@@ -98,6 +98,7 @@ typedef struct dns_totext_ctx {
uint32_t current_ttl;
bool current_ttl_valid;
dns_ttl_t serve_stale_ttl;
dns_indent_t indent;
} dns_totext_ctx_t;
LIBDNS_EXTERNAL_DATA const dns_master_style_t
......@@ -175,7 +176,7 @@ dns_master_style_debug = {
};
/*%
* Similar, but indented (i.e., prepended with dns_master_indentstr).
* Similar, but indented (i.e., prepended with indentctx.string).
*/
LIBDNS_EXTERNAL_DATA const dns_master_style_t
dns_master_style_indent = {
......@@ -207,12 +208,6 @@ dns_master_style_yaml = {
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] = " ";
......@@ -251,6 +246,9 @@ struct dns_dumpctx {
#define NXDOMAIN(x) (((x)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
static const dns_indent_t default_indent = { "\t", 1 };
static const dns_indent_t default_yamlindent = { " ", 1 };
/*%
* Output tabs and spaces to go from column '*current' to
* column 'to', and update '*current' to reflect the new
......@@ -317,11 +315,21 @@ indent(unsigned int *current, unsigned int to, int tabwidth,
}
static isc_result_t
totext_ctx_init(const dns_master_style_t *style, dns_totext_ctx_t *ctx) {
totext_ctx_init(const dns_master_style_t *style, const dns_indent_t *indentctx,
dns_totext_ctx_t *ctx)
{
isc_result_t result;
REQUIRE(style->tab_width != 0);
if (indentctx == NULL) {
if ((style->flags & DNS_STYLEFLAG_YAML) != 0) {
indentctx = &default_yamlindent;
} else {
indentctx = &default_indent;
}
}
ctx->style = *style;
ctx->class_printed = false;
......@@ -347,11 +355,11 @@ totext_ctx_init(const dns_master_style_t *style, dns_totext_ctx_t *ctx) {
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++) {
unsigned int i, len = strlen(indentctx->string);
for (i = 0; i < indentctx->count; i++) {
if (isc_buffer_availablelength(&buf) < len)
return (DNS_R_TEXTTOOLONG);
isc_buffer_putstr(&buf, dns_master_indentstr);
isc_buffer_putstr(&buf, indentctx->string);
}
}
......@@ -392,6 +400,7 @@ totext_ctx_init(const dns_master_style_t *style, dns_totext_ctx_t *ctx) {
ctx->current_ttl = 0;
ctx->current_ttl_valid = false;
ctx->serve_stale_ttl = 0;
ctx->indent = indentctx ? *indentctx : default_indent;
return (ISC_R_SUCCESS);
}
......@@ -445,8 +454,8 @@ ncache_summary(dns_rdataset_t *rdataset, bool omit_final_dot,
(ctx->style.flags & DNS_STYLEFLAG_YAML) != 0)
{
unsigned int i;
for (i = 0; i < dns_master_indent; i++) {
CHECK(str_totext(dns_master_indentstr,
for (i = 0; i < ctx->indent.count; i++) {
CHECK(str_totext(ctx->indent.string,
target));
}
}
......@@ -534,8 +543,8 @@ rdataset_totext(dns_rdataset_t *rdataset,
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,
for (i = 0; i < ctx->indent.count; i++)
RETERR(str_totext(ctx->indent.string,
target));
}
......@@ -801,7 +810,7 @@ dns_rdataset_totext(dns_rdataset_t *rdataset,
{
dns_totext_ctx_t ctx;
isc_result_t result;
result = totext_ctx_init(&dns_master_style_debug, &ctx);
result = totext_ctx_init(&dns_master_style_debug, NULL, &ctx);
if (result != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"could not set master file style");
......@@ -829,11 +838,11 @@ isc_result_t
dns_master_rdatasettotext(const dns_name_t *owner_name,
dns_rdataset_t *rdataset,
const dns_master_style_t *style,
isc_buffer_t *target)
dns_indent_t *indent, isc_buffer_t *target)
{
dns_totext_ctx_t ctx;
isc_result_t result;
result = totext_ctx_init(style, &ctx);
result = totext_ctx_init(style, indent, &ctx);
if (result != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"could not set master file style");
......@@ -852,7 +861,7 @@ dns_master_questiontotext(const dns_name_t *owner_name,
{
dns_totext_ctx_t ctx;
isc_result_t result;
result = totext_ctx_init(style, &ctx);
result = totext_ctx_init(style, NULL, &ctx);
if (result != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"could not set master file style");
......@@ -1039,8 +1048,8 @@ dump_rdatasets_text(isc_mem_t *mctx, const dns_name_t *name,
(ctx->style.flags & DNS_STYLEFLAG_YAML) != 0)
{
unsigned int j;
for (j = 0; j < dns_master_indent; j++)
fprintf(f, "%s", dns_master_indentstr);
for (j = 0; j < ctx->indent.count; j++)
fprintf(f, "%s", ctx->indent.string);
}
fprintf(f, "; %s\n", dns_trust_totext(rds->trust));
}
......@@ -1072,8 +1081,8 @@ dump_rdatasets_text(isc_mem_t *mctx, const dns_name_t *name,
(ctx->style.flags & DNS_STYLEFLAG_YAML) != 0)
{
unsigned int j;
for (j = 0; j < dns_master_indent; j++)
fprintf(f, "%s", dns_master_indentstr);
for (j = 0; j < ctx->indent.count; j++)
fprintf(f, "%s", ctx->indent.string);
}
fprintf(f, "; resign=%s\n", buf);
}
......@@ -1493,7 +1502,7 @@ dumpctx_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
ISC_UNREACHABLE();
}
result = totext_ctx_init(style, &dctx->tctx);
result = totext_ctx_init(style, NULL, &dctx->tctx);
if (result != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"could not set master file style");
......@@ -1935,7 +1944,7 @@ dns_master_dumpnodetostream(isc_mem_t *mctx, dns_db_t *db,
dns_totext_ctx_t ctx;
dns_rdatasetiter_t *rdsiter = NULL;
result = totext_ctx_init(style, &ctx);
result = totext_ctx_init(style, NULL, &ctx);
if (result != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"could not set master file style");
......
......@@ -428,6 +428,8 @@ msginit(dns_message_t *m) {
m->tkey = 0;
m->rdclass_set = 0;
m->querytsig = NULL;
m->indent.string = "\t";
m->indent.count = 0;
}
static inline void
......@@ -3259,8 +3261,8 @@ dns_message_checksig(dns_message_t *msg, dns_view_t *view) {
if ((__flags & DNS_STYLEFLAG_INDENT) == 0ULL && \
(__flags & DNS_STYLEFLAG_YAML) == 0ULL) \
break; \
for (__i = 0; __i < dns_master_indent; __i++) { \
ADD_STRING(target, dns_master_indentstr); \
for (__i = 0; __i < msg->indent.count; __i++) { \
ADD_STRING(target, msg->indent.string); \
} \
} while (0)
......@@ -3268,23 +3270,26 @@ isc_result_t
dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
const dns_master_style_t *style,
dns_messagetextflag_t flags,
isc_buffer_t *target) {
isc_buffer_t *target)
{
dns_name_t *name, empty_name;
dns_rdataset_t *rdataset;
isc_result_t result = ISC_R_SUCCESS;
bool seensoa = false;
unsigned int saveindent;
size_t saved_count;
dns_masterstyle_flags_t sflags;
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]))
saved_count = msg->indent.count;
if (ISC_LIST_EMPTY(msg->sections[section])) {
goto cleanup;
}
sflags = dns_master_styleflags(style);
INDENT(style);
if ((sflags & DNS_STYLEFLAG_YAML) != 0) {
......@@ -3310,7 +3315,7 @@ dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
goto cleanup;
}
if ((sflags & DNS_STYLEFLAG_YAML) != 0) {
dns_master_indent++;
msg->indent.count++;
}
do {
name = NULL;
......@@ -3342,6 +3347,7 @@ dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
result = dns_master_rdatasettotext(name,
rdataset,
style,
&msg->indent,
target);
}
if (result != ISC_R_SUCCESS)
......@@ -3350,7 +3356,7 @@ dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
result = dns_message_nextname(msg, section);
} while (result == ISC_R_SUCCESS);
if ((sflags & DNS_STYLEFLAG_YAML) != 0) {
dns_master_indent--;
msg->indent.count--;
}
if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 &&
(flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0 &&
......@@ -3363,7 +3369,7 @@ dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
result = ISC_R_SUCCESS;
cleanup:
dns_master_indent = saveindent;
msg->indent.count = saved_count;
return (result);
}
......@@ -3479,13 +3485,15 @@ dns_message_pseudosectiontoyaml(dns_message_t *msg,
dns_rdata_t rdata;
isc_buffer_t optbuf;
uint16_t optcode, optlen;
size_t saved_count;
unsigned char *optdata;
unsigned int saveindent = dns_master_indent;
REQUIRE(DNS_MESSAGE_VALID(msg));
REQUIRE(target != NULL);
REQUIRE(VALID_PSEUDOSECTION(section));
saved_count = msg->indent.count;
switch (section) {
case DNS_PSEUDOSECTION_OPT:
ps = dns_message_getopt(msg);
......@@ -3495,11 +3503,11 @@ dns_message_pseudosectiontoyaml(dns_message_t *msg,
INDENT(style);
ADD_STRING(target, "OPT_PSEUDOSECTION:\n");
dns_master_indent++;
msg->indent.count++;
INDENT(style);
ADD_STRING(target, "EDNS:\n");
dns_master_indent++;
msg->indent.count++;
INDENT(style);
ADD_STRING(target, "version: ");
......@@ -3747,7 +3755,8 @@ dns_message_pseudosectiontoyaml(dns_message_t *msg,
}
INDENT(style);
ADD_STRING(target, "TSIG_PSEUDOSECTION:\n");
result = dns_master_rdatasettotext(name, ps, style, target);
result = dns_master_rdatasettotext(name, ps, style,
&msg->indent, target);
ADD_STRING(target, "\n");
goto cleanup;
case DNS_PSEUDOSECTION_SIG0:
......@@ -3758,7 +3767,8 @@ dns_message_pseudosectiontoyaml(dns_message_t *msg,
}
INDENT(style);
ADD_STRING(target, "SIG0_PSEUDOSECTION:\n");
result = dns_master_rdatasettotext(name, ps, style, target);
result = dns_master_rdatasettotext(name, ps, style,
&msg->indent, target);
if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 &&
(flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0)
ADD_STRING(target, "\n");
......@@ -3768,7 +3778,7 @@ dns_message_pseudosectiontoyaml(dns_message_t *msg,
result = ISC_R_UNEXPECTED;
cleanup:
dns_master_indent = saveindent;
msg->indent.count = saved_count;
return (result);
}
......@@ -3793,9 +3803,11 @@ dns_message_pseudosectiontotext(dns_message_t *msg,
REQUIRE(target != NULL);
REQUIRE(VALID_PSEUDOSECTION(section));
if ((dns_master_styleflags(style) & DNS_STYLEFLAG_YAML) != 0)
if ((dns_master_styleflags(style) & DNS_STYLEFLAG_YAML) != 0) {
return (dns_message_pseudosectiontoyaml(msg, section, style,
flags, target));
}
switch (section) {
case DNS_PSEUDOSECTION_OPT:
ps = dns_message_getopt(msg);
......@@ -4039,7 +4051,8 @@ dns_message_pseudosectiontotext(dns_message_t *msg,
INDENT(style);
if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0)
ADD_STRING(target, ";; TSIG PSEUDOSECTION:\n");
result = dns_master_rdatasettotext(name, ps, style, target);
result = dns_master_rdatasettotext(name, ps, style,
&msg->indent, target);
if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 &&
(flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0)
ADD_STRING(target, "\n");
......@@ -4051,7 +4064,8 @@ dns_message_pseudosectiontotext(dns_message_t *msg,
INDENT(style);
if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0)
ADD_STRING(target, ";; SIG0 PSEUDOSECTION:\n");
result = dns_master_rdatasettotext(name, ps, style, target);
result = dns_master_rdatasettotext(name, ps, style,
&msg->indent, target);
if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 &&
(flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0)
ADD_STRING(target, "\n");
......
......@@ -1086,7 +1086,7 @@ modrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
goto cleanup;
result = dns_master_rdatasettotext(sdlznode->name, rdataset,
style, buffer);
style, NULL, buffer);
if (result != ISC_R_SUCCESS)
goto cleanup;
......
......@@ -429,8 +429,8 @@ totext_test(void **state) {
assert_int_equal(result, ISC_R_SUCCESS);
isc_buffer_init(&target, buf, BIGBUFLEN);
result = dns_master_rdatasettotext(dns_rootname,
&rdataset, &dns_master_style_debug,
result = dns_master_rdatasettotext(dns_rootname, &rdataset,
&dns_master_style_debug, NULL,
&target);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(isc_buffer_usedlength(&target), 0);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment