mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-09 08:37:04 +02:00
MEDIUM: proto: Change the prototype of the connect() method.
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.
This commit is contained in:
parent
22c9b440dc
commit
fdcb007ad8
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
int tcp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct sockaddr_storage *remote);
|
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_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_connect_probe(struct connection *conn);
|
||||||
int tcp_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir);
|
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);
|
int tcp_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir);
|
||||||
|
@ -489,7 +489,8 @@ static inline int si_connect(struct stream_interface *si, struct connection *con
|
|||||||
return SF_ERR_INTERNAL;
|
return SF_ERR_INTERNAL;
|
||||||
|
|
||||||
if (!conn_ctrl_ready(conn) || !conn_xprt_ready(conn)) {
|
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)
|
if (ret != SF_ERR_NONE)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ struct protocol {
|
|||||||
int (*unbind_all)(struct protocol *proto); /* unbind all bound listeners */
|
int (*unbind_all)(struct protocol *proto); /* unbind all bound listeners */
|
||||||
int (*enable_all)(struct protocol *proto); /* enable all bound listeners */
|
int (*enable_all)(struct protocol *proto); /* enable all bound listeners */
|
||||||
int (*disable_all)(struct protocol *proto); /* disable 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_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 (*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 */
|
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 */
|
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 */
|
#endif /* _TYPES_PROTOCOL_H */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
16
src/checks.c
16
src/checks.c
@ -1545,7 +1545,7 @@ static int connect_conn_chk(struct task *t)
|
|||||||
struct protocol *proto;
|
struct protocol *proto;
|
||||||
struct tcpcheck_rule *tcp_rule = NULL;
|
struct tcpcheck_rule *tcp_rule = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
int quickack;
|
int connflags = 0;
|
||||||
|
|
||||||
/* we cannot have a connection here */
|
/* we cannot have a connection here */
|
||||||
if (conn)
|
if (conn)
|
||||||
@ -1637,14 +1637,15 @@ static int connect_conn_chk(struct task *t)
|
|||||||
cs_attach(cs, check, &check_conn_cb);
|
cs_attach(cs, check, &check_conn_cb);
|
||||||
|
|
||||||
/* only plain tcp-check supports quick ACK */
|
/* only plain tcp-check supports quick ACK */
|
||||||
quickack = check->type == 0 || check->type == PR_O2_TCPCHK_CHK;
|
if (check->type != 0)
|
||||||
|
connflags |= CONNECT_HAS_DATA;
|
||||||
if (tcp_rule && tcp_rule->action == TCPCHK_ACT_EXPECT)
|
if ((check->type == 0 || check->type == PR_O2_TCPCHK_CHK) &&
|
||||||
quickack = 0;
|
(!tcp_rule || tcp_rule->action != TCPCHK_ACT_EXPECT))
|
||||||
|
connflags |= CONNECT_DELACK_ALWAYS;
|
||||||
|
|
||||||
ret = SF_ERR_INTERNAL;
|
ret = SF_ERR_INTERNAL;
|
||||||
if (proto && proto->connect)
|
if (proto && proto->connect)
|
||||||
ret = proto->connect(conn, check->type, quickack ? 2 : 0);
|
ret = proto->connect(conn, connflags);
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_OPENSSL
|
#ifdef USE_OPENSSL
|
||||||
@ -2845,8 +2846,7 @@ static int tcpcheck_main(struct check *check)
|
|||||||
ret = SF_ERR_INTERNAL;
|
ret = SF_ERR_INTERNAL;
|
||||||
if (proto && proto->connect)
|
if (proto && proto->connect)
|
||||||
ret = proto->connect(conn,
|
ret = proto->connect(conn,
|
||||||
1 /* I/O polling is always needed */,
|
CONNECT_HAS_DATA /* I/O polling is always needed */ | (next && next->action == TCPCHK_ACT_EXPECT) ? 0 : CONNECT_DELACK_ALWAYS);
|
||||||
(next && next->action == TCPCHK_ACT_EXPECT) ? 0 : 2);
|
|
||||||
if (check->current_step->conn_opts & TCPCHK_OPT_SEND_PROXY) {
|
if (check->current_step->conn_opts & TCPCHK_OPT_SEND_PROXY) {
|
||||||
conn->send_proxy_ofs = 1;
|
conn->send_proxy_ofs = 1;
|
||||||
conn->flags |= CO_FL_SEND_PROXY;
|
conn->flags |= CO_FL_SEND_PROXY;
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
static void sockpair_add_listener(struct listener *listener, int port);
|
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_listener(struct listener *listener, char *errmsg, int errlen);
|
||||||
static int sockpair_bind_listeners(struct protocol *proto, 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 */
|
/* Note: must not be declared <const> as its list will be overwritten */
|
||||||
static struct protocol proto_sockpair = {
|
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
|
* The connection's fd is inserted only when SF_ERR_NONE is returned, otherwise
|
||||||
* it's invalid and the caller has nothing to do.
|
* 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;
|
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 */
|
/* 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)
|
if (global.tune.server_sndbuf)
|
||||||
setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &global.tune.server_sndbuf, sizeof(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
|
* layer when the connection is already OK otherwise we'll have
|
||||||
* no other opportunity to do it later (eg: health checks).
|
* 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 */
|
conn_xprt_want_send(conn); /* prepare to send data if any */
|
||||||
|
|
||||||
return SF_ERR_NONE; /* connection is OK */
|
return SF_ERR_NONE; /* connection is OK */
|
||||||
|
@ -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
|
* 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
|
* 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
|
* 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
|
* 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 :
|
* 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
|
* - 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
|
* - CONNECT_DELACK_SMART_CONNECT = delayed ACK if backend has tcp-smart-connect, regardless of data
|
||||||
* - 2 = delayed ACK regardless of backend options
|
* - CONNECT_DELACK_ALWAYS = delayed ACK regardless of backend options
|
||||||
*
|
*
|
||||||
* Note that a pending send_proxy message accounts for data.
|
* 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.
|
* 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;
|
int fd;
|
||||||
struct server *srv;
|
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
|
* machine with the first ACK. We only do this if there are pending
|
||||||
* data in the buffer.
|
* 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));
|
setsockopt(fd, IPPROTO_TCP, TCP_QUICKACK, &zero, sizeof(zero));
|
||||||
#endif
|
#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
|
* layer when the connection is already OK otherwise we'll have
|
||||||
* no other opportunity to do it later (eg: health checks).
|
* 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 */
|
conn_xprt_want_send(conn); /* prepare to send data if any */
|
||||||
|
|
||||||
return SF_ERR_NONE; /* connection is OK */
|
return SF_ERR_NONE; /* connection is OK */
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
static int uxst_bind_listener(struct listener *listener, char *errmsg, int errlen);
|
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_bind_listeners(struct protocol *proto, char *errmsg, int errlen);
|
||||||
static int uxst_unbind_listeners(struct protocol *proto);
|
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 void uxst_add_listener(struct listener *listener, int port);
|
||||||
static int uxst_pause_listener(struct listener *l);
|
static int uxst_pause_listener(struct listener *l);
|
||||||
static int uxst_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir);
|
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
|
* The connection's fd is inserted only when SF_ERR_NONE is returned, otherwise
|
||||||
* it's invalid and the caller has nothing to do.
|
* 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;
|
int fd;
|
||||||
struct server *srv;
|
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 */
|
/* 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)
|
if (global.tune.server_sndbuf)
|
||||||
setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &global.tune.server_sndbuf, sizeof(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
|
* layer when the connection is already OK otherwise we'll have
|
||||||
* no other opportunity to do it later (eg: health checks).
|
* 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 */
|
conn_xprt_want_send(conn); /* prepare to send data if any */
|
||||||
|
|
||||||
return SF_ERR_NONE; /* connection is OK */
|
return SF_ERR_NONE; /* connection is OK */
|
||||||
|
Loading…
Reference in New Issue
Block a user