Skip to content

transport: introduce Bind trait and move orig dst to the type level#957

Merged
hawkw merged 34 commits intomainfrom
eliza/orig-dst-layer
Mar 31, 2021
Merged

transport: introduce Bind trait and move orig dst to the type level#957
hawkw merged 34 commits intomainfrom
eliza/orig-dst-layer

Conversation

@hawkw
Copy link
Contributor

@hawkw hawkw commented Mar 25, 2021

This branch introduces a new transport::listen::Bind trait that
abstracts over binding and listening on a socket. Now, rather than
owning an instance of the BindTcp type, ServerConfigs are passed as
a parameter to a type implementing the Bind trait. This will
eventually allow end-to-end testing without creating actual TCP sockets,
as Bind produces a Stream of an IO type and an Addrs type.

PR #955 changed the proxy stacks to be a target type which implements
the Param trait for various types of address, rather than a fixed
type. This PR also changes the inbound and outbound proxies to take
targets which implement Param<OrigDstAddr>, rather than requiring
Param<Option<OrigDstAddr>> and punting fallibility to every point
where original dst addresses are used.

The BindTcp type is now generic over a more general GetAddrs trait,
rather than a SO_ORIGINAL_DST-specific OrigDstAddr trait. Rather
than always producing a listen::Addrs with an Option<OrigDstAddr>,
we now produce a variable addresses type, which may or may not incldue
the original destination address (the admin and tap servers don't
require SO_ORIGINAL_DST). This allows whether or not original
destination addresses are included to be determined at compile time
rather than at runtime.

Finally, the incorrect feature flagging of mock original destination
addresses has been fixed, The "mock-orig-dst" feature has been removed,
and the integration tests now simply construct their own mock GetAddrs
function that's used to configure the test proxy. In the future, we
should be able to refactor the tests to avoid this by simply passing in
their own mock Bind types which produce streams of in-memory mock
connections, rather than actual TCP connections.

hawkw added 13 commits March 23, 2021 14:37
Signed-off-by: Eliza Weisman <[email protected]>
Signed-off-by: Eliza Weisman <[email protected]>
Signed-off-by: Eliza Weisman <[email protected]>
Signed-off-by: Eliza Weisman <[email protected]>
Signed-off-by: Eliza Weisman <[email protected]>
Signed-off-by: Eliza Weisman <[email protected]>
Signed-off-by: Eliza Weisman <[email protected]>
Signed-off-by: Eliza Weisman <[email protected]>
Signed-off-by: Eliza Weisman <[email protected]>
Signed-off-by: Eliza Weisman <[email protected]>
Signed-off-by: Eliza Weisman <[email protected]>
@hawkw hawkw changed the title [WIP] factor out SO_ORIGINAL_DST detection into a stack layer factor out SO_ORIGINAL_DST detection into a stack layer Mar 26, 2021
@hawkw hawkw marked this pull request as ready for review March 26, 2021 18:46
@hawkw hawkw requested a review from a team March 26, 2021 18:46
This fixes telemetry tests expecting the address to be 127.0.0.1:0 (which
worked on my machine, for whatever reason?).

Signed-off-by: Eliza Weisman <[email protected]>
Copy link
Member

@olix0r olix0r left a comment

Choose a reason for hiding this comment

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

I need to give this a deeper read through, but my first impression is that we really should not need a GetAddrs trait to be exposed to all of the stacks... I.e., we should keep the same general signature for the stacks that they are constructed with a parameterized target and we shouldn't have to have all of the address filtering business in every stack.

hawkw added 8 commits March 29, 2021 11:27
Signed-off-by: Eliza Weisman <[email protected]>
Signed-off-by: Eliza Weisman <[email protected]>
Signed-off-by: Eliza Weisman <[email protected]>
how the HECK did i manage to break that, wtf??

Signed-off-by: Eliza Weisman <[email protected]>
Signed-off-by: Eliza Weisman <[email protected]>
+ Param<OrigDstAddr>
+ Clone
+ Send,
B::Io: io::Peek + io::PeerAddr + Debug + Unpin,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

we could avoid having to write these bounds out in as many places by just making them into bounds on the definition of the Bind trait, since it turns out everything requires these traits as well. I wasn't sure if it was worth making the trait definition more restrictive or not...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

also, we could try to figure out a way to get rid of the PeerAddr trait and just get client addresses from the target always. IDK if this matters or is worth doing...

Copy link
Member

Choose a reason for hiding this comment

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

we need peeraddr for now at least, as the http server marks extensions with the client addr, but we can't have the http server created per-client (since we may need to do cached resolutions before this) -- so we'd either need to rework caching or have an Io type that supports extensions...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah, i took a look at that on Monday and i think that we're better off keeping it, and if we are going to get rid of it, that's out of scope for this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@olix0r 7b16586 moves all the bounds on the Bind::Io type to the Bind trait so they're not repeated everywhere else (and removes some of the Bind::Addrs bounds that the Bind trait already requires).

We could also put the Param<Local<ServerAddr>> and Param<Remote<ClientAddr>> bounds on Bind::Addrs so they aren't repeated, but it felt a little weird to see it require only Param<OrigDstAddr> at use-sites; i could go either way on this...

@hawkw hawkw changed the title factor out SO_ORIGINAL_DST detection into a stack layer transport: introduce Bind trait and move orig dst to the type level Mar 29, 2021
@hawkw hawkw requested a review from olix0r March 29, 2021 23:07
@olix0r
Copy link
Member

olix0r commented Mar 30, 2021

What does the mock-orig-dst feature do now? Is it necessary at all?

@hawkw
Copy link
Contributor Author

hawkw commented Mar 30, 2021

What does the mock-orig-dst feature do now? Is it necessary at all?

It just controls whether or not the MockOrigDstAddr type exists. Since it's only used in tests, I thought it was better to have that type only be enabled by the test crates when building tests, and not in the app build.

@olix0r
Copy link
Member

olix0r commented Mar 30, 2021

It just controls whether or not the MockOrigDstAddr type exists. Since it's only used in tests, I thought it was better to have that type only be enabled by the test crates when building tests, and not in the app build.

Can the type live in the test crate?

@hawkw
Copy link
Contributor Author

hawkw commented Mar 30, 2021

It just controls whether or not the MockOrigDstAddr type exists. Since it's only used in tests, I thought it was better to have that type only be enabled by the test crates when building tests, and not in the app build.

Can the type live in the test crate?

...yes, now i feel a bit silly for not thinking of that!

olix0r added 2 commits March 30, 2021 22:29
Making the config types generic over the orig-dst strategy promulgates
generics across all of the stacks. But the binding logic is only
necessary at the very "top" of the stack where the accept loop is
driven.

This change eliminates the `GetAddrs` trait and modifies the `Bind`
trait to take params that allow the binding implementation to be
configured (i.e., from the environment). `OrigDstAddr` binding is
provided as a `Bind` implementation that wraps the `BindTcp` strategy.

This lets us eliminate the `mock-orig-dst` feature by moving the
`MockOrigDst` helpers into the integration test suite.
@olix0r
Copy link
Member

olix0r commented Mar 31, 2021

@hawkw I tried hacking together #962 on top of this to remove the orig-dst constraints from the config types, which hopefully simplifies things a bit.

Comment on lines -35 to -36
# may be set to `mock-orig-dst` for profiling builds, or to `multithreaded` to
# enable the multithreaded Tokio runtime.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I removed this part of the comment since the mock-orig-dst feature is now removed and the multithreaded feature is enabled by default.

@hawkw
Copy link
Contributor Author

hawkw commented Mar 31, 2021

It just controls whether or not the MockOrigDstAddr type exists. Since it's only used in tests, I thought it was better to have that type only be enabled by the test crates when building tests, and not in the app build.

Can the type live in the test crate?

...yes, now i feel a bit silly for not thinking of that!

@olix0r removed the feature flag in 97b9590, good call!

hawkw and others added 7 commits March 31, 2021 10:31
Signed-off-by: Eliza Weisman <[email protected]>
Signed-off-by: Eliza Weisman <[email protected]>

; Conflicts:
;	linkerd/app/integration/src/proxy.rs
;	linkerd/app/src/admin.rs
;	linkerd/app/src/env.rs
;	linkerd/app/src/lib.rs
;	linkerd/proxy/transport/Cargo.toml
;	linkerd/proxy/transport/src/listen.rs
Signed-off-by: Eliza Weisman <[email protected]>
Comment on lines +68 to +75
let incoming = incoming.map(|res| {
let (inner, tcp) = res?;
let orig_dst = orig_dst_addr(&tcp)?;
let addrs = Addrs { inner, orig_dst };
Ok((addrs, tcp))
});

Ok((addr, Box::pin(incoming)))
Copy link
Member

Choose a reason for hiding this comment

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

btw, I tried to get rid of the box, but this closure captures B (types -- not values) so we get a expected fn pointer found closure compiler error. if you know of a way to avoid the box, by all means...

@hawkw hawkw merged commit 07e9249 into main Mar 31, 2021
@hawkw hawkw deleted the eliza/orig-dst-layer branch March 31, 2021 21:30
olix0r added a commit to linkerd/linkerd2 that referenced this pull request Apr 7, 2021
This release fixes a caching issue in the outbound proxy's "ingress
mode" that could cause the incorrect client to be used for requests.
This caching has been fixed so that clients cannot be incorrectly reused
across logical destinations.

---

* transport: introduce Bind trait and move orig dst to the type level (linkerd/linkerd2-proxy#957)
* Initial fuzzer integration (linkerd/linkerd2-proxy#961)
* Fix caching in ingress mode (linkerd/linkerd2-proxy#965)
olix0r added a commit to linkerd/linkerd2 that referenced this pull request Apr 7, 2021
This release fixes a caching issue in the outbound proxy's "ingress
mode" that could cause the incorrect client to be used for requests.
This caching has been fixed so that clients cannot be incorrectly reused
across logical destinations.

---

* transport: introduce Bind trait and move orig dst to the type level (linkerd/linkerd2-proxy#957)
* Initial fuzzer integration (linkerd/linkerd2-proxy#961)
* Fix caching in ingress mode (linkerd/linkerd2-proxy#965)
Pothulapati pushed a commit to linkerd/linkerd2 that referenced this pull request Apr 14, 2021
This release fixes a caching issue in the outbound proxy's "ingress
mode" that could cause the incorrect client to be used for requests.
This caching has been fixed so that clients cannot be incorrectly reused
across logical destinations.

---

* transport: introduce Bind trait and move orig dst to the type level (linkerd/linkerd2-proxy#957)
* Initial fuzzer integration (linkerd/linkerd2-proxy#961)
* Fix caching in ingress mode (linkerd/linkerd2-proxy#965)
jijeesh pushed a commit to jijeesh/linkerd2 that referenced this pull request Apr 21, 2021
This release fixes a caching issue in the outbound proxy's "ingress
mode" that could cause the incorrect client to be used for requests.
This caching has been fixed so that clients cannot be incorrectly reused
across logical destinations.

---

* transport: introduce Bind trait and move orig dst to the type level (linkerd/linkerd2-proxy#957)
* Initial fuzzer integration (linkerd/linkerd2-proxy#961)
* Fix caching in ingress mode (linkerd/linkerd2-proxy#965)

Signed-off-by: Jijeesh <[email protected]>
kleimkuhler pushed a commit to linkerd/linkerd2 that referenced this pull request May 12, 2021
This release fixes a caching issue in the outbound proxy's "ingress
mode" that could cause the incorrect client to be used for requests.
This caching has been fixed so that clients cannot be incorrectly reused
across logical destinations.

---

* transport: introduce Bind trait and move orig dst to the type level (linkerd/linkerd2-proxy#957)
* Initial fuzzer integration (linkerd/linkerd2-proxy#961)
* Fix caching in ingress mode (linkerd/linkerd2-proxy#965)
kleimkuhler pushed a commit to linkerd/linkerd2 that referenced this pull request May 12, 2021
This release fixes a caching issue in the outbound proxy's "ingress
mode" that could cause the incorrect client to be used for requests.
This caching has been fixed so that clients cannot be incorrectly reused
across logical destinations.

---

* transport: introduce Bind trait and move orig dst to the type level (linkerd/linkerd2-proxy#957)
* Initial fuzzer integration (linkerd/linkerd2-proxy#961)
* Fix caching in ingress mode (linkerd/linkerd2-proxy#965)
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.

2 participants