aboutgitcodebugslistschat
path: root/tcp.c
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2023-02-14 10:48:19 +1100
committerStefano Brivio <sbrivio@redhat.com>2023-02-14 17:24:40 +0100
commite456c1ccdc846ac6ee479b5dcb27a0d2f47400ac (patch)
treeb2cfcae609e7bf03c0438f40e11cac05f3eda5b5 /tcp.c
parentee8353cd646b35a7081217c82503783c1fc96c2c (diff)
downloadpasst-e456c1ccdc846ac6ee479b5dcb27a0d2f47400ac.tar
passt-e456c1ccdc846ac6ee479b5dcb27a0d2f47400ac.tar.gz
passt-e456c1ccdc846ac6ee479b5dcb27a0d2f47400ac.tar.bz2
passt-e456c1ccdc846ac6ee479b5dcb27a0d2f47400ac.tar.lz
passt-e456c1ccdc846ac6ee479b5dcb27a0d2f47400ac.tar.xz
passt-e456c1ccdc846ac6ee479b5dcb27a0d2f47400ac.tar.zst
passt-e456c1ccdc846ac6ee479b5dcb27a0d2f47400ac.zip
tcp: Make a helper to refill each socket pool
tcp_sock_refill() contains two near-identical loops to refill the IPv4 and IPv6 socket pools. In addition, if we get an error on the IPv4 pool we exit early and won't attempt to refill the IPv6 pool. At least theoretically, these are independent from each other and there's value to filling up either pool without the other. So, there's no strong reason to give up on one because the other failed. Address both of these with a helper function 'tcp_sock_refill_pool()' to refill a single given pool. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'tcp.c')
-rw-r--r--tcp.c63
1 files changed, 33 insertions, 30 deletions
diff --git a/tcp.c b/tcp.c
index 8424d8e..5d13244 100644
--- a/tcp.c
+++ b/tcp.c
@@ -3010,6 +3010,34 @@ static int tcp_ns_socks_init(void *arg)
}
/**
+ * tcp_sock_refill_pool() - Refill one pool of pre-opened sockets
+ * @c: Execution context
+ * @pool: Pool of sockets to refill
+ * @af: Address family to use
+ */
+static void tcp_sock_refill_pool(const struct ctx *c, int pool[], int af)
+{
+ int i;
+
+ for (i = 0; i < TCP_SOCK_POOL_SIZE; i++) {
+ int *s = &pool[i];
+
+ if (*s >= 0)
+ break;
+
+ *s = socket(af, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP);
+ if (*s > SOCKET_MAX) {
+ close(*s);
+ *s = -1;
+ return;
+ }
+
+ if (*s >= 0)
+ tcp_sock_set_bufsize(c, *s);
+ }
+}
+
+/**
* struct tcp_sock_refill_arg - Arguments for tcp_sock_refill()
* @c: Execution context
* @ns: Set to refill pool of sockets created in namespace
@@ -3028,7 +3056,7 @@ struct tcp_sock_refill_arg {
static int tcp_sock_refill(void *arg)
{
struct tcp_sock_refill_arg *a = (struct tcp_sock_refill_arg *)arg;
- int i, *p4, *p6;
+ int *p4, *p6;
if (a->ns) {
ns_enter(a->c);
@@ -3039,36 +3067,11 @@ static int tcp_sock_refill(void *arg)
p6 = init_sock_pool6;
}
- for (i = 0; a->c->ifi4 && i < TCP_SOCK_POOL_SIZE; i++, p4++) {
- if (*p4 >= 0)
- break;
-
- *p4 = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP);
- if (*p4 > SOCKET_MAX) {
- close(*p4);
- *p4 = -1;
- return -EIO;
- }
-
- if (*p4 >= 0)
- tcp_sock_set_bufsize(a->c, *p4);
- }
-
- for (i = 0; a->c->ifi6 && i < TCP_SOCK_POOL_SIZE; i++, p6++) {
- if (*p6 >= 0)
- break;
-
- *p6 = socket(AF_INET6, SOCK_STREAM | SOCK_NONBLOCK,
- IPPROTO_TCP);
- if (*p6 > SOCKET_MAX) {
- close(*p6);
- *p6 = -1;
- return -EIO;
- }
+ if (a->c->ifi4)
+ tcp_sock_refill_pool(a->c, p4, AF_INET);
- if (*p6 >= 0)
- tcp_sock_set_bufsize(a->c, *p6);
- }
+ if (a->c->ifi6)
+ tcp_sock_refill_pool(a->c, p6, AF_INET6);
return 0;
}