varnishtest "PROXY1 protocol tests"

server s1 {
	rxreq
	expect req.http.X-Forwarded-For == 1.2.3.4
	txresp

	rxreq
	expect req.http.X-Forwarded-For == 1:f::2
	txresp

	rxreq
	expect req.http.X-Forwarded-For == 1:f::3
	txresp
} -start

varnish v1 -proto "PROXY" -vcl+backend {
	import std;

	sub vcl_deliver {
		set resp.http.url = req.url;
		set resp.http.li = local.ip;
		set resp.http.lp = std.port(local.ip);
		set resp.http.ri = remote.ip;
		set resp.http.rp = std.port(remote.ip);
		set resp.http.ci = client.ip;
		set resp.http.cp = std.port(client.ip);
		set resp.http.si = server.ip;
		set resp.http.sp = std.port(server.ip);
	}
} -start

logexpect l1 -v v1 {
	expect * 1002	ProxyGarbage	"PROXY1: Too few fields"
	expect * 1003	ProxyGarbage	"PROXY1: Too many fields"
	expect * 1004	ProxyGarbage	"PROXY1: Wrong TCP\\[46\\] field"
	expect * 1005	ProxyGarbage	"PROXY1: Cannot resolve source address"
	expect * 1007	ProxyGarbage	"PROXY1: Cannot resolve destination address"
	expect * 1009	ProxyGarbage	"PROXY1: Cannot resolve source address"
	expect * 1011	ProxyGarbage	"PROXY1: Cannot resolve source address"
	expect * 1015	Proxy		"1 1.2.3.4 1234 5.6.7.8 5678"
	expect * 1018	Proxy		"1 1:f::2 1234 5:a::8 5678"
	expect * 1021	Proxy		"1 1:f::3 1234 5:a::8 5678"
	expect * 1025	ProxyGarbage	"PROXY1: Too many fields"
	expect * 1026	ProxyGarbage	"PROXY1: Too many fields"
} -start

client c1 {
	send "XYZ\r\n"
	expect_close
} -run

varnish v1 -vsl_catchup

client c1 {
	send "PROXY "
	timeout 8
	expect_close
} -run

varnish v1 -vsl_catchup

client c1 {
	send "PROXY A B C D\r\n"
	timeout 8
	expect_close
} -run

varnish v1 -vsl_catchup

client c1 {
	send "PROXY A B C D E F\r\n"
	timeout 8
	expect_close
} -run

varnish v1 -vsl_catchup

client c1 {
	send "PROXY A B C D E\r\n"
	timeout 8
	expect_close
} -run

varnish v1 -vsl_catchup

client c1 {
	send "PROXY TCP4 B C D E\r\n"
	timeout 8
	expect_close
} -run

varnish v1 -vsl_catchup

client c1 {
	send "PROXY TCP4 1.2.3.4 C D E\r\n"
	timeout 8
	expect_close
} -run

varnish v1 -vsl_catchup

client c1 {
	send "PROXY TCP4 1.2.3.4 D 1234 E\r\n"
	timeout 8
	expect_close
} -run

varnish v1 -vsl_catchup

client c1 {
	send "PROXY TCP4 1.2.3.4 5.6.7.8 1234 E\r\n"
	timeout 8
	expect_close
} -run

varnish v1 -vsl_catchup

client c1 {
	send "PROXY TCP6 B C D E\r\n"
	timeout 8
	expect_close
} -run

varnish v1 -vsl_catchup

client c1 {
	send "PROXY TCP6 1:f::2 C D E\r\n"
	timeout 8
	expect_close
} -run

varnish v1 -vsl_catchup

client c1 {
	send "PROXY TCP6 1:f::2 1234 D E\r\n"
	timeout 8
	expect_close
} -run

varnish v1 -vsl_catchup

client c1 {
	send "PROXY TCP6 1:f::2 5:a::8 1234 E\r\n"
	timeout 8
	expect_close
} -run

varnish v1 -vsl_catchup

client c1 {
	send "PROXY TCP4 1:f::2 5:a::8 1234 5678\r\n"
	timeout 8
	expect_close
} -run

varnish v1 -vsl_catchup

client c1 {
	send "PROXY TCP6 1.2.3.4 5.6.7.8 1234 5678\r\n"
	timeout 8
	expect_close
} -run

varnish v1 -vsl_catchup

# Finally try something which works...
client c1 -proxy1 "1.2.3.4:1234 5.6.7.8:5678" {
	txreq -url /1
	rxresp
	expect resp.http.url == "/1"
	expect resp.http.ci == "1.2.3.4"
	expect resp.http.cp == "1234"
	expect resp.http.si == "5.6.7.8"
	expect resp.http.sp == "5678"
	expect resp.http.li == ${v1_addr}
	expect resp.http.lp == ${v1_port}
	expect resp.http.ri != "1.2.3.4"
	expect resp.http.rp != "1234"
} -run

varnish v1 -vsl_catchup

client c1 -proxy1 "[1:f::2]:1234 [5:a::8]:5678" {
	txreq -url /2
	rxresp
	expect resp.http.url == "/2"
	expect resp.http.ci == "1:f::2"
	expect resp.http.cp == "1234"
	expect resp.http.si == "5:a::8"
	expect resp.http.sp == "5678"
	expect resp.http.li == ${v1_addr}
	expect resp.http.lp == ${v1_port}
	expect resp.http.ri != "1:f::2"
	expect resp.http.rp != "1234"
} -run

varnish v1 -vsl_catchup

# Try with appended request (See also: #1728)
client c2 {
	send "PROXY TCP6 1:f::3 5:a::8 1234 5678\r\nGET /3 HTTP/1.1\r\nHost: ${string,repeat,54,a}\r\n\r\n"
	rxresp
	expect resp.http.url == "/3"
} -run

varnish v1 -vsl_catchup

# Malformed (missing \r)
client c2 {
	send "PROXY TCP4 1.2.3.4 5.6.7.8 1234 5678\n"
	expect_close
} -run

varnish v1 -vsl_catchup

# Malformed, too long (106)
# NB: Should check VSL for proper disposal
client c2 {
	send "PROXY TCP4 1.2.3.4 5.6.7.8 1234 5678 ${string,repeat,68," "}\r\n"
	expect_close
} -run

varnish v1 -vsl_catchup

# Malformed, too long (107)
# NB: Should check VSL for proper disposal
client c2 {
	send "PROXY TCP4 1.2.3.4 5.6.7.8 1234 5678 ${string,repeat,69," "}\r\n"
	expect_close
} -run

varnish v1 -vsl_catchup

# Malformed, too long (108)
# NB: Should check VSL for proper disposal
client c2 {
	send "PROXY TCP4 1.2.3.4 5.6.7.8 1234 5678 ${string,repeat,70," "}\r\n"
	expect_close
} -run

varnish v1 -vsl_catchup

logexpect l1 -wait
