aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2025-12-02 15:02:14 +1100
committerStefano Brivio <sbrivio@redhat.com>2025-12-02 23:07:40 +0100
commite3c4c4175ce61280efd0f5effb233b0f2f37fab1 (patch)
treecac50f6acfa5cab6fea27511ed4aac9105eebfb9
parentcec1ca854975e9f2201219946bf4aa624abd2ed0 (diff)
downloadpasst-e3c4c4175ce61280efd0f5effb233b0f2f37fab1.tar
passt-e3c4c4175ce61280efd0f5effb233b0f2f37fab1.tar.gz
passt-e3c4c4175ce61280efd0f5effb233b0f2f37fab1.tar.bz2
passt-e3c4c4175ce61280efd0f5effb233b0f2f37fab1.tar.lz
passt-e3c4c4175ce61280efd0f5effb233b0f2f37fab1.tar.xz
passt-e3c4c4175ce61280efd0f5effb233b0f2f37fab1.tar.zst
passt-e3c4c4175ce61280efd0f5effb233b0f2f37fab1.zip
tcp: Always populate oaddr field for socket initiated flows
When we receive a TCP connection, we get the peer address from the accept() call. In the case of a listening socket with an unspecified address (:: or 0.0.0.0) the local address of the accept()ed socket could vary. We don't get that from the accept() - we must explicitly call getsockname() to get it. Currently we avoid the latency of that extra syscall, and therefore don't populate the initiating 'oaddr' field of a flow created by an incoming TCP socket connection. This more or less works, because we rarely need that local address, but it does cause some oddities: * For migration we need the local address to recreate the socket on the destination, so we *do* call getsockname() in vhost-user mode * It limits our options in terms of forwarding connections flexibly based on the address to which they're received * It differs from UDP, where we explicitly use the IP_PKTINFO cmsg to populate oaddr. * It means (some) flow debug messages will contain wildcards instead of real local addresses In theory we can elide this call when accept()ing from a socket bound to a specific address instead of a wildcard. However to do that will need revisions to the data structures we use to keep track of listening sockets. The lack of this information is making it hard to implement some fixes we want. So, pay the price of the extra syscall to get this information, with the hope that we can later optimise it away for some cases. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r--tcp.c8
1 files changed, 3 insertions, 5 deletions
diff --git a/tcp.c b/tcp.c
index c844da7..fa95f6b 100644
--- a/tcp.c
+++ b/tcp.c
@@ -2369,11 +2369,9 @@ void tcp_listen_handler(const struct ctx *c, union epoll_ref ref,
ini = flow_initiate_sa(flow, ref.tcp_listen.pif, &sa,
NULL, ref.tcp_listen.port);
- if (c->mode == MODE_VU) { /* Rebind to same address after migration */
- if (getsockname(s, &sa.sa, &sl) ||
- inany_from_sockaddr(&ini->oaddr, &ini->oport, &sa) < 0)
- err_perror("Can't get local address for socket %i", s);
- }
+ if (getsockname(s, &sa.sa, &sl) ||
+ inany_from_sockaddr(&ini->oaddr, &ini->oport, &sa) < 0)
+ err_perror("Can't get local address for socket %i", s);
if (!inany_is_unicast(&ini->eaddr) || ini->eport == 0) {
char sastr[SOCKADDR_STRLEN];