1
0
mirror of https://passt.top/passt synced 2024-10-01 03:25:48 +00:00

tcp: ...and so I got a socket called zero

I thought I'd get away with it, but no, after some clean-ups, I
finally got a socket with number 0. Fix up all the convenient,
yet botched assumptions.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
Stefano Brivio 2021-10-15 20:42:11 +02:00
parent bd47b68ebf
commit 6943d41d6c

75
tcp.c
View File

@ -1883,7 +1883,7 @@ static void tcp_conn_from_tap(struct ctx *c, int af, void *addr,
sock_pool_p = &init_sock_pool6[i]; sock_pool_p = &init_sock_pool6[i];
else else
sock_pool_p = &init_sock_pool4[i]; sock_pool_p = &init_sock_pool4[i];
if ((ref.s = s = *sock_pool_p) > 0) { if ((ref.s = s = *sock_pool_p) >= 0) {
*sock_pool_p = -1; *sock_pool_p = -1;
break; break;
} }
@ -2701,7 +2701,7 @@ static void tcp_splice_connect_finish(struct ctx *c,
} }
} }
if (conn->pipe_from_to[0] <= 0) { if (conn->pipe_from_to[0] < 0) {
if (pipe2(conn->pipe_to_from, O_NONBLOCK) || if (pipe2(conn->pipe_to_from, O_NONBLOCK) ||
pipe2(conn->pipe_from_to, O_NONBLOCK)) { pipe2(conn->pipe_from_to, O_NONBLOCK)) {
tcp_splice_destroy(c, conn); tcp_splice_destroy(c, conn);
@ -2736,7 +2736,7 @@ static void tcp_splice_connect_finish(struct ctx *c,
static int tcp_splice_connect(struct ctx *c, struct tcp_splice_conn *conn, static int tcp_splice_connect(struct ctx *c, struct tcp_splice_conn *conn,
int s, int v6, in_port_t port) int s, int v6, in_port_t port)
{ {
int sock_conn = (s > 0) ? s : socket(v6 ? AF_INET6 : AF_INET, int sock_conn = (s >= 0) ? s : socket(v6 ? AF_INET6 : AF_INET,
SOCK_STREAM | SOCK_NONBLOCK, SOCK_STREAM | SOCK_NONBLOCK,
IPPROTO_TCP); IPPROTO_TCP);
union epoll_ref ref_accept = { .proto = IPPROTO_TCP, .s = conn->from, union epoll_ref ref_accept = { .proto = IPPROTO_TCP, .s = conn->from,
@ -2763,10 +2763,10 @@ static int tcp_splice_connect(struct ctx *c, struct tcp_splice_conn *conn,
conn->to = sock_conn; conn->to = sock_conn;
if (s <= 0) if (s < 0)
tcp_sock_set_bufsize(c, sock_conn); tcp_sock_set_bufsize(c, conn->to);
setsockopt(s, SOL_TCP, TCP_QUICKACK, &one, sizeof(one)); setsockopt(conn->to, SOL_TCP, TCP_QUICKACK, &one, sizeof(one));
if (v6) { if (v6) {
sa = (struct sockaddr *)&addr6; sa = (struct sockaddr *)&addr6;
@ -2853,13 +2853,13 @@ static int tcp_splice_new(struct ctx *c, struct tcp_splice_conn *conn,
sock_pool_p = v6 ? init_sock_pool6 : init_sock_pool4; sock_pool_p = v6 ? init_sock_pool6 : init_sock_pool4;
for (i = 0; i < TCP_SOCK_POOL_SIZE; i++, sock_pool_p++) { for (i = 0; i < TCP_SOCK_POOL_SIZE; i++, sock_pool_p++) {
if ((s = *sock_pool_p) > 0) { if ((s = *sock_pool_p) >= 0) {
*sock_pool_p = -1; *sock_pool_p = -1;
break; break;
} }
} }
if (s <= 0 && bitmap_isset(c->tcp.port_to_tap, port)) { if (s < 0 && bitmap_isset(c->tcp.port_to_tap, port)) {
NS_CALL(tcp_splice_connect_ns, &ns_arg); NS_CALL(tcp_splice_connect_ns, &ns_arg);
return ns_arg.ret; return ns_arg.ret;
} }
@ -3358,7 +3358,7 @@ static void tcp_sock_init_one(struct ctx *c, int ns, in_port_t port)
s = sock_l4(c, AF_INET, IPPROTO_TCP, port, s = sock_l4(c, AF_INET, IPPROTO_TCP, port,
c->mode == MODE_PASTA ? BIND_EXT : BIND_ANY, c->mode == MODE_PASTA ? BIND_EXT : BIND_ANY,
tref.u32); tref.u32);
if (s > 0) if (s >= 0)
tcp_sock_set_bufsize(c, s); tcp_sock_set_bufsize(c, s);
else else
s = -1; s = -1;
@ -3371,7 +3371,7 @@ static void tcp_sock_init_one(struct ctx *c, int ns, in_port_t port)
tref.splice = 1; tref.splice = 1;
s = sock_l4(c, AF_INET, IPPROTO_TCP, port, s = sock_l4(c, AF_INET, IPPROTO_TCP, port,
BIND_LOOPBACK, tref.u32); BIND_LOOPBACK, tref.u32);
if (s > 0) if (s >= 0)
tcp_sock_set_bufsize(c, s); tcp_sock_set_bufsize(c, s);
else else
s = -1; s = -1;
@ -3393,7 +3393,7 @@ static void tcp_sock_init_one(struct ctx *c, int ns, in_port_t port)
s = sock_l4(c, AF_INET6, IPPROTO_TCP, port, s = sock_l4(c, AF_INET6, IPPROTO_TCP, port,
c->mode == MODE_PASTA ? BIND_EXT : BIND_ANY, c->mode == MODE_PASTA ? BIND_EXT : BIND_ANY,
tref.u32); tref.u32);
if (s > 0) if (s >= 0)
tcp_sock_set_bufsize(c, s); tcp_sock_set_bufsize(c, s);
else else
s = -1; s = -1;
@ -3406,7 +3406,7 @@ static void tcp_sock_init_one(struct ctx *c, int ns, in_port_t port)
tref.splice = 1; tref.splice = 1;
s = sock_l4(c, AF_INET6, IPPROTO_TCP, port, s = sock_l4(c, AF_INET6, IPPROTO_TCP, port,
BIND_LOOPBACK, tref.u32); BIND_LOOPBACK, tref.u32);
if (s > 0) if (s >= 0)
tcp_sock_set_bufsize(c, s); tcp_sock_set_bufsize(c, s);
else else
s = -1; s = -1;
@ -3453,7 +3453,7 @@ static void tcp_splice_pipe_refill(struct ctx *c)
int i; int i;
for (i = 0; i < TCP_SPLICE_PIPE_POOL_SIZE; i++) { for (i = 0; i < TCP_SPLICE_PIPE_POOL_SIZE; i++) {
if (splice_pipe_pool[i][0][0] > 0) if (splice_pipe_pool[i][0][0] >= 0)
break; break;
if (pipe2(splice_pipe_pool[i][0], O_NONBLOCK)) if (pipe2(splice_pipe_pool[i][0], O_NONBLOCK))
continue; continue;
@ -3502,7 +3502,7 @@ static int tcp_sock_refill(void *arg)
} }
for (i = 0; a->c->v4 && i < TCP_SOCK_POOL_SIZE; i++, p4++) { for (i = 0; a->c->v4 && i < TCP_SOCK_POOL_SIZE; i++, p4++) {
if (*p4 > 0) { if (*p4 >= 0) {
break; break;
} }
*p4 = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP); *p4 = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP);
@ -3510,7 +3510,7 @@ static int tcp_sock_refill(void *arg)
} }
for (i = 0; a->c->v6 && i < TCP_SOCK_POOL_SIZE; i++, p6++) { for (i = 0; a->c->v6 && i < TCP_SOCK_POOL_SIZE; i++, p6++) {
if (*p6 > 0) { if (*p6 >= 0) {
break; break;
} }
*p6 = socket(AF_INET6, SOCK_STREAM | SOCK_NONBLOCK, *p6 = socket(AF_INET6, SOCK_STREAM | SOCK_NONBLOCK,
@ -3553,6 +3553,15 @@ int tcp_sock_init(struct ctx *c, struct timespec *now)
if (c->v6) if (c->v6)
tcp_sock6_iov_init(); tcp_sock6_iov_init();
memset(splice_pipe_pool, 0xff, sizeof(splice_pipe_pool));
memset(init_sock_pool4, 0xff, sizeof(init_sock_pool4));
memset(init_sock_pool6, 0xff, sizeof(init_sock_pool6));
memset(ns_sock_pool4, 0xff, sizeof(ns_sock_pool4));
memset(ns_sock_pool6, 0xff, sizeof(ns_sock_pool6));
memset(tcp_sock_init_lo, 0xff, sizeof(tcp_sock_init_lo));
memset(tcp_sock_init_ext, 0xff, sizeof(tcp_sock_init_ext));
memset(tcp_sock_ns, 0xff, sizeof(tcp_sock_ns));
c->tcp.refill_ts = *now; c->tcp.refill_ts = *now;
tcp_sock_refill(&refill_arg); tcp_sock_refill(&refill_arg);
@ -3715,14 +3724,14 @@ static int tcp_port_rebind(void *arg)
for (port = 0; port < USHRT_MAX; port++) { for (port = 0; port < USHRT_MAX; port++) {
if (!bitmap_isset(a->c->tcp.port_to_init, port)) { if (!bitmap_isset(a->c->tcp.port_to_init, port)) {
if (tcp_sock_ns[port][V4] > 0) { if (tcp_sock_ns[port][V4] >= 0) {
close(tcp_sock_ns[port][V4]); close(tcp_sock_ns[port][V4]);
tcp_sock_ns[port][V4] = 0; tcp_sock_ns[port][V4] = -1;
} }
if (tcp_sock_ns[port][V6] > 0) { if (tcp_sock_ns[port][V6] >= 0) {
close(tcp_sock_ns[port][V6]); close(tcp_sock_ns[port][V6]);
tcp_sock_ns[port][V6] = 0; tcp_sock_ns[port][V6] = -1;
} }
continue; continue;
@ -3732,31 +3741,31 @@ static int tcp_port_rebind(void *arg)
if (bitmap_isset(a->c->tcp.port_to_tap, port)) if (bitmap_isset(a->c->tcp.port_to_tap, port))
continue; continue;
if ((a->c->v4 && !tcp_sock_ns[port][V4]) || if ((a->c->v4 && tcp_sock_ns[port][V4] == -1) ||
(a->c->v6 && !tcp_sock_ns[port][V6])) (a->c->v6 && tcp_sock_ns[port][V6] == -1))
tcp_sock_init_one(a->c, 1, port); tcp_sock_init_one(a->c, 1, port);
} }
} else { } else {
for (port = 0; port < USHRT_MAX; port++) { for (port = 0; port < USHRT_MAX; port++) {
if (!bitmap_isset(a->c->tcp.port_to_tap, port)) { if (!bitmap_isset(a->c->tcp.port_to_tap, port)) {
if (tcp_sock_init_ext[port][V4] > 0) { if (tcp_sock_init_ext[port][V4] >= 0) {
close(tcp_sock_init_ext[port][V4]); close(tcp_sock_init_ext[port][V4]);
tcp_sock_init_ext[port][V4] = 0; tcp_sock_init_ext[port][V4] = -1;
} }
if (tcp_sock_init_ext[port][V6] > 0) { if (tcp_sock_init_ext[port][V6] >= 0) {
close(tcp_sock_init_ext[port][V6]); close(tcp_sock_init_ext[port][V6]);
tcp_sock_init_ext[port][V6] = 0; tcp_sock_init_ext[port][V6] = -1;
} }
if (tcp_sock_init_lo[port][V4] > 0) { if (tcp_sock_init_lo[port][V4] >= 0) {
close(tcp_sock_init_lo[port][V4]); close(tcp_sock_init_lo[port][V4]);
tcp_sock_init_lo[port][V4] = 0; tcp_sock_init_lo[port][V4] = -1;
} }
if (tcp_sock_init_lo[port][V6] > 0) { if (tcp_sock_init_lo[port][V6] >= 0) {
close(tcp_sock_init_lo[port][V6]); close(tcp_sock_init_lo[port][V6]);
tcp_sock_init_lo[port][V6] = 0; tcp_sock_init_lo[port][V6] = -1;
} }
continue; continue;
} }
@ -3765,8 +3774,8 @@ static int tcp_port_rebind(void *arg)
if (bitmap_isset(a->c->tcp.port_to_init, port)) if (bitmap_isset(a->c->tcp.port_to_init, port))
continue; continue;
if ((a->c->v4 && !tcp_sock_init_ext[port][V4]) || if ((a->c->v4 && tcp_sock_init_ext[port][V4] == -1) ||
(a->c->v6 && !tcp_sock_init_ext[port][V6])) (a->c->v6 && tcp_sock_init_ext[port][V6] == -1))
tcp_sock_init_one(a->c, 0, port); tcp_sock_init_one(a->c, 0, port);
} }
} }
@ -3812,8 +3821,8 @@ void tcp_timer(struct ctx *c, struct timespec *now)
tcp_sock_refill(&refill_arg); tcp_sock_refill(&refill_arg);
if (c->mode == MODE_PASTA) { if (c->mode == MODE_PASTA) {
refill_arg.ns = 1; refill_arg.ns = 1;
if ((c->v4 && ns_sock_pool4[TCP_SOCK_POOL_TSH] <= 0) || if ((c->v4 && ns_sock_pool4[TCP_SOCK_POOL_TSH] < 0) ||
(c->v6 && ns_sock_pool6[TCP_SOCK_POOL_TSH] <= 0)) (c->v6 && ns_sock_pool6[TCP_SOCK_POOL_TSH] < 0))
NS_CALL(tcp_sock_refill, &refill_arg); NS_CALL(tcp_sock_refill, &refill_arg);
tcp_splice_pipe_refill(c); tcp_splice_pipe_refill(c);