[master] 9837045 Send a PROXY v1 line with backend probes
Dridi Boukelmoune
dridi.boukelmoune at gmail.com
Mon Mar 6 13:55:06 CET 2017
commit 9837045a011db7496b6a0680687c48fbbac41186
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date: Fri Mar 3 10:46:31 2017 +0100
Send a PROXY v1 line with backend probes
It consists in the source and destination being the same socket address.
Refs #2151
diff --git a/bin/varnishd/cache/cache_backend_probe.c b/bin/varnishd/cache/cache_backend_probe.c
index 1d743f8..9f451c7 100644
--- a/bin/varnishd/cache/cache_backend_probe.c
+++ b/bin/varnishd/cache/cache_backend_probe.c
@@ -43,6 +43,9 @@
#include <stdio.h>
#include <stdlib.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+
#include "binary_heap.h"
#include "vcli_serve.h"
#include "vrt.h"
@@ -213,6 +216,49 @@ vbp_reset(struct vbp_target *vt)
* want to measure the backends response without local distractions.
*/
+static int
+vbp_write(struct vbp_target *vt, int sock, const void *buf, size_t len)
+{
+ int i;
+
+ i = write(sock, buf, len);
+ if (i != len) {
+ if (i < 0)
+ vt->err_xmit |= 1;
+ VTCP_close(&sock);
+ return (-1);
+ }
+ return (0);
+}
+
+static int
+vbp_write_proxy_v1(struct vbp_target *vt, int sock)
+{
+ char buf[105]; /* maximum size for a TCP6 PROXY line with null char */
+ char addr[VTCP_ADDRBUFSIZE];
+ char port[VTCP_PORTBUFSIZE];
+ struct sockaddr_storage ss;
+ struct vsb vsb;
+ socklen_t l;
+
+ VTCP_myname(sock, addr, sizeof addr, port, sizeof port);
+ AN(VSB_new(&vsb, buf, sizeof buf, VSB_FIXEDLEN));
+ AZ(VSB_cat(&vsb, "PROXY"));
+
+ l = sizeof ss;
+ AZ(getsockname(sock, (void *)&ss, &l));
+ if (ss.ss_family == AF_INET6)
+ VSB_printf(&vsb, " TCP6 ");
+ else if (ss.ss_family == AF_INET)
+ VSB_printf(&vsb, " TCP4 ");
+ else
+ WRONG("Unknown family");
+ VSB_printf(&vsb, "%s %s %s %s\r\n", addr, addr, port, port);
+ AZ(VSB_finish(&vsb));
+
+ return (vbp_write(vt, sock, VSB_data(&vsb), VSB_len(&vsb)));
+}
+
static void
vbp_poke(struct vbp_target *vt)
{
@@ -248,14 +294,18 @@ vbp_poke(struct vbp_target *vt)
return;
}
+ /* Send the PROXY header */
+ assert(vt->backend->proxy_header >= 0);
+ assert(vt->backend->proxy_header <= 2);
+ if (vt->backend->proxy_header == 1) {
+ if (vbp_write_proxy_v1(vt, s) != 0)
+ return;
+ } else if (vt->backend->proxy_header == 2)
+ INCOMPL();
+
/* Send the request */
- i = write(s, vt->req, vt->req_len);
- if (i != vt->req_len) {
- if (i < 0)
- vt->err_xmit |= 1;
- VTCP_close(&s);
+ if (vbp_write(vt, s, vt->req, vt->req_len) != 0)
return;
- }
vt->good_xmit |= 1;
pfd->fd = s;
diff --git a/bin/varnishtest/tests/o00004.vtc b/bin/varnishtest/tests/o00004.vtc
new file mode 100644
index 0000000..03c67d5
--- /dev/null
+++ b/bin/varnishtest/tests/o00004.vtc
@@ -0,0 +1,50 @@
+varnishtest "Sending proxy headers via health probes"
+
+# Double-proxy scheme stolen from o00002.vtc
+
+server s1 {
+ rxreq
+ expect req.http.x-forwarded-for == "127.0.0.1"
+ txresp
+} -start
+
+varnish v1 -proto PROXY -vcl+backend {
+ import debug;
+
+ sub vcl_recv {
+ if (client.ip != remote.ip || server.ip != local.ip) {
+ return (synth(400));
+ }
+ }
+} -start
+
+varnish v2 -proto PROXY -vcl {
+ import std;
+
+ probe p {
+ .window = 1;
+ .threshold = 1;
+ .interval =0.5s;
+ }
+ backend bp1 {
+ .host = "${v1_addr}";
+ .port = "${v1_port}";
+ .proxy_header = 1;
+ .probe = p;
+ }
+ backend bp2 {
+ .host = "${v1_addr}";
+ .port = "${v1_port}";
+ .proxy_header = 2;
+ }
+
+ sub vcl_init {
+ # dummy backend ref
+ if (bp2) { }
+ }
+} -start
+
+server s1 -wait
+
+delay 1
+varnish v2 -cliexpect "vcl1.bp1[ ]+probe[ ]+Healthy[ ]+1/1" backend.list
More information about the varnish-commit
mailing list