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