]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: protocol: add a pair of check_events/ignore_events functions at the ctrl layer
authorWilly Tarreau <w@1wt.eu>
Fri, 11 Dec 2020 16:02:50 +0000 (17:02 +0100)
committerWilly Tarreau <w@1wt.eu>
Fri, 11 Dec 2020 16:02:50 +0000 (17:02 +0100)
Right now the connection subscribe/unsubscribe code needs to manipulate
FDs, which is not compatible with QUIC. In practice what we need there
is to be able to either subscribe or wake up depending on readiness at
the moment of subscription.

This commit introduces two new functions at the control layer, which are
provided by the socket code, to check for FD readiness or subscribe to it
at the control layer. For now it's not used.

include/haproxy/protocol-t.h
include/haproxy/sock.h
src/proto_sockpair.c
src/proto_tcp.c
src/proto_uxst.c
src/sock.c

index cd642b46e8c504f8d578c2a70398624f3cd0ba48..ce92765eaa9949f3610a86659001b97224a7e10b 100644 (file)
@@ -100,6 +100,8 @@ struct protocol {
        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 */
        int (*drain)(struct connection *);              /* drain pending data; 0=failed, >0=success */
+       int (*check_events)(struct connection *conn, int event_type);  /* subscribe to socket events */
+       void (*ignore_events)(struct connection *conn, int event_type);  /* unsubscribe from socket events */
 
        /* functions acting on the receiver */
        int (*rx_suspend)(struct receiver *rx);         /* temporarily suspend this receiver for a soft restart */
index 20f4dee082aa8790b2e4157f4045122273fec98a..1a5b68c5a411889bf9ec9397eb547af1a1c281e2 100644 (file)
@@ -48,6 +48,8 @@ void sock_conn_ctrl_close(struct connection *conn);
 void sock_conn_iocb(int fd);
 int sock_conn_check(struct connection *conn);
 int sock_drain(struct connection *conn);
+int sock_check_events(struct connection *conn, int event_type);
+void sock_ignore_events(struct connection *conn, int event_type);
 
 
 #endif /* _HAPROXY_SOCK_H */
index 9c16b2bcfe05d43bb59d390e8f93c1e05c59efcd..ca4fc6d8b4c54441b2c65ad78466e2bc0d5033ea 100644 (file)
@@ -78,6 +78,8 @@ struct protocol proto_sockpair = {
        .ctrl_close     = sock_conn_ctrl_close,
        .connect        = sockpair_connect_server,
        .drain          = sock_drain,
+       .check_events   = sock_check_events,
+       .ignore_events  = sock_ignore_events,
 
        /* binding layer */
        /* Note: suspend/resume not supported */
index dcc524ddbe82da98a58a8f5c9864a4c5d7f15c3e..485603d57aa8b20349dca96e97511d156c6356c7 100644 (file)
@@ -68,6 +68,8 @@ struct protocol proto_tcpv4 = {
        .ctrl_close     = sock_conn_ctrl_close,
        .connect        = tcp_connect_server,
        .drain          = sock_drain,
+       .check_events   = sock_check_events,
+       .ignore_events  = sock_ignore_events,
 
        /* binding layer */
        .rx_suspend     = tcp_suspend_receiver,
@@ -108,6 +110,8 @@ struct protocol proto_tcpv6 = {
        .ctrl_close     = sock_conn_ctrl_close,
        .connect        = tcp_connect_server,
        .drain          = sock_drain,
+       .check_events   = sock_check_events,
+       .ignore_events  = sock_ignore_events,
 
        /* binding layer */
        .rx_suspend     = tcp_suspend_receiver,
index 9b1fc38d5dfc33bd79b75e237f709828c4fd3ac3..f33099e7025bb1678fdb960cc7fa00ec7e0298c3 100644 (file)
@@ -64,6 +64,8 @@ struct protocol proto_uxst = {
        .ctrl_close     = sock_conn_ctrl_close,
        .connect        = uxst_connect_server,
        .drain          = sock_drain,
+       .check_events   = sock_check_events,
+       .ignore_events  = sock_ignore_events,
 
        /* binding layer */
        .rx_suspend     = uxst_suspend_receiver,
index cd1e3ffa63851c0f1e94c0096c54db6f4c33c669..20ebdd0e4e595b99947f26530d26b3b8cec89b7f 100644 (file)
@@ -872,6 +872,45 @@ int sock_drain(struct connection *conn)
        return 1;
 }
 
+/* Checks the connection's FD for readiness of events <event_type>, which may
+ * only be a combination of SUB_RETRY_RECV and SUB_RETRY_SEND. Those which are
+ * ready are returned. The ones that are not ready are enabled. The caller is
+ * expected to do what is needed to handle ready events and to deal with
+ * subsequent wakeups caused by the requested events' readiness.
+ */
+int sock_check_events(struct connection *conn, int event_type)
+{
+       int ret = 0;
+
+       if (event_type & SUB_RETRY_RECV) {
+               if (fd_recv_ready(conn->handle.fd))
+                       ret |= SUB_RETRY_RECV;
+               else
+                       fd_want_recv(conn->handle.fd);
+       }
+
+       if (event_type & SUB_RETRY_SEND) {
+               if (fd_send_ready(conn->handle.fd))
+                       ret |= SUB_RETRY_SEND;
+               else
+                       fd_want_send(conn->handle.fd);
+       }
+
+       return ret;
+}
+
+/* Ignore readiness events from connection's FD for events of types <event_type>
+ * which may only be a combination of SUB_RETRY_RECV and SUB_RETRY_SEND.
+ */
+void sock_ignore_events(struct connection *conn, int event_type)
+{
+       if (event_type & SUB_RETRY_RECV)
+               fd_stop_recv(conn->handle.fd);
+
+       if (event_type & SUB_RETRY_SEND)
+               fd_stop_send(conn->handle.fd);
+}
+
 /*
  * Local variables:
  *  c-indent-level: 8