From de471c46555fb0517103165c9582f83b891ea47f Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 8 Dec 2020 15:50:56 +0100 Subject: [PATCH] MINOR: protocol: add a set of ctrl_init/ctrl_close methods for setup/teardown Currnetly conn_ctrl_init() does an fd_insert() and conn_ctrl_close() does an fd_delete(). These are the two only short-term obstacles against using a non-fd handle to set up a connection. Let's have pur these into the protocol layer, along with the other connection-level stuff so that the generic connection code uses them instead. This will allow to define new ones for other protocols (e.g. QUIC). Since we only support regular sockets at the moment, the code was placed into sock.c and shared with proto_tcp, proto_uxst and proto_sockpair. --- include/haproxy/protocol-t.h | 2 ++ include/haproxy/sock.h | 2 ++ src/proto_sockpair.c | 2 ++ src/proto_tcp.c | 4 ++++ src/proto_uxst.c | 2 ++ src/sock.c | 19 +++++++++++++++++++ 6 files changed, 31 insertions(+) diff --git a/include/haproxy/protocol-t.h b/include/haproxy/protocol-t.h index 137a09af5..5205de690 100644 --- a/include/haproxy/protocol-t.h +++ b/include/haproxy/protocol-t.h @@ -96,6 +96,8 @@ struct protocol { int (*resume)(struct listener *l); /* try to resume a suspended listener */ struct connection *(*accept_conn)(struct listener *l, int *status); /* accept a new connection */ /* functions acting on connections */ + void (*ctrl_init)(struct connection *); /* completes initialization of the connection */ + void (*ctrl_close)(struct connection *); /* completes release of the connection */ int (*connect)(struct connection *, int flags); /* connect function if any, see below for flags values */ /* functions acting on the receiver */ diff --git a/include/haproxy/sock.h b/include/haproxy/sock.h index 6e81b1b22..6c9b7b7d6 100644 --- a/include/haproxy/sock.h +++ b/include/haproxy/sock.h @@ -43,6 +43,8 @@ int sock_find_compatible_fd(const struct receiver *rx); int sock_accepting_conn(const struct receiver *rx); struct connection *sock_accept_conn(struct listener *l, int *status); void sock_accept_iocb(int fd); +void sock_conn_ctrl_init(struct connection *conn); +void sock_conn_ctrl_close(struct connection *conn); #endif /* _HAPROXY_SOCK_H */ diff --git a/src/proto_sockpair.c b/src/proto_sockpair.c index d3a6b9884..7124f565f 100644 --- a/src/proto_sockpair.c +++ b/src/proto_sockpair.c @@ -74,6 +74,8 @@ struct protocol proto_sockpair = { .add = default_add_listener, .unbind = default_unbind_listener, .accept_conn = sockpair_accept_conn, + .ctrl_init = sock_conn_ctrl_init, + .ctrl_close = sock_conn_ctrl_close, .connect = sockpair_connect_server, /* binding layer */ diff --git a/src/proto_tcp.c b/src/proto_tcp.c index 19651c0fd..4a5e9c216 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -64,6 +64,8 @@ struct protocol proto_tcpv4 = { .suspend = default_suspend_listener, .resume = default_resume_listener, .accept_conn = sock_accept_conn, + .ctrl_init = sock_conn_ctrl_init, + .ctrl_close = sock_conn_ctrl_close, .connect = tcp_connect_server, /* binding layer */ @@ -101,6 +103,8 @@ struct protocol proto_tcpv6 = { .suspend = default_suspend_listener, .resume = default_resume_listener, .accept_conn = sock_accept_conn, + .ctrl_init = sock_conn_ctrl_init, + .ctrl_close = sock_conn_ctrl_close, .connect = tcp_connect_server, /* binding layer */ diff --git a/src/proto_uxst.c b/src/proto_uxst.c index 1714e101d..1c6ea77dc 100644 --- a/src/proto_uxst.c +++ b/src/proto_uxst.c @@ -60,6 +60,8 @@ struct protocol proto_uxst = { .unbind = default_unbind_listener, .suspend = default_suspend_listener, .accept_conn = sock_accept_conn, + .ctrl_init = sock_conn_ctrl_init, + .ctrl_close = sock_conn_ctrl_close, .connect = uxst_connect_server, /* binding layer */ diff --git a/src/sock.c b/src/sock.c index 9eff7f104..c7a5f80f7 100644 --- a/src/sock.c +++ b/src/sock.c @@ -625,6 +625,25 @@ void sock_accept_iocb(int fd) listener_accept(l); } +/* This completes the initialization of connection by inserting its FD + * into the fdtab, associating it with the regular connection handler. It will + * be bound to the current thread only. This call cannot fail. + */ +void sock_conn_ctrl_init(struct connection *conn) +{ + fd_insert(conn->handle.fd, conn, conn_fd_handler, tid_bit); +} + +/* This completes the release of connection by removing its FD from the + * fdtab and deleting it. The connection must not use the FD anymore past this + * point. The FD may be modified in the connection. + */ +void sock_conn_ctrl_close(struct connection *conn) +{ + fd_delete(conn->handle.fd); + conn->handle.fd = DEAD_FD_MAGIC; +} + /* * Local variables: * c-indent-level: 8