From: Willy Tarreau Date: Thu, 23 Jan 2020 15:27:54 +0000 (+0100) Subject: MEDIUM: connection: use CO_FL_WAIT_XPRT more consistently than L4/L6/HANDSHAKE X-Git-Tag: v2.2-dev2~91 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=911db9bd295a0a63652feaf64d1f4cce1325f9d1;p=thirdparty%2Fhaproxy.git MEDIUM: connection: use CO_FL_WAIT_XPRT more consistently than L4/L6/HANDSHAKE As mentioned in commit c192b0ab95 ("MEDIUM: connection: remove CO_FL_CONNECTED and only rely on CO_FL_WAIT_*"), there is a lack of consistency on which flags are checked among L4/L6/HANDSHAKE depending on the code areas. A number of sample fetch functions only check for L4L6 to report MAY_CHANGE, some places only check for HANDSHAKE and many check both L4L6 and HANDSHAKE. This patch starts to make all of this more consistent by introducing a new mask CO_FL_WAIT_XPRT which is the union of L4/L6/HANDSHAKE and reports whether the transport layer is ready or not. All inconsistent call places were updated to rely on this one each time the goal was to check for the readiness of the transport layer. --- diff --git a/include/types/connection.h b/include/types/connection.h index 0e98b64a24..74b550adf0 100644 --- a/include/types/connection.h +++ b/include/types/connection.h @@ -192,6 +192,7 @@ enum { /* below we have all handshake flags grouped into one */ CO_FL_HANDSHAKE = CO_FL_SEND_PROXY | CO_FL_ACCEPT_PROXY | CO_FL_ACCEPT_CIP | CO_FL_SOCKS4_SEND | CO_FL_SOCKS4_RECV, + CO_FL_WAIT_XPRT = CO_FL_WAIT_L4_CONN | CO_FL_HANDSHAKE | CO_FL_WAIT_L6_CONN, CO_FL_SSL_WAIT_HS = 0x08000000, /* wait for an SSL handshake to complete */ diff --git a/src/backend.c b/src/backend.c index 97a62eb464..2cf8c751ac 100644 --- a/src/backend.c +++ b/src/backend.c @@ -626,7 +626,7 @@ int assign_server(struct stream *s) tmpsrv->nbpend + 1 < s->be->max_ka_queue))) && srv_currently_usable(tmpsrv)) { list_for_each_entry(conn, &srv_list->conn_list, session_list) { - if (!(conn->flags & CO_FL_WAIT_L4L6)) { + if (!(conn->flags & CO_FL_WAIT_XPRT)) { srv = tmpsrv; s->target = &srv->obj_type; goto out_ok; @@ -1220,7 +1220,7 @@ int connect_server(struct stream *s) } } - if (((!reuse || (srv_conn && (srv_conn->flags & CO_FL_WAIT_L4L6))) + if (((!reuse || (srv_conn && (srv_conn->flags & CO_FL_WAIT_XPRT))) && ha_used_fds > global.tune.pool_high_count) && srv && srv->idle_orphan_conns) { struct connection *tokill_conn; @@ -1934,7 +1934,7 @@ void back_handle_st_con(struct stream *s) } /* first, let's see if we've made any progress on this connection */ - if (!conn->mux && !(conn->flags & CO_FL_WAIT_L4L6)) { + if (!conn->mux && !(conn->flags & CO_FL_WAIT_XPRT)) { /* connection finished to set up */ struct server *srv; diff --git a/src/checks.c b/src/checks.c index 2a495efae7..233d754e11 100644 --- a/src/checks.c +++ b/src/checks.c @@ -886,7 +886,7 @@ static void __event_srv_chk_r(struct conn_stream *cs) } /* the rest of the code below expects the connection to be ready! */ - if (conn->flags & CO_FL_WAIT_L4L6 && !done) + if (conn->flags & CO_FL_WAIT_XPRT && !done) goto wait_more_data; /* Intermediate or complete response received. @@ -1392,7 +1392,7 @@ static void __event_srv_chk_r(struct conn_stream *cs) default: /* good connection is enough for pure TCP check */ - if (!(conn->flags & CO_FL_WAIT_L4L6) && !check->type) { + if (!(conn->flags & CO_FL_WAIT_XPRT) && !check->type) { if (check->use_ssl) set_server_check_status(check, HCHK_STATUS_L6OK, NULL); else @@ -1477,7 +1477,7 @@ static int wake_srv_chk(struct conn_stream *cs) chk_report_conn_err(check, errno, 0); task_wakeup(check->task, TASK_WOKEN_IO); } - else if (!(conn->flags & CO_FL_HANDSHAKE) && !check->type) { + else if (!(conn->flags & CO_FL_WAIT_XPRT) && !check->type) { /* we may get here if only a connection probe was required : we * don't have any data to send nor anything expected in response, * so the completion of the connection establishment is enough. @@ -2285,7 +2285,7 @@ static struct task *process_chk_conn(struct task *t, void *context, unsigned sho * sending since otherwise we won't be woken up. */ __event_srv_chk_w(cs); - if (!(conn->flags & CO_FL_WAIT_L4_CONN) || + if (!(conn->flags & CO_FL_WAIT_XPRT) || !(check->wait_list.events & SUB_RETRY_SEND)) __event_srv_chk_r(cs); } @@ -2352,7 +2352,7 @@ static struct task *process_chk_conn(struct task *t, void *context, unsigned sho */ if (check->result == CHK_RES_UNKNOWN) { /* good connection is enough for pure TCP check */ - if (!(conn->flags & CO_FL_WAIT_L4L6) && !check->type) { + if (!(conn->flags & CO_FL_WAIT_XPRT) && !check->type) { if (check->use_ssl) set_server_check_status(check, HCHK_STATUS_L6OK, NULL); else @@ -2785,7 +2785,7 @@ static int tcpcheck_main(struct check *check) next = LIST_NEXT(&next->list, struct tcpcheck_rule *, list); if ((check->current_step || &next->list == head) && - (conn->flags & (CO_FL_WAIT_L4L6 | CO_FL_HANDSHAKE))) { + (conn->flags & CO_FL_WAIT_XPRT)) { /* we allow up to min(inter, timeout.connect) for a connection * to establish but only when timeout.check is set * as it may be to short for a full check otherwise @@ -3034,7 +3034,7 @@ static int tcpcheck_main(struct check *check) break; /* don't do anything until the connection is established */ - if (conn->flags & CO_FL_WAIT_L4L6) + if (conn->flags & CO_FL_WAIT_XPRT) break; } /* end 'connect' */ @@ -3233,7 +3233,7 @@ static int tcpcheck_main(struct check *check) } /* end loop over double chained step list */ /* don't do anything until the connection is established */ - if (conn->flags & CO_FL_WAIT_L4L6) { + if (conn->flags & CO_FL_WAIT_XPRT) { /* update expire time, should be done by process_chk */ /* we allow up to min(inter, timeout.connect) for a connection * to establish but only when timeout.check is set diff --git a/src/connection.c b/src/connection.c index 319f85e5f1..dcecf14096 100644 --- a/src/connection.c +++ b/src/connection.c @@ -136,7 +136,7 @@ void conn_fd_handler(int fd) * informations to create one, typically from the ALPN. If we're * done with the handshake, attempt to create one. */ - if (unlikely(!conn->mux) && !(conn->flags & CO_FL_HANDSHAKE)) + if (unlikely(!conn->mux) && !(conn->flags & CO_FL_WAIT_XPRT)) if (conn_create_mux(conn) < 0) return; @@ -155,9 +155,8 @@ void conn_fd_handler(int fd) * Note that the wake callback is allowed to release the connection and * the fd (and return < 0 in this case). */ - if ((io_available || (((conn->flags ^ flags) & CO_FL_NOTIFY_DONE) || - ((flags & (CO_FL_WAIT_L4L6|CO_FL_HANDSHAKE)) && - (conn->flags & (CO_FL_WAIT_L4L6|CO_FL_HANDSHAKE)) == 0))) && + if ((io_available || ((conn->flags ^ flags) & CO_FL_NOTIFY_DONE) || + ((flags & CO_FL_WAIT_XPRT) && !(conn->flags & CO_FL_WAIT_XPRT))) && conn->mux && conn->mux->wake && conn->mux->wake(conn) < 0) return; @@ -1530,7 +1529,7 @@ int smp_fetch_fc_rcvd_proxy(const struct arg *args, struct sample *smp, const ch if (!conn) return 0; - if (conn->flags & CO_FL_WAIT_L4L6) { + if (conn->flags & CO_FL_WAIT_XPRT) { smp->flags |= SMP_F_MAY_CHANGE; return 0; } @@ -1551,7 +1550,7 @@ int smp_fetch_fc_pp_authority(const struct arg *args, struct sample *smp, const if (!conn) return 0; - if (conn->flags & CO_FL_WAIT_L4L6) { + if (conn->flags & CO_FL_WAIT_XPRT) { smp->flags |= SMP_F_MAY_CHANGE; return 0; } diff --git a/src/mux_fcgi.c b/src/mux_fcgi.c index 85bc2cbd1d..3fb85b5712 100644 --- a/src/mux_fcgi.c +++ b/src/mux_fcgi.c @@ -2770,7 +2770,7 @@ static int fcgi_send(struct fcgi_conn *fconn) } - if (conn->flags & (CO_FL_HANDSHAKE|CO_FL_WAIT_L4_CONN|CO_FL_WAIT_L6_CONN)) { + if (conn->flags & CO_FL_WAIT_XPRT) { /* a handshake was requested */ goto schedule; } @@ -2954,7 +2954,7 @@ static int fcgi_process(struct fcgi_conn *fconn) * any stream that was waiting for it. */ if (!(fconn->flags & FCGI_CF_WAIT_FOR_HS) && - (conn->flags & (CO_FL_EARLY_SSL_HS | CO_FL_HANDSHAKE | CO_FL_EARLY_DATA)) == CO_FL_EARLY_DATA) { + (conn->flags & (CO_FL_EARLY_SSL_HS | CO_FL_WAIT_XPRT | CO_FL_EARLY_DATA)) == CO_FL_EARLY_DATA) { struct eb32_node *node; struct fcgi_strm *fstrm; @@ -3016,7 +3016,7 @@ static int fcgi_ctl(struct connection *conn, enum mux_ctl_type mux_ctl, void *ou int ret = 0; switch (mux_ctl) { case MUX_STATUS: - if (!(conn->flags & CO_FL_WAIT_L4L6)) + if (!(conn->flags & CO_FL_WAIT_XPRT)) ret |= MUX_STATUS_READY; return ret; default: diff --git a/src/mux_h1.c b/src/mux_h1.c index eee595c4ee..212a279c62 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -2667,7 +2667,7 @@ static size_t h1_snd_buf(struct conn_stream *cs, struct buffer *buf, size_t coun * now, as we don't want to remove everything from the channel buffer * before we're sure we can send it. */ - if (h1c->conn->flags & (CO_FL_WAIT_L4L6|CO_FL_HANDSHAKE)) { + if (h1c->conn->flags & CO_FL_WAIT_XPRT) { TRACE_LEAVE(H1_EV_STRM_SEND, h1c->conn, h1s); return 0; } @@ -2781,7 +2781,7 @@ static int h1_ctl(struct connection *conn, enum mux_ctl_type mux_ctl, void *outp int ret = 0; switch (mux_ctl) { case MUX_STATUS: - if (!(conn->flags & CO_FL_WAIT_L4L6)) + if (!(conn->flags & CO_FL_WAIT_XPRT)) ret |= MUX_STATUS_READY; return ret; default: diff --git a/src/mux_h2.c b/src/mux_h2.c index 9c1a77e66a..1a1d2ff532 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -3425,7 +3425,7 @@ static int h2_send(struct h2c *h2c) return 1; } - if (conn->flags & (CO_FL_HANDSHAKE|CO_FL_WAIT_L4_CONN|CO_FL_WAIT_L6_CONN)) { + if (conn->flags & CO_FL_WAIT_XPRT) { /* a handshake was requested */ goto schedule; } @@ -3578,7 +3578,7 @@ static int h2_process(struct h2c *h2c) * any stream that was waiting for it. */ if (!(h2c->flags & H2_CF_WAIT_FOR_HS) && - (conn->flags & (CO_FL_EARLY_SSL_HS | CO_FL_HANDSHAKE | CO_FL_EARLY_DATA)) == CO_FL_EARLY_DATA) { + (conn->flags & (CO_FL_EARLY_SSL_HS | CO_FL_WAIT_XPRT | CO_FL_EARLY_DATA)) == CO_FL_EARLY_DATA) { struct eb32_node *node; struct h2s *h2s; diff --git a/src/mux_pt.c b/src/mux_pt.c index d9da001f0a..4418a65f40 100644 --- a/src/mux_pt.c +++ b/src/mux_pt.c @@ -150,7 +150,7 @@ static int mux_pt_wake(struct connection *conn) /* If we had early data, and we're done with the handshake * then whe know the data are safe, and we can remove the flag. */ - if ((conn->flags & (CO_FL_EARLY_DATA | CO_FL_EARLY_SSL_HS | CO_FL_HANDSHAKE)) == + if ((conn->flags & (CO_FL_EARLY_DATA | CO_FL_EARLY_SSL_HS | CO_FL_WAIT_XPRT)) == CO_FL_EARLY_DATA) conn->flags &= ~CO_FL_EARLY_DATA; return ret; @@ -348,7 +348,7 @@ static int mux_pt_ctl(struct connection *conn, enum mux_ctl_type mux_ctl, void * int ret = 0; switch (mux_ctl) { case MUX_STATUS: - if (!(conn->flags & CO_FL_WAIT_L4L6)) + if (!(conn->flags & CO_FL_WAIT_XPRT)) ret |= MUX_STATUS_READY; return ret; default: diff --git a/src/session.c b/src/session.c index d80392d1d2..c62cc1097e 100644 --- a/src/session.c +++ b/src/session.c @@ -270,7 +270,7 @@ int session_accept_fd(struct listener *l, int cfd, struct sockaddr_storage *addr * v | | | * conn -- owner ---> task <-----+ */ - if (cli_conn->flags & (CO_FL_HANDSHAKE | CO_FL_EARLY_SSL_HS)) { + if (cli_conn->flags & (CO_FL_WAIT_XPRT | CO_FL_EARLY_SSL_HS)) { if (unlikely((sess->task = task_new(tid_bit)) == NULL)) goto out_free_sess; diff --git a/src/ssl_sock.c b/src/ssl_sock.c index dafd258e87..cbf51b796c 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -6517,7 +6517,7 @@ static size_t ssl_sock_to_buf(struct connection *conn, void *xprt_ctx, struct bu } #endif - if (conn->flags & (CO_FL_HANDSHAKE | CO_FL_SSL_WAIT_HS)) + if (conn->flags & (CO_FL_WAIT_XPRT | CO_FL_SSL_WAIT_HS)) /* a handshake was requested */ return 0; @@ -6628,7 +6628,7 @@ static size_t ssl_sock_from_buf(struct connection *conn, void *xprt_ctx, const s if (!ctx) goto out_error; - if (conn->flags & (CO_FL_HANDSHAKE | CO_FL_SSL_WAIT_HS | CO_FL_EARLY_SSL_HS)) + if (conn->flags & (CO_FL_WAIT_XPRT | CO_FL_SSL_WAIT_HS | CO_FL_EARLY_SSL_HS)) /* a handshake was requested */ return 0; @@ -6830,7 +6830,7 @@ static void ssl_sock_shutw(struct connection *conn, void *xprt_ctx, int clean) { struct ssl_sock_ctx *ctx = xprt_ctx; - if (conn->flags & (CO_FL_HANDSHAKE | CO_FL_SSL_WAIT_HS)) + if (conn->flags & (CO_FL_WAIT_XPRT | CO_FL_SSL_WAIT_HS)) return; if (!clean) /* don't sent notify on SSL_shutdown */ @@ -7411,7 +7411,7 @@ smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char ctx = conn->xprt_ctx; - if (conn->flags & CO_FL_WAIT_L6_CONN) { + if (conn->flags & CO_FL_WAIT_XPRT) { smp->flags |= SMP_F_MAY_CHANGE; return 0; } @@ -7442,7 +7442,7 @@ smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, return 0; ctx = conn->xprt_ctx; - if (conn->flags & CO_FL_WAIT_L6_CONN) { + if (conn->flags & CO_FL_WAIT_XPRT) { smp->flags |= SMP_F_MAY_CHANGE; return 0; } @@ -7489,7 +7489,7 @@ smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *k ctx = conn->xprt_ctx; - if (conn->flags & CO_FL_WAIT_L6_CONN) { + if (conn->flags & CO_FL_WAIT_XPRT) { smp->flags |= SMP_F_MAY_CHANGE; return 0; } @@ -7536,7 +7536,7 @@ smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, return 0; ctx = conn->xprt_ctx; - if (conn->flags & CO_FL_WAIT_L6_CONN) { + if (conn->flags & CO_FL_WAIT_XPRT) { smp->flags |= SMP_F_MAY_CHANGE; return 0; } @@ -7582,7 +7582,7 @@ smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char return 0; ctx = conn->xprt_ctx; - if (conn->flags & CO_FL_WAIT_L6_CONN) { + if (conn->flags & CO_FL_WAIT_XPRT) { smp->flags |= SMP_F_MAY_CHANGE; return 0; } @@ -7628,7 +7628,7 @@ smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, return 0; ctx = conn->xprt_ctx; - if (conn->flags & CO_FL_WAIT_L6_CONN) { + if (conn->flags & CO_FL_WAIT_XPRT) { smp->flags |= SMP_F_MAY_CHANGE; return 0; } @@ -7690,7 +7690,7 @@ smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char return 0; ctx = conn->xprt_ctx; - if (conn->flags & CO_FL_WAIT_L6_CONN) { + if (conn->flags & CO_FL_WAIT_XPRT) { smp->flags |= SMP_F_MAY_CHANGE; return 0; } @@ -7736,7 +7736,7 @@ smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, return 0; ctx = conn->xprt_ctx; - if (conn->flags & CO_FL_WAIT_L6_CONN) { + if (conn->flags & CO_FL_WAIT_XPRT) { smp->flags |= SMP_F_MAY_CHANGE; return 0; } @@ -7792,7 +7792,7 @@ smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, return 0; ctx = conn->xprt_ctx; - if (conn->flags & CO_FL_WAIT_L6_CONN) { + if (conn->flags & CO_FL_WAIT_XPRT) { smp->flags |= SMP_F_MAY_CHANGE; return 0; } @@ -7825,7 +7825,7 @@ smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char * return 0; ctx = conn->xprt_ctx; - if (conn->flags & CO_FL_WAIT_L6_CONN) { + if (conn->flags & CO_FL_WAIT_XPRT) { smp->flags |= SMP_F_MAY_CHANGE; return 0; } @@ -7865,7 +7865,7 @@ smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char * return 0; ctx = conn->xprt_ctx; - if (conn->flags & CO_FL_WAIT_L6_CONN) { + if (conn->flags & CO_FL_WAIT_XPRT) { smp->flags |= SMP_F_MAY_CHANGE; return 0; } @@ -7917,7 +7917,7 @@ smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char * return 0; ctx = conn->xprt_ctx; - if (conn->flags & CO_FL_WAIT_L6_CONN) { + if (conn->flags & CO_FL_WAIT_XPRT) { smp->flags |= SMP_F_MAY_CHANGE; return 0; } @@ -8397,7 +8397,7 @@ smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const cha return 0; ctx = conn->xprt_ctx; - if (conn->flags & CO_FL_WAIT_L6_CONN) { + if (conn->flags & CO_FL_WAIT_XPRT) { smp->flags |= SMP_F_MAY_CHANGE; return 0; } @@ -8435,7 +8435,7 @@ smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *k return 0; ctx = conn->xprt_ctx; - if (conn->flags & CO_FL_WAIT_L6_CONN) { + if (conn->flags & CO_FL_WAIT_XPRT) { smp->flags = SMP_F_MAY_CHANGE; return 0; } @@ -8458,7 +8458,7 @@ smp_fetch_ssl_c_ca_err_depth(const struct arg *args, struct sample *smp, const c if (!conn || conn->xprt != &ssl_sock) return 0; - if (conn->flags & CO_FL_WAIT_L6_CONN) { + if (conn->flags & CO_FL_WAIT_XPRT) { smp->flags = SMP_F_MAY_CHANGE; return 0; } @@ -8482,7 +8482,7 @@ smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, if (!conn || conn->xprt != &ssl_sock) return 0; - if (conn->flags & CO_FL_WAIT_L6_CONN) { + if (conn->flags & CO_FL_WAIT_XPRT) { smp->flags = SMP_F_MAY_CHANGE; return 0; } @@ -8507,7 +8507,7 @@ smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *k if (!conn || conn->xprt != &ssl_sock) return 0; - if (conn->flags & CO_FL_WAIT_L6_CONN) { + if (conn->flags & CO_FL_WAIT_XPRT) { smp->flags = SMP_F_MAY_CHANGE; return 0; } diff --git a/src/stream_interface.c b/src/stream_interface.c index 16bd3f8f7c..0a2e7d1d0c 100644 --- a/src/stream_interface.c +++ b/src/stream_interface.c @@ -451,7 +451,7 @@ static void stream_int_notify(struct stream_interface *si) struct connection *conn = objt_cs(si->end) ? objt_cs(si->end)->conn : NULL; if (((oc->flags & (CF_SHUTW|CF_SHUTW_NOW)) == CF_SHUTW_NOW) && - (si->state == SI_ST_EST) && (!conn || !(conn->flags & (CO_FL_HANDSHAKE | CO_FL_EARLY_SSL_HS)))) + (si->state == SI_ST_EST) && (!conn || !(conn->flags & (CO_FL_WAIT_XPRT | CO_FL_EARLY_SSL_HS)))) si_shutw(si); oc->wex = TICK_ETERNITY; } @@ -607,14 +607,14 @@ static int si_cs_process(struct conn_stream *cs) * in the event there's an analyser waiting for the end of * the handshake. */ - if (!(conn->flags & (CO_FL_HANDSHAKE | CO_FL_EARLY_SSL_HS)) && + if (!(conn->flags & (CO_FL_WAIT_XPRT | CO_FL_EARLY_SSL_HS)) && (cs->flags & CS_FL_WAIT_FOR_HS)) { cs->flags &= ~CS_FL_WAIT_FOR_HS; task_wakeup(si_task(si), TASK_WOKEN_MSG); } if (!si_state_in(si->state, SI_SB_EST|SI_SB_DIS|SI_SB_CLO) && - (conn->flags & (CO_FL_WAIT_L4L6 | CO_FL_HANDSHAKE)) == 0) { + (conn->flags & CO_FL_WAIT_XPRT) == 0) { si->exp = TICK_ETERNITY; oc->flags |= CF_WRITE_NULL; if (si->state == SI_ST_CON)