Skip to content

ddtrace/tracer/textmap: Setting _dd.propagation_error tag on faulty context propagation#1969

Closed
dianashevchenko wants to merge 5 commits into
mainfrom
shevchenko/dd_propagation-error
Closed

ddtrace/tracer/textmap: Setting _dd.propagation_error tag on faulty context propagation#1969
dianashevchenko wants to merge 5 commits into
mainfrom
shevchenko/dd_propagation-error

Conversation

@dianashevchenko

Copy link
Copy Markdown
Contributor

What does this PR do?

This PR recognises faulty context propagation when dd_p.tid (TraceID) is inconsistent or malformed

  • wrong length
  • non-hex characters
  • isn't consistent with the traceID passed from traceParent (W3C case scenario)

Motivation

Describe how to test/QA your changes

Reviewer's Checklist

  • Changed code has unit tests for its functionality.
  • If this interacts with the agent in a new way, a system test has been added.

@dianashevchenko
dianashevchenko requested a review from a team May 9, 2023 09:55
@pr-commenter

pr-commenter Bot commented May 9, 2023

Copy link
Copy Markdown

Benchmarks

Comparing candidate commit 738be73 in PR branch shevchenko/dd_propagation-error with baseline commit c9996a7 in branch main.

Found 0 performance improvements and 0 performance regressions! Performance is the same for 18 metrics, 0 unstable metrics.

@ajgajg1134 ajgajg1134 changed the title Setting _dd.propagation_error tag on faulty context propagation ddtrace/tracer/textmap: Setting _dd.propagation_error tag on faulty context propagation May 10, 2023

@ajgajg1134 ajgajg1134 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

overall looks good! Just a few comments in the tests mainly

Comment thread ddtrace/tracer/textmap.go Outdated
}
if ctx.trace != nil {
if ctx.trace != nil && ctx.trace.propagatingTag(keyTraceID128) != "" {
// TODO: this always assumed it was valid so I copied that logic here, maybe we shouldn't

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

looks like we can remove this comment now?


func TestMalformedTIDPropagationErrorTag(t *testing.T) {
assert := assert.New(t)
t.Run("datadog", func(t *testing.T) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is there a more descriptive name for this and the next test?

Comment thread ddtrace/tracer/textmap_test.go Outdated
root := tracer.StartSpan("web.request", ChildOf(sctx)).(*span)
root.Finish()
assert.Contains(root.Meta, keyPropagationError)
assert.Equal(root.Meta[keyPropagationError], "malformed_tid XXXXXXXXXXXXXXXX")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
assert.Equal(root.Meta[keyPropagationError], "malformed_tid XXXXXXXXXXXXXXXX")
assert.Equal("malformed_tid XXXXXXXXXXXXXXXX", root.Meta[keyPropagationError])

Comment thread ddtrace/tracer/textmap_test.go Outdated
root := tracer.StartSpan("web.request", ChildOf(sctx)).(*span)
root.Finish()
assert.Contains(root.Meta, keyPropagationError)
assert.Equal(root.Meta[keyPropagationError], "inconsistent_tid 640cfd8d0000ffff")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
assert.Equal(root.Meta[keyPropagationError], "inconsistent_tid 640cfd8d0000ffff")
assert.Equal("inconsistent_tid 640cfd8d0000ffff", root.Meta[keyPropagationError])

Comment thread ddtrace/tracer/textmap_test.go Outdated
root := tracer.StartSpan("web.request", ChildOf(sctx)).(*span)
root.Finish()
assert.Contains(root.Meta, keyPropagationError)
assert.Equal(root.Meta[keyPropagationError], "malformed_tid XXXX")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
assert.Equal(root.Meta[keyPropagationError], "malformed_tid XXXX")
assert.Equal("malformed_tid XXXX", root.Meta[keyPropagationError])

assert := assert.New(t)
t.Run("datadog", func(t *testing.T) {
t.Setenv(headerPropagationStyleExtract, "datadog")
tracer := newTracer(WithPropagator(NewPropagator(nil)))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

defer tracer.Stop() in these tests to ensure we cleanup the goroutines started that are associated with them

Comment thread ddtrace/tracer/textmap.go Outdated
Comment on lines +389 to +391
if len(ctx.trace.propagatingTag(keyTraceID128)) != 16 {
ctx.trace.unsetPropagatingTag(keyTraceID128)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we do this below where we're doing the hex parsing instead? Checking the validity of keyTraceID128 in two places makes this a bit more complicated than it needs to be. Plus, we also want to unset this propagating tag if the hex is invalid, so the logic should be the same. Right now, we're still keeping the _dd.p.tid tag even if it's invalid hex, which isn't correct per the RFC:

if the tag value is a valid 32 character lower-case hexadecimal encoded number, set the higher-order 64 bits of the TraceId to its (decoded) value.
if the tag value is malformed, discard the tag value and, optionally, set the dd.propagation_error tag to:
malformed_tid + <_dd.p.tid value>

@dianashevchenko dianashevchenko May 12, 2023

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.

gotcha

Comment thread ddtrace/tracer/textmap.go Outdated
Comment on lines +957 to +963
if key == "t.tid" {
if ok := validIDRgx.MatchString(val); !ok {
ctx.trace.setTag(keyPropagationError, fmt.Sprintf("malformed_tid %s", val))
} else if val != ctx.traceID.UpperHex() {
ctx.trace.setTag(keyPropagationError, fmt.Sprintf("inconsistent_tid %s", val))
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

(From Slack convo) this is all optional, right? Based on the RFC and comments, it sounds like it's perfectly valid to just not propagate/use the _dd.p.tid tag when using W3C trace context propagation. If this is optional, then let's not do this unless we have a very compelling reason that it'll help customers. The code is already fairly complicated, so let's avoid doing more than we need to.

i.e. you can just add a continue right here instead if key == "t.tid" to not propagate it.

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.

I'm not sure I see what you mean. Is that what you suggest ? :

   if key == "t.tid" && (val != ctx.traceID.UpperHex() || (!validIDRgx.MatchString(val))) {
	continue
    }
     setPropagatingTag(key, val)

@ahmed-mez

Copy link
Copy Markdown
Contributor

We already shipped the fix in #2076 and decided to not add the _dd.propagation_error tag so I'm closing this PR.

@ahmed-mez ahmed-mez closed this Jun 29, 2023
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