[master] dd0f6a5 Allow comparisons of IP addresses in VCL

Dridi Boukelmoune dridi.boukelmoune at gmail.com
Wed Nov 30 17:01:05 CET 2016


commit dd0f6a5491d8f0753f4af2ec4fc8334f634c7f61
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date:   Wed Nov 30 16:33:12 2016 +0100

    Allow comparisons of IP addresses in VCL
    
    It's a loose comparison of socket addresses, not including the port
    number. But not loose enough to compare IPv4 addresses to v4-mapped
    IPv6 addresses.
    
    Fixes #2142

diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c
index 8a84e10..b829cd9 100644
--- a/bin/varnishd/cache/cache_vrt.c
+++ b/bin/varnishd/cache/cache_vrt.c
@@ -522,3 +522,11 @@ VRT_memmove(void *dst, const void *src, unsigned len)
 
 	(void)memmove(dst, src, len);
 }
+
+int
+VRT_ipcmp(const struct suckaddr *sua1, const struct suckaddr *sua2)
+{
+	if (sua1 == NULL || sua2 == NULL)
+		return(1);
+	return (VSA_Compare_IP(sua1, sua2));
+}
diff --git a/bin/varnishtest/tests/r02142.vtc b/bin/varnishtest/tests/r02142.vtc
new file mode 100644
index 0000000..5100f29
--- /dev/null
+++ b/bin/varnishtest/tests/r02142.vtc
@@ -0,0 +1,20 @@
+varnishtest "Compare IP addresses"
+
+server s1 {
+	rxreq
+	txresp
+} -start
+
+varnish v1 -vcl+backend {
+	sub vcl_deliver {
+		set resp.http.exact-match = (client.ip == remote.ip);
+		set resp.http.loose-match = (client.ip == server.ip);
+	}
+} -start
+
+client c1 {
+	txreq
+	rxresp
+	expect resp.http.exact-match == true
+	expect resp.http.loose-match == true
+} -run
diff --git a/include/vrt.h b/include/vrt.h
index 8aaa551..8668bca 100644
--- a/include/vrt.h
+++ b/include/vrt.h
@@ -299,6 +299,7 @@ void VRT_hashdata(VRT_CTX, const char *str, ...);
 /* Simple stuff */
 int VRT_strcmp(const char *s1, const char *s2);
 void VRT_memmove(void *dst, const void *src, unsigned len);
+int VRT_ipcmp(const struct suckaddr *sua1, const struct suckaddr *sua2);
 
 void VRT_Rollback(VRT_CTX, const struct http *);
 
diff --git a/include/vsa.h b/include/vsa.h
index e692003..c28a7e9 100644
--- a/include/vsa.h
+++ b/include/vsa.h
@@ -36,6 +36,7 @@ extern const int vsa_suckaddr_len;
 int VSA_Sane(const struct suckaddr *);
 unsigned VSA_Port(const struct suckaddr *);
 int VSA_Compare(const struct suckaddr *, const struct suckaddr *);
+int VSA_Compare_IP(const struct suckaddr *, const struct suckaddr *);
 struct suckaddr *VSA_Clone(const struct suckaddr *sua);
 
 const void *VSA_Get_Sockaddr(const struct suckaddr *, socklen_t *sl);
diff --git a/lib/libvarnish/vsa.c b/lib/libvarnish/vsa.c
index 4809dfe..a20d713 100644
--- a/lib/libvarnish/vsa.c
+++ b/lib/libvarnish/vsa.c
@@ -41,6 +41,7 @@
 #include "vas.h"
 #include "vsa.h"
 #include "vrt.h"
+#include "vdef.h"
 #include "miniobj.h"
 
 /*
@@ -315,6 +316,29 @@ VSA_Compare(const struct suckaddr *sua1, const struct suckaddr *sua2)
 	return (memcmp(sua1, sua2, vsa_suckaddr_len));
 }
 
+int
+VSA_Compare_IP(const struct suckaddr *sua1, const struct suckaddr *sua2)
+{
+
+	assert(VSA_Sane(sua1));
+	assert(VSA_Sane(sua2));
+
+	if (sua1->sa.sa_family != sua2->sa.sa_family)
+		return (-1);
+
+	switch(sua1->sa.sa_family) {
+		case PF_INET:
+			return (memcmp(&sua1->sa4.sin_addr,
+			    &sua2->sa4.sin_addr, sizeof(struct in_addr)));
+		case PF_INET6:
+			return (memcmp(&sua1->sa6.sin6_addr,
+			    &sua2->sa6.sin6_addr, sizeof(struct in6_addr)));
+	}
+
+	WRONG("Just plain insane");
+	NEEDLESS_RETURN(-1);
+}
+
 struct suckaddr *
 VSA_Clone(const struct suckaddr *sua)
 {
diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c
index 250a12e..0f6ef44 100644
--- a/lib/libvcc/vcc_expr.c
+++ b/lib/libvcc/vcc_expr.c
@@ -1097,6 +1097,9 @@ static const struct cmps {
 	NUM_REL(REAL),
 	NUM_REL(TIME),
 
+	{IP,		T_EQ,	"!VRT_ipcmp(\v1, \v2)" },
+	{IP,		T_NEQ,	"VRT_ipcmp(\v1, \v2)" },
+
 	{STRING,	T_EQ,	"!VRT_strcmp(\v1, \v2)" },
 	{STRING,	T_NEQ,	"VRT_strcmp(\v1, \v2)" },
 



More information about the varnish-commit mailing list