diff options
author | Stefano Brivio <sbrivio@redhat.com> | 2024-06-18 12:32:17 +0200 |
---|---|---|
committer | Stefano Brivio <sbrivio@redhat.com> | 2024-06-19 15:00:55 +0200 |
commit | 54a9d3801b9549e68bd169e2c938c265ef46e973 (patch) | |
tree | aeaf74713d3e9ce7bb6f0e9e2e404d608c2bae8a /tap.c | |
parent | 020ff7a40eb5daa5bbaa0afd6b9319cbfb143b01 (diff) | |
download | passt-54a9d3801b9549e68bd169e2c938c265ef46e973.tar passt-54a9d3801b9549e68bd169e2c938c265ef46e973.tar.gz passt-54a9d3801b9549e68bd169e2c938c265ef46e973.tar.bz2 passt-54a9d3801b9549e68bd169e2c938c265ef46e973.tar.lz passt-54a9d3801b9549e68bd169e2c938c265ef46e973.tar.xz passt-54a9d3801b9549e68bd169e2c938c265ef46e973.tar.zst passt-54a9d3801b9549e68bd169e2c938c265ef46e973.zip |
tcp: Don't rely on bind() to fail to decide that connection target is valid
Commit e1a2e2780c91 ("tcp: Check if connection is local or low RTT
was seen before using large MSS") added a call to bind() before we
issue a connect() to the target for an outbound connection.
If bind() fails, but neither with EADDRNOTAVAIL, nor with EACCESS, we
can conclude that the target address is a local (host) address, and we
can use an unlimited MSS.
While at it, according to the reasoning of that commit, if bind()
succeeds, we would know right away that nobody is listening at that
(local) address and port, and we don't even need to call connect(): we
can just fail early and reset the connection attempt.
But if non-local binds are enabled via net.ipv4.ip_nonlocal_bind or
net.ipv6.ip_nonlocal_bind sysctl, binding to a non-local address will
actually succeed, so we can't rely on it to fail in general.
The visible issue with the existing behaviour is that we would reset
any outbound connection to non-local addresses, if non-local binds are
enabled.
Keep the significant optimisation for local addresses along with the
bind() call, but if it succeeds, don't draw any conclusion: close the
socket, grab another one, and proceed normally.
This will incur a small latency penalty if non-local binds are
enabled (we'll likely fetch an existing socket from the pool but
additionally call close()), or if the target is local but not bound:
we'll need to call connect() and get a failure before relaying that
failure back.
Link: https://github.com/containers/podman/issues/23003
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'tap.c')
0 files changed, 0 insertions, 0 deletions