[master] e8c074b Restrict return(vcl) to before any restart, and reset the req.http to avoid any memory leaks.

Poul-Henning Kamp phk at FreeBSD.org
Tue Jan 10 12:47:04 CET 2017


commit e8c074b9abd382f0734c69596cdd532f0cadfe9e
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Tue Jan 10 11:45:28 2017 +0000

    Restrict return(vcl) to before any restart, and reset the req.http
    to avoid any memory leaks.
    
    Closes	#2177

diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c
index 694260e..e6a18b6 100644
--- a/bin/varnishd/cache/cache_req_fsm.c
+++ b/bin/varnishd/cache/cache_req_fsm.c
@@ -691,8 +691,10 @@ cnt_recv(struct worker *wrk, struct req *req)
 	}
 
 	VCL_recv_method(req->vcl, wrk, req, NULL, NULL);
-	if (wrk->handling == VCL_RET_VCL) {
+	if (wrk->handling == VCL_RET_VCL && req->restarts == 0) {
 		req->director_hint = VCL_DefaultDirector(req->vcl);
+		HTTP_Copy(req->http, req->http0);
+		WS_Reset(req->ws, req->ws_req);
 		AN(req->director_hint);
 		VCL_recv_method(req->vcl, wrk, req, NULL, NULL);
 	}
@@ -724,7 +726,9 @@ cnt_recv(struct worker *wrk, struct req *req)
 	switch(recv_handling) {
 	case VCL_RET_VCL:
 		VSLb(req->vsl, SLT_VCL_Error,
-		    "return(vcl) only allowed from active (top) VCL.");
+		    "Illegal return(vcl): %s",
+		    req->restarts ? "Not after restarts" :
+		    "Only from active VCL");
 		req->err_code = 503;
 		req->req_step = R_STP_SYNTH;
 		return (REQ_FSM_MORE);
diff --git a/bin/varnishtest/tests/r02177.vtc b/bin/varnishtest/tests/r02177.vtc
new file mode 100644
index 0000000..9d4e437
--- /dev/null
+++ b/bin/varnishtest/tests/r02177.vtc
@@ -0,0 +1,64 @@
+varnishtest "restart then switch to label"
+
+server s1 {
+	rxreq
+	txresp
+} -start
+
+server s2 {
+	rxreq
+	txresp -status 404
+} -start
+
+varnish v1 -vcl {
+	backend s1 { .host="${s1_addr}"; .port="${s1_port}"; }
+} -start
+
+varnish v1 -cli "vcl.label lbl1 vcl1"
+
+varnish v1 -vcl {
+	backend s1 { .host="${s1_addr}"; .port="${s1_port}"; }
+
+	sub vcl_recv {
+		return (vcl(lbl1));
+	}
+}
+
+varnish v1 -cli "vcl.label lbl2 vcl2"
+
+varnish v1 -vcl {
+	backend s2 { .host="${s2_addr}"; .port="${s2_port}"; }
+
+	sub vcl_recv {
+		if (req.restarts > 0) {
+			return (vcl(lbl1));
+		}
+		if (req.http.restart) {
+			return (vcl(lbl2));
+		}
+	}
+
+	sub vcl_miss {
+		return (restart);
+	}
+}
+
+varnish v1 -cliok "vcl.list"
+
+logexpect l1 -v v1 -g raw {
+	expect * * VCL_Error "Illegal return.vcl.: Not after restarts"
+	expect * * VCL_Error "Illegal return.vcl.: Only from active VCL"
+
+} -start
+
+client c1 {
+	txreq
+	rxresp
+	expect resp.status == 503
+
+	txreq -hdr "restart: yes"
+	rxresp
+	expect resp.status == 503
+} -run
+
+logexpect l1 -wait



More information about the varnish-commit mailing list