Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Normalize connections before sending them to sensor #277

Merged
merged 13 commits into from
Feb 25, 2020

Conversation

misberner
Copy link
Contributor

@misberner misberner commented Feb 5, 2020

Shrink the state we are sending by normalizing connections as follows:

  • If the connection is incoming (we are the server), clear the address part of the local endpoint (doesn't matter which interface), only retain the port. Also, clear the port of the remote endpoint (it's ephemeral so it doesn't matter).
  • If the connection is outgoing (we are the client), clear the local endpoint - we neither care about the address nor about the ephemeral port; the container ID is all we need.


state_.swap(new_state);
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, this is weird. new_state and state_ will no longer be in sync, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, I guess new_state is a misnomor, it's now fetched_state. Will change. Or where there any semantic concerns?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, that's fine. Btw, will we ever call without normalize? If not, we can just keep the state normalized all the time.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nope, we cannot keep the state normalized, as that would not allow us to determine when a (normalized) connection is still open, since we lose track of the raw connections. This could possibly be worked around, but requires substantial changes.

Concretely, if we see:

1. Open 1.2.3.4:54321 -> 5.6.7.8:443 [normalized: 0.0.0.0:0 -> 5.6.7.8:443]
2. Open 1.2.3.4:65432 -> 5.6.7.8:443 [normalized: 0.0.0.0:0 -> 5.6.7.8:443]
3. Close 1.2.3.4:65432 -> 5.6.7.8:443 [normalized: 0.0.0.0:0 -> 5.6.7.8:443]

And we keep the state as normalized, how do you know that 0.0.0.0:0 -> 5.6.7.8:443 is still active? Even if you do some form of counting, it is not robust against cases where you see a close for a connection that you never saw being opened (e.g., due to drops).

Copy link
Contributor

Choose a reason for hiding this comment

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

Understood.

@misberner misberner force-pushed the mi-normalize-connections branch from 0cea9c7 to 8d725c0 Compare February 6, 2020 02:10
@ghost
Copy link

ghost commented Feb 6, 2020

COLLECTOR_TAG=3.0.2-35-gf249fc4a45
COLLECTOR_BUILDER_TAG=circle-build-aca3deaf-2685-49e2-8429-46fca1337c30

Results for Performance Benchmarks on build #39231

Kernel Method Without Collector Time (secs) With Collector Time (secs)
"coreos.coreos-stable" "ebpf" 128.75 138.36
"coreos.coreos-stable" "module" 140.26 149.69
"cos.cos-69-lts" "ebpf" 105.51 258.44
"cos.cos-73-lts" "ebpf" 107.24 256.21
"rhel.rhel-7" "ebpf" 104.24 111.75
"rhel.rhel-7" "module" 109.04 117.2
"rhel.rhel-8" "module" 100.54 107.73
"ubuntu-os.ubuntu-1604-lts" "ebpf" 109.61 265.21
"ubuntu-os.ubuntu-1604-lts" "module" 114.52 124.46
"ubuntu-os.ubuntu-1804-lts" "module" 108.41 117.3

Copy link
Contributor

@viswajithiii viswajithiii left a comment

Choose a reason for hiding this comment

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

Nice.

@@ -35,22 +35,29 @@ namespace collector {
// ConnStatus encapsulates the status of a connection, comprised of the timestamp when the connection was last seen
// alive (in microseconds since epoch), and a flag indicating whether the connection is currently active.
class ConnStatus {
private:
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we move the private block below up here too?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The reason this is up here is that we are declaring a static constant. The privat block below declares a constructor and an instance field. I would prefer to keep it in that order - it's not quite compliant with the google style guide which says to always put public first, but I think the code is easier to read if we put the definition of the constant first.

public:
ConnStatus() : data_(0UL) {}
ConnStatus(int64_t microtimestamp, bool active) : data_((microtimestamp & ~0x1UL) | ((active) ? 0x1 : 0x0)) {}
ConnStatus(int64_t microtimestamp, bool active) : data_((static_cast<uint64_t>(microtimestamp) >> 1) | ((active) ? kActiveFlag : 0UL)) {}
Copy link
Contributor

Choose a reason for hiding this comment

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

Doesn't doing this clobber the last bit of microtimestamp?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup - that was the case even before. 1 microsecond isn't really meaningful.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually, have decided to just drop the highest bit - 2^63 microseconds are roughly 300k years.


void SetActive(bool active) {
if (active) data_ |= 0x1UL;
else data_ &= ~0x1UL;
if (active) data_ |= kActiveFlag;
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider factoring out these two lines from SetActive and WithStatus

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done


state_.swap(new_state);
Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, that's fine. Btw, will we ever call without normalize? If not, we can just keep the state normalized all the time.

if (active) new_data |= kActiveFlag;
else new_data &= ~kActiveFlag;
return ConnStatus(new_data);
return ConnStatus(MakeActive(new_data, active));
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: can just pass data_ here directly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@misberner misberner force-pushed the mi-normalize-connections branch from 5e5fbe3 to 01bb888 Compare February 8, 2020 22:26
@misberner misberner force-pushed the mi-normalize-connections branch from 01bb888 to f249fc4 Compare February 9, 2020 20:24
@misberner misberner merged commit c41b723 into master Feb 25, 2020
@misberner misberner deleted the mi-normalize-connections branch February 25, 2020 21:41
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants