diff options
Diffstat (limited to '')
-rw-r--r-- | reg-tests/connection/cli_src_dst.vtc | 290 | ||||
l--------- | reg-tests/connection/common.pem | 1 | ||||
-rw-r--r-- | reg-tests/connection/dispatch.vtc | 42 | ||||
-rw-r--r-- | reg-tests/connection/http_reuse_aggressive.vtc | 45 | ||||
-rw-r--r-- | reg-tests/connection/http_reuse_always.vtc | 43 | ||||
-rw-r--r-- | reg-tests/connection/http_reuse_be_transparent.vtc | 81 | ||||
-rw-r--r-- | reg-tests/connection/http_reuse_conn_hash.vtc | 163 | ||||
-rw-r--r-- | reg-tests/connection/http_reuse_dispatch.vtc | 79 | ||||
-rw-r--r-- | reg-tests/connection/http_reuse_never.vtc | 79 | ||||
-rw-r--r-- | reg-tests/connection/http_reuse_safe.vtc | 78 | ||||
-rw-r--r-- | reg-tests/connection/proxy_protocol_random_fail.vtc | 60 | ||||
-rw-r--r-- | reg-tests/connection/proxy_protocol_send_unique_id.vtc | 42 | ||||
-rw-r--r-- | reg-tests/connection/proxy_protocol_send_unique_id_alpn.vtc | 33 | ||||
-rw-r--r-- | reg-tests/connection/proxy_protocol_tlv_validation.vtc | 142 | ||||
-rw-r--r-- | reg-tests/connection/tcp_to_http_upgrade.vtc | 162 |
15 files changed, 1340 insertions, 0 deletions
diff --git a/reg-tests/connection/cli_src_dst.vtc b/reg-tests/connection/cli_src_dst.vtc new file mode 100644 index 0000000..6809d39 --- /dev/null +++ b/reg-tests/connection/cli_src_dst.vtc @@ -0,0 +1,290 @@ +varnishtest "Test multi-level client source and destination addresses" + +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'" +feature ignore_unknown_macro + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe1 + bind "fd@${fe1}" + tcp-request connection set-src ipv4(10.0.0.1) + tcp-request connection set-dst ipv4(10.0.0.2) + + tcp-request session set-var(sess.sess_fc_src) fc_src + tcp-request session set-var(sess.sess_fc_dst) fc_dst + tcp-request session set-var(sess.sess_src) src + tcp-request session set-var(sess.sess_dst) dst + + tcp-request inspect-delay 100ms + tcp-request content set-var(txn.strm_fc_src) fc_src + tcp-request content set-var(txn.strm_fc_dst) fc_dst + tcp-request content set-var(txn.strm_src) src + tcp-request content set-var(txn.strm_dst) dst + + http-after-response set-header sess-fc-src %[var(sess.sess_fc_src)] + http-after-response set-header sess-src %[var(sess.sess_src)] + http-after-response set-header sess-fc-dst %[var(sess.sess_fc_dst)] + http-after-response set-header sess-dst %[var(sess.sess_dst)] + http-after-response set-header strm-fc-src %[var(txn.strm_fc_src)] + http-after-response set-header strm-src %[var(txn.strm_src)] + http-after-response set-header strm-fc-dst %[var(txn.strm_fc_dst)] + http-after-response set-header strm-dst %[var(txn.strm_dst)] + + default_backend be + + frontend fe2 + bind "fd@${fe2}" + tcp-request connection set-src ipv4(10.0.0.1) + tcp-request connection set-dst ipv4(10.0.0.2) + + tcp-request session set-src ipv4(10.1.0.1) + tcp-request session set-dst ipv4(10.1.0.2) + tcp-request session set-var(sess.sess_fc_src) fc_src + tcp-request session set-var(sess.sess_fc_dst) fc_dst + tcp-request session set-var(sess.sess_src) src + tcp-request session set-var(sess.sess_dst) dst + + tcp-request inspect-delay 100ms + tcp-request content set-var(txn.strm_fc_src) fc_src + tcp-request content set-var(txn.strm_fc_dst) fc_dst + tcp-request content set-var(txn.strm_src) src + tcp-request content set-var(txn.strm_dst) dst + + http-after-response set-header sess-fc-src %[var(sess.sess_fc_src)] + http-after-response set-header sess-src %[var(sess.sess_src)] + http-after-response set-header sess-fc-dst %[var(sess.sess_fc_dst)] + http-after-response set-header sess-dst %[var(sess.sess_dst)] + http-after-response set-header strm-fc-src %[var(txn.strm_fc_src)] + http-after-response set-header strm-src %[var(txn.strm_src)] + http-after-response set-header strm-fc-dst %[var(txn.strm_fc_dst)] + http-after-response set-header strm-dst %[var(txn.strm_dst)] + + default_backend be + + frontend fe3 + bind "fd@${fe3}" + tcp-request connection set-src ipv4(10.0.0.1) + tcp-request connection set-dst ipv4(10.0.0.2) + + tcp-request session set-src ipv4(10.1.0.1) + tcp-request session set-dst ipv4(10.1.0.2) + tcp-request session set-var(sess.sess_fc_src) fc_src + tcp-request session set-var(sess.sess_fc_dst) fc_dst + tcp-request session set-var(sess.sess_src) src + tcp-request session set-var(sess.sess_dst) dst + + tcp-request inspect-delay 100ms + tcp-request content set-src ipv4(10.2.0.1) + tcp-request content set-dst ipv4(10.2.0.2) + tcp-request content set-var(txn.strm_fc_src) fc_src + tcp-request content set-var(txn.strm_fc_dst) fc_dst + tcp-request content set-var(txn.strm_src) src + tcp-request content set-var(txn.strm_dst) dst + + http-after-response set-header sess-fc-src %[var(sess.sess_fc_src)] + http-after-response set-header sess-src %[var(sess.sess_src)] + http-after-response set-header sess-fc-dst %[var(sess.sess_fc_dst)] + http-after-response set-header sess-dst %[var(sess.sess_dst)] + http-after-response set-header strm-fc-src %[var(txn.strm_fc_src)] + http-after-response set-header strm-src %[var(txn.strm_src)] + http-after-response set-header strm-fc-dst %[var(txn.strm_fc_dst)] + http-after-response set-header strm-dst %[var(txn.strm_dst)] + + + frontend fe4 + bind "fd@${fe4}" + + tcp-request connection set-src ipv4(10.0.0.1) + tcp-request connection set-dst ipv4(10.0.0.2) + + tcp-request session set-var(sess.sess_fc_src) fc_src + tcp-request session set-var(sess.sess_fc_dst) fc_dst + tcp-request session set-var(sess.sess_src) src + tcp-request session set-var(sess.sess_dst) dst + + http-request set-src hdr(x-forwarded-for) + http-request set-dst hdr(x-original-to) + http-request set-var(txn.strm_fc_src) fc_src + http-request set-var(txn.strm_fc_dst) fc_dst + http-request set-var(txn.strm_src) src + http-request set-var(txn.strm_dst) dst + + http-after-response set-header sess-fc-src %[var(sess.sess_fc_src)] + http-after-response set-header sess-src %[var(sess.sess_src)] + http-after-response set-header sess-fc-dst %[var(sess.sess_fc_dst)] + http-after-response set-header sess-dst %[var(sess.sess_dst)] + http-after-response set-header strm-fc-src %[var(txn.strm_fc_src)] + http-after-response set-header strm-src %[var(txn.strm_src)] + http-after-response set-header strm-fc-dst %[var(txn.strm_fc_dst)] + http-after-response set-header strm-dst %[var(txn.strm_dst)] + + default_backend be + + backend be + http-request return status 200 + + listen li1 + bind "fd@${li1}" + + tcp-request connection set-src ipv4(10.0.0.1) + tcp-request connection set-dst ipv4(10.0.0.2) + + http-request set-src ipv4(192.168.0.1) + http-request set-dst ipv4(192.168.0.2) + + http-after-response set-header li1-fc-src %[fc_src] + http-after-response set-header li1-src %[src] + http-after-response set-header li1-fc-dst %[fc_dst] + http-after-response set-header li1-dst %[dst] + + + server srv ${h1_li3_addr}:${h1_li3_port} send-proxy + + listen li2 + bind "fd@${li2}" + + tcp-request connection set-src ipv4(10.0.0.1) + tcp-request connection set-dst ipv4(10.0.0.2) + + http-request set-src ipv4(192.168.0.1) + http-request set-dst ipv4(192.168.0.2) + + http-after-response set-header li2-fc-src %[fc_src] + http-after-response set-header li2-src %[src] + http-after-response set-header li2-fc-dst %[fc_dst] + http-after-response set-header li2-dst %[dst] + + server srv ${h1_li3_addr}:${h1_li3_port} send-proxy-v2 + + listen li3 + bind "fd@${li3}" accept-proxy + + tcp-request connection set-src ipv4(10.1.0.1) + tcp-request connection set-dst ipv4(10.1.0.2) + + http-after-response set-header li3-fc-src %[fc_src] + http-after-response set-header li3-src %[src] + http-after-response set-header li3-fc-dst %[fc_dst] + http-after-response set-header li3-dst %[dst] + + http-request return status 200 + +} -start + + +client c1 -connect ${h1_fe1_sock} { + txreq + rxresp + expect resp.http.sess-fc-src == 10.0.0.1 + expect resp.http.sess-src == 10.0.0.1 + expect resp.http.strm-fc-src == 10.0.0.1 + expect resp.http.strm-src == 10.0.0.1 + + expect resp.http.sess-fc-dst == 10.0.0.2 + expect resp.http.sess-dst == 10.0.0.2 + expect resp.http.strm-fc-dst == 10.0.0.2 + expect resp.http.strm-dst == 10.0.0.2 +} -run + +client c2 -connect ${h1_fe2_sock} { + txreq + rxresp + expect resp.http.sess-fc-src == 10.0.0.1 + expect resp.http.sess-src == 10.1.0.1 + expect resp.http.strm-fc-src == 10.0.0.1 + expect resp.http.strm-src == 10.1.0.1 + + expect resp.http.sess-fc-dst == 10.0.0.2 + expect resp.http.sess-dst == 10.1.0.2 + expect resp.http.strm-fc-dst == 10.0.0.2 + expect resp.http.strm-dst == 10.1.0.2 +} -run + +client c3 -connect ${h1_fe3_sock} { + txreq + rxresp + expect resp.http.sess-fc-src == 10.0.0.1 + expect resp.http.sess-src == 10.1.0.1 + expect resp.http.strm-fc-src == 10.0.0.1 + expect resp.http.strm-src == 10.2.0.1 + + expect resp.http.sess-fc-dst == 10.0.0.2 + expect resp.http.sess-dst == 10.1.0.2 + expect resp.http.strm-fc-dst == 10.0.0.2 + expect resp.http.strm-dst == 10.2.0.2 +} -run + +client c4 -connect ${h1_fe4_sock} { + txreq \ + -hdr "x-forwarded-for: 192.168.0.1" \ + -hdr "x-original-to: 192.168.0.2" + rxresp + expect resp.http.sess-fc-src == 10.0.0.1 + expect resp.http.sess-src == 10.0.0.1 + expect resp.http.strm-fc-src == 10.0.0.1 + expect resp.http.strm-src == 192.168.0.1 + + expect resp.http.sess-fc-dst == 10.0.0.2 + expect resp.http.sess-dst == 10.0.0.2 + expect resp.http.strm-fc-dst == 10.0.0.2 + expect resp.http.strm-dst == 192.168.0.2 + + txreq \ + -hdr "x-forwarded-for: 192.168.1.1" \ + -hdr "x-original-to: 192.168.1.2" + rxresp + expect resp.http.sess-fc-src == 10.0.0.1 + expect resp.http.sess-src == 10.0.0.1 + expect resp.http.strm-fc-src == 10.0.0.1 + expect resp.http.strm-src == 192.168.1.1 + + expect resp.http.sess-fc-dst == 10.0.0.2 + expect resp.http.sess-dst == 10.0.0.2 + expect resp.http.strm-fc-dst == 10.0.0.2 + expect resp.http.strm-dst == 192.168.1.2 + + txreq + rxresp + expect resp.http.sess-fc-src == 10.0.0.1 + expect resp.http.sess-src == 10.0.0.1 + expect resp.http.strm-fc-src == 10.0.0.1 + expect resp.http.strm-src == 10.0.0.1 + + expect resp.http.sess-fc-dst == 10.0.0.2 + expect resp.http.sess-dst == 10.0.0.2 + expect resp.http.strm-fc-dst == 10.0.0.2 + expect resp.http.strm-dst == 10.0.0.2 +} -run + +client c5 -connect ${h1_li1_sock} { + txreq + rxresp + expect resp.http.li1-fc-src == 10.0.0.1 + expect resp.http.li1-src == 192.168.0.1 + expect resp.http.li1-fc-dst == 10.0.0.2 + expect resp.http.li1-dst == 192.168.0.2 + + expect resp.http.li3-fc-src == 10.1.0.1 + expect resp.http.li3-src == 192.168.0.1 + expect resp.http.li3-fc-dst == 10.1.0.2 + expect resp.http.li3-dst == 192.168.0.2 +} -run + +client c6 -connect ${h1_li2_sock} { + txreq + rxresp + expect resp.http.li2-fc-src == 10.0.0.1 + expect resp.http.li2-src == 192.168.0.1 + expect resp.http.li2-fc-dst == 10.0.0.2 + expect resp.http.li2-dst == 192.168.0.2 + + expect resp.http.li3-fc-src == 10.1.0.1 + expect resp.http.li3-src == 192.168.0.1 + expect resp.http.li3-fc-dst == 10.1.0.2 + expect resp.http.li3-dst == 192.168.0.2 +} -run diff --git a/reg-tests/connection/common.pem b/reg-tests/connection/common.pem new file mode 120000 index 0000000..a4433d5 --- /dev/null +++ b/reg-tests/connection/common.pem @@ -0,0 +1 @@ +../ssl/common.pem
\ No newline at end of file diff --git a/reg-tests/connection/dispatch.vtc b/reg-tests/connection/dispatch.vtc new file mode 100644 index 0000000..8696b50 --- /dev/null +++ b/reg-tests/connection/dispatch.vtc @@ -0,0 +1,42 @@ +varnishtest "Validate proper operation of the 'dispatch' mode" +feature ignore_unknown_macro + +server s1 { + rxreq + txresp +} -start + +server s2 { + rxreq + txresp +} -start + +haproxy h1 -conf { +defaults + log global + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + +listen fe_tcp + bind "fd@${fe_tcp}" + mode tcp + dispatch ${s1_addr}:${s1_port} + +listen fe_http + bind "fd@${fe_http}" + mode http + dispatch ${s2_addr}:${s2_port} +} -start + +client c1 -connect ${h1_fe_tcp_sock} { + txreq -url "/" + rxresp + expect resp.status == 200 +} -run + +client c2 -connect ${h1_fe_http_sock} { + txreq -url "/" + rxresp + expect resp.status == 200 +} -run diff --git a/reg-tests/connection/http_reuse_aggressive.vtc b/reg-tests/connection/http_reuse_aggressive.vtc new file mode 100644 index 0000000..71f4cee --- /dev/null +++ b/reg-tests/connection/http_reuse_aggressive.vtc @@ -0,0 +1,45 @@ +varnishtest "Test the http-reuse aggressive mode" + +#REQUIRE_VERSION=2.2 + +feature ignore_unknown_macro + +haproxy h1 -conf { + defaults + mode http + + listen sender + bind "fd@${feS}" + http-reuse aggressive + server srv ${h1_feR_addr}:${h1_feR_port} + + listen receiver + bind "fd@${feR}" + http-request return status 200 + http-after-response set-header http_first_request %[http_first_req] +} -start + +# bootstrap +client c1 -connect ${h1_feS_sock} { + txreq + rxresp + expect resp.http.http_first_request == "1" +} -run + +# first request should not be reused as no safe connection for the moment +client c2 -connect ${h1_feS_sock} { + txreq + rxresp + expect resp.http.http_first_request == "1" + + txreq + rxresp + expect resp.http.http_first_request == "0" +} -run + +# first request must be reused with the safe connection +client c3 -connect ${h1_feS_sock} { + txreq + rxresp + expect resp.http.http_first_request == "0" +} -run diff --git a/reg-tests/connection/http_reuse_always.vtc b/reg-tests/connection/http_reuse_always.vtc new file mode 100644 index 0000000..136fe4e --- /dev/null +++ b/reg-tests/connection/http_reuse_always.vtc @@ -0,0 +1,43 @@ +varnishtest "Test the http-reuse always mode" + +#REQUIRE_VERSION=2.2 + +feature ignore_unknown_macro + +haproxy h1 -conf { + defaults + mode http + + listen sender + bind "fd@${feS}" + http-reuse always + server srv ${h1_feR_addr}:${h1_feR_port} + + listen receiver + bind "fd@${feR}" + http-request return status 200 + http-after-response set-header http_first_request %[http_first_req] +} -start + +# bootstrap +client c1 -connect ${h1_feS_sock} { + txreq + rxresp + expect resp.http.http_first_request == "1" +} -run + +client c2 -connect ${h1_feS_sock} { + txreq + rxresp + expect resp.http.http_first_request == "0" + + txreq + rxresp + expect resp.http.http_first_request == "0" +} -run + +client c3 -connect ${h1_feS_sock} { + txreq + rxresp + expect resp.http.http_first_request == "0" +} -run diff --git a/reg-tests/connection/http_reuse_be_transparent.vtc b/reg-tests/connection/http_reuse_be_transparent.vtc new file mode 100644 index 0000000..1cadb35 --- /dev/null +++ b/reg-tests/connection/http_reuse_be_transparent.vtc @@ -0,0 +1,81 @@ +varnishtest "Test the proper interaction between http-reuse and backend in transparent mode" + +# If backend is used with the transparent mode, the connection are considered +# as private and should only be reused for requests of the same session. +# This is similar to the http-reuse never mode + +#REQUIRE_VERSION=2.4 + +feature ignore_unknown_macro + +haproxy h1 -conf { + defaults + mode http + + listen sender + bind "fd@${feS}" + http-request set-header client-id %[req.hdr(client-id)] if { req.hdr(client-id) -m found } + option transparent + http-request set-dst-port int(${h1_feR_port}) + + listen receiver + bind "fd@${feR}" + http-request set-var(sess.client_id) req.hdr(client-id) + http-request return status 200 + http-after-response set-header http_first_request %[http_first_req] + http-after-response set-header client-id %[var(sess.client_id)] +} -start + +client c1 -connect ${h1_feS_sock} { + txreq \ + -hdr "client-id: c1" + rxresp + expect resp.http.http_first_request == "1" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c1" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c1" +} -run + +client c2 -connect ${h1_feS_sock} { + txreq \ + -hdr "client-id: c2" + rxresp + expect resp.http.http_first_request == "1" + expect resp.http.client-id == "c2" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c2" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c2" +} -run + +client c3 -connect ${h1_feS_sock} { + txreq \ + -hdr "client-id: c3" + rxresp + expect resp.http.http_first_request == "1" + expect resp.http.client-id == "c3" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c3" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c3" +} -run + diff --git a/reg-tests/connection/http_reuse_conn_hash.vtc b/reg-tests/connection/http_reuse_conn_hash.vtc new file mode 100644 index 0000000..991e86f --- /dev/null +++ b/reg-tests/connection/http_reuse_conn_hash.vtc @@ -0,0 +1,163 @@ +varnishtest "Test the http-reuse with special connection parameters" +#REQUIRE_VERSION=2.4 +#REQUIRE_OPTIONS=OPENSSL + +feature ignore_unknown_macro + +haproxy h1 -conf { + defaults + mode http + + # sni + listen sender-sni + bind "fd@${feS_sni}" + server srv2 ${h1_feR_ssl_addr}:${h1_feR_ssl_port} ssl sni "req.hdr(x-sni)" verify none pool-low-conn 2 + + # set-dst + # specify dst1_addr for server, which should be identical to dst2_addr + # port is specified by the client in header x-dst-port + listen sender-set-dst + bind "fd@${feS_dst}" + http-request set-dst-port hdr(x-dst-port) + server srv2 ${h1_feR_dst1_addr}:0 pool-low-conn 2 + + # proxy protocol + # must use reuse always as consecutive requests are from different client + listen sender-proxy + bind "fd@${feS_proxy}" accept-proxy + http-reuse always + server srv2 ${h1_feR_proxy_addr}:${h1_feR_proxy_port} send-proxy pool-low-conn 2 + + listen receiver + bind "fd@${feR_ssl}" ssl crt ${testdir}/common.pem + bind "fd@${feR_proxy}" accept-proxy + http-request return status 200 + http-after-response set-header http_first_request %[http_first_req] + + listen receiver-dst1 + bind "fd@${feR_dst1}" + http-request return status 200 hdr "x-dst" "dst1" + http-after-response set-header http_first_request %[http_first_req] + + listen receiver-dst2 + bind "fd@${feR_dst2}" + http-request return status 200 hdr "x-dst" "dst2" + http-after-response set-header http_first_request %[http_first_req] +} -start + +# http-reuse with sni parameters +client c_sni -connect ${h1_feS_sni_sock} { + # first request + txreq \ + -hdr "x-sni: www.custom.com" + rxresp + expect resp.http.http_first_request == "1" + + # second request with same sni, connection must be reused + txreq \ + -hdr "x-sni: www.custom.com" + rxresp + expect resp.http.http_first_request == "0" + + # third request with a different sni, a new connection must be used + txreq \ + -hdr "x-sni: www.custom2.com" + rxresp + expect resp.http.http_first_request == "1" + + # fourth request, reuse sni2 + txreq \ + -hdr "x-sni: www.custom2.com" + rxresp + expect resp.http.http_first_request == "0" +} -run + +# http-reuse with destination address +client c_dst1 -connect ${h1_feS_dst_sock} { + txreq \ + -hdr "x-dst-port: ${h1_feR_dst1_port}" + rxresp + expect resp.status == 200 + expect resp.http.x-dst == "dst1" + expect resp.http.http_first_request == "1" + + txreq \ + -hdr "x-dst-port: ${h1_feR_dst1_port}" + rxresp + expect resp.status == 200 + expect resp.http.x-dst == "dst1" + expect resp.http.http_first_request == "0" + + txreq \ + -hdr "x-dst-port: ${h1_feR_dst2_port}" + rxresp + expect resp.status == 200 + expect resp.http.x-dst == "dst2" + expect resp.http.http_first_request == "1" + + txreq \ + -hdr "x-dst-port: ${h1_feR_dst1_port}" + rxresp + expect resp.status == 200 + expect resp.http.x-dst == "dst1" + expect resp.http.http_first_request == "0" + + txreq \ + -hdr "x-dst-port: ${h1_feR_dst2_port}" + rxresp + expect resp.status == 200 + expect resp.http.x-dst == "dst2" + expect resp.http.http_first_request == "0" +} -run + +## first request with proxy protocol +client c_proxy -connect ${h1_feS_proxy_sock} -proxy1 "127.0.0.1:40000 ${h1_feS_proxy_addr}:${h1_feS_proxy_port}" { + txreq + rxresp + expect resp.status == 200 + expect resp.http.http_first_request == "1" + + txreq + rxresp + expect resp.status == 200 + expect resp.http.http_first_request == "0" +} -run + +## second request with different proxy protocol +# this have the nice effect to fill the server pool to 2 connection +# (pool-low-conn value) to allow takeover on multi thread run +client c_proxy -connect ${h1_feS_proxy_sock} -proxy1 "127.0.0.1:50000 ${h1_feS_proxy_addr}:${h1_feS_proxy_port}" { + txreq + rxresp + expect resp.status == 200 + expect resp.http.http_first_request == "1" +} -run + +## third request, reuse same proxy protocol entry +client c_proxy -connect ${h1_feS_proxy_sock} -proxy1 "127.0.0.1:40000 ${h1_feS_proxy_addr}:${h1_feS_proxy_port}" { + txreq + rxresp + expect resp.status == 200 + expect resp.http.http_first_request == "0" +} -run + +## fourth request with different proxy protocol entry, no reuse +client c_proxy -connect ${h1_feS_proxy_sock} -proxy1 "127.0.0.1:60000 ${h1_feS_proxy_addr}:${h1_feS_proxy_port}" { + txreq + rxresp + expect resp.status == 200 + expect resp.http.http_first_request == "1" +} -run + +## fifth request, reuse proxy protocol +client c_proxy -connect ${h1_feS_proxy_sock} -proxy1 "127.0.0.1:50000 ${h1_feS_proxy_addr}:${h1_feS_proxy_port}" { + txreq + rxresp + expect resp.status == 200 + expect resp.http.http_first_request == "0" + + txreq + rxresp + expect resp.status == 200 + expect resp.http.http_first_request == "0" +} -run diff --git a/reg-tests/connection/http_reuse_dispatch.vtc b/reg-tests/connection/http_reuse_dispatch.vtc new file mode 100644 index 0000000..a419727 --- /dev/null +++ b/reg-tests/connection/http_reuse_dispatch.vtc @@ -0,0 +1,79 @@ +varnishtest "Test the proper interaction between http-reuse and dispatch mode" + +# With dispatch, the connection are considered as private and should only be +# reused for requests of the same session +# This is similar to the http-reuse never mode + +#REQUIRE_VERSION=2.4 + +feature ignore_unknown_macro + +haproxy h1 -conf { + defaults + mode http + + listen sender + bind "fd@${feS}" + http-request set-header client-id %[req.hdr(client-id)] if { req.hdr(client-id) -m found } + dispatch ${h1_feR_addr}:${h1_feR_port} + + listen receiver + bind "fd@${feR}" + http-request set-var(sess.client_id) req.hdr(client-id) + http-request return status 200 + http-after-response set-header http_first_request %[http_first_req] + http-after-response set-header client-id %[var(sess.client_id)] +} -start + +client c1 -connect ${h1_feS_sock} { + txreq \ + -hdr "client-id: c1" + rxresp + expect resp.http.http_first_request == "1" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c1" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c1" +} -run + +client c2 -connect ${h1_feS_sock} { + txreq \ + -hdr "client-id: c2" + rxresp + expect resp.http.http_first_request == "1" + expect resp.http.client-id == "c2" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c2" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c2" +} -run + +client c3 -connect ${h1_feS_sock} { + txreq \ + -hdr "client-id: c3" + rxresp + expect resp.http.http_first_request == "1" + expect resp.http.client-id == "c3" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c3" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c3" +} -run diff --git a/reg-tests/connection/http_reuse_never.vtc b/reg-tests/connection/http_reuse_never.vtc new file mode 100644 index 0000000..fc74631 --- /dev/null +++ b/reg-tests/connection/http_reuse_never.vtc @@ -0,0 +1,79 @@ +varnishtest "Test the http-reuse never mode" + +#REQUIRE_VERSION=2.2 + +feature ignore_unknown_macro + +haproxy h1 -conf { + defaults + mode http + + # limit idle pool to one connection + # this is to mirror http-reuse safe test, but in this case to ensure that + # connection are never reused as expected + listen sender + bind "fd@${feS}" + http-reuse never + http-request set-header client-id %[req.hdr(client-id)] if { req.hdr(client-id) -m found } + server srv ${h1_feR_addr}:${h1_feR_port} pool-max-conn 1 + + listen receiver + bind "fd@${feR}" + http-request set-var(sess.client_id) req.hdr(client-id) + http-request return status 200 + http-after-response set-header http_first_request %[http_first_req] + http-after-response set-header client-id %[var(sess.client_id)] +} -start + +client c1 -connect ${h1_feS_sock} { + txreq \ + -hdr "client-id: c1" + rxresp + expect resp.http.http_first_request == "1" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c1" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c1" +} -run + +client c2 -connect ${h1_feS_sock} { + txreq \ + -hdr "client-id: c2" + rxresp + expect resp.http.http_first_request == "1" + expect resp.http.client-id == "c2" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c2" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c2" +} -run + +client c3 -connect ${h1_feS_sock} { + txreq \ + -hdr "client-id: c3" + rxresp + expect resp.http.http_first_request == "1" + expect resp.http.client-id == "c3" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c3" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c3" +} -run diff --git a/reg-tests/connection/http_reuse_safe.vtc b/reg-tests/connection/http_reuse_safe.vtc new file mode 100644 index 0000000..fa00dd4 --- /dev/null +++ b/reg-tests/connection/http_reuse_safe.vtc @@ -0,0 +1,78 @@ +varnishtest "Test the http-reuse safe mode" + +#REQUIRE_VERSION=2.2 + +feature ignore_unknown_macro + +haproxy h1 -conf { + defaults + mode http + + # limit idle pool to one connection + # this forces connection reuse for the transaction after the first one + listen sender + bind "fd@${feS}" + http-reuse safe + http-request set-header client-id %[req.hdr(client-id)] if { req.hdr(client-id) -m found } + server srv ${h1_feR_addr}:${h1_feR_port} pool-max-conn 1 + + listen receiver + bind "fd@${feR}" + http-request set-var(sess.client_id) req.hdr(client-id) + http-request return status 200 + http-after-response set-header http_first_request %[http_first_req] + http-after-response set-header client-id %[var(sess.client_id)] +} -start + +client c1 -connect ${h1_feS_sock} { + txreq \ + -hdr "client-id: c1" + rxresp + expect resp.http.http_first_request == "1" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c1" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c1" +} -run + +client c2 -connect ${h1_feS_sock} { + txreq \ + -hdr "client-id: c2" + rxresp + expect resp.http.http_first_request == "1" + expect resp.http.client-id == "c2" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c1" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c1" +} -run + +client c3 -connect ${h1_feS_sock} { + txreq \ + -hdr "client-id: c3" + rxresp + expect resp.http.http_first_request == "1" + expect resp.http.client-id == "c3" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c1" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c1" +} -run diff --git a/reg-tests/connection/proxy_protocol_random_fail.vtc b/reg-tests/connection/proxy_protocol_random_fail.vtc new file mode 100644 index 0000000..bcaa03c --- /dev/null +++ b/reg-tests/connection/proxy_protocol_random_fail.vtc @@ -0,0 +1,60 @@ +#commit b406b87 +# BUG/MEDIUM: connection: don't store recv() result into trash.data +# +# Cyril Bonté discovered that the proxy protocol randomly fails since +# commit 843b7cb ("MEDIUM: chunks: make the chunk struct's fields match +# the buffer struct"). This is because we used to store recv()'s return +# code into trash.data which is now unsigned, so it never compares as +# negative against 0. Let's clean this up and test the result itself +# without storing it first. + +varnishtest "PROXY protocol random failures" +#REQUIRE_OPTIONS=OPENSSL + +feature ignore_unknown_macro + +#REGTEST_TYPE=broken + +syslog Slog_1 -repeat 8 -level info { + recv + expect ~ "Connect from .* to ${h1_ssl_addr}:${h1_ssl_port}" + recv + expect ~ "ssl-offload-http/http .* \"POST (https://.*:${h1_ssl_port})?/[1-8] HTTP/(2\\.0|1\\.1)\"" +} -start + +haproxy h1 -conf { + global + tune.ssl.default-dh-param 2048 + stats bind-process 1 + log ${Slog_1_addr}:${Slog_1_port} len 2048 local0 debug err + + defaults + mode http + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + log global + + listen http + bind unix@"${tmpdir}/http.socket" accept-proxy name ssl-offload-http + option forwardfor + + listen ssl-offload-http + option httplog + bind "fd@${ssl}" ssl crt ${testdir}/common.pem ssl no-sslv3 alpn h2,http/1.1 + server http unix@"${tmpdir}/http.socket" send-proxy +} -start + + +shell { + HOST=${h1_ssl_addr} + if [ "$HOST" = "::1" ] ; then + HOST="\[::1\]" + fi + for i in 1 2 3 4 5 6 7 8 ; do + urls="$urls https://$HOST:${h1_ssl_port}/$i" + done + curl -i -k -d 'x=x' $urls & wait $! +} + +syslog Slog_1 -wait diff --git a/reg-tests/connection/proxy_protocol_send_unique_id.vtc b/reg-tests/connection/proxy_protocol_send_unique_id.vtc new file mode 100644 index 0000000..4f6b848 --- /dev/null +++ b/reg-tests/connection/proxy_protocol_send_unique_id.vtc @@ -0,0 +1,42 @@ +varnishtest "Check that the unique ID TLV is properly sent" + +#REQUIRE_VERSION=2.2 + +feature ignore_unknown_macro + +haproxy h1 -conf { + defaults + mode http + log global + unique-id-format %{+X}o\ TEST-%[req.hdr(in)] + + listen sender + bind "fd@${feS}" + + unique-id-header unique_id + + server example ${h1_feR_addr}:${h1_feR_port} send-proxy-v2 proxy-v2-options unique-id + + listen receiver + bind "fd@${feR}" accept-proxy + + http-request set-var(txn.http_unique_id) req.hdr(unique_id) + http-request set-var(txn.proxy_unique_id) fc_pp_unique_id + http-after-response set-header http_unique_id %[var(txn.http_unique_id)] + http-after-response set-header proxy_unique_id %[var(txn.proxy_unique_id)] + http-request return status 200 +} -start + +# Validate that a correct header passes +client c1 -connect ${h1_feS_sock} { + txreq -url "/" \ + -hdr "in: foo" + rxresp + expect resp.http.http_unique_id == "TEST-foo" + expect resp.http.proxy_unique_id == "TEST-foo" + txreq -url "/" \ + -hdr "in: bar" + rxresp + expect resp.http.http_unique_id == "TEST-bar" + expect resp.http.proxy_unique_id == "TEST-bar" +} -run diff --git a/reg-tests/connection/proxy_protocol_send_unique_id_alpn.vtc b/reg-tests/connection/proxy_protocol_send_unique_id_alpn.vtc new file mode 100644 index 0000000..87e590a --- /dev/null +++ b/reg-tests/connection/proxy_protocol_send_unique_id_alpn.vtc @@ -0,0 +1,33 @@ +varnishtest "Check that the unique ID TLV is properly sent for servers with ALPN option" + +#REQUIRE_VERSION=2.2 +#REQUIRE_OPTIONS=OPENSSL + +feature ignore_unknown_macro + +haproxy h1 -conf { + defaults + mode http + log global + unique-id-format %{+X}o\ TEST-%[req.hdr(in)] + + listen sender + bind "fd@${feS}" + + server example ${h1_feR_addr}:${h1_feR_port} send-proxy-v2 proxy-v2-options unique-id ssl alpn XXX verify none + + listen receiver + bind "fd@${feR}" ssl crt ${testdir}/common.pem accept-proxy + + http-request set-var(txn.proxy_unique_id) fc_pp_unique_id + http-after-response set-header proxy_unique_id %[var(txn.proxy_unique_id)] + http-request return status 200 +} -start + +# Validate that a correct header passes +client c1 -connect ${h1_feS_sock} { + txreq -url "/" \ + -hdr "in: foo" + rxresp + expect resp.http.proxy_unique_id == "TEST-foo" +} -run diff --git a/reg-tests/connection/proxy_protocol_tlv_validation.vtc b/reg-tests/connection/proxy_protocol_tlv_validation.vtc new file mode 100644 index 0000000..8c7d734 --- /dev/null +++ b/reg-tests/connection/proxy_protocol_tlv_validation.vtc @@ -0,0 +1,142 @@ +varnishtest "Check that the TLVs are properly validated" + +#REQUIRE_VERSION=2.4 + +feature ignore_unknown_macro + +# We need one HAProxy for each test, because apparently the connection by +# the client is reused, leading to connection resets. + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend a + bind "fd@${fe1}" accept-proxy + http-after-response set-header echo %[fc_pp_authority,hex] + http-request return status 200 +} -start + +# Validate that a correct header passes +client c1 -connect ${h1_fe1_sock} { + # PROXY v2 signature + sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a" + # version + PROXY + sendhex "21" + # TCP4 + sendhex "11" + # length of the address (12) + length of the TLV (8) + sendhex "00 14" + # 127.0.0.1 42 127.0.0.1 1337 + sendhex "7F 00 00 01 7F 00 00 01 00 2A 05 39" + # PP2_TYPE_AUTHORITY + length of the value + "12345" + sendhex "02 00 05 31 32 33 34 35" + + txreq -url "/" + rxresp + expect resp.http.echo == "3132333435" +} -run + +haproxy h2 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend a + bind "fd@${fe1}" accept-proxy + http-after-response set-header echo %[fc_pp_authority,hex] + http-request return status 200 +} -start + +# Validate that a TLV after the end of the PROXYv2 header is not parsed +# and handle by the HTTP parser, leading to a 400 bad request error +client c2 -connect ${h2_fe1_sock} { + # PROXY v2 signature + sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a" + # version + PROXY + sendhex "21" + # TCP4 + sendhex "11" + # length of the address (12) + length of the TLV (8) + sendhex "00 14" + # 127.0.0.1 42 127.0.0.1 1337 + sendhex "7F 00 00 01 7F 00 00 01 00 2A 05 39" + # PP2_TYPE_AUTHORITY + length of the value + "12345" + sendhex "02 00 05 31 32 33 34 35" + # after the end of the PROXYv2 header: PP2_TYPE_AUTHORITY + length of the value + "54321" + sendhex "02 00 05 35 34 33 32 31" + + txreq -url "/" + rxresp + expect resp.status == 400 + expect resp.http.echo == <undef> +} -run + +haproxy h3 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend a + bind "fd@${fe1}" accept-proxy + http-after-response set-header echo %[fc_pp_authority,hex] + http-request return status 200 +} -start + +# Validate that a TLV length exceeding the PROXYv2 length fails +client c3 -connect ${h3_fe1_sock} { + # PROXY v2 signature + sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a" + # version + PROXY + sendhex "21" + # TCP4 + sendhex "11" + # length of the address (12) + too small length of the TLV (8) + sendhex "00 14" + # 127.0.0.1 42 127.0.0.1 1337 + sendhex "7F 00 00 01 7F 00 00 01 00 2A 05 39" + # PP2_TYPE_AUTHORITY + length of the value + "1234512345" + sendhex "02 00 0A 31 32 33 34 35 31 32 33 34 35" + + txreq -url "/" + expect_close +} -run + +haproxy h4 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend a + bind "fd@${fe1}" accept-proxy + http-after-response set-header echo %[fc_pp_authority,hex] + http-request return status 200 +} -start + +# Validate that TLVs not ending with the PROXYv2 header fail +client c4 -connect ${h4_fe1_sock} { + # PROXY v2 signature + sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a" + # version + PROXY + sendhex "21" + # TCP4 + sendhex "11" + # length of the address (12) + too big length of the TLV (8) + sendhex "00 14" + # 127.0.0.1 42 127.0.0.1 1337 + sendhex "7F 00 00 01 7F 00 00 01 00 2A 05 39" + # PP2_TYPE_AUTHORITY + length of the value + "1234" + sendhex "02 00 04 31 32 33 34" + + txreq -url "/" + expect_close +} -run diff --git a/reg-tests/connection/tcp_to_http_upgrade.vtc b/reg-tests/connection/tcp_to_http_upgrade.vtc new file mode 100644 index 0000000..093ba48 --- /dev/null +++ b/reg-tests/connection/tcp_to_http_upgrade.vtc @@ -0,0 +1,162 @@ +varnishtest "Test connection upgrades from TCP to HTTP" + +#REQUIRE_VERSION=2.4 + +feature ignore_unknown_macro + +server s1 { + # TCP > H1 using "switch-mode http" + rxreq + expect req.http.x-stream-mode == tcp + expect req.http.x-name == fe1 + txresp + rxreq + expect req.http.x-stream-mode == http + expect req.http.x-name == fe1 + txresp + + accept + + # TCP > H1 using backend mode + rxreq + expect req.http.x-name == be + txresp + rxreq + expect req.http.x-name == be + txresp + + accept + + # TCP > H2 using "switch-mode http" + rxreq + expect req.http.x-stream-mode == http + expect req.http.x-name == fe1 + txresp + rxreq + expect req.http.x-stream-mode == http + expect req.http.x-name == fe1 + txresp + + # To be sure no other request was received + accept + rxreq + txresp +} -start + +haproxy h1 -conf { + frontend fe1 + mode tcp + bind "fd@${fe1h1}" + + tcp-request inspect-delay 1s + tcp-request content set-var(req.stream_mode) internal.strm.is_htx,iif(http,tcp) + tcp-request content switch-mode http if HTTP + tcp-request content reject # never reached + + http-request set-header x-stream-mode %[var(req.stream_mode)] + http-request set-header x-name %[fe_name] + + default_backend be + + frontend fe2 + mode tcp + bind "fd@${fe2h1}" + default_backend be + + backend be + mode http + http-request set-header x-name %[be_name] unless { req.fhdr(x-name) -m found } + server s1 ${s1_addr}:${s1_port} + + listen li1 + mode http + bind "fd@${li1h1}" + server s1 ${h1_fe1h1_addr}:${h1_fe1h1_port} proto h2 + + listen err1 + mode http + bind "fd@${err1h1}" proto h1 + server s1 ${s1_addr}:${s1_port} + + listen err2 + mode tcp + bind "fd@${err2h1}" + + tcp-request inspect-delay 1s + tcp-request content switch-mode http proto h1 if HTTP + tcp-request content reject # never reached + + default_backend be + + listen err3 + mode tcp + bind "fd@${err3h1}" proto none + + tcp-request inspect-delay 1s + tcp-request content switch-mode http if HTTP + tcp-request content reject # never reached + + default_backend be +} -start + +# TCP > H1 using "switch-mode http" +client c1 -connect ${h1_fe1h1_sock} { + txreq + rxresp + expect resp.status == 200 + + txreq + rxresp + expect resp.status == 200 +} -run + +# TCP > H1 using backend mode +client c2 -connect ${h1_fe2h1_sock} { + txreq + rxresp + expect resp.status == 200 + + txreq + rxresp + expect resp.status == 200 +} -run + + +# TCP > H2 using "switch-mode http" +client c3 -connect ${h1_li1h1_sock} { + txreq + rxresp + expect resp.status == 200 + + txreq + rxresp + expect resp.status == 200 +} -run + +# implicit H1 > H2 upgrade not performed +client c_err1 -connect ${h1_err1h1_sock} { + send "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" + rxresp + expect resp.status == 400 +} -run + + +# TCP > H1 > H2 upgrade not allowed +client c_err2 -connect ${h1_err2h1_sock} { + send "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" + rxresp + expect resp.status == 400 +} -run + + +# TCP > HTTP upgrade not allowed +client c_err3 -connect ${h1_err3h1_sock} { + txreq + expect_close +} -run + +# To be sure no other request was received by the server +client c_end -connect ${s1_sock} { + txreq + rxresp +} -run |