[master] cb94438 Add std.ip() conversion function
Poul-Henning Kamp
phk at varnish-cache.org
Fri Aug 9 12:24:41 CEST 2013
commit cb94438d7e393dcf4d45db5a66030cb7eb167695
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Fri Aug 9 10:24:32 2013 +0000
Add std.ip() conversion function
diff --git a/bin/varnishtest/tests/m00011.vtc b/bin/varnishtest/tests/m00011.vtc
new file mode 100644
index 0000000..0a7e517
--- /dev/null
+++ b/bin/varnishtest/tests/m00011.vtc
@@ -0,0 +1,28 @@
+varnishtest "Test std.ip"
+
+
+server s1 {
+ rxreq
+ txresp -body "1"
+} -start
+
+
+varnish v1 -vcl+backend {
+
+ import std from "${topbuild}/lib/libvmod_std/.libs/libvmod_std.so" ;
+ sub vcl_deliver {
+ set resp.http.foo0 = std.ip("8.8.8.*", client.ip);
+ set resp.http.foo1 = std.ip("9.9.9.*", server.ip);
+ set resp.http.foo2 = std.ip("1.2.3.*", "127.0.0.2");
+ set resp.http.foo3 = std.ip("1.2.3.5", "127.0.0.3");
+ }
+} -start
+
+client c1 {
+ txreq -url "/foo1"
+ rxresp
+ expect resp.http.foo0 == "127.0.0.1"
+ expect resp.http.foo1 == "127.0.0.1"
+ expect resp.http.foo2 == "127.0.0.2"
+ expect resp.http.foo3 == "1.2.3.5"
+} -run
diff --git a/include/vsa.h b/include/vsa.h
index c9d521a..3ac8eb2 100644
--- a/include/vsa.h
+++ b/include/vsa.h
@@ -30,9 +30,9 @@
#ifndef VSA_H_INCLUDED
#define VSA_H_INCLUDED
-int VSA_Sane(const struct sockaddr_storage *ss);
-socklen_t VSA_Len(const struct sockaddr_storage *ss);
-unsigned VSA_Port(const struct sockaddr_storage *ss);
-int VSA_Compare(const struct sockaddr_storage *ss1, const void *ss2);
+int VSA_Sane(const void *);
+socklen_t VSA_Len(const void *);
+unsigned VSA_Port(const void *);
+int VSA_Compare(const void *, const void *);
#endif
diff --git a/lib/libvarnish/vsa.c b/lib/libvarnish/vsa.c
index 51f214a..1f2a92f 100644
--- a/lib/libvarnish/vsa.c
+++ b/lib/libvarnish/vsa.c
@@ -42,9 +42,11 @@
#include "vsa.h"
int
-VSA_Sane(const struct sockaddr_storage *ss)
+VSA_Sane(const void *s)
{
- switch(ss->ss_family) {
+ const struct sockaddr *sa = s;
+
+ switch(sa->sa_family) {
case PF_INET:
case PF_INET6:
return (1);
@@ -54,9 +56,11 @@ VSA_Sane(const struct sockaddr_storage *ss)
}
socklen_t
-VSA_Len(const struct sockaddr_storage *ss)
+VSA_Len(const void *s)
{
- switch(ss->ss_family) {
+ const struct sockaddr *sa = s;
+
+ switch(sa->sa_family) {
case PF_INET:
return (sizeof(struct sockaddr_in));
case PF_INET6:
@@ -67,29 +71,33 @@ VSA_Len(const struct sockaddr_storage *ss)
}
int
-VSA_Compare(const struct sockaddr_storage *ss1, const void *ss2)
+VSA_Compare(const void *s1, const void *s2)
{
- switch(ss1->ss_family) {
+ const struct sockaddr *sa = s1;
+
+ switch(sa->sa_family) {
case PF_INET:
case PF_INET6:
- return (memcmp(ss1, ss2, VSA_Len(ss1)));
+ return (memcmp(s1, s2, VSA_Len(s1)));
default:
return (-1);
}
}
unsigned
-VSA_Port(const struct sockaddr_storage *ss)
+VSA_Port(const void *s)
{
- switch(ss->ss_family) {
+ const struct sockaddr *sa = s;
+
+ switch(sa->sa_family) {
case PF_INET:
{
- const struct sockaddr_in *ain = (const void *)ss;
+ const struct sockaddr_in *ain = s;
return (ntohs((ain->sin_port)));
}
case PF_INET6:
{
- const struct sockaddr_in6 *ain = (const void *)ss;
+ const struct sockaddr_in6 *ain = s;
return (ntohs((ain->sin6_port)));
}
default:
diff --git a/lib/libvmod_std/vmod.vcc b/lib/libvmod_std/vmod.vcc
index 3238164..1f4e33e 100644
--- a/lib/libvmod_std/vmod.vcc
+++ b/lib/libvmod_std/vmod.vcc
@@ -36,3 +36,4 @@ Function STRING fileread(PRIV_CALL, STRING)
Function DURATION duration(STRING, DURATION)
Function INT integer(STRING, INT)
Function VOID collect(HEADER)
+Function IP ip(STRING, IP)
diff --git a/lib/libvmod_std/vmod_std_conversions.c b/lib/libvmod_std/vmod_std_conversions.c
index c763aa3..b5649b6 100644
--- a/lib/libvmod_std/vmod_std_conversions.c
+++ b/lib/libvmod_std/vmod_std_conversions.c
@@ -33,9 +33,14 @@
#include <math.h>
#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
#include "cache/cache.h"
#include "vrt.h"
+#include "vsa.h"
#include "vcc_if.h"
VCL_DURATION __match_proto__()
@@ -117,3 +122,37 @@ vmod_integer(const struct vrt_ctx *ctx, const char *p, VCL_INT i)
return (r);
}
+
+VCL_IP
+vmod_ip(const struct vrt_ctx *ctx, VCL_STRING s, VCL_IP d)
+{
+ struct addrinfo hints, *res0;
+ const struct addrinfo *res;
+ int error;
+ char *p;
+
+ CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+ AN(d);
+ assert(VSA_Sane(d));
+
+ if (s != NULL) {
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ error = getaddrinfo(s, "80", &hints, &res0);
+ if (!error) {
+ for (res = res0; res != NULL; res = res->ai_next) {
+ if (VSA_Sane(res->ai_addr) &&
+ res->ai_addrlen >= VSA_Len(res->ai_addr)) {
+ d = res->ai_addr;
+ break;
+ }
+ }
+ }
+ }
+ AN(d);
+ p = WS_Alloc(ctx->ws, VSA_Len(d));
+ AN(p);
+ memcpy(p, d, VSA_Len(d));
+ return (p);
+}
More information about the varnish-commit
mailing list