Commit 08d4e804 authored by Dridi Boukelmoune's avatar Dridi Boukelmoune

hash: Close an expiry loophole

The opposite of 'EXP_Ttl(req, oc) > req->t_req' should not have been
'EXP_Ttl(NULL, oc) < req->t_req'. If we somehow enter the lookup when
the two operands are equal, the objcore suffers a phenomenon known as
Schrödinger's expiry.

The chances of running into this scenario range from epsilon to 100%.

Because 't_req' is stable across restarts, a soft purge will reliably
trigger this case.

Test case by Alve Elde who first demonstrated the problem.
parent 11aa2c98
......@@ -485,7 +485,7 @@ HSH_Lookup(struct req *req, struct objcore **ocp, struct objcore **bocp)
break;
}
if (EXP_Ttl(NULL, oc) < req->t_req && /* ignore req.ttl */
if (EXP_Ttl(NULL, oc) <= req->t_req && /* ignore req.ttl */
oc->t_origin > exp_t_origin) {
/* record the newest object */
exp_oc = oc;
......
varnishtest "304 revalidations with purge.soft()"
server s1 {
rxreq
txresp -hdr "etag: foo" -body "foo"
rxreq
expect req.http.If-None-Match == "foo"
txresp -status 304 -hdr "etag: foo"
} -start
varnish v1 -vcl+backend {
import purge;
sub vcl_hit {
if (req.restarts == 0) {
purge.soft();
return (restart);
}
}
sub vcl_backend_response {
set beresp.ttl = 1d;
set beresp.grace = 1d;
set beresp.keep = 1d;
}
} -start
client c1 {
txreq
rxresp
expect resp.status == 200
expect resp.body == "foo"
txreq
rxresp
expect resp.status == 200
expect resp.body == "foo"
} -run
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment