Skip to content

Plugin dnstap: add support for "extra" field in payload#6226

Merged
yongtang merged 14 commits into
coredns:masterfrom
chenyuheng:master
Aug 14, 2023
Merged

Plugin dnstap: add support for "extra" field in payload#6226
yongtang merged 14 commits into
coredns:masterfrom
chenyuheng:master

Conversation

@chenyuheng

Copy link
Copy Markdown
Contributor

1. Why is this pull request needed and what does it do?

As proposed in #6092 , this PR adds supports to customize "extra" field in dnstap payload, the field could be set in the config file.

The "extra" field in defined in dnstap.proto.

2. Which issues (if any) are related?

#6092

3. Which documentation changes (if any) need to be made?

The plugin README: https://github.com/coredns/coredns/blob/master/plugin/dnstap/README.md

4. Does this introduce a backward incompatible change or deprecation?

No

Signed-off-by: chenyuheng <chenyuheng99@qq.com>
Signed-off-by: chenyuheng <chenyuheng99@qq.com>
Signed-off-by: chenyuheng <chenyuheng99@qq.com>
@chenyuheng chenyuheng requested a review from yongtang as a code owner July 25, 2023 21:29
Signed-off-by: chenyuheng <chenyuheng99@qq.com>
@chenyuheng

Copy link
Copy Markdown
Contributor Author

This comment shows the result of manually testting for this change.

Note that the current dnstap command line tool won't output "extra" field, so I tested this change with my edited dnstap command line tool, I will try to make another PR to update the change to the golang-dnstap repository later.

With Corefile:

.:8053 {
	dnstap /tmp/dnstap.sock {
		identity test_1
		version test0.1
		extra EXTRA_FIELD_TEST_233
	}
	forward . 8.8.8.8
}

The dnstap command line tool will have:

image

Comment thread plugin/dnstap/handler.go Outdated
Message: m,
Identity: h.Identity,
Version: h.Version,
Extra: h.Extra,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what you implemented here is assigning a preconfigured text to Extra (which can be useful as well), whereas #6092 suggests extracting and assigning value of preconfigured metadata label.

The metadata value is normally created by other plugin, e.g. if you specify label "forward/upstream", it is expected that plugin 'forward' should provide this value. The plugin which provides metadata can generate different values for different queries, and this is the key difference from what you have implemented.

Please get familiar with plugin metadata https://github.com/coredns/coredns/tree/master/plugin/metadata as well as the package https://github.com/coredns/coredns/tree/master/plugin/pkg/replacer which can make your work easier

I also recommend to look at plugins 'rewrite' and 'log' as examples of plugins which read metadata from other plugins.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your kind review! I have introduced the replacer package in my new commits.

Since the replacer requires context, status (request.Request) and rr (*dnstest.Recorder), I have added a new function called TapMessageWithMetadata to receive these context objects and process the metadata replacement accordingly.

The old function TapMessage has not been removed, as external plugins may have dependencies on it.

Comment thread plugin/dnstap/README.md Outdated
Signed-off-by: chenyuheng <chenyuheng99@qq.com>
Signed-off-by: chenyuheng <chenyuheng99@qq.com>

@rdrozhdzh rdrozhdzh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add also more unit tests to make sure the new functionality works as expected

Comment thread plugin/dnstap/README.md Outdated
Comment thread plugin/dnstap/README.md Outdated
Comment thread plugin/dnstap/handler.go Outdated

// TapMessageWithMetadata sends the message m to the dnstap interface, with "Extra" field being interpreted by the provided metadata context.
func (h Dnstap) TapMessageWithMetadata(m *tap.Message, ctx context.Context, state *request.Request, rr *dnstest.Recorder) {
func (h Dnstap) TapMessageWithMetadata(m *tap.Message, ctx context.Context, state request.Request, rr *dnstest.Recorder) {

@rdrozhdzh rdrozhdzh Jul 28, 2023

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest to remove the rr *dnstest.Recorder at all, and always pass nil to Replacer. I believe this parameter creates more inconveniences than benefits.

The recorder parameter is needed only for handling several standard labels like

// Recorded replacements.
case "{rcode}":
if rr == nil || rr.Msg == nil {
return append(b, EmptyValue...)
}
if rcode := dns.RcodeToString[rr.Rcode]; rcode != "" {
return append(b, rcode...)
}
return strconv.AppendInt(b, int64(rr.Rcode), 10)
case "{rsize}":
if rr == nil {
return append(b, EmptyValue...)
}
return strconv.AppendInt(b, int64(rr.Len), 10)
case "{duration}":
if rr == nil {
return append(b, EmptyValue...)
}
secs := time.Since(rr.Start).Seconds()
return append(strconv.AppendFloat(b, secs, 'f', -1, 64), 's')
case headerReplacer + "rflags}":
if rr != nil && rr.Msg != nil {
return appendFlags(b, rr.Msg.MsgHdr)
}
return append(b, EmptyValue...)

This code can safely work with nil, i.e. it will not panic.

The reason why it's not so important to support these DNS response labels (as well as other DNS labels) is because DNSTAP already provides an alternative standardized way for transferring this data.

Regarding parameter state, this is more commonly used data type, and we can keep it. This should not be a big problem for developers of other plugins to provide it. However, if we decide to not support the standard DNS labels (as explained above), we can eliminate this parameter as well. You can pass empty Request{} to the replacer (this needs to be tested with all standard labels to avoid panics)

The only important parameter here is Context, which provides access to metadata.

I would appreciate a feedback from community regarding support of standard DNS labels (do we really need them?) for DNSTAP extra section, i.e.

// labels are all supported labels that can be used in the default Replacer.
var labels = map[string]struct{}{
"{type}": {},
"{name}": {},
"{class}": {},
"{proto}": {},
"{size}": {},
"{remote}": {},
"{port}": {},
"{local}": {},
// Header values.
headerReplacer + "id}": {},
headerReplacer + "opcode}": {},
headerReplacer + "do}": {},
headerReplacer + "bufsize}": {},
// Recorded replacements.
"{rcode}": {},
"{rsize}": {},
"{duration}": {},
headerReplacer + "rflags}": {},
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I have updated these codes in my new commits. I will update the unit tests tomorrow.

For the state parameter, maybe we can just keep the function as:

func (h Dnstap) TapMessageWithMetadata(ctx context.Context, m *tap.Message, state request.Request) 

Leave the choice to plugin developers, if they think their plugins does not need to support these standard labels, they simply just pass the empty State{}

Comment thread plugin/forward/dnstap.go Outdated
Comment thread plugin/dnstap/handler.go Outdated
Signed-off-by: chenyuheng <chenyuheng99@qq.com>
Signed-off-by: chenyuheng <chenyuheng99@qq.com>
Signed-off-by: chenyuheng <chenyuheng99@qq.com>
@chenyuheng chenyuheng requested a review from stp-ip as a code owner July 28, 2023 19:38
Signed-off-by: chenyuheng <chenyuheng99@qq.com>
Signed-off-by: chenyuheng <chenyuheng99@qq.com>
@chenyuheng chenyuheng requested a review from rdrozhdzh July 30, 2023 01:13

@rdrozhdzh rdrozhdzh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general looks good, see minor comments

Comment thread plugin/dnstap/README.md Outdated
Comment thread plugin/dnstap/handler.go Outdated
Comment thread plugin/dnstap/handler.go Outdated
Comment thread plugin/dnstap/handler_test.go Outdated
Comment thread plugin/dnstap/handler_test.go Outdated
Comment thread plugin/dnstap/setup_test.go Outdated
Comment thread plugin/dnstap/writer.go Outdated
Comment thread plugin/pkg/replacer/replacer_test.go Outdated
Signed-off-by: chenyuheng <chenyuheng99@qq.com>
@codecov

codecov Bot commented Aug 1, 2023

Copy link
Copy Markdown

Codecov Report

Merging #6226 (74094f9) into master (93c57b6) will increase coverage by 2.67%.
Report is 1000 commits behind head on master.
The diff coverage is 61.52%.

@@            Coverage Diff             @@
##           master    #6226      +/-   ##
==========================================
+ Coverage   55.70%   58.37%   +2.67%     
==========================================
  Files         224      251      +27     
  Lines       10016    16418    +6402     
==========================================
+ Hits         5579     9584    +4005     
- Misses       3978     6247    +2269     
- Partials      459      587     +128     
Files Changed Coverage Δ
core/dnsserver/config.go 0.00% <ø> (ø)
core/dnsserver/register.go 13.27% <0.00%> (-4.71%) ⬇️
plugin/auto/auto.go 0.00% <0.00%> (ø)
plugin/auto/xfr.go 0.00% <0.00%> (ø)
plugin/auto/zone.go 78.94% <ø> (+0.68%) ⬆️
plugin/autopath/autopath.go 73.61% <ø> (-1.39%) ⬇️
plugin/azure/azure.go 10.61% <0.00%> (-0.57%) ⬇️
plugin/azure/setup.go 56.36% <0.00%> (-4.14%) ⬇️
plugin/backend_lookup.go 0.00% <0.00%> (ø)
plugin/bind/bind.go 50.00% <0.00%> (-50.00%) ⬇️
... and 78 more

... and 168 files with indirect coverage changes

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

Signed-off-by: chenyuheng <chenyuheng99@qq.com>
Comment thread plugin/dnstap/handler.go Outdated
Comment thread plugin/dnstap/writer.go Outdated
Comment thread plugin/pkg/replacer/replacer_test.go Outdated
Signed-off-by: chenyuheng <chenyuheng99@qq.com>

@rdrozhdzh rdrozhdzh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me

@yongtang yongtang merged commit 90d5561 into coredns:master Aug 14, 2023
@dmachard

Copy link
Copy Markdown
Contributor

@chenyuheng FYI the DNS-collector tool supports the extra field, any contributions will be appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants