diff --git a/dev/flags/flags.c b/dev/flags/flags.c index 5473903ce..8317b7550 100644 --- a/dev/flags/flags.c +++ b/dev/flags/flags.c @@ -219,6 +219,8 @@ void show_cs_flags(unsigned int f) printf("0\n"); return; } + SHOW_FLAG(f, CS_FL_NOLINGER); + SHOW_FLAG(f, CS_FL_NOHALF); SHOW_FLAG(f, CS_FL_ADDR_FROM_SET); SHOW_FLAG(f, CS_FL_ADDR_TO_SET); SHOW_FLAG(f, CS_FL_ISBACK); @@ -267,8 +269,6 @@ void show_si_flags(unsigned int f) SHOW_FLAG(f, SI_FL_ISBACK); SHOW_FLAG(f, SI_FL_DONT_WAKE); SHOW_FLAG(f, SI_FL_INDEP_STR); - SHOW_FLAG(f, SI_FL_NOLINGER); - SHOW_FLAG(f, SI_FL_NOHALF); SHOW_FLAG(f, SI_FL_SRC_ADDR); SHOW_FLAG(f, SI_FL_WANT_GET); SHOW_FLAG(f, SI_FL_CLEAN_ABRT); diff --git a/include/haproxy/conn_stream-t.h b/include/haproxy/conn_stream-t.h index 55f338b09..877bace13 100644 --- a/include/haproxy/conn_stream-t.h +++ b/include/haproxy/conn_stream-t.h @@ -82,6 +82,9 @@ enum { CS_FL_ADDR_FROM_SET = 0x00000002, /* source address is set */ CS_FL_ADDR_TO_SET = 0x00000004, /* destination address is set */ + + CS_FL_NOLINGER = 0x00000008, /* may close without lingering. One-shot. */ + CS_FL_NOHALF = 0x00000010, /* no half close, close both sides at once */ }; /* cs_shutr() modes */ diff --git a/include/haproxy/stream_interface-t.h b/include/haproxy/stream_interface-t.h index 7766f4cb5..ebd9d3515 100644 --- a/include/haproxy/stream_interface-t.h +++ b/include/haproxy/stream_interface-t.h @@ -88,8 +88,6 @@ enum { SI_FL_ISBACK = 0x00000010, /* 0 for front-side SI, 1 for back-side */ SI_FL_DONT_WAKE = 0x00000020, /* resync in progress, don't wake up */ SI_FL_INDEP_STR = 0x00000040, /* independent streams = don't update rex on write */ - SI_FL_NOLINGER = 0x00000080, /* may close without lingering. One-shot. */ - SI_FL_NOHALF = 0x00000100, /* no half close, close both sides at once */ SI_FL_SRC_ADDR = 0x00001000, /* get the source ip/port with getsockname */ /* unused: 0x00000200 */ SI_FL_WANT_GET = 0x00004000, /* a stream-int would like to get some data from the buffer */ diff --git a/src/backend.c b/src/backend.c index 5429e352a..56e3c1780 100644 --- a/src/backend.c +++ b/src/backend.c @@ -1641,7 +1641,7 @@ static int connect_server(struct stream *s) /* disable lingering */ if (s->be->options & PR_O_TCP_NOLING) - cs_si(s->csb)->flags |= SI_FL_NOLINGER; + s->csb->flags |= CS_FL_NOLINGER; if (s->flags & SF_SRV_REUSED) { _HA_ATOMIC_INC(&s->be->be_counters.reuse); @@ -2175,7 +2175,7 @@ void back_handle_st_con(struct stream *s) if ((rep->flags & CF_SHUTW) || ((req->flags & CF_SHUTW_NOW) && (channel_is_empty(req) || (s->be->options & PR_O_ABRT_CLOSE)))) { - cs->si->flags |= SI_FL_NOLINGER; + cs->flags |= CS_FL_NOLINGER; si_shutw(cs->si); cs->si->err_type |= SI_ET_CONN_ABRT; if (s->srv_error) @@ -2391,7 +2391,7 @@ void back_handle_st_rdy(struct stream *s) ((req->flags & CF_SHUTW_NOW) && (channel_is_empty(req) || (s->be->options & PR_O_ABRT_CLOSE)))) { /* give up */ - cs->si->flags |= SI_FL_NOLINGER; + cs->flags |= CS_FL_NOLINGER; si_shutw(cs->si); cs->si->err_type |= SI_ET_CONN_ABRT; if (s->srv_error) diff --git a/src/cli.c b/src/cli.c index 56629b0ec..4d0e293fc 100644 --- a/src/cli.c +++ b/src/cli.c @@ -2684,7 +2684,7 @@ int pcli_wait_for_response(struct stream *s, struct channel *rep, int an_bit) pcli_write_prompt(s); - cs_si(s->csb)->flags |= SI_FL_NOLINGER | SI_FL_NOHALF; + s->csb->flags |= CS_FL_NOLINGER | CS_FL_NOHALF; si_shutr(cs_si(s->csb)); si_shutw(cs_si(s->csb)); diff --git a/src/dns.c b/src/dns.c index 92f37b4f7..f60639a7d 100644 --- a/src/dns.c +++ b/src/dns.c @@ -916,7 +916,7 @@ static struct appctx *dns_session_create(struct dns_session *ds) s = DISGUISE(cs_strm(cs)); s->csb->dst = addr; - cs_si(s->csb)->flags |= SI_FL_NOLINGER; + s->csb->flags |= CS_FL_NOLINGER; s->target = &ds->dss->srv->obj_type; s->flags = SF_ASSIGNED|SF_ADDR_SET; diff --git a/src/http_ana.c b/src/http_ana.c index a1b6b1fdb..c1700f2f9 100644 --- a/src/http_ana.c +++ b/src/http_ana.c @@ -1112,7 +1112,7 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit) if (s->be->options & PR_O_ABRT_CLOSE) { channel_auto_read(req); if ((req->flags & (CF_SHUTR|CF_READ_NULL)) && !(txn->flags & TX_CON_WANT_TUN)) - cs_si(s->csb)->flags |= SI_FL_NOLINGER; + s->csb->flags |= CS_FL_NOLINGER; channel_auto_close(req); } else if (s->txn->meth == HTTP_METH_POST) { @@ -1358,7 +1358,7 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit) stream_inc_http_fail_ctr(s); } - si_b->flags |= SI_FL_NOLINGER; + s->csb->flags |= CS_FL_NOLINGER; http_reply_and_close(s, txn->status, http_error_message(s)); if (!(s->flags & SF_ERR_MASK)) @@ -1388,7 +1388,7 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit) txn->status = 504; stream_inc_http_fail_ctr(s); - si_b->flags |= SI_FL_NOLINGER; + s->csb->flags |= CS_FL_NOLINGER; http_reply_and_close(s, txn->status, http_error_message(s)); if (!(s->flags & SF_ERR_MASK)) @@ -1445,7 +1445,7 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit) txn->status = 502; stream_inc_http_fail_ctr(s); - si_b->flags |= SI_FL_NOLINGER; + s->csb->flags |= CS_FL_NOLINGER; http_reply_and_close(s, txn->status, http_error_message(s)); if (!(s->flags & SF_ERR_MASK)) @@ -1740,7 +1740,7 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit) if (!(s->flags & SF_FINST_MASK)) s->flags |= SF_FINST_H; - si_b->flags |= SI_FL_NOLINGER; + s->csb->flags |= CS_FL_NOLINGER; DBG_TRACE_DEVEL("leaving on error", STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA|STRM_EV_HTTP_ERR, s, txn); return 0; @@ -2050,7 +2050,7 @@ int http_process_res_common(struct stream *s, struct channel *rep, int an_bit, s return_prx_cond: s->logs.t_data = -1; /* was not a valid response */ - cs_si(s->csb)->flags |= SI_FL_NOLINGER; + s->csb->flags |= CS_FL_NOLINGER; if (!(s->flags & SF_ERR_MASK)) s->flags |= SF_ERR_PRXCOND; @@ -4318,7 +4318,7 @@ static void http_end_request(struct stream *s) /* if the server closes the connection, we want to immediately react * and close the socket to save packets and syscalls. */ - cs_si(s->csb)->flags |= SI_FL_NOHALF; + s->csb->flags |= CS_FL_NOHALF; /* In any case we've finished parsing the request so we must * disable Nagle when sending data because 1) we're not going @@ -4393,7 +4393,7 @@ static void http_end_request(struct stream *s) http_msg_closed: /* if we don't know whether the server will close, we need to hard close */ if (txn->rsp.flags & HTTP_MSGF_XFER_LEN) - cs_si(s->csb)->flags |= SI_FL_NOLINGER; /* we want to close ASAP */ + s->csb->flags |= CS_FL_NOLINGER; /* we want to close ASAP */ /* see above in MSG_DONE why we only do this in these states */ if (!(s->be->options & PR_O_ABRT_CLOSE)) channel_dont_read(chn); diff --git a/src/http_client.c b/src/http_client.c index 83faffed2..7adc82de9 100644 --- a/src/http_client.c +++ b/src/http_client.c @@ -526,7 +526,7 @@ struct appctx *httpclient_start(struct httpclient *hc) } s->csb->dst = addr; - cs_si(s->csb)->flags |= SI_FL_NOLINGER; + s->csb->flags |= CS_FL_NOLINGER; s->flags |= SF_ASSIGNED|SF_ADDR_SET; s->res.flags |= CF_READ_DONTWAIT; diff --git a/src/peers.c b/src/peers.c index 4d86126f2..7c40e4541 100644 --- a/src/peers.c +++ b/src/peers.c @@ -3210,7 +3210,7 @@ static struct appctx *peer_session_create(struct peers *peers, struct peer *peer /* initiate an outgoing connection */ s->csb->dst = addr; - cs_si(s->csb)->flags |= SI_FL_NOLINGER; + s->csb->flags |= CS_FL_NOLINGER; s->flags = SF_ASSIGNED|SF_ADDR_SET; s->target = peer_session_target(peer, s); diff --git a/src/sink.c b/src/sink.c index e7ad4bd03..8dfe33e9f 100644 --- a/src/sink.c +++ b/src/sink.c @@ -657,7 +657,7 @@ static struct appctx *sink_forward_session_create(struct sink *sink, struct sink s = DISGUISE(cs_strm(cs)); s->csb->dst = addr; - cs_si(s->csb)->flags |= SI_FL_NOLINGER; + s->csb->flags |= CS_FL_NOLINGER; s->target = &sft->srv->obj_type; s->flags = SF_ASSIGNED|SF_ADDR_SET; diff --git a/src/stream.c b/src/stream.c index fbf32ebcf..a42c8968f 100644 --- a/src/stream.c +++ b/src/stream.c @@ -1638,26 +1638,26 @@ struct task *process_stream(struct task *t, void *context, unsigned int state) channel_check_timeouts(req); if (unlikely((req->flags & (CF_SHUTW|CF_WRITE_TIMEOUT)) == CF_WRITE_TIMEOUT)) { - si_b->flags |= SI_FL_NOLINGER; + s->csb->flags |= CS_FL_NOLINGER; si_shutw(si_b); } if (unlikely((req->flags & (CF_SHUTR|CF_READ_TIMEOUT)) == CF_READ_TIMEOUT)) { - if (si_f->flags & SI_FL_NOHALF) - si_f->flags |= SI_FL_NOLINGER; + if (s->csf->flags & CS_FL_NOHALF) + s->csf->flags |= CS_FL_NOLINGER; si_shutr(si_f); } channel_check_timeouts(res); if (unlikely((res->flags & (CF_SHUTW|CF_WRITE_TIMEOUT)) == CF_WRITE_TIMEOUT)) { - si_f->flags |= SI_FL_NOLINGER; + s->csf->flags |= CS_FL_NOLINGER; si_shutw(si_f); } if (unlikely((res->flags & (CF_SHUTR|CF_READ_TIMEOUT)) == CF_READ_TIMEOUT)) { - if (si_b->flags & SI_FL_NOHALF) - si_b->flags |= SI_FL_NOLINGER; + if (s->csb->flags & CS_FL_NOHALF) + s->csb->flags |= CS_FL_NOLINGER; si_shutr(si_b); } @@ -2236,7 +2236,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state) if (unlikely((req->flags & (CF_SHUTW|CF_SHUTW_NOW)) == CF_SHUTW_NOW && channel_is_empty(req))) { if (req->flags & CF_READ_ERROR) - si_b->flags |= SI_FL_NOLINGER; + s->csb->flags |= CS_FL_NOLINGER; si_shutw(si_b); } @@ -2247,8 +2247,8 @@ struct task *process_stream(struct task *t, void *context, unsigned int state) /* shutdown(read) pending */ if (unlikely((req->flags & (CF_SHUTR|CF_SHUTR_NOW)) == CF_SHUTR_NOW)) { - if (si_f->flags & SI_FL_NOHALF) - si_f->flags |= SI_FL_NOLINGER; + if (s->csf->flags & CS_FL_NOHALF) + s->csf->flags |= CS_FL_NOLINGER; si_shutr(si_f); } @@ -2372,8 +2372,8 @@ struct task *process_stream(struct task *t, void *context, unsigned int state) /* shutdown(read) pending */ if (unlikely((res->flags & (CF_SHUTR|CF_SHUTR_NOW)) == CF_SHUTR_NOW)) { - if (si_b->flags & SI_FL_NOHALF) - si_b->flags |= SI_FL_NOLINGER; + if (s->csb->flags & CS_FL_NOHALF) + s->csb->flags |= CS_FL_NOLINGER; si_shutr(si_b); } diff --git a/src/stream_interface.c b/src/stream_interface.c index dcbe1a172..2c196ce44 100644 --- a/src/stream_interface.c +++ b/src/stream_interface.c @@ -162,7 +162,7 @@ void si_retnclose(struct stream_interface *si, * This function performs a shutdown-read on a detached stream interface in a * connected or init state (it does nothing for other states). It either shuts * the read side or marks itself as closed. The buffer flags are updated to - * reflect the new state. If the stream interface has SI_FL_NOHALF, we also + * reflect the new state. If the stream interface has CS_FL_NOHALF, we also * forward the close to the write side. The owner task is woken up if it exists. */ static void stream_int_shutr(struct stream_interface *si) @@ -182,7 +182,7 @@ static void stream_int_shutr(struct stream_interface *si) si->state = SI_ST_DIS; __cs_strm(si->cs)->conn_exp = TICK_ETERNITY; } - else if (si->flags & SI_FL_NOHALF) { + else if (si->cs->flags & CS_FL_NOHALF) { /* we want to immediately forward this close to the write side */ return stream_int_shutw(si); } @@ -222,10 +222,10 @@ static void stream_int_shutw(struct stream_interface *si) /* we have to shut before closing, otherwise some short messages * may never leave the system, especially when there are remaining * unread data in the socket input buffer, or when nolinger is set. - * However, if SI_FL_NOLINGER is explicitly set, we know there is + * However, if CS_FL_NOLINGER is explicitly set, we know there is * no risk so we close both sides immediately. */ - if (!(si->cs->endp->flags & CS_EP_ERROR) && !(si->flags & SI_FL_NOLINGER) && + if (!(si->cs->endp->flags & CS_EP_ERROR) && !(si->cs->flags & CS_FL_NOLINGER) && !(ic->flags & (CF_SHUTR|CF_DONT_READ))) return; @@ -238,7 +238,7 @@ static void stream_int_shutw(struct stream_interface *si) si->state = SI_ST_DIS; /* fall through */ default: - si->flags &= ~SI_FL_NOLINGER; + si->cs->flags &= ~CS_FL_NOLINGER; si_rx_shut_blk(si); ic->flags |= CF_SHUTR; ic->rex = TICK_ETERNITY; @@ -1017,7 +1017,7 @@ void si_update_both(struct stream_interface *si_f, struct stream_interface *si_b * a connection in a connected or init state (it does nothing for other * states). It either shuts the read side or marks itself as closed. The buffer * flags are updated to reflect the new state. If the stream interface has - * SI_FL_NOHALF, we also forward the close to the write side. If a control + * CS_FL_NOHALF, we also forward the close to the write side. If a control * layer is defined, then it is supposed to be a socket layer and file * descriptors are then shutdown or closed accordingly. The function * automatically disables polling if needed. @@ -1043,7 +1043,7 @@ static void stream_int_shutr_conn(struct stream_interface *si) si->state = SI_ST_DIS; __cs_strm(cs)->conn_exp = TICK_ETERNITY; } - else if (si->flags & SI_FL_NOHALF) { + else if (si->cs->flags & CS_FL_NOHALF) { /* we want to immediately forward this close to the write side */ return stream_int_shutw_conn(si); } @@ -1083,14 +1083,14 @@ static void stream_int_shutw_conn(struct stream_interface *si) /* we have to shut before closing, otherwise some short messages * may never leave the system, especially when there are remaining * unread data in the socket input buffer, or when nolinger is set. - * However, if SI_FL_NOLINGER is explicitly set, we know there is + * However, if CS_FL_NOLINGER is explicitly set, we know there is * no risk so we close both sides immediately. */ if (cs->endp->flags & CS_EP_ERROR) { /* quick close, the socket is already shut anyway */ } - else if (si->flags & SI_FL_NOLINGER) { + else if (cs->flags & CS_FL_NOLINGER) { /* unclean data-layer shutdown, typically an aborted request * or a forwarded shutdown from a client to a server due to * option abortonclose. No need for the TLS layer to try to @@ -1124,7 +1124,7 @@ static void stream_int_shutw_conn(struct stream_interface *si) si->state = SI_ST_DIS; /* fall through */ default: - si->flags &= ~SI_FL_NOLINGER; + cs->flags &= ~CS_FL_NOLINGER; si_rx_shut_blk(si); ic->flags |= CF_SHUTR; ic->rex = TICK_ETERNITY; @@ -1574,7 +1574,7 @@ static int si_cs_recv(struct conn_stream *cs) /* * This function propagates a null read received on a socket-based connection. - * It updates the stream interface. If the stream interface has SI_FL_NOHALF, + * It updates the stream interface. If the stream interface has CS_FL_NOHALF, * the close is also forwarded to the write side as an abort. */ static void stream_int_read0(struct stream_interface *si) @@ -1597,7 +1597,7 @@ static void stream_int_read0(struct stream_interface *si) if (oc->flags & CF_SHUTW) goto do_close; - if (si->flags & SI_FL_NOHALF) { + if (cs->flags & CS_FL_NOHALF) { /* we want to immediately forward this close to the write side */ /* force flag on ssl to keep stream in cache */ cs_shutw(cs, CS_SHW_SILENT); @@ -1663,7 +1663,7 @@ void si_applet_wake_cb(struct stream_interface *si) * This function performs a shutdown-read on a stream interface attached to an * applet in a connected or init state (it does nothing for other states). It * either shuts the read side or marks itself as closed. The buffer flags are - * updated to reflect the new state. If the stream interface has SI_FL_NOHALF, + * updated to reflect the new state. If the stream interface has CS_FL_NOHALF, * we also forward the close to the write side. The owner task is woken up if * it exists. */ @@ -1689,7 +1689,7 @@ static void stream_int_shutr_applet(struct stream_interface *si) si->state = SI_ST_DIS; __cs_strm(si->cs)->conn_exp = TICK_ETERNITY; } - else if (si->flags & SI_FL_NOHALF) { + else if (si->cs->flags & CS_FL_NOHALF) { /* we want to immediately forward this close to the write side */ return stream_int_shutw_applet(si); } @@ -1730,10 +1730,10 @@ static void stream_int_shutw_applet(struct stream_interface *si) /* we have to shut before closing, otherwise some short messages * may never leave the system, especially when there are remaining * unread data in the socket input buffer, or when nolinger is set. - * However, if SI_FL_NOLINGER is explicitly set, we know there is + * However, if CS_FL_NOLINGER is explicitly set, we know there is * no risk so we close both sides immediately. */ - if (!(si->cs->endp->flags & CS_EP_ERROR) && !(si->flags & SI_FL_NOLINGER) && + if (!(si->cs->endp->flags & CS_EP_ERROR) && !(si->cs->flags & CS_FL_NOLINGER) && !(ic->flags & (CF_SHUTR|CF_DONT_READ))) return; @@ -1747,7 +1747,7 @@ static void stream_int_shutw_applet(struct stream_interface *si) si->state = SI_ST_DIS; /* fall through */ default: - si->flags &= ~SI_FL_NOLINGER; + si->cs->flags &= ~CS_FL_NOLINGER; si_rx_shut_blk(si); ic->flags |= CF_SHUTR; ic->rex = TICK_ETERNITY; diff --git a/src/tcp_act.c b/src/tcp_act.c index 005051509..19e7eeaf8 100644 --- a/src/tcp_act.c +++ b/src/tcp_act.c @@ -289,7 +289,7 @@ static enum act_return tcp_exec_action_silent_drop(struct act_rule *rule, struct * is present, returning with ERR will cause lingering to be disabled. */ if (strm) - strm->csf->si->flags |= SI_FL_NOLINGER; + strm->csf->flags |= CS_FL_NOLINGER; if (conn->flags & CO_FL_FDLESS) goto out; diff --git a/src/tcp_rules.c b/src/tcp_rules.c index 6c45f483e..4293cbda1 100644 --- a/src/tcp_rules.c +++ b/src/tcp_rules.c @@ -392,7 +392,7 @@ int tcp_inspect_response(struct stream *s, struct channel *rep, int an_bit) goto deny; } else if (rule->action == ACT_TCP_CLOSE) { - chn_prod(rep)->si->flags |= SI_FL_NOLINGER | SI_FL_NOHALF; + chn_prod(rep)->flags |= CS_FL_NOLINGER | CS_FL_NOHALF; cs_must_kill_conn(chn_prod(rep)); si_shutr(chn_prod(rep)->si); si_shutw(chn_prod(rep)->si);