[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