[master] 66d14ff Add -proxy1 and -proxy2 support to varnishtest
Federico G. Schwindt
fgsch at lodoss.net
Sun Jun 19 15:09:05 CEST 2016
commit 66d14ff3230122687f7277eb75ea5010cfc9082b
Author: Federico G. Schwindt <fgsch at lodoss.net>
Date: Sun Jun 19 14:04:47 2016 +0100
Add -proxy1 and -proxy2 support to varnishtest
Fixes #1989.
diff --git a/bin/varnishtest/Makefile.am b/bin/varnishtest/Makefile.am
index 9d8c0b5..d6dbc10 100644
--- a/bin/varnishtest/Makefile.am
+++ b/bin/varnishtest/Makefile.am
@@ -23,19 +23,20 @@ AM_CPPFLAGS = \
bin_PROGRAMS = varnishtest
varnishtest_SOURCES = \
+ programs.h \
+ vmods.h \
vtc.c \
vtc.h \
- vmods.h \
- programs.h \
vtc_barrier.c \
vtc_client.c \
vtc_http.c \
- vtc_main.c \
vtc_log.c \
- vtc_server.c \
- vtc_varnish.c \
vtc_logexp.c \
- vtc_process.c
+ vtc_main.c \
+ vtc_process.c \
+ vtc_proxy.c \
+ vtc_server.c \
+ vtc_varnish.c
varnishtest_LDADD = \
$(top_builddir)/lib/libvarnish/libvarnish.la \
diff --git a/bin/varnishtest/tests/o00000.vtc b/bin/varnishtest/tests/o00000.vtc
index 1bf1e1d..5bd0a12 100644
--- a/bin/varnishtest/tests/o00000.vtc
+++ b/bin/varnishtest/tests/o00000.vtc
@@ -140,8 +140,7 @@ logexpect l1 -v v1 {
} -start
# Finally try something which works...
-client c1 {
- send "PROXY TCP4 1.2.3.4 5.6.7.8 1234 5678\r\n"
+client c1 -proxy1 "1.2.3.4:1234 5.6.7.8:5678" {
txreq -url /1
rxresp
expect resp.http.url == "/1"
@@ -156,8 +155,7 @@ client c1 {
} -run
delay .1
-client c1 {
- send "PROXY TCP6 1:f::2 5:a::8 1234 5678\r\n"
+client c1 -proxy1 "[1:f::2]:1234 [5:a::8]:5678" {
txreq -url /2
rxresp
expect resp.http.url == "/2"
@@ -175,14 +173,14 @@ delay .1
logexpect l1 -wait
# Try with appended request (See also: #1728)
-client c1 {
+client c2 {
send "PROXY TCP6 1:f::3 5:a::8 1234 5678\r\nGET /3 HTTP/1.1\r\nHdr1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n\r\n"
rxresp
expect resp.http.url == "/3"
} -run
# Malformed (missing \r)
-client c1 {
+client c2 {
send "PROXY TCP4 1.2.3.4 5.6.7.8 1234 5678\n"
expect_close
} -run
@@ -190,7 +188,7 @@ delay .1
# Malformed, too long (106)
# NB: Should check VSL for proper disposal
-client c1 {
+client c2 {
send "PROXY TCP4 1.2.3.4 5.6.7.8 1234 5678 \r\n"
expect_close
} -run
@@ -198,7 +196,7 @@ delay .1
# Malformed, too long (107)
# NB: Should check VSL for proper disposal
-client c1 {
+client c2 {
send "PROXY TCP4 1.2.3.4 5.6.7.8 1234 5678 \r\n"
expect_close
} -run
@@ -206,7 +204,7 @@ delay .1
# Malformed, too long (108)
# NB: Should check VSL for proper disposal
-client c1 {
+client c2 {
send "PROXY TCP4 1.2.3.4 5.6.7.8 1234 5678 \r\n"
expect_close
} -run
diff --git a/bin/varnishtest/tests/o00001.vtc b/bin/varnishtest/tests/o00001.vtc
index c906963..02ff279 100644
--- a/bin/varnishtest/tests/o00001.vtc
+++ b/bin/varnishtest/tests/o00001.vtc
@@ -120,14 +120,8 @@ client c1 {
} -run
delay .1
-client c1 {
- # good IPv4
- sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a"
- sendhex "21 11 00 0c"
- sendhex "01 02 03 04"
- sendhex "05 06 07 08"
- sendhex "09 0a"
- sendhex "0b 0c"
+# good IPv4
+client c1 -proxy2 "1.2.3.4:2314 5.6.7.8:2828" {
txreq
rxresp
expect resp.status == 200
@@ -144,14 +138,9 @@ client c1 {
} -run
delay .1
-client c1 {
- # good IPv6
- sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a"
- sendhex "21 21 00 24"
- sendhex "01 02 03 04 05 06 00 00 00 00 00 00 0d 0e 0f 10"
- sendhex "81 82 83 84 85 86 00 00 00 00 00 00 8d 8e 8f 80"
- sendhex "09 0a"
- sendhex "0b 0c"
+# good IPv6
+client c1 \
+ -proxy2 "[102:304:506::d0e:f10]:2314 [8182:8384:8586::8d8e:8f80]:2828" {
txreq
rxresp
expect resp.status == 200
diff --git a/bin/varnishtest/tests/o00002.vtc b/bin/varnishtest/tests/o00002.vtc
index 5c6fee0..13fba7d 100644
--- a/bin/varnishtest/tests/o00002.vtc
+++ b/bin/varnishtest/tests/o00002.vtc
@@ -70,32 +70,28 @@ varnish v2 -proto PROXY -vcl {
}
} -start
-client c1 -connect ${v2_sock} {
- send "PROXY TCP4 1.2.3.4 5.6.7.8 1111 5678\r\n"
+client c1 -connect ${v2_sock} -proxy1 "1.2.3.4:1111 5.6.7.8:5678" {
txreq -url /1
rxresp
expect resp.body == "proxy1"
} -run
delay .2
-client c1 -connect ${v2_sock} {
- send "PROXY TCP4 1.2.3.4 5.6.7.8 2222 5678\r\n"
+client c1 -connect ${v2_sock} -proxy1 "1.2.3.4:2222 5.6.7.8:5678" {
txreq -url /2
rxresp
expect resp.body == "proxy2"
} -run
delay .2
-client c1 -connect ${v2_sock} {
- send "PROXY TCP6 1:f::2 5:a::8 3333 5678\r\n"
+client c1 -connect ${v2_sock} -proxy1 "[1:f::2]:3333 [5:a::8]:5678" {
txreq -url /3
rxresp
expect resp.body == "proxy3"
} -run
delay .2
-client c1 -connect ${v2_sock} {
- send "PROXY TCP6 1:f::2 5:a::8 4444 5678\r\n"
+client c1 -connect ${v2_sock} -proxy1 "[1:f::2]:4444 [5:a::8]:5678" {
txreq -url /4
rxresp
expect resp.body == "proxy4"
diff --git a/bin/varnishtest/tests/o00003.vtc b/bin/varnishtest/tests/o00003.vtc
index d821ce7..c883131 100644
--- a/bin/varnishtest/tests/o00003.vtc
+++ b/bin/varnishtest/tests/o00003.vtc
@@ -14,8 +14,7 @@ varnish v1 -proto PROXY -vcl+backend {
}
} -start
-client c1 {
- send "PROXY TCP4 1.2.3.4 5.6.7.8 1111 5678\r\n"
+client c1 -proxy1 "1.2.3.4:1111 5.6.7.8:5678" {
txreq
rxresp
expect resp.http.li == ${v1_addr}
diff --git a/bin/varnishtest/vtc.h b/bin/varnishtest/vtc.h
index 23095d4..b2b730a 100644
--- a/bin/varnishtest/vtc.h
+++ b/bin/varnishtest/vtc.h
@@ -43,6 +43,7 @@
struct vtclog;
struct cmds;
+struct suckaddr;
#define CMD_ARGS \
char * const *av, void *priv, const struct cmds *cmd, struct vtclog *vl
@@ -90,6 +91,9 @@ void vtc_dump(struct vtclog *vl, int lvl, const char *pfx,
void vtc_hexdump(struct vtclog *vl, int lvl, const char *pfx,
const unsigned char *str, int len);
+int vtc_send_proxy(int fd, int version, const struct suckaddr *sac,
+ const struct suckaddr *sas);
+
int exec_file(const char *fn, const char *script, const char *tmpdir,
char *logbuf, unsigned loglen);
diff --git a/bin/varnishtest/vtc_client.c b/bin/varnishtest/vtc_client.c
index 74bc8e7..67c86d1 100644
--- a/bin/varnishtest/vtc_client.c
+++ b/bin/varnishtest/vtc_client.c
@@ -31,12 +31,14 @@
#include <sys/types.h>
#include <sys/socket.h>
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "vtc.h"
+#include "vsa.h"
#include "vss.h"
#include "vtcp.h"
@@ -51,6 +53,9 @@ struct client {
char connect[256];
+ char *proxy_spec;
+ int proxy_version;
+
unsigned repeat;
unsigned running;
@@ -61,6 +66,47 @@ static VTAILQ_HEAD(, client) clients =
VTAILQ_HEAD_INITIALIZER(clients);
/**********************************************************************
+ * Send the proxy header
+ */
+
+static int __match_proto__(vss_resolved_f)
+proxy_cb(void *priv, const struct suckaddr *sa)
+{
+ struct suckaddr **addr = priv;
+ *addr = VSA_Clone(sa);
+ return (1);
+}
+
+static void
+client_proxy(struct vtclog *vl, int fd, int version, char *spec)
+{
+ struct suckaddr *sac, *sas;
+ const char *err;
+ char *p, *p2;
+ int error;
+
+ p = strdup(spec);
+ AN(p);
+ p2 = strchr(p, ' ');
+ AN(p2);
+ *p2++ = '\0';
+
+ error = VSS_resolver(p, NULL, proxy_cb, &sac, &err);
+ if (err != NULL)
+ vtc_log(vl, 0, "Could not resolve client address: %s", err);
+ assert(error == 1);
+ error = VSS_resolver(p2, NULL, proxy_cb, &sas, &err);
+ if (err != NULL)
+ vtc_log(vl, 0, "Could not resolve server address: %s", err);
+ assert(error == 1);
+ if (vtc_send_proxy(fd, version, sac, sas))
+ vtc_log(vl, 0, "Write failed: %s", strerror(errno));
+ free(p);
+ free(sac);
+ free(sas);
+}
+
+/**********************************************************************
* Client thread
*/
@@ -101,6 +147,8 @@ client_thread(void *priv)
VTCP_myname(fd, mabuf, sizeof mabuf, mpbuf, sizeof mpbuf);
vtc_log(vl, 3, "connected fd %d from %s %s to %s",
fd, mabuf, mpbuf, VSB_data(vsb));
+ if (c->proxy_spec != NULL)
+ client_proxy(vl, fd, c->proxy_version, c->proxy_spec);
fd = http_process(vl, c->spec, fd, NULL);
vtc_log(vl, 3, "closing fd %d", fd);
VTCP_close(&fd);
@@ -146,6 +194,7 @@ client_delete(struct client *c)
vtc_logclose(c->vl);
free(c->spec);
free(c->name);
+ free(c->proxy_spec);
/* XXX: MEMLEAK (?)*/
FREE_OBJ(c);
}
@@ -247,6 +296,18 @@ cmd_client(CMD_ARGS)
av++;
continue;
}
+ if (!strcmp(*av, "-proxy1")) {
+ REPLACE(c->proxy_spec, av[1]);
+ c->proxy_version = 1;
+ av++;
+ continue;
+ }
+ if (!strcmp(*av, "-proxy2")) {
+ REPLACE(c->proxy_spec, av[1]);
+ c->proxy_version = 2;
+ av++;
+ continue;
+ }
if (!strcmp(*av, "-repeat")) {
c->repeat = atoi(av[1]);
av++;
diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c
index 184384c..753ac8a 100644
--- a/bin/varnishtest/vtc_http.c
+++ b/bin/varnishtest/vtc_http.c
@@ -101,15 +101,23 @@
* "IP PORT".
*
* \-connect STRING (client only)
- * Indicate the server to connect to. STRING is also of the form
- * "IP PORT".
+ * Indicate the server to connect to. STRING is also of the form
+ * "IP PORT".
*
* \-dispatch (server only, s0 only)
- * Normally, to keep things simple, server threads only handle one
- * connection at a time, but the -dispatch switch allows to accept
- * any number of connection and handle them following the given spec.
+ * Normally, to keep things simple, server threads only handle one
+ * connection at a time, but the -dispatch switch allows to accept
+ * any number of connection and handle them following the given spec.
+ *
+ * However, -dispatch is only allowed for the server name "s0".
+ *
+ * \-proxy1 STRING (client only)
+ * Use the PROXY protocol version 1 for this connection. STRING
+ * is of the form "CLIENT:PORT SERVER:PORT".
*
- * However, -dispatch is only allowed for the server name "s0".
+ * \-proxy2 STRING (client only)
+ * Use the PROXY protocol version 2 for this connection. STRING
+ * is of the form "CLIENT:PORT SERVER:PORT".
*
* SECTION: client-server.spec Specification
*/
diff --git a/bin/varnishtest/vtc_proxy.c b/bin/varnishtest/vtc_proxy.c
new file mode 100644
index 0000000..e61658c
--- /dev/null
+++ b/bin/varnishtest/vtc_proxy.c
@@ -0,0 +1,132 @@
+/*-
+ * Copyright (c) 2015 Varnish Software AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include <unistd.h>
+
+#include "vtc.h"
+
+#include "vend.h"
+#include "vsa.h"
+#include "vtcp.h"
+
+static const char vpx1_sig[] = {'P', 'R', 'O', 'X', 'Y'};
+static const char vpx2_sig[] = {
+ '\r', '\n', '\r', '\n', '\0', '\r', '\n',
+ 'Q', 'U', 'I', 'T', '\n',
+};
+
+static void
+vpx_enc_addr(struct vsb *vsb, int proto, const struct suckaddr *s)
+{
+ const struct sockaddr_in *sin4;
+ const struct sockaddr_in6 *sin6;
+ socklen_t sl;
+
+ if (proto == PF_INET6) {
+ sin6 = VSA_Get_Sockaddr(s, &sl); //lint !e826
+ AN(sin6);
+ assert(sl >= sizeof(*sin6));
+ VSB_bcat(vsb, &sin6->sin6_addr, sizeof(sin6->sin6_addr));
+ } else {
+ sin4 = VSA_Get_Sockaddr(s, &sl); //lint !e826
+ AN(sin4);
+ assert(sl >= sizeof(*sin4));
+ VSB_bcat(vsb, &sin4->sin_addr, sizeof(sin4->sin_addr));
+ }
+}
+
+static void
+vpx_enc_port(struct vsb *vsb, const struct suckaddr *s)
+{
+ uint8_t b[2];
+
+ vbe16enc(b, (uint16_t)VSA_Port(s));
+ VSB_bcat(vsb, b, sizeof(b));
+}
+
+int
+vtc_send_proxy(int fd, int version, const struct suckaddr *sac,
+ const struct suckaddr *sas)
+{
+ struct vsb *vsb;
+ char hc[VTCP_ADDRBUFSIZE];
+ char pc[VTCP_PORTBUFSIZE];
+ char hs[VTCP_ADDRBUFSIZE];
+ char ps[VTCP_PORTBUFSIZE];
+ int i, len;
+ int proto;
+
+ AN(sac);
+ AN(sas);
+
+ assert(version == 1 || version == 2);
+ vsb = VSB_new_auto();
+ AN(vsb);
+
+ proto = VSA_Get_Proto(sas);
+ assert(proto == PF_INET6 || proto == PF_INET);
+
+ if (version == 1) {
+ VSB_bcat(vsb, vpx1_sig, sizeof(vpx1_sig));
+ if (proto == PF_INET6)
+ VSB_printf(vsb, " TCP6 ");
+ else if (proto == PF_INET)
+ VSB_printf(vsb, " TCP4 ");
+ VTCP_name(sac, hc, sizeof(hc), pc, sizeof(pc));
+ VTCP_name(sas, hs, sizeof(hs), ps, sizeof(ps));
+ VSB_printf(vsb, "%s %s %s %s\r\n", hc, hs, pc, ps);
+ } else if (version == 2) {
+ VSB_bcat(vsb, vpx2_sig, sizeof(vpx2_sig));
+ VSB_putc(vsb, 0x21);
+ if (proto == PF_INET6) {
+ VSB_putc(vsb, 0x21);
+ VSB_putc(vsb, 0x00);
+ VSB_putc(vsb, 0x24);
+ } else if (proto == PF_INET) {
+ VSB_putc(vsb, 0x11);
+ VSB_putc(vsb, 0x00);
+ VSB_putc(vsb, 0x0c);
+ }
+ vpx_enc_addr(vsb, proto, sac);
+ vpx_enc_addr(vsb, proto, sas);
+ vpx_enc_port(vsb, sac);
+ vpx_enc_port(vsb, sas);
+ } else
+ WRONG("Wrong proxy version");
+
+ AZ(VSB_finish(vsb));
+ len = VSB_len(vsb);
+ i = write(fd, VSB_data(vsb), len);
+ VSB_delete(vsb);
+ return (i != len);
+}
More information about the varnish-commit
mailing list