]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: proto: Change the prototype of the connect() method.
authorOlivier Houchard <ohouchard@haproxy.com>
Mon, 6 May 2019 16:32:29 +0000 (18:32 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 6 May 2019 20:12:57 +0000 (22:12 +0200)
The connect() method had 2 arguments, "data", that tells if there's pending
data to be sent, and "delack" that tells if we have to use a delayed ack
inconditionally, or if the backend is configured with tcp-smart-connect.
Turn that into one argument, "flags".
That way it'll be easier to provide more informations to connect() without
adding extra arguments.

include/proto/proto_tcp.h
include/proto/stream_interface.h
include/types/protocol.h
src/checks.c
src/proto_sockpair.c
src/proto_tcp.c
src/proto_uxst.c

index d4e09c7a65adee0f24ba4cf2ab2c5c706c5bc06f..76f89b1f34d7837e7c89addf39c471e4558880f8 100644 (file)
@@ -29,7 +29,7 @@
 
 int tcp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct sockaddr_storage *remote);
 int tcp_pause_listener(struct listener *l);
-int tcp_connect_server(struct connection *conn, int data, int delack);
+int tcp_connect_server(struct connection *conn, int flags);
 int tcp_connect_probe(struct connection *conn);
 int tcp_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir);
 int tcp_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir);
index 3cccc8fce1aee710bdde0f77c6b6bea9fa254aac..8a4b77afe00943c4ef77dd1a6dc320d6852334af 100644 (file)
@@ -489,7 +489,8 @@ static inline int si_connect(struct stream_interface *si, struct connection *con
                return SF_ERR_INTERNAL;
 
        if (!conn_ctrl_ready(conn) || !conn_xprt_ready(conn)) {
-               ret = conn->ctrl->connect(conn, !channel_is_empty(si_oc(si)), 0);
+               ret = conn->ctrl->connect(conn, channel_is_empty(si_oc(si)) ?
+                                         CONNECT_HAS_DATA : 0);
                if (ret != SF_ERR_NONE)
                        return ret;
 
index 378e2b0e165eaac0662f64c2f0928c41f8cb27ba..a33d12922bad91c231a0f34da502dcec518f3f3f 100644 (file)
@@ -73,7 +73,7 @@ struct protocol {
        int (*unbind_all)(struct protocol *proto);      /* unbind all bound listeners */
        int (*enable_all)(struct protocol *proto);      /* enable all bound listeners */
        int (*disable_all)(struct protocol *proto);     /* disable all bound listeners */
-       int (*connect)(struct connection *, int data, int delack);  /* connect function if any */
+       int (*connect)(struct connection *, int flags); /* connect function if any, see below for flags values */
        int (*get_src)(int fd, struct sockaddr *, socklen_t, int dir); /* syscall used to retrieve src addr */
        int (*get_dst)(int fd, struct sockaddr *, socklen_t, int dir); /* syscall used to retrieve dst addr */
        int (*drain)(int fd);                           /* indicates whether we can safely close the fd */
@@ -85,6 +85,9 @@ struct protocol {
        struct list list;                               /* list of registered protocols */
 };
 
+#define CONNECT_HAS_DATA                        0x00000001 /* There's data available to be sent */
+#define CONNECT_DELACK_SMART_CONNECT            0x00000002 /* Use a delayed ACK if the backend has tcp-smart-connect */
+#define CONNECT_DELACK_ALWAYS                   0x00000004 /* Use a delayed ACK */
 #endif /* _TYPES_PROTOCOL_H */
 
 /*
index aeb3b79b66a4d31139f64cdb911eed71983300bc..a7b4b2fcea7e411543ef155ae9a2ae8eda483959 100644 (file)
@@ -1545,7 +1545,7 @@ static int connect_conn_chk(struct task *t)
        struct protocol *proto;
        struct tcpcheck_rule *tcp_rule = NULL;
        int ret;
-       int quickack;
+       int connflags = 0;
 
        /* we cannot have a connection here */
        if (conn)
@@ -1637,14 +1637,15 @@ static int connect_conn_chk(struct task *t)
        cs_attach(cs, check, &check_conn_cb);
 
        /* only plain tcp-check supports quick ACK */
-       quickack = check->type == 0 || check->type == PR_O2_TCPCHK_CHK;
-
-       if (tcp_rule && tcp_rule->action == TCPCHK_ACT_EXPECT)
-               quickack = 0;
+       if (check->type != 0)
+               connflags |= CONNECT_HAS_DATA;
+       if ((check->type == 0 || check->type == PR_O2_TCPCHK_CHK) &&
+           (!tcp_rule || tcp_rule->action != TCPCHK_ACT_EXPECT))
+               connflags |= CONNECT_DELACK_ALWAYS;
 
        ret = SF_ERR_INTERNAL;
        if (proto && proto->connect)
-               ret = proto->connect(conn, check->type, quickack ? 2 : 0);
+               ret = proto->connect(conn, connflags);
 
 
 #ifdef USE_OPENSSL
@@ -2845,8 +2846,7 @@ static int tcpcheck_main(struct check *check)
                        ret = SF_ERR_INTERNAL;
                        if (proto && proto->connect)
                                ret = proto->connect(conn,
-                                                    1 /* I/O polling is always needed */,
-                                                    (next && next->action == TCPCHK_ACT_EXPECT) ? 0 : 2);
+                                                    CONNECT_HAS_DATA /* I/O polling is always needed */ | (next && next->action == TCPCHK_ACT_EXPECT) ? 0 : CONNECT_DELACK_ALWAYS);
                        if (check->current_step->conn_opts & TCPCHK_OPT_SEND_PROXY) {
                                conn->send_proxy_ofs = 1;
                                conn->flags |= CO_FL_SEND_PROXY;
index 713da370ab8c76b43989d138d5593e9491c19a0e..97a93480af6488d2595f7422c4c2d56c622d2604 100644 (file)
@@ -49,7 +49,7 @@
 static void sockpair_add_listener(struct listener *listener, int port);
 static int sockpair_bind_listener(struct listener *listener, char *errmsg, int errlen);
 static int sockpair_bind_listeners(struct protocol *proto, char *errmsg, int errlen);
-static int sockpair_connect_server(struct connection *conn, int data, int delack);
+static int sockpair_connect_server(struct connection *conn, int flags);
 
 /* Note: must not be declared <const> as its list will be overwritten */
 static struct protocol proto_sockpair = {
@@ -237,7 +237,7 @@ int send_fd_uxst(int fd, int send_fd)
  * The connection's fd is inserted only when SF_ERR_NONE is returned, otherwise
  * it's invalid and the caller has nothing to do.
  */
-static int sockpair_connect_server(struct connection *conn, int data, int delack)
+static int sockpair_connect_server(struct connection *conn, int flags)
 {
        int sv[2], fd, dst_fd = -1;
 
@@ -289,7 +289,8 @@ static int sockpair_connect_server(struct connection *conn, int data, int delack
        }
 
        /* if a send_proxy is there, there are data */
-       data |= conn->send_proxy_ofs;
+       if (conn->send_proxy_ofs)
+               flags |= CONNECT_HAS_DATA;
 
        if (global.tune.server_sndbuf)
                 setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &global.tune.server_sndbuf, sizeof(global.tune.server_sndbuf));
@@ -334,10 +335,10 @@ static int sockpair_connect_server(struct connection *conn, int data, int delack
                 * layer when the connection is already OK otherwise we'll have
                 * no other opportunity to do it later (eg: health checks).
                 */
-               data = 1;
+               flags |= CONNECT_HAS_DATA;
        }
 
-       if (data)
+       if (flags & CONNECT_HAS_DATA)
                conn_xprt_want_send(conn);  /* prepare to send data if any */
 
        return SF_ERR_NONE;  /* connection is OK */
index d4cad223a730036d2d780c4a3589ba95a03ec3b0..e668a85f10f7cce345f9b3620ecd91133dec5d91 100644 (file)
@@ -266,11 +266,11 @@ static int create_server_socket(struct connection *conn)
  * depending on conn->target. Only OBJ_TYPE_PROXY and OBJ_TYPE_SERVER are
  * supported. The <data> parameter is a boolean indicating whether there are data
  * waiting for being sent or not, in order to adjust data write polling and on
- * some platforms, the ability to avoid an empty initial ACK. The <delack> argument
- * allows the caller to force using a delayed ACK when establishing the connection :
+ * some platforms, the ability to avoid an empty initial ACK. The <flags> argument
+ * allows the caller to force using a delayed ACK when establishing the connection
  *   - 0 = no delayed ACK unless data are advertised and backend has tcp-smart-connect
- *   - 1 = delayed ACK if backend has tcp-smart-connect, regardless of data
- *   - 2 = delayed ACK regardless of backend options
+ *   - CONNECT_DELACK_SMART_CONNECT = delayed ACK if backend has tcp-smart-connect, regardless of data
+ *   - CONNECT_DELACK_ALWAYS = delayed ACK regardless of backend options
  *
  * Note that a pending send_proxy message accounts for data.
  *
@@ -287,7 +287,7 @@ static int create_server_socket(struct connection *conn)
  * it's invalid and the caller has nothing to do.
  */
 
-int tcp_connect_server(struct connection *conn, int data, int delack)
+int tcp_connect_server(struct connection *conn, int flags)
 {
        int fd;
        struct server *srv;
@@ -481,7 +481,10 @@ int tcp_connect_server(struct connection *conn, int data, int delack)
         * machine with the first ACK. We only do this if there are pending
         * data in the buffer.
         */
-       if (delack == 2 || ((delack || data || conn->send_proxy_ofs) && (be->options2 & PR_O2_SMARTCON)))
+       if (flags & (CONNECT_DELACK_ALWAYS) ||
+           ((flags & CONNECT_DELACK_SMART_CONNECT ||
+             (flags & CONNECT_HAS_DATA) || conn->send_proxy_ofs) &&
+            (be->options2 & PR_O2_SMARTCON)))
                 setsockopt(fd, IPPROTO_TCP, TCP_QUICKACK, &zero, sizeof(zero));
 #endif
 
@@ -572,10 +575,10 @@ int tcp_connect_server(struct connection *conn, int data, int delack)
                 * layer when the connection is already OK otherwise we'll have
                 * no other opportunity to do it later (eg: health checks).
                 */
-               data = 1;
+               flags |= CONNECT_HAS_DATA;
        }
 
-       if (data)
+       if (flags & CONNECT_HAS_DATA)
                conn_xprt_want_send(conn);  /* prepare to send data if any */
 
        return SF_ERR_NONE;  /* connection is OK */
index 980a22649b1f19b640de67137b3db1acb8ac9184..42e0dc878f8d303b0bb75b019615e16592c71bbf 100644 (file)
@@ -48,7 +48,7 @@
 static int uxst_bind_listener(struct listener *listener, char *errmsg, int errlen);
 static int uxst_bind_listeners(struct protocol *proto, char *errmsg, int errlen);
 static int uxst_unbind_listeners(struct protocol *proto);
-static int uxst_connect_server(struct connection *conn, int data, int delack);
+static int uxst_connect_server(struct connection *conn, int flags);
 static void uxst_add_listener(struct listener *listener, int port);
 static int uxst_pause_listener(struct listener *l);
 static int uxst_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir);
@@ -430,7 +430,7 @@ static int uxst_pause_listener(struct listener *l)
  * The connection's fd is inserted only when SF_ERR_NONE is returned, otherwise
  * it's invalid and the caller has nothing to do.
  */
-static int uxst_connect_server(struct connection *conn, int data, int delack)
+static int uxst_connect_server(struct connection *conn, int flags)
 {
        int fd;
        struct server *srv;
@@ -510,7 +510,8 @@ static int uxst_connect_server(struct connection *conn, int data, int delack)
        }
 
        /* if a send_proxy is there, there are data */
-       data |= conn->send_proxy_ofs;
+       if (conn->send_proxy_ofs)
+               flags |= CONNECT_HAS_DATA;
 
        if (global.tune.server_sndbuf)
                 setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &global.tune.server_sndbuf, sizeof(global.tune.server_sndbuf));
@@ -585,10 +586,10 @@ static int uxst_connect_server(struct connection *conn, int data, int delack)
                 * layer when the connection is already OK otherwise we'll have
                 * no other opportunity to do it later (eg: health checks).
                 */
-               data = 1;
+               flags |= CONNECT_HAS_DATA;
        }
 
-       if (data)
+       if (flags & CONNECT_HAS_DATA)
                conn_xprt_want_send(conn);  /* prepare to send data if any */
 
        return SF_ERR_NONE;  /* connection is OK */