diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h index cb69f2c2c7b..58ee70db1f4 100644 --- a/bin/varnishd/cache/cache.h +++ b/bin/varnishd/cache/cache.h @@ -395,9 +395,9 @@ struct busyobj { #include "tbl/bo_flags.h" /* Timeouts */ - vtim_dur connect_timeout; - vtim_dur first_byte_timeout; - vtim_dur between_bytes_timeout; + vtim_dur bereq_connect_timeout; + vtim_dur beresp_start_timeout; + vtim_dur beresp_idle_timeout; /* Timers */ vtim_real t_first; /* First timestamp logged */ @@ -562,13 +562,16 @@ struct sess { vtim_real t_open; /* fd accepted */ vtim_real t_idle; /* fd accepted or resp sent */ - vtim_dur timeout_idle; - vtim_dur timeout_linger; - vtim_dur send_timeout; - vtim_dur idle_send_timeout; + vtim_dur idle_timeout; + vtim_dur linger_interrupt; + vtim_dur resp_send_timeout; + vtim_dur resp_idle_interrupt; }; #define SESS_TMO(sp, tmo) \ + (isnan((sp)->tmo) ? cache_param->sess_##tmo : (sp)->tmo) + +#define RESP_TMO(sp, tmo) \ (isnan((sp)->tmo) ? cache_param->tmo : (sp)->tmo) /* Prototypes etc ----------------------------------------------------*/ diff --git a/bin/varnishd/cache/cache_acceptor.c b/bin/varnishd/cache/cache_acceptor.c index afdfbf22260..664b52268f0 100644 --- a/bin/varnishd/cache/cache_acceptor.c +++ b/bin/varnishd/cache/cache_acceptor.c @@ -204,9 +204,9 @@ vca_sock_opt_init(void) SET_VAL(SO_LINGER, so, lg, disable_so_linger); SET_VAL(SO_KEEPALIVE, so, i, enable_so_keepalive); NEW_VAL(SO_SNDTIMEO, so, tv, - VTIM_timeval(cache_param->idle_send_timeout)); + VTIM_timeval(cache_param->resp_idle_interrupt)); NEW_VAL(SO_RCVTIMEO, so, tv, - VTIM_timeval(cache_param->timeout_idle)); + VTIM_timeval(cache_param->sess_idle_timeout)); SET_VAL(TCP_NODELAY, so, i, enable_tcp_nodelay); #if defined(HAVE_TCP_KEEP) NEW_VAL(TCP_KEEPIDLE, so, i, diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index 7ac117cc407..6ec10431430 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -152,7 +152,7 @@ vbe_dir_getfd(VRT_CTX, struct worker *wrk, VCL_BACKEND dir, struct backend *bp, bo->htc->doclose = SC_NULL; CHECK_OBJ_NOTNULL(bo->htc->doclose, STREAM_CLOSE_MAGIC); - FIND_TMO(connect_timeout, tmod, bo, bp); + FIND_TMO(bereq_connect_timeout, tmod, bo, bp); pfd = VCP_Get(bp->conn_pool, tmod, wrk, force_fresh, &err); if (pfd == NULL) { Lck_Lock(bp->director->mtx); @@ -211,10 +211,10 @@ vbe_dir_getfd(VRT_CTX, struct worker *wrk, VCL_BACKEND dir, struct backend *bp, bo->htc->priv = pfd; bo->htc->rfd = fdp; bo->htc->doclose = SC_NULL; - FIND_TMO(first_byte_timeout, - bo->htc->first_byte_timeout, bo, bp); - FIND_TMO(between_bytes_timeout, - bo->htc->between_bytes_timeout, bo, bp); + FIND_TMO(beresp_start_timeout, + bo->htc->beresp_start_timeout, bo, bp); + FIND_TMO(beresp_idle_timeout, + bo->htc->beresp_idle_timeout, bo, bp); return (pfd); } @@ -303,7 +303,7 @@ vbe_dir_gethdrs(VRT_CTX, VCL_BACKEND d) if (i == 0 && PFD_State(pfd) != PFD_STATE_USED) { if (VCP_Wait(wrk, pfd, VTIM_real() + - bo->htc->first_byte_timeout) != 0) { + bo->htc->beresp_start_timeout) != 0) { bo->htc->doclose = SC_RX_TIMEOUT; VSLb(bo->vsl, SLT_FetchError, "first byte timeout (reused connection)"); diff --git a/bin/varnishd/cache/cache_conn_pool.c b/bin/varnishd/cache/cache_conn_pool.c index 2a2a76ca8cc..4b5f73af5fc 100644 --- a/bin/varnishd/cache/cache_conn_pool.c +++ b/bin/varnishd/cache/cache_conn_pool.c @@ -278,7 +278,7 @@ VCP_Recycle(const struct worker *wrk, struct pfd **pfdp) pfd->waited->idle = VTIM_real(); pfd->state = PFD_STATE_AVAIL; pfd->waited->func = vcp_handle; - pfd->waited->tmo = cache_param->backend_idle_timeout; + pfd->waited->tmo = cache_param->backend_pool_timeout; if (Wait_Enter(wrk->pool->waiter, pfd->waited)) { cp->methods->close(pfd); memset(pfd, 0x33, sizeof *pfd); diff --git a/bin/varnishd/cache/cache_panic.c b/bin/varnishd/cache/cache_panic.c index 473c2f1aa71..ba12980ed8e 100644 --- a/bin/varnishd/cache/cache_panic.c +++ b/bin/varnishd/cache/cache_panic.c @@ -171,10 +171,10 @@ pan_htc(struct vsb *vsb, const struct http_conn *htc) (intmax_t)htc->content_length); VSB_printf(vsb, "body_status = %s,\n", htc->body_status ? htc->body_status->name : "NULL"); - VSB_printf(vsb, "first_byte_timeout = %f,\n", - htc->first_byte_timeout); - VSB_printf(vsb, "between_bytes_timeout = %f,\n", - htc->between_bytes_timeout); + VSB_printf(vsb, "beresp_start_timeout = %f,\n", + htc->beresp_start_timeout); + VSB_printf(vsb, "beresp_idle_timeout = %f,\n", + htc->beresp_idle_timeout); VSB_indent(vsb, -2); VSB_cat(vsb, "},\n"); } diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c index d0834fc6c56..760bbeddc4b 100644 --- a/bin/varnishd/cache/cache_session.c +++ b/bin/varnishd/cache/cache_session.c @@ -431,10 +431,10 @@ SES_New(struct pool *pp) sp->t_open = NAN; sp->t_idle = NAN; - sp->timeout_idle = NAN; - sp->timeout_linger = NAN; - sp->send_timeout = NAN; - sp->idle_send_timeout = NAN; + sp->idle_timeout = NAN; + sp->linger_interrupt = NAN; + sp->resp_send_timeout = NAN; + sp->resp_idle_interrupt = NAN; Lck_New(&sp->mtx, lck_sess); CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); return (sp); @@ -529,7 +529,7 @@ SES_Wait(struct sess *sp, const struct transport *xp) wp->priv2 = (uintptr_t)xp; wp->idle = sp->t_idle; wp->func = ses_handle; - wp->tmo = SESS_TMO(sp, timeout_idle); + wp->tmo = SESS_TMO(sp, idle_timeout); if (Wait_Enter(pp->waiter, wp)) SES_Delete(sp, SC_PIPE_OVERFLOW, NAN); } diff --git a/bin/varnishd/cache/cache_varnishd.h b/bin/varnishd/cache/cache_varnishd.h index f5c37744850..ac9b6fc2e74 100644 --- a/bin/varnishd/cache/cache_varnishd.h +++ b/bin/varnishd/cache/cache_varnishd.h @@ -108,8 +108,8 @@ struct http_conn { void *priv; /* Timeouts */ - vtim_dur first_byte_timeout; - vtim_dur between_bytes_timeout; + vtim_dur beresp_start_timeout; + vtim_dur beresp_idle_timeout; }; enum htc_status_e { diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c index 8d2da90ca64..1fb1ec4786e 100644 --- a/bin/varnishd/cache/cache_vrt_var.c +++ b/bin/varnishd/cache/cache_vrt_var.c @@ -331,28 +331,28 @@ VRT_l_client_identity(VRT_CTX, const char *str, VCL_STRANDS s) /*--------------------------------------------------------------------*/ -#define BEREQ_TIMEOUT(which) \ +#define FETCH_TIMEOUT(msg, which) \ VCL_VOID \ -VRT_l_bereq_##which(VRT_CTX, VCL_DURATION num) \ +VRT_l_##msg##_##which(VRT_CTX, VCL_DURATION num) \ { \ \ CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); \ CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC); \ - ctx->bo->which = (num > 0.0 ? num : 0.0); \ + ctx->bo->msg##_##which = (num > 0.0 ? num : 0.0); \ } \ \ VCL_DURATION \ -VRT_r_bereq_##which(VRT_CTX) \ +VRT_r_##msg##_##which(VRT_CTX) \ { \ \ CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); \ CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC); \ - return (ctx->bo->which); \ + return (ctx->bo->msg##_##which); \ } -BEREQ_TIMEOUT(connect_timeout) -BEREQ_TIMEOUT(first_byte_timeout) -BEREQ_TIMEOUT(between_bytes_timeout) +FETCH_TIMEOUT(bereq, connect_timeout) +FETCH_TIMEOUT(beresp, idle_timeout) +FETCH_TIMEOUT(beresp, start_timeout) /*--------------------------------------------------------------------*/ @@ -973,6 +973,37 @@ VRT_r_resp_do_esi(VRT_CTX) return (!ctx->req->disable_esi); } +/*-------------------------------------------------------------------- + * XXX: Response timeouts are currently broken since they operate at + * the session level. Customizing a response timeout for one client + * transaction will still leak into the next HTTP/1 transaction or + * simply result in concurrent meddlings on h2 sessions. In particular + * socket options should only apply to HTTP/1 and this should probably + * be moved to protocol-specific code. + */ + +#define RESP_TIMEOUT(x, setter) \ +VCL_VOID \ +VRT_l_resp_##x(VRT_CTX, VCL_DURATION d) \ +{ \ + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); \ + CHECK_OBJ_NOTNULL(ctx->sp, SESS_MAGIC); \ + d = vmax(d, 0.0); \ + setter; \ + ctx->sp->resp_##x = d; \ +} \ + \ +VCL_DURATION \ +VRT_r_resp_##x(VRT_CTX) \ +{ \ + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); \ + CHECK_OBJ_NOTNULL(ctx->sp, SESS_MAGIC); \ + return (RESP_TMO(ctx->sp, resp_##x)); \ +} + +RESP_TIMEOUT(idle_interrupt, VTCP_set_send_timeout(ctx->sp->fd, d)) +RESP_TIMEOUT(send_timeout, ) + /*--------------------------------------------------------------------*/ #define VRT_BODY_L(which) \ @@ -1050,34 +1081,23 @@ HTTP_VAR(beresp) /*--------------------------------------------------------------------*/ -static inline void -set_idle_send_timeout(const struct sess *sp, VCL_DURATION d) -{ - struct timeval tv = VTIM_timeval(d); - VTCP_Assert(setsockopt(sp->fd, SOL_SOCKET, SO_SNDTIMEO, - &tv, sizeof tv)); -} - -#define SESS_VAR_DUR(x, setter) \ +#define SESS_VAR_DUR(x) \ VCL_VOID \ -VRT_l_sess_##x(VRT_CTX, VCL_DURATION d) \ +VRT_l_sess_##x(VRT_CTX, VCL_DURATION d) \ { \ CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); \ CHECK_OBJ_NOTNULL(ctx->sp, SESS_MAGIC); \ d = vmax(d, 0.0); \ - setter; \ ctx->sp->x = d; \ } \ \ VCL_DURATION \ -VRT_r_sess_##x(VRT_CTX) \ +VRT_r_sess_##x(VRT_CTX) \ { \ CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); \ CHECK_OBJ_NOTNULL(ctx->sp, SESS_MAGIC); \ return (SESS_TMO(ctx->sp, x)); \ } -SESS_VAR_DUR(timeout_idle, ) -SESS_VAR_DUR(timeout_linger, ) -SESS_VAR_DUR(send_timeout, ) -SESS_VAR_DUR(idle_send_timeout, set_idle_send_timeout(ctx->sp, d)) +SESS_VAR_DUR(idle_timeout) +SESS_VAR_DUR(linger_interrupt) diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c index 2db4f8efa8f..b49fa5e00b2 100644 --- a/bin/varnishd/http1/cache_http1_deliver.c +++ b/bin/varnishd/http1/cache_http1_deliver.c @@ -139,7 +139,7 @@ V1D_Deliver(struct req *req, struct boc *boc, int sendbody) AZ(req->wrk->v1l); V1L_Open(req->wrk, req->wrk->aws, &req->sp->fd, req->vsl, - req->t_prev + SESS_TMO(req->sp, send_timeout), + req->t_prev + RESP_TMO(req->sp, resp_send_timeout), cache_param->http1_iovs); if (WS_Overflowed(req->wrk->aws)) { diff --git a/bin/varnishd/http1/cache_http1_fetch.c b/bin/varnishd/http1/cache_http1_fetch.c index 7d0e6c01510..e369a93ebc1 100644 --- a/bin/varnishd/http1/cache_http1_fetch.c +++ b/bin/varnishd/http1/cache_http1_fetch.c @@ -97,7 +97,7 @@ V1F_SendReq(struct worker *wrk, struct busyobj *bo, uint64_t *ctr_hdrbytes, } VTCP_blocking(*htc->rfd); /* XXX: we should timeout instead */ - /* XXX: need a send_timeout for the backend side */ + /* XXX: need a bereq_send_timeout */ V1L_Open(wrk, wrk->aws, htc->rfd, bo->vsl, nan(""), 0); hdrbytes = HTTP1_Write(wrk, hp, HTTP1_Req); @@ -190,9 +190,9 @@ V1F_FetchRespHdr(struct busyobj *bo) CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC); CHECK_OBJ_NOTNULL(bo->htc, HTTP_CONN_MAGIC); - t = VTIM_real() + htc->first_byte_timeout; + t = VTIM_real() + htc->beresp_start_timeout; hs = HTC_RxStuff(htc, HTTP1_Complete, NULL, NULL, - t, NAN, htc->between_bytes_timeout, cache_param->http_resp_size); + t, NAN, htc->beresp_idle_timeout, cache_param->http_resp_size); if (hs != HTC_S_COMPLETE) { bo->acct.beresp_hdrbytes += htc->rxbuf_e - htc->rxbuf_b; @@ -225,7 +225,7 @@ V1F_FetchRespHdr(struct busyobj *bo) } return (htc->rxbuf_e == htc->rxbuf_b ? 1 : -1); } - VTCP_set_read_timeout(*htc->rfd, htc->between_bytes_timeout); + VTCP_set_read_timeout(*htc->rfd, htc->beresp_idle_timeout); hp = bo->beresp; diff --git a/bin/varnishd/http1/cache_http1_fsm.c b/bin/varnishd/http1/cache_http1_fsm.c index 641f6e805d5..a76556798c8 100644 --- a/bin/varnishd/http1/cache_http1_fsm.c +++ b/bin/varnishd/http1/cache_http1_fsm.c @@ -319,8 +319,8 @@ HTTP1_Session(struct worker *wrk, struct req *req) hs = HTC_RxStuff(req->htc, HTTP1_Complete, &req->t_first, &req->t_req, - sp->t_idle + SESS_TMO(sp, timeout_linger), - sp->t_idle + SESS_TMO(sp, timeout_idle), + sp->t_idle + SESS_TMO(sp, linger_interrupt), + sp->t_idle + SESS_TMO(sp, idle_timeout), NAN, cache_param->http_req_size); assert(!WS_IsReserved(req->htc->ws)); diff --git a/bin/varnishd/http1/cache_http1_pipe.c b/bin/varnishd/http1/cache_http1_pipe.c index d273ae4f440..a874586b0a1 100644 --- a/bin/varnishd/http1/cache_http1_pipe.c +++ b/bin/varnishd/http1/cache_http1_pipe.c @@ -143,7 +143,7 @@ V1P_Process(const struct req *req, int fd, struct v1p_acct *v1a) fds[0].revents = 0; fds[1].revents = 0; i = poll(fds, 2, - (int)(cache_param->pipe_timeout * 1e3)); + (int)(cache_param->pipe_idle_timeout * 1e3)); if (i < 1) break; if (fds[0].revents && diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c index c408acd65a5..e8faafb1f29 100644 --- a/bin/varnishd/http2/cache_http2_proto.c +++ b/bin/varnishd/http2/cache_http2_proto.c @@ -1039,7 +1039,7 @@ h2_vfp_body(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, ssize_t *lp) break; i = Lck_CondWaitTimeout(r2->cond, &h2->sess->mtx, - SESS_TMO(h2->sess, timeout_idle)); + SESS_TMO(h2->sess, idle_timeout)); if (i == ETIMEDOUT) { retval = VFP_ERROR; break; @@ -1241,7 +1241,7 @@ h2_stream_tmo(struct h2_sess *h2, const struct h2_req *r2, vtim_real now) CHECK_OBJ_NOTNULL(r2, H2_REQ_MAGIC); Lck_AssertHeld(&h2->sess->mtx); - /* NB: when now is NAN, it means that idle_send_timeout was hit + /* NB: when now is NAN, it means that resp_idle_interrupt was hit * on a lock condwait operation. */ if (isnan(now)) @@ -1251,17 +1251,17 @@ h2_stream_tmo(struct h2_sess *h2, const struct h2_req *r2, vtim_real now) return (0); if (isnan(now) || (r2->t_winupd != 0 && - now - r2->t_winupd > SESS_TMO(h2->sess, idle_send_timeout))) { + now - r2->t_winupd > RESP_TMO(h2->sess, resp_idle_interrupt))) { VSLb(h2->vsl, SLT_Debug, - "H2: stream %u: Hit idle_send_timeout waiting for" + "H2: stream %u: Hit resp_idle_interrupt waiting for" " WINDOW_UPDATE", r2->stream); r = 1; } if (r == 0 && r2->t_send != 0 && - now - r2->t_send > SESS_TMO(h2->sess, send_timeout)) { + now - r2->t_send > RESP_TMO(h2->sess, resp_send_timeout)) { VSLb(h2->vsl, SLT_Debug, - "H2: stream %u: Hit send_timeout", r2->stream); + "H2: stream %u: Hit resp_send_timeout", r2->stream); r = 1; } @@ -1365,7 +1365,7 @@ h2_rxframe(struct worker *wrk, struct h2_sess *h2) h2->sess->t_idle = VTIM_real(); hs = HTC_RxStuff(h2->htc, h2_frame_complete, NULL, NULL, NAN, - h2->sess->t_idle + SESS_TMO(h2->sess, timeout_idle), + h2->sess->t_idle + SESS_TMO(h2->sess, idle_timeout), NAN, h2->local_settings.max_frame_size + 9); switch (hs) { case HTC_S_COMPLETE: diff --git a/bin/varnishd/http2/cache_http2_send.c b/bin/varnishd/http2/cache_http2_send.c index 2b66615cac1..71182ffd931 100644 --- a/bin/varnishd/http2/cache_http2_send.c +++ b/bin/varnishd/http2/cache_http2_send.c @@ -56,20 +56,20 @@ h2_cond_wait(pthread_cond_t *cond, struct h2_sess *h2, struct h2_req *r2) Lck_AssertHeld(&h2->sess->mtx); - if (cache_param->idle_send_timeout > 0.) - tmo = cache_param->idle_send_timeout; + if (cache_param->resp_idle_interrupt > 0.) + tmo = cache_param->resp_idle_interrupt; r = Lck_CondWaitTimeout(cond, &h2->sess->mtx, tmo); assert(r == 0 || r == ETIMEDOUT); now = VTIM_real(); - /* NB: when we grab idle_send_timeout before acquiring the session - * lock we may time out, but once we wake up both send_timeout and - * idle_send_timeout may have changed meanwhile. For this reason + /* NB: when we grab resp_idle_interrupt before acquiring the session + * lock we may time out, but once we wake up both resp_send_timeout + * and resp_idle_interrupt may have changed meanwhile. For this reason * h2_stream_tmo() may not log what timed out and we need to call * again with a magic NAN "now" that indicates to h2_stream_tmo() - * that the stream reached the idle_send_timeout via the lock and + * that the stream reached the resp_idle_interrupt via the lock and * force it to log it. */ if (h2_stream_tmo(h2, r2, now)) diff --git a/bin/varnishd/http2/cache_http2_session.c b/bin/varnishd/http2/cache_http2_session.c index 846b319f183..a59e58e4163 100644 --- a/bin/varnishd/http2/cache_http2_session.c +++ b/bin/varnishd/http2/cache_http2_session.c @@ -289,8 +289,9 @@ h2_ou_session(struct worker *wrk, struct h2_sess *h2, /* Wait for PRISM response */ hs = HTC_RxStuff(h2->htc, H2_prism_complete, - NULL, NULL, NAN, h2->sess->t_idle + cache_param->timeout_idle, NAN, - sizeof H2_prism); + NULL, NULL, NAN, + h2->sess->t_idle + cache_param->sess_idle_timeout, + NAN, sizeof H2_prism); if (hs != HTC_S_COMPLETE) { VSLb(h2->vsl, SLT_Debug, "H2: No/Bad OU PRISM (hs=%d)", hs); r2->scheduled = 0; diff --git a/bin/varnishd/mgt/mgt_child.c b/bin/varnishd/mgt/mgt_child.c index da4308c81ec..bfa813be0ce 100644 --- a/bin/varnishd/mgt/mgt_child.c +++ b/bin/varnishd/mgt/mgt_child.c @@ -422,7 +422,8 @@ mgt_launch_child(struct cli *cli) AN(child_std_vlu); /* Wait for cache/cache_cli.c::CLI_Run() to check in */ - if (VCLI_ReadResult(child_cli_in, &u, NULL, mgt_param.cli_timeout)) { + if (VCLI_ReadResult(child_cli_in, &u, NULL, + mgt_param.cli_resp_timeout)) { assert(u == CLIS_COMMS); pidr = waitpid(pid, &i, 0); assert(pidr == pid); @@ -535,7 +536,7 @@ mgt_reap_child(void) XXXAN(vsb); /* Wait for child to die */ - for (i = 0; i < mgt_param.cli_timeout * 10; i++) { + for (i = 0; i < mgt_param.cli_resp_timeout * 10; i++) { r = waitpid(child_pid, &status, WNOHANG); if (r == child_pid) break; @@ -627,9 +628,9 @@ mgt_reap_child(void) * for us to do but to drag it behind the barn and get it over with. * * The typical case is where the child process fails to return a reply - * before the cli_timeout expires. This invalidates the CLI pipes for - * all future use, as we don't know if the child was just slow and the - * result gets piped later on, or if the child is catatonic. + * before the cli_resp_timeout expires. This invalidates the CLI pipes + * for all future use, as we don't know if the child was just slow and + * the result gets piped later on, or if the child is catatonic. */ void diff --git a/bin/varnishd/mgt/mgt_cli.c b/bin/varnishd/mgt/mgt_cli.c index 5692335a506..1b6a75cde2a 100644 --- a/bin/varnishd/mgt/mgt_cli.c +++ b/bin/varnishd/mgt/mgt_cli.c @@ -154,7 +154,7 @@ mcf_askchild(struct cli *cli, const char * const *av, void *priv) MCH_Cli_Fail(); return; } - if (VCLI_ReadResult(cli_i, &u, &q, mgt_param.cli_timeout)) + if (VCLI_ReadResult(cli_i, &u, &q, mgt_param.cli_resp_timeout)) MCH_Cli_Fail(); VCLI_SetResult(cli, u); VCLI_Out(cli, "%s", q); @@ -205,7 +205,7 @@ mgt_cli_askchild(unsigned *status, char **resp, const char *fmt, ...) return (CLIS_COMMS); } - if (VCLI_ReadResult(cli_i, &u, resp, mgt_param.cli_timeout)) + if (VCLI_ReadResult(cli_i, &u, resp, mgt_param.cli_resp_timeout)) MCH_Cli_Fail(); *status = u; return (u == CLIS_OK || u == CLIS_TRUNCATED ? 0 : u); diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c index b34fe677204..1760616773d 100644 --- a/bin/varnishd/mgt/mgt_param.c +++ b/bin/varnishd/mgt/mgt_param.c @@ -671,6 +671,7 @@ static void mcf_wash_param(struct cli *cli, struct parspec *pp, enum mcf_which_e which, const char *name, struct vsb *vsb) { + struct parspec *pp_orig; const char *val; int err; @@ -685,8 +686,9 @@ mcf_wash_param(struct cli *cli, struct parspec *pp, enum mcf_which_e which, if (pp->func == tweak_alias) { assert(which == MCF_DEFAULT); - pp->priv = mcf_findpar(pp->def); - pp->def = NULL; + pp_orig = mcf_findpar(pp->def); + pp->priv = pp_orig; + pp->def = pp_orig->def; return; } diff --git a/bin/varnishd/mgt/mgt_param_tweak.c b/bin/varnishd/mgt/mgt_param_tweak.c index 6990f1b79f0..117df7b53d3 100644 --- a/bin/varnishd/mgt/mgt_param_tweak.c +++ b/bin/varnishd/mgt/mgt_param_tweak.c @@ -50,6 +50,36 @@ const char * const JSON_FMT = (const char *)&JSON_FMT; +/*-------------------------------------------------------------------- + * Tweak alias + */ + +static inline const struct parspec * +alias_resolve(const struct parspec *par) +{ + + AN(par); + if (par->func == tweak_alias) + par = TRUST_ME(par->priv); + AN(par); + return (par); +} + +int v_matchproto_(tweak_t) +tweak_alias(struct vsb *vsb, const struct parspec *par, const char *arg) +{ + const struct parspec *orig; + struct parspec alias[1]; + + orig = alias_resolve(par); + assert(orig != par); + memcpy(alias, orig, sizeof *orig); + alias->name = par->name; + alias->priv = TRUST_ME(orig); + alias->func = tweak_alias; + return (orig->func(vsb, alias, arg)); +} + /*-------------------------------------------------------------------- * Generic handling of double typed parameters */ @@ -139,6 +169,7 @@ int v_matchproto_(tweak_t) tweak_timeout(struct vsb *vsb, const struct parspec *par, const char *arg) { + par = alias_resolve(par); return (tweak_generic_double(vsb, arg, par, parse_duration, "%.3f")); } @@ -148,6 +179,7 @@ int v_matchproto_(tweak_t) tweak_double(struct vsb *vsb, const struct parspec *par, const char *arg) { + par = alias_resolve(par); return (tweak_generic_double(vsb, arg, par, parse_decimal, "%g")); } @@ -184,6 +216,7 @@ tweak_boolean(struct vsb *vsb, const struct parspec *par, const char *arg) volatile unsigned *dest; int val; + par = alias_resolve(par); dest = par->priv; if (arg != NULL && arg != JSON_FMT) { val = parse_boolean(vsb, arg); @@ -265,6 +298,7 @@ tweak_uint(struct vsb *vsb, const struct parspec *par, const char *arg) { volatile unsigned *dest; + par = alias_resolve(par); dest = par->priv; return (tweak_generic_uint(vsb, dest, arg, par->min, par->max, par->dyn_min_reason, par->dyn_max_reason)); @@ -354,6 +388,7 @@ tweak_bytes(struct vsb *vsb, const struct parspec *par, const char *arg) { volatile ssize_t *dest; + par = alias_resolve(par); dest = par->priv; return (tweak_generic_bytes(vsb, dest, arg, par->min, par->max)); } @@ -366,6 +401,7 @@ tweak_bytes_u(struct vsb *vsb, const struct parspec *par, const char *arg) volatile unsigned *d1; volatile ssize_t dest; + par = alias_resolve(par); d1 = par->priv; dest = *d1; if (tweak_generic_bytes(vsb, &dest, arg, par->min, par->max)) @@ -384,6 +420,7 @@ tweak_vsl_buffer(struct vsb *vsb, const struct parspec *par, const char *arg) volatile unsigned *d1; volatile ssize_t dest; + par = alias_resolve(par); d1 = par->priv; dest = *d1; if (tweak_generic_bytes(vsb, &dest, arg, par->min, par->max)) @@ -399,6 +436,7 @@ tweak_vsl_reclen(struct vsb *vsb, const struct parspec *par, const char *arg) volatile unsigned *d1; volatile ssize_t dest; + par = alias_resolve(par); d1 = par->priv; dest = *d1; if (tweak_generic_bytes(vsb, &dest, arg, par->min, par->max)) @@ -415,6 +453,7 @@ tweak_string(struct vsb *vsb, const struct parspec *par, const char *arg) { char **p = TRUST_ME(par->priv); + par = alias_resolve(par); AN(p); if (arg == NULL) { VSB_quote(vsb, *p, -1, 0); @@ -438,6 +477,7 @@ tweak_poolparam(struct vsb *vsb, const struct parspec *par, const char *arg) char **av; int retval = 0; + par = alias_resolve(par); pp = par->priv; if (arg == JSON_FMT) { VSB_cat(vsb, "{\n"); @@ -508,6 +548,8 @@ int v_matchproto_(tweak_t) tweak_thread_pool_min(struct vsb *vsb, const struct parspec *par, const char *arg) { + + par = alias_resolve(par); if (tweak_uint(vsb, par, arg)) return (-1); @@ -523,6 +565,7 @@ tweak_thread_pool_max(struct vsb *vsb, const struct parspec *par, const char *arg) { + par = alias_resolve(par); if (tweak_uint(vsb, par, arg)) return (-1); @@ -545,6 +588,8 @@ tweak_storage(struct vsb *vsb, const struct parspec *par, const char *arg) * that when the child is running calls out through CLI to change * the stevedore being used. */ + par = alias_resolve(par); + if (arg == NULL || arg == JSON_FMT) return (tweak_string(vsb, par, arg)); @@ -569,24 +614,6 @@ tweak_storage(struct vsb *vsb, const struct parspec *par, const char *arg) return (tweak_string(vsb, par, arg)); } -/*-------------------------------------------------------------------- - * Tweak alias - */ - -int v_matchproto_(tweak_t) -tweak_alias(struct vsb *vsb, const struct parspec *par, const char *arg) -{ - const struct parspec *orig; - struct parspec alias[1]; - - orig = TRUST_ME(par->priv); - AN(orig); - memcpy(alias, orig, sizeof *orig); - alias->name = par->name; - alias->priv = TRUST_ME(orig); - return (alias->func(vsb, alias, arg)); -} - /*-------------------------------------------------------------------- * Tweak bits */ @@ -706,6 +733,7 @@ int v_matchproto_(tweak_t) tweak_vsl_mask(struct vsb *vsb, const struct parspec *par, const char *arg) { + par = alias_resolve(par); return (tweak_generic_bits(vsb, par, arg, mgt_param.vsl_mask, SLT__Reserved, VSL_tags, "VSL tag", '-')); } @@ -724,6 +752,7 @@ int v_matchproto_(tweak_t) tweak_debug(struct vsb *vsb, const struct parspec *par, const char *arg) { + par = alias_resolve(par); return (tweak_generic_bits(vsb, par, arg, mgt_param.debug_bits, DBG_Reserved, debug_tags, "debug bit", '+')); } @@ -742,6 +771,7 @@ int v_matchproto_(tweak_t) tweak_experimental(struct vsb *vsb, const struct parspec *par, const char *arg) { + par = alias_resolve(par); return (tweak_generic_bits(vsb, par, arg, mgt_param.experimental_bits, EXPERIMENT_Reserved, experimental_tags, "experimental bit", '+')); } @@ -760,6 +790,7 @@ int v_matchproto_(tweak_t) tweak_feature(struct vsb *vsb, const struct parspec *par, const char *arg) { + par = alias_resolve(par); return (tweak_generic_bits(vsb, par, arg, mgt_param.feature_bits, FEATURE_Reserved, feature_tags, "feature bit", '+')); } @@ -781,9 +812,8 @@ tweak_vcc_feature(struct vsb *vsb, const struct parspec *par, const char *arg) char buf[32]; int val; - if (arg != NULL && arg != JSON_FMT && - strcmp(par->name, "vcc_feature")) { - orig = TRUST_ME(par->priv); + orig = alias_resolve(par); + if (arg != NULL && arg != JSON_FMT && orig != par) { val = parse_boolean(vsb, arg); if (val < 0) return (-1); diff --git a/bin/varnishd/proxy/cache_proxy_proto.c b/bin/varnishd/proxy/cache_proxy_proto.c index db008a2300e..2fa020a123c 100644 --- a/bin/varnishd/proxy/cache_proxy_proto.c +++ b/bin/varnishd/proxy/cache_proxy_proto.c @@ -545,7 +545,7 @@ vpx_new_session(struct worker *wrk, void *arg) HTC_RxInit(req->htc, req->ws); hs = HTC_RxStuff(req->htc, vpx_complete, NULL, NULL, NAN, - sp->t_idle + cache_param->timeout_idle, NAN, VPX_MAX_LEN); + sp->t_idle + cache_param->sess_idle_timeout, NAN, VPX_MAX_LEN); if (hs != HTC_S_COMPLETE) { Req_Release(req); SES_DeleteHS(sp, hs, NAN); diff --git a/bin/varnishtest/tests/b00078.vtc b/bin/varnishtest/tests/b00078.vtc index 86178d8a88e..a8ebcbdfc05 100644 --- a/bin/varnishtest/tests/b00078.vtc +++ b/bin/varnishtest/tests/b00078.vtc @@ -25,3 +25,5 @@ shell -err { varnish v1 -cliexpect vcc_feature "param.show vcc_allow_inline_c" varnish v1 -cliexpect vcc_feature "param.show vcc_err_unref" varnish v1 -cliexpect vcc_feature "param.show vcc_unsafe_path" + +varnish v1 -cliexpect backend_pool_timeout "param.show backend_idle_timeout" diff --git a/bin/varnishtest/tests/b00079.vtc b/bin/varnishtest/tests/b00079.vtc new file mode 100644 index 00000000000..f364eb376b9 --- /dev/null +++ b/bin/varnishtest/tests/b00079.vtc @@ -0,0 +1,22 @@ +varnishtest "deprecated variables" + +varnish v1 -errvcl "Field 'first_byte_timeout' redefined" { + backend be { + .beresp_start_timeout = 1s; + .first_byte_timeout = 1s; + } +} + +varnish v1 -errvcl "Field 'between_bytes_timeout' redefined" { + backend be { + .beresp_idle_timeout = 1s; + .between_bytes_timeout = 1s; + } +} + +varnish v1 -errvcl "Field 'connect_timeout' redefined" { + backend be { + .bereq_connect_timeout = 1s; + .connect_timeout = 1s; + } +} diff --git a/bin/varnishtest/tests/t02016.vtc b/bin/varnishtest/tests/t02016.vtc index 29ffea35480..3b297fb4803 100644 --- a/bin/varnishtest/tests/t02016.vtc +++ b/bin/varnishtest/tests/t02016.vtc @@ -8,12 +8,12 @@ server s1 { varnish v1 -cliok "param.set feature +http2" varnish v1 -vcl+backend "" -start -# coverage for send_timeout with c1 +# coverage for resp_send_timeout with c1 -varnish v1 -cliok "param.set send_timeout 1" +varnish v1 -cliok "param.set resp_send_timeout 1" logexpect l1 -v v1 { - expect * * Debug "Hit send_timeout" + expect * * Debug "Hit resp_send_timeout" } -start client c1 { @@ -44,13 +44,13 @@ client c1 { logexpect l1 -wait -# coverage for idle_send_timeout with c2 +# coverage for resp_idle_interrupt with c2 -varnish v1 -cliok "param.set idle_send_timeout 1" -varnish v1 -cliok "param.reset send_timeout" +varnish v1 -cliok "param.set resp_idle_interrupt 1" +varnish v1 -cliok "param.reset resp_send_timeout" logexpect l2 -v v1 { - expect * * Debug "Hit idle_send_timeout" + expect * * Debug "Hit resp_idle_interrupt" } -start client c2 { @@ -79,12 +79,12 @@ client c2 { logexpect l2 -wait -# coverage for idle_send_timeout change with c3 +# coverage for resp_idle_interrupt change with c3 barrier b3 cond 2 logexpect l3 -v v1 { - expect * * Debug "Hit idle_send_timeout" + expect * * Debug "Hit resp_idle_interrupt" } -start client c3 { @@ -113,7 +113,7 @@ client c3 { } -start barrier b3 sync -varnish v1 -cliok "param.reset idle_send_timeout" +varnish v1 -cliok "param.reset resp_idle_interrupt" client c3 -wait logexpect l3 -wait diff --git a/doc/sphinx/reference/index.rst b/doc/sphinx/reference/index.rst index 09ae6342dcb..897cbeea3b0 100644 --- a/doc/sphinx/reference/index.rst +++ b/doc/sphinx/reference/index.rst @@ -78,6 +78,7 @@ The Varnishd program :maxdepth: 1 VarnishD - The program which does the actual work + Run Time Parameters - The varnishd tunable parameters Varnishtest ----------- diff --git a/doc/sphinx/reference/varnish-params.rst b/doc/sphinx/reference/varnish-params.rst new file mode 100644 index 00000000000..bd4ba8f2f0d --- /dev/null +++ b/doc/sphinx/reference/varnish-params.rst @@ -0,0 +1,123 @@ +.. + Copyright (c) 2010-2022 Varnish Software AS + SPDX-License-Identifier: BSD-2-Clause + See LICENSE file for full text of license + +.. role:: ref(emphasis) + +.. _varnish-params(7): + +============== +varnish-params +============== + +--------------------------- +Varnish Run Time Parameters +--------------------------- + +:Manual section: 7 + +This document describes ``varnishd`` parameters that may be initialized +during startup with the ``-p`` option and later changed during run time +through the CLI with the ``param.set`` and ``param.reset`` commands. + +Run Time Parameter Flags +------------------------ + +Runtime parameters are marked with shorthand flags to avoid repeating +the same text over and over in the table below. The meaning of the +flags are: + +* `experimental` + + We have no solid information about good/bad/optimal values for this + parameter. Feedback with experience and observations are most + welcome. + +* `delayed` + + This parameter can be changed on the fly, but will not take effect + immediately. + +* `restart` + + The worker process must be stopped and restarted, before this + parameter takes effect. + +* `reload` + + The VCL programs must be reloaded for this parameter to take effect. + +* `wizard` + + Do not touch unless you *really* know what you're doing. + +* `only_root` + + Only works if `varnishd` is running as root. + +Default Value Exceptions on 32 bit Systems +------------------------------------------ + +Be aware that on 32 bit systems, certain default or maximum values are +reduced relative to the values listed below, in order to conserve VM +space: + +* workspace_client: 24k +* workspace_backend: 20k +* http_resp_size: 8k +* http_req_size: 12k +* gzip_buffer: 4k +* vsl_buffer: 4k +* vsl_space: 1G (maximum) +* thread_pool_stack: 64k + +Timeout Parameters +------------------ + +All timeout parameters follow a consistent naming scheme: + + __ + +The subject may be one of the following: + +- ``sess`` (client session) +- ``req`` (client request) +- ``resp`` (client response) +- ``pipe`` (client transaction turning into a pipe) +- ``bereq`` (backend request) +- ``beresp`` (backend response) +- ``backend`` (backend resource) +- ``cli`` (command line session) +- ``thread`` (worker thread) + +Common events are: + +- ``idle`` (waiting for data to be sent or received) +- ``send`` (complete delivery) +- ``start`` (first byte fetched) +- ``pool`` (time spent in a pool) + +.. More common events for later: +.. - ``fetch`` (complete fetch) +.. - ``task`` (complete task) + +Finally, there are two types of timeouts: + +- ``timeout`` (definitive failure condition) +- ``interrupt`` (triggered to verify another condition) + +List of Parameters +------------------ + +This text is produced from the same text you will find in the CLI if +you use the param.show command: + +.. include:: ../include/params.rst + +See also: +--------- + +* :ref:`varnishadm(1)` +* :ref:`varnishd(1)` +* :ref:`varnish-cli(7)` diff --git a/doc/sphinx/reference/varnishd.rst b/doc/sphinx/reference/varnishd.rst index cdb08d40ef7..c5d9f91147d 100644 --- a/doc/sphinx/reference/varnishd.rst +++ b/doc/sphinx/reference/varnishd.rst @@ -168,7 +168,7 @@ outputs documentation in reStructuredText, aka RST). -x parameter Print documentation of the runtime parameters (-p options), see - `List of Parameters`_. + :ref:`varnish-params(7)`. -x vsl @@ -235,7 +235,7 @@ Tuning options -p Set the parameter specified by param to the specified value, see - `List of Parameters`_ for details. This option can be used multiple + :ref:`varnish-params(7)` for details. This option can be used multiple times to specify multiple parameters. -s <[name=]type[,options]> @@ -250,7 +250,8 @@ Tuning options Specifies size of the space for the VSL records, shorthand for ``-p vsl_space=``. Scaling suffixes like 'K' and 'M' can be - used up to (G)igabytes. See `vsl_space`_ for more information. + used up to (G)igabytes. See :ref:`varnish-params(7)` for more + information. Security options ---------------- @@ -514,72 +515,6 @@ Note that it is necessary to include an explicit `vcl.use` command to select which VCL should be the active VCL when relying on CLI Command File to load the configurations at startup. -.. _ref-varnishd-params: - -RUN TIME PARAMETERS -=================== - -Run Time Parameter Flags ------------------------- - -Runtime parameters are marked with shorthand flags to avoid repeating -the same text over and over in the table below. The meaning of the -flags are: - -* `experimental` - - We have no solid information about good/bad/optimal values for this - parameter. Feedback with experience and observations are most - welcome. - -* `delayed` - - This parameter can be changed on the fly, but will not take effect - immediately. - -* `restart` - - The worker process must be stopped and restarted, before this - parameter takes effect. - -* `reload` - - The VCL programs must be reloaded for this parameter to take effect. - -* `wizard` - - Do not touch unless you *really* know what you're doing. - -* `only_root` - - Only works if `varnishd` is running as root. - -Default Value Exceptions on 32 bit Systems ------------------------------------------- - -Be aware that on 32 bit systems, certain default or maximum values are -reduced relative to the values listed below, in order to conserve VM -space: - -* workspace_client: 24k -* workspace_backend: 20k -* http_resp_size: 8k -* http_req_size: 12k -* gzip_buffer: 4k -* vsl_buffer: 4k -* vsl_space: 1G (maximum) -* thread_pool_stack: 64k - -.. _List of Parameters: - -List of Parameters ------------------- - -This text is produced from the same text you will find in the CLI if -you use the param.show command: - -.. include:: ../include/params.rst - EXIT CODES ========== @@ -607,6 +542,7 @@ SEE ALSO * :ref:`varnishstat(1)` * :ref:`varnishtop(1)` * :ref:`varnish-cli(7)` +* :ref:`varnish-params(7)` * :ref:`vcl(7)` HISTORY diff --git a/doc/sphinx/reference/vcl-backend.rst b/doc/sphinx/reference/vcl-backend.rst index a1f66e9f7f7..04f44354ac7 100644 --- a/doc/sphinx/reference/vcl-backend.rst +++ b/doc/sphinx/reference/vcl-backend.rst @@ -95,9 +95,9 @@ Timeout Attributes These attributes control how patient `varnishd` is during backend fetches:: - .connect_timeout = 1.4s; - .first_byte_timeout = 20s; - .between_bytes_timeout = 10s; + .bereq_connect_timeout = 1.4s; + .beresp_start_timeout = 20s; + .beresp_idle_timeout = 10s; The default values comes parameters with the same names, see :ref:`varnishd(1)`. diff --git a/doc/sphinx/reference/vcl_var.rst b/doc/sphinx/reference/vcl_var.rst index be15b644829..249fd4a304a 100644 --- a/doc/sphinx/reference/vcl_var.rst +++ b/doc/sphinx/reference/vcl_var.rst @@ -532,20 +532,14 @@ bereq.backend or backend, respectively. -bereq.between_bytes_timeout +bereq.between_bytes_timeout ``VCL <= 4.1`` - Type: DURATION - - Readable from: backend - - Writable from: backend + Type: DEPRECATED - Default: ``.between_bytes_timeout`` attribute from the - :ref:`backend_definition`, which defaults to the - ``between_bytes_timeout`` parameter, see :ref:`varnishd(1)`. + Alias of: beresp.idle_timeout - The time in seconds to wait between each received byte from the - backend. Not available in pipe mode. + This variable is deprecated and may be removed in a future + release. bereq.body @@ -574,20 +568,14 @@ bereq.connect_timeout established. -bereq.first_byte_timeout - - Type: DURATION - - Readable from: backend +bereq.first_byte_timeout ``VCL <= 4.1`` - Writable from: backend + Type: DEPRECATED - Default: ``.first_byte_timeout`` attribute from the - :ref:`backend_definition`, which defaults to the - ``first_byte_timeout`` parameter, see :ref:`varnishd(1)`. + Alias of: beresp.start_timeout - The time in seconds to wait getting the first byte back - from the backend. Not available in pipe mode. + This variable is deprecated and may be removed in a future + release. bereq.hash @@ -1009,6 +997,40 @@ beresp.reason The HTTP status message returned by the server. +beresp.idle_timeout + + Type: DURATION + + Readable from: backend + + Writable from: backend + + Default: ``.beresp_idle_timeout`` attribute from the + :ref:`backend_definition`, which defaults to the + ``beresp_idle_timeout`` parameter, see + :ref:`varnish-params(7)`. + + The time in seconds to wait between each received byte from the + backend. Not available in pipe mode. + + +beresp.start_timeout + + Type: DURATION + + Readable from: backend + + Writable from: backend + + Default: ``.beresp_start_timeout`` attribute from the + :ref:`backend_definition`, which defaults to the + ``beresp_start_timeout`` parameter, see + :ref:`varnish-params(7)`. + + The time in seconds to wait getting the first byte back + from the backend. Not available in pipe mode. + + beresp.status Type: INT @@ -1322,6 +1344,19 @@ resp.http.* See ``req.http.*`` for general notes. +resp.idle_interrupt + + Type: DURATION + + Readable from: client + + Writable from: client + + Send timeout for individual pieces of response data on client + connections, defaults to the ``resp_idle_interrupt`` parameter, + see :ref:`varnish-params(7)`. + + resp.is_streaming Type: BOOL @@ -1363,6 +1398,18 @@ resp.reason The HTTP status message that will be returned. +resp.send_timeout + + Type: DURATION + + Readable from: client + + Writable from: client + + Total timeout for ordinary HTTP1 responses, defaults to the + ``resp_send_timeout`` parameter, see :ref:`varnish-params(7)`. + + resp.status Type: INT @@ -1427,7 +1474,17 @@ transactions may take place. It may comprise the traffic over an HTTP/1 keep-alive connection, or the multiplexed traffic over an HTTP/2 connection. -sess.idle_send_timeout +sess.idle_send_timeout ``VCL <= 4.1`` + + Type: DEPRECATED + + Alias of: resp.idle_interrupt + + This variable is deprecated and may be removed in a future + release. + + +sess.idle_timeout Type: DURATION @@ -1435,12 +1492,11 @@ sess.idle_send_timeout Writable from: client - Send timeout for individual pieces of data on client - connections, defaults to the ``idle_send_timeout`` parameter, - see :ref:`varnishd(1)` + Idle timeout for this session, defaults to the + ``sess_idle_timeout`` parameter, see :ref:`varnish-params(7)`. -sess.send_timeout +sess.linger_interrupt Type: DURATION @@ -1448,32 +1504,38 @@ sess.send_timeout Writable from: client - Total timeout for ordinary HTTP1 responses, defaults to the - ``send_timeout`` parameter, see :ref:`varnishd(1)` + Linger timeout for this session, defaults to the + ``sess_linger_interrupt`` parameter, see :ref:`varnish-params(7)`. -sess.timeout_idle +sess.send_timeout ``VCL <= 4.1`` - Type: DURATION + Type: DEPRECATED - Readable from: client + Alias of: resp.send_timeout - Writable from: client + This variable is deprecated and may be removed in a future + release. - Idle timeout for this session, defaults to the - ``timeout_idle`` parameter, see :ref:`varnishd(1)` +sess.timeout_idle ``VCL <= 4.1`` -sess.timeout_linger + Type: DEPRECATED - Type: DURATION + Alias of: sess.idle_timeout - Readable from: client + This variable is deprecated and may be removed in a future + release. - Writable from: client - Linger timeout for this session, defaults to the - ``timeout_linger`` parameter, see :ref:`varnishd(1)` +sess.timeout_linger ``VCL <= 4.1`` + + Type: DEPRECATED + + Alias of: sess.linger_interrupt + + This variable is deprecated and may be removed in a future + release. sess.xid ``VCL >= 4.1`` diff --git a/doc/sphinx/users-guide/params.rst b/doc/sphinx/users-guide/params.rst index 2d7e85b497c..4928ef951ff 100644 --- a/doc/sphinx/users-guide/params.rst +++ b/doc/sphinx/users-guide/params.rst @@ -18,4 +18,4 @@ you're doing. We've worked hard to make the defaults sane and Varnish should be able to handle most workloads with the default settings. For a complete listing of all parameters and their specifics see -:ref:`List of Parameters`. +:ref:`varnish-params(7)`. diff --git a/doc/sphinx/users-guide/vcl-backends.rst b/doc/sphinx/users-guide/vcl-backends.rst index f6d7bcb0955..74d7b152b3d 100644 --- a/doc/sphinx/users-guide/vcl-backends.rst +++ b/doc/sphinx/users-guide/vcl-backends.rst @@ -286,5 +286,5 @@ address information, irrespective of which VCLs they are defined in, their connections are taken from a common pool. If not actively closed by the backend, pooled connections are kept -open by Varnish until the :ref:`ref_param_backend_idle_timeout` +open by Varnish until the :ref:`ref_param_backend_pool_timeout` expires. diff --git a/include/tbl/params.h b/include/tbl/params.h index 9cf5de58146..0297f097f7c 100644 --- a/include/tbl/params.h +++ b/include/tbl/params.h @@ -237,7 +237,7 @@ PARAM_SIMPLE( ) PARAM_SIMPLE( - /* name */ first_byte_timeout, + /* name */ beresp_start_timeout, /* type */ timeout, /* min */ "0", /* max */ NULL, @@ -252,7 +252,7 @@ PARAM_SIMPLE( ) PARAM_SIMPLE( - /* name */ between_bytes_timeout, + /* name */ beresp_idle_timeout, /* type */ timeout, /* min */ "0", /* max */ NULL, @@ -266,7 +266,7 @@ PARAM_SIMPLE( ) PARAM_SIMPLE( - /* name */ backend_idle_timeout, + /* name */ backend_pool_timeout, /* type */ timeout, /* min */ "1", /* max */ NULL, @@ -325,7 +325,7 @@ PARAM_SIMPLE( ) PARAM_SIMPLE( - /* name */ cli_timeout, + /* name */ cli_resp_timeout, /* type */ timeout, /* min */ "0.000", /* max */ NULL, @@ -361,7 +361,7 @@ PARAM_SIMPLE( ) PARAM_SIMPLE( - /* name */ connect_timeout, + /* name */ bereq_connect_timeout, /* type */ timeout, /* min */ "0.000", /* max */ NULL, @@ -627,16 +627,17 @@ PARAM_SIMPLE( ) PARAM_SIMPLE( - /* name */ idle_send_timeout, + /* name */ resp_idle_interrupt, /* type */ timeout, /* min */ "0.000", /* max */ NULL, /* def */ "60.000", /* units */ "seconds", /* descr */ - "Send timeout for individual pieces of data on client connections." - " May get extended if 'send_timeout' applies.\n\n" - "When this timeout is hit, the session is closed.\n\n" + "This timeout triggers when no data is sent while Varnish is " + "actively trying to send a piece of the response to a client. " + "Once it triggers, 'resp_send_timeout' can be checked and " + "enforced.\n\n" "See the man page for `setsockopt(2)` or `socket(7)` under" " ``SO_SNDTIMEO`` for more information.", /* flags */ DELAYED_EFFECT @@ -753,7 +754,7 @@ PARAM_SIMPLE( ) PARAM_SIMPLE( - /* name */ pipe_timeout, + /* name */ pipe_idle_timeout, /* type */ timeout, /* min */ "0.000", /* max */ NULL, @@ -792,19 +793,22 @@ PARAM_SIMPLE( ) PARAM_SIMPLE( - /* name */ send_timeout, + /* name */ resp_send_timeout, /* type */ timeout, /* min */ "0.000", /* max */ NULL, /* def */ "600.000", /* units */ "seconds", /* descr */ - "Total timeout for ordinary HTTP1 responses. Does not apply to some" + "Total timeout to deliver a client response. Does not apply to some" " internally generated errors and pipe mode.\n\n" - "When 'idle_send_timeout' is hit while sending an HTTP1 response, the" - " timeout is extended unless the total time already taken for sending" - " the response in its entirety exceeds this many seconds.\n\n" - "When this timeout is hit, the session is closed", + "This timeout is checked whenever more data needs to be sent. When" + " Varnish is waiting for data to be transmitted, it may be waiting" + " for the transmission itself or some other condition. During such" + " a wait, 'resp_idle_interrupt' may trigger to grant opportunities" + " to check and enforce this timeout.\n\n" + "This means that a slow but steady delivery of a client response may" + " outlive this timeout.", /* flags */ DELAYED_EFFECT ) @@ -919,7 +923,7 @@ PARAM_SIMPLE( #undef PLATFORM_FLAGS PARAM_SIMPLE( - /* name */ timeout_idle, + /* name */ sess_idle_timeout, /* type */ timeout, /* min */ "0.000", /* max */ NULL, @@ -935,7 +939,7 @@ PARAM_SIMPLE( ) PARAM_SIMPLE( - /* name */ timeout_linger, + /* name */ sess_linger_interrupt, /* type */ timeout, /* min */ "0.000", /* max */ NULL, @@ -1695,6 +1699,16 @@ PARAM_ALIAS(deprecated_dummy, debug) PARAM_ALIAS(vcc_err_unref, vcc_feature) PARAM_ALIAS(vcc_allow_inline_c, vcc_feature) PARAM_ALIAS(vcc_unsafe_path, vcc_feature) +PARAM_ALIAS(first_byte_timeout, beresp_start_timeout) +PARAM_ALIAS(between_bytes_timeout, beresp_idle_timeout) +PARAM_ALIAS(backend_idle_timeout, backend_pool_timeout) +PARAM_ALIAS(cli_timeout, cli_resp_timeout) +PARAM_ALIAS(connect_timeout, bereq_connect_timeout) +PARAM_ALIAS(idle_send_timeout, resp_idle_interrupt) +PARAM_ALIAS(pipe_timeout, pipe_idle_timeout) +PARAM_ALIAS(send_timeout, resp_send_timeout) +PARAM_ALIAS(timeout_idle, sess_idle_timeout) +PARAM_ALIAS(timeout_linger, sess_linger_interrupt) # undef PARAM_ALIAS # undef PARAM_PCRE2 diff --git a/include/tbl/sess_close.h b/include/tbl/sess_close.h index b91c93951c9..c0977335eba 100644 --- a/include/tbl/sess_close.h +++ b/include/tbl/sess_close.h @@ -40,7 +40,7 @@ SESS_CLOSE(RX_BODY, rx_body, 1, "Failure receiving body") SESS_CLOSE(RX_JUNK, rx_junk, 1, "Received junk data") SESS_CLOSE(RX_OVERFLOW, rx_overflow, 1, "Received buffer overflow") SESS_CLOSE(RX_TIMEOUT, rx_timeout, 1, "Receive timeout") -SESS_CLOSE(RX_CLOSE_IDLE, rx_close_idle,0, "timeout_idle reached") +SESS_CLOSE(RX_CLOSE_IDLE, rx_close_idle,0, "sess_idle_timeout reached") SESS_CLOSE(TX_PIPE, tx_pipe, 0, "Piped transaction") SESS_CLOSE(TX_ERROR, tx_error, 1, "Error transaction") SESS_CLOSE(TX_EOF, tx_eof, 0, "EOF transmission") diff --git a/include/vrt.h b/include/vrt.h index c4afdc6b6aa..3d909e34c57 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -63,6 +63,18 @@ * VRT_AddVFP() deprecated * VRT_RemoveVDP() deprecated * VRT_RemoveVFP() deprecated + * VRT_l_bereq_between_bytes_timeout() renamed to VRT_l_beresp_idle_timeout() + * VRT_r_bereq_between_bytes_timeout() renamed to VRT_r_beresp_idle_timeout() + * VRT_l_bereq_first_byte_timeout() renamed to VRT_l_beresp_start_timeout() + * VRT_r_bereq_first_byte_timeout() renamed to VRT_r_beresp_start_timeout() + * VRT_l_sess_idle_send_timeout() renamed to VRT_l_resp_idle_interrupt() + * VRT_r_sess_idle_send_timeout() renamed to VRT_r_resp_idle_interrupt() + * VRT_l_sess_send_timeout() renamed to VRT_l_resp_send_timeout() + * VRT_r_sess_send_timeout() renamed to VRT_r_resp_send_timeout() + * VRT_l_sess_timeout_idle() renamed to VRT_l_sess_idle_timeout() + * VRT_r_sess_timeout_idle() renamed to VRT_r_sess_idle_timeout() + * VRT_l_sess_timeout_linger() renamed to VRT_l_sess_linger_interrupt() + * VRT_r_sess_timeout_linger() renamed to VRT_r_sess_linger_interrupt() * 15.0 (2022-03-15) * VRT_r_req_transport() added * VRT_Assign_Backend() added @@ -553,9 +565,9 @@ struct vrt_endpoint { #define VRT_BACKEND_FIELDS(rigid) \ rigid char *vcl_name; \ rigid char *hosthdr; \ - vtim_dur connect_timeout; \ - vtim_dur first_byte_timeout; \ - vtim_dur between_bytes_timeout; \ + vtim_dur bereq_connect_timeout; \ + vtim_dur beresp_start_timeout; \ + vtim_dur beresp_idle_timeout; \ unsigned max_connections; \ unsigned proxy_header; @@ -563,9 +575,9 @@ struct vrt_endpoint { do { \ DA(vcl_name); \ DA(hosthdr); \ - DN(connect_timeout); \ - DN(first_byte_timeout); \ - DN(between_bytes_timeout); \ + DN(bereq_connect_timeout); \ + DN(beresp_start_timeout); \ + DN(beresp_idle_timeout); \ DN(max_connections); \ DN(proxy_header); \ } while(0) diff --git a/include/vtcp.h b/include/vtcp.h index c561c2567c1..d17b36070c5 100644 --- a/include/vtcp.h +++ b/include/vtcp.h @@ -64,6 +64,7 @@ int VTCP_bind(const struct suckaddr *addr, const char **errp); int VTCP_listen(const struct suckaddr *addr, int depth, const char **errp); int VTCP_listen_on(const char *addr, const char *def_port, int depth, const char **errp); +void VTCP_set_send_timeout(int s, vtim_dur seconds); void VTCP_set_read_timeout(int s, vtim_dur seconds); int VTCP_read(int fd, void *ptr, size_t len, vtim_dur tmo); // #endif diff --git a/lib/libvarnish/vtcp.c b/lib/libvarnish/vtcp.c index 6c1d154a2f4..e1cddf159a5 100644 --- a/lib/libvarnish/vtcp.c +++ b/lib/libvarnish/vtcp.c @@ -361,6 +361,15 @@ VTCP_set_read_timeout(int s, vtim_dur seconds) &timeout, sizeof timeout)); } +void +VTCP_set_send_timeout(int s, vtim_dur seconds) +{ + struct timeval timeout = VTIM_timeval(seconds); + + VTCP_Assert(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, + &timeout, sizeof timeout)); +} + /*-------------------------------------------------------------------- */ diff --git a/lib/libvcc/vcc_backend.c b/lib/libvcc/vcc_backend.c index 8b357a58eeb..d205def2b48 100644 --- a/lib/libvcc/vcc_backend.c +++ b/lib/libvcc/vcc_backend.c @@ -377,9 +377,9 @@ vcc_ParseHostDef(struct vcc *tl, const struct token *t_be, const char *vgcname) "?port", "?path", "?host_header", - "?connect_timeout", - "?first_byte_timeout", - "?between_bytes_timeout", + "?bereq_connect_timeout,connect_timeout", + "?beresp_start_timeout,first_byte_timeout", + "?beresp_idle_timeout,between_bytes_timeout", "?probe", "?max_connections", "?proxy_header", @@ -439,20 +439,23 @@ vcc_ParseHostDef(struct vcc *tl, const struct token *t_be, const char *vgcname) t_hosthdr = tl->t; vcc_NextToken(tl); SkipToken(tl, ';'); - } else if (vcc_IdIs(t_field, "connect_timeout")) { - Fb(tl, 0, "\t.connect_timeout = "); + } else if (vcc_IdIs(t_field, + "bereq_connect_timeout,connect_timeout")) { + Fb(tl, 0, "\t.bereq_connect_timeout = "); vcc_Duration(tl, &t); ERRCHK(tl); Fb(tl, 0, "%g,\n", t); SkipToken(tl, ';'); - } else if (vcc_IdIs(t_field, "first_byte_timeout")) { - Fb(tl, 0, "\t.first_byte_timeout = "); + } else if (vcc_IdIs(t_field, + "beresp_start_timeout,first_byte_timeout")) { + Fb(tl, 0, "\t.beresp_start_timeout = "); vcc_Duration(tl, &t); ERRCHK(tl); Fb(tl, 0, "%g,\n", t); SkipToken(tl, ';'); - } else if (vcc_IdIs(t_field, "between_bytes_timeout")) { - Fb(tl, 0, "\t.between_bytes_timeout = "); + } else if (vcc_IdIs(t_field, + "beresp_idle_timeout,between_bytes_timeout")) { + Fb(tl, 0, "\t.beresp_idle_timeout = "); vcc_Duration(tl, &t); ERRCHK(tl); Fb(tl, 0, "%g,\n", t); diff --git a/lib/libvcc/vcc_token.c b/lib/libvcc/vcc_token.c index 82ab2885f2e..89dde6b4450 100644 --- a/lib/libvcc/vcc_token.c +++ b/lib/libvcc/vcc_token.c @@ -304,21 +304,32 @@ vcc__Expect(struct vcc *tl, unsigned tok, unsigned line) } /*-------------------------------------------------------------------- - * Compare ID token to string, return true of match + * Compare ID token to string, return true of match. + * + * The string may be a comma-separated list of identifiers. */ int vcc_IdIs(const struct token *t, const char *p) { - const char *q; + txt id; assert(t->tok == ID); - for (q = t->b; q < t->e && *p != '\0'; p++, q++) - if (*q != *p) - return (0); - if (q != t->e || *p != '\0') - return (0); - return (1); + AN(p); + AN(*p); + while (*p != '\0') { + id.b = p; + id.e = strchr(p, ','); + if (id.e == NULL) + id.e = strchr(p, '\0'); + + if (Tlen(*t) == Tlen(id) && !memcmp(t->b, id.b, Tlen(id))) + return (1); + p = id.e; + if (*p == ',') + p++; + } + return (0); } /*-------------------------------------------------------------------- diff --git a/lib/libvsc/VSC_main.vsc b/lib/libvsc/VSC_main.vsc index 7b32584c951..a8d12afb81e 100644 --- a/lib/libvsc/VSC_main.vsc +++ b/lib/libvsc/VSC_main.vsc @@ -519,7 +519,7 @@ :group: wrk :oneliner: Session herd - Number of times the timeout_linger triggered + Number of times the sess_linger_interrupt triggered .. varnish_vsc:: sc_rem_close :level: diag @@ -574,7 +574,7 @@ :oneliner: Session Err RX_CLOSE_IDLE Number of session closes with Error RX_CLOSE_IDLE: - timeout_idle has been exceeded while waiting for a + sess_idle_timeout has been exceeded while waiting for a client request. .. varnish_vsc:: sc_tx_pipe diff --git a/man/Makefile.am b/man/Makefile.am index b78dc7cfe92..e4be66ac728 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -3,6 +3,7 @@ dist_man_MANS = \ varnish-cli.7 \ varnish-counters.7 \ + varnish-params.7 \ vcl.7 \ vcl-backend.7 \ vcl-probe.7 \ @@ -46,6 +47,10 @@ varnish-counters.7: $(top_builddir)/doc/sphinx/reference/varnish-counters.rst \ $(top_builddir)/doc/sphinx/include/counters.rst $(BUILD_MAN) $(top_builddir)/doc/sphinx/reference/varnish-counters.rst $@ +varnish-params.7: $(top_builddir)/doc/sphinx/reference/varnish-params.rst \ + $(top_builddir)/doc/sphinx/include/params.rst + $(BUILD_MAN) $(top_builddir)/doc/sphinx/reference/varnish-params.rst $@ + vcl.7: $(top_builddir)/doc/sphinx/reference/vcl.rst \ $(top_builddir)/doc/sphinx/reference/vcl_var.rst \ $(top_srcdir)/bin/varnishd/builtin.vcl @@ -57,7 +62,8 @@ vcl-backend.7: $(top_builddir)/doc/sphinx/reference/vcl-backend.rst vcl-probe.7: $(top_builddir)/doc/sphinx/reference/vcl-probe.rst $(BUILD_MAN) $(top_builddir)/doc/sphinx/reference/vcl-probe.rst $@ -vcl-var.7: $(top_builddir)/doc/sphinx/reference/vcl-var.rst +vcl-var.7: $(top_builddir)/doc/sphinx/reference/vcl-var.rst \ + $(top_builddir)/doc/sphinx/reference/vcl_var.rst $(BUILD_MAN) $(top_builddir)/doc/sphinx/reference/vcl-var.rst $@ vsl.7: $(top_builddir)/doc/sphinx/reference/vsl.rst \