[8.x](backport #41581) [packetbeat] Expire source port mappings. #41601
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.
port->pid mappings were only overwritten, never expired, the overwriting mechanism has some issues:
The observable effect is that the user will see wrong process correlations to older/long lived processes, imagine the follwing:
Related to a very long SDH, where a more in depth explanation of the bug can be found here, with a program to reproduce it.
The solution is to discard mappings that are "old enough", with a hardcoded window of 10 seconds, so as long as the port is not re-used in this window, we are fine.
This also makes sure the cache never becomes "immutable", since mappings will invariably get old, forcing a refresh.
It's a very conservative approach as I don't want to introduce other bugs by redesigning it, work is on the way to change how the cache works in linux anyway.
While here, I've noticed the locking was also wrong, we were doing the lookup unlocked, and also having to relock in case we have to update the mapping, so change this to grab the lock once and only once, interleaving is baad.
Proposed commit message
Checklist
- [ ] I have made corresponding changes to the documentation- [ ] I have made corresponding change to the default configuration files- [ ] I have added tests that prove my fix is effective or that my feature worksCHANGELOG.next.asciidocorCHANGELOG-developer.next.asciidoc.Test
The following program can be used to demonstrate the bug:
Build and run with:
It will do one connection per source port to the specified address (192.168.1.50:12345) and send some bytes, to make it easier, 192.168.1.50 should be in another machine than packetbeat, you can then run
tcpbench, by yours truly, or any other service that will accept tcp connections and eat some bytes:After running
all_your_mappings_are_belong_to_us, if you do a tcp connection to any other port, packetbeat will incorrectly assume it belongs toall_your_mappings_are_belong_to_us, see screenshotsTested on 8.14.3 and main.
Screenshots
The circled in red thing is a
wgetto google.com, yet it things it's fromall_your_mappings_are_belong_to_us.After the fix, the mappings correctly show
wgetThis is an automatic backport of pull request #41581 done by Mergify.