-
Notifications
You must be signed in to change notification settings - Fork 712
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix a subtle bug in render mapping #339
Merged
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Worth checking if Also, worth a unit test for the map fns? |
peterbourgon
added a commit
that referenced
this pull request
Jul 31, 2015
Another implicit invariant in the data model is that edges are always of the form (local -> remote). That is, the source of an edge must always be a node that originates from within Scope's domain of visibility. This was evident by the presence of ingress and egress fields in edge/aggregate metadata. When building the sniffer, I accidentally and incorrectly violated this invariant, by constructing distinct edges for (local -> remote) and (remote -> local), and collapsing ingress and egress byte counts to a single scalar. I experienced a variety of subtle undefined behavior as a result. See #339. This change reverts to the old, correct methodology. Consequently the sniffer needs to be able to find out which side of the sniffed packet is local v. remote, and to do that it needs access to local networks. I moved the discovery from the probe/host package into probe/main.go. As part of that work I discovered that package report also maintains its own, independent "cache" of local networks. Except it contains only the (optional) Docker bridge network, if it's been populated by the probe, and it's only used by the report.Make{Endpoint,Address}NodeID constructors to scope local addresses. Normally, scoping happens during rendering, and only for pseudo nodes -- see current LeafMap Render localNetworks. This is pretty convoluted and should be either be made consistent or heavily commented.
peterbourgon
added a commit
that referenced
this pull request
Jul 31, 2015
Another implicit invariant in the data model is that edges are always of the form (local -> remote). That is, the source of an edge must always be a node that originates from within Scope's domain of visibility. This was evident by the presence of ingress and egress fields in edge/aggregate metadata. When building the sniffer, I accidentally and incorrectly violated this invariant, by constructing distinct edges for (local -> remote) and (remote -> local), and collapsing ingress and egress byte counts to a single scalar. I experienced a variety of subtle undefined behavior as a result. See #339. This change reverts to the old, correct methodology. Consequently the sniffer needs to be able to find out which side of the sniffed packet is local v. remote, and to do that it needs access to local networks. I moved the discovery from the probe/host package into probe/main.go. As part of that work I discovered that package report also maintains its own, independent "cache" of local networks. Except it contains only the (optional) Docker bridge network, if it's been populated by the probe, and it's only used by the report.Make{Endpoint,Address}NodeID constructors to scope local addresses. Normally, scoping happens during rendering, and only for pseudo nodes -- see current LeafMap Render localNetworks. This is pretty convoluted and should be either be made consistent or heavily commented.
peterbourgon
added a commit
that referenced
this pull request
Jul 31, 2015
Another implicit invariant in the data model is that edges are always of the form (local -> remote). That is, the source of an edge must always be a node that originates from within Scope's domain of visibility. This was evident by the presence of ingress and egress fields in edge/aggregate metadata. When building the sniffer, I accidentally and incorrectly violated this invariant, by constructing distinct edges for (local -> remote) and (remote -> local), and collapsing ingress and egress byte counts to a single scalar. I experienced a variety of subtle undefined behavior as a result. See #339. This change reverts to the old, correct methodology. Consequently the sniffer needs to be able to find out which side of the sniffed packet is local v. remote, and to do that it needs access to local networks. I moved the discovery from the probe/host package into probe/main.go. As part of that work I discovered that package report also maintains its own, independent "cache" of local networks. Except it contains only the (optional) Docker bridge network, if it's been populated by the probe, and it's only used by the report.Make{Endpoint,Address}NodeID constructors to scope local addresses. Normally, scoping happens during rendering, and only for pseudo nodes -- see current LeafMap Render localNetworks. This is pretty convoluted and should be either be made consistent or heavily commented.
A NodeMetadata with a nil Metadata field is always invalid. I've added that constraint to the topology validator.
👍 |
During rendering, RenderableNodes are created by Map funcs, which take only NodeMetadata. Previously, it was simply assumed that the relevant keys for a given Map func would be present in the metadata. If that implicit invariant failed, the returned RenderableNode would be invalid, with e.g. an ID of "hostid::". That, in turn, would trigger undefined behavior later on in the rendering workflow. This bug was detected by creating a partial node metadata for a non-local endpoint node. That node was detected during the first phase of rendering, and given an invalid renderable node ID of "myhostname::", which prevented it from attaching to TheInternet pseudonode. It eventually got removed from the set of valid nodes, which meant nodes that were adjacent to it suddenly became orphans, and got filtered out by the FilterUnconnected step of the rendering pipeline. With this change, every map func checks for the presence of mandatory fields, i.e. the fields that compose the resulting renderable node's ID. Also, - Add unit tests for LeafMapFuncs - Topology Validate checks NodeMetadatas must not have nil Metadata
ea63606
to
b3868c5
Compare
peterbourgon
added a commit
that referenced
this pull request
Aug 3, 2015
Fix a subtle bug in render mapping
peterbourgon
added a commit
that referenced
this pull request
Aug 3, 2015
Another implicit invariant in the data model is that edges are always of the form (local -> remote). That is, the source of an edge must always be a node that originates from within Scope's domain of visibility. This was evident by the presence of ingress and egress fields in edge/aggregate metadata. When building the sniffer, I accidentally and incorrectly violated this invariant, by constructing distinct edges for (local -> remote) and (remote -> local), and collapsing ingress and egress byte counts to a single scalar. I experienced a variety of subtle undefined behavior as a result. See #339. This change reverts to the old, correct methodology. Consequently the sniffer needs to be able to find out which side of the sniffed packet is local v. remote, and to do that it needs access to local networks. I moved the discovery from the probe/host package into probe/main.go. As part of that work I discovered that package report also maintains its own, independent "cache" of local networks. Except it contains only the (optional) Docker bridge network, if it's been populated by the probe, and it's only used by the report.Make{Endpoint,Address}NodeID constructors to scope local addresses. Normally, scoping happens during rendering, and only for pseudo nodes -- see current LeafMap Render localNetworks. This is pretty convoluted and should be either be made consistent or heavily commented.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
During rendering, RenderableNodes are created by Map funcs, which take only NodeMetadata. Previously, it was simply assumed that the relevant keys for a given Map func would be present in the metadata. If that implicit invariant failed, the returned RenderableNode would be invalid, with e.g. an ID of
"hostid::". That, in turn, would trigger undefined behavior later on in the rendering workflow.
This bug was detected by creating a partial node metadata for a non-local endpoint node. That node was detected during the first phase of rendering, and given an invalid renderable node ID of "myhostname::", which prevented it from attaching to TheInternet pseudonode. It eventually got removed from the set
of valid nodes, which meant nodes that were adjacent to it suddenly became orphans, and got filtered out by the FilterUnconnected step of the rendering pipeline.
With this change, every map func checks for the presence of mandatory fields, i.e. the fields that compose the resulting renderable node's ID.