envoy: Patch original destination cluster to handle parallel host instantiation #778
+479
−53
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.
Original destination cluster creates Host instances for the destination addresses on-demand. When multiple worker threads need to forward to the same destination at the same time (as is possible with
curl --parallel
, for example), separate instances of the destination Host objects are created. Meanwhile, Envoy usesHostSharedPtr
as a map key in connection pool containers, which leads to multiple different connections being created for the same destination, even from the same worker, as the originally used Host instance is replaced with another, depending on which worker thread gets to add their Host object to the shared cluster state first. Multiple connections to the same destination fail when the original source address and port is being used, as is typically needed for Cilium policy enforcement, due to socket bind failing withcannot bind requested address
error.This PR fixes this by modifying the original destination cluster implementation to only create one Host object for any destination for any one cluster instance. This requires closer coordination between the worker threads in a form of an additional mutex, on which a write lock is taken whenever a new Host needs to be created. This synchronizes creation of new Hosts between the threads so that a new Host instance is created only if one has not yet been created by any of the worker threads.
Another possible way of fixing this issue would be to replace
HostSharedPtr
with the destination address as a map key, wherever it is used. This strategy could fix related issues with other cluster and/or load balancer types, it they were to exist. Upstream discussion is needed to settle on the proper fix, and we can adapt as needed when that is done.It is yet to be decided if and when this should be backported.